CVE-2015-10017 (Scala, published 2023-01-06T11:15Z)
Description: value: A vulnerability has been found in HPI-Information-Systems ProLOD and classified as critical. This vulnerability affects unknown code. The manipulation of the argument this leads to sql injection. The name of the patch is 3f710905458d49c77530bd3cbcd8960457566b73. It is recommended to apply a patch to fix this issue. The identifier of this vulnerability is VDB-217552.
Severity: nan (CVSS v3 base score: 9.8)
Weakness: CWE-89 \u2014 Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection')
The product constructs all or part of an SQL command using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the intended SQL command when it is sent to a downstream component. Without sufficient removal or quoting of SQL syntax in user-controllable inputs, the generated SQL query can cause those inputs to be interpreted as SQL instead of ordinary user data.
Repository: https://github.com/HPI-Information-Systems/ProLOD
Files changed:
prolod-common/src/main/scala/prolod/common/config/DatabaseConnection.scala
prolod-server/app/controllers/prolod/server/GraphLod.scala
Commit message: validate dataset name to prevent sql injection from this parameter


Vulnerable code:
	def getClusters(s: String, ontologyNamespace : String): Seq[Group] = {
		val table = s
			case e : SqlSyntaxErrorException => println("This dataset has no clusters: " + s)
				println(e.getMessage + System.lineSeparator() + sql.toString)
			case e : SqlSyntaxErrorException => println(e.getMessage)
			case e : SqlSyntaxErrorException => println(e.getMessage)
							case e: SqlException => println(e.getMessage)
									println(e.getMessage)
			val sql = sql"""SELECT ONTOLOGY_NAMESPACE FROM PROLOD_MAIN.SCHEMATA WHERE SCHEMA_NAME = '#${s}'""".as[String]
			case e: SqlException => println(e.getMessage + System.lineSeparator())
			case e: SqlSyntaxErrorException   => println(e.getMessage + System.lineSeparator())
			val sql = sql"""SELECT NAMESPACE FROM PROLOD_MAIN.SCHEMATA WHERE SCHEMA_NAME = '#${s}'""".as[String]
			case e: SqlException => println(e.getMessage + System.lineSeparator())
				val sql = sql"""SELECT COUNT(*) FROM #${dataset}.MAINTABLE as m, #${dataset}.predicatetable as p, #${dataset}.objecttable as o WHERE m.predicate_id = p.id  AND o.tuple_id = m.tuple_id  AND p.predicate = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type' AND o.object = '#${ontologyNamespace}#${cluster.name}'""".as[(Int)]
    val patternDiameter = db.getPatternDiameter(datasetId, data.patterns.last.id)
    data.diameter = patternDiameter

Fixed code:
	def validateDatasetString(table: String) = {
		if(!table.matches("[A-Za-z]+")) {
			throw new RuntimeException("illegal table name: " + table)
		}
	}

	def getClusters(table: String, ontologyNamespace : String): Seq[Group] = {
		validateDatasetString(table)
			case e : SqlSyntaxErrorException => println("This dataset has no clusters: " + table)
		validateDatasetString(dataset)
				println("error getting stats: " + e.getMessage + System.lineSeparator() + sql.toString)
		validateDatasetString(dataset)
			case e : SqlSyntaxErrorException => println("error getting diameter" + e.getMessage)
		validateDatasetString(dataset)
			case e : SqlSyntaxErrorException => println("error getting entity details" + e.getMessage)
		validateDatasetString(name)
							case e: SqlException => println("error inserting pattern: " + e.getMessage)
									println("error inserting pattern (2)" + e.getMessage)
		validateDatasetString(table)
		validateDatasetString(dataset)
		validateDatasetString(name)
			val sql = sql"""SELECT ONTOLOGY_NAMESPACE FROM PROLOD_MAIN.SCHEMATA WHERE SCHEMA_NAME = ${s}""".as[String]
			case e: SqlException => println("error getting ontology namespace: " + e.getMessage + System.lineSeparator())
			case e: SqlSyntaxErrorException   => println("syntax in ontology namespace: " + e.getMessage + System.lineSeparator())
			val sql = sql"""SELECT NAMESPACE FROM PROLOD_MAIN.SCHEMATA WHERE SCHEMA_NAME = ${s}""".as[String]
			case e: SqlException => println("error getting namespace: " + e.getMessage + System.lineSeparator())
		validateDatasetString(name)
		validateDatasetString(dataset)
				val sql = sql"""SELECT COUNT(*) FROM #${dataset}.MAINTABLE as m, #${dataset}.predicatetable as p, #${dataset}.objecttable as o WHERE m.predicate_id = p.id  AND o.tuple_id = m.tuple_id  AND p.predicate = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type' AND o.object = ${ontologyNamespace + cluster.name}""".as[(Int)]
    if(data.patterns.nonEmpty) {
      val patternDiameter = db.getPatternDiameter(datasetId, data.patterns.last.id)
      data.diameter = patternDiameter
    }