CVE-2022-4963 (published 2024-03-21T02:44Z)

A vulnerability was found in Folio Spring Module Core up to 1.1.5. It has been rated as critical. Affected by this issue is the function dropSchema of the file tenant/src/main/java/org/folio/spring/tenant/hibernate/HibernateSchemaService.java of the component Schema Name Handler. The manipulation leads to sql injection. Upgrading to version 2.0.0 is able to address this issue. The name of the patch is d374a5f77e6b58e36f0e0e4419be18b95edcd7ff. It is recommended to upgrade the affected component. The identifier of this vulnerability is VDB-257516.


Weakness information:
cwe_id: CWE-89
cwe_name: Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection')
description: 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.
extended_description: 
            
            
         
         

Fix information:
repo_url: https://github.com/folio-org/spring-module-core
commit_details: repo_url: https://github.com/folio-org/spring-module-core
author: Julian Ladisch
author_date: 2022-11-21 18:46:32+01:00
msg: FOLIO-3645: schema name SQL injection

SELECT EXISTS now uses a prepared statement.

PostgreSQL doesn't support a prepared statement for CREATE SCHEMA and DROP SCHEMA.
Instead we validate the schema name before use to mitigate any SQL injection attack.
repository: repo_url: https://github.com/folio-org/spring-module-core
repo_name: folio-org/spring-module-core
description: Spring module core libraries for Spring development with Okapi
repo_language: Java
owner: folio-org
file_changes: filename: HibernateSchemaService.java
change_type: ModificationType.MODIFY
diff: @@ -6,6 +6,7 @@ import java.io.IOException;
 import java.nio.charset.StandardCharsets;
 import java.sql.Connection;
 import java.sql.DriverManager;
+import java.sql.PreparedStatement;
 import java.sql.ResultSet;
 import java.sql.SQLException;
 import java.sql.Statement;
@@ -41,8 +42,6 @@ import org.springframework.core.io.ResourceLoader;
 import org.springframework.core.type.filter.AnnotationTypeFilter;
 import org.springframework.stereotype.Service;
 
-import static org.hibernate.cfg.AvailableSettings.*;
-
 @Service("hibernateSchemaService")
 public class HibernateSchemaService implements InitializingBean {
 
@@ -177,9 +176,10 @@ public class HibernateSchemaService implements InitializingBean {
   }
 
   private boolean schemaExists(Connection connection, String schema) throws SQLException {
-    try (Statement statement = connection.createStatement()) {
-      String queryTemplate = "SELECT EXISTS(SELECT 1 FROM information_schema.schemata WHERE schema_name = '%s');";
-      ResultSet resultSet = statement.executeQuery(String.format(queryTemplate, schema));
+    String sql = "SELECT EXISTS(SELECT 1 FROM information_schema.schemata WHERE schema_name = ?)";
+    try (PreparedStatement statement = connection.prepareStatement(sql)) {
+      statement.setString(1, schema);
+      ResultSet resultSet = statement.executeQuery();
       if (resultSet.next()) {
         return resultSet.getBoolean(1);
       }

programming_language: Java
filename: SchemaService.java
change_type: ModificationType.MODIFY
diff: @@ -1,5 +1,6 @@
 package org.folio.spring.tenant.service;
 
+import java.util.regex.Pattern;
 import org.folio.spring.tenant.properties.BuildInfoProperties;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
@@ -7,11 +8,17 @@ import org.springframework.stereotype.Service;
 @Service
 public class SchemaService {
 
+  private static final Pattern SCHEMA_REGEXP = Pattern.compile("[a-zA-Z0-9_]+");
+
   @Autowired
   private BuildInfoProperties buildInfoProperties;
 
   public String getSchema(String tenant) {
-    return String.format("%s_%s", tenant, buildInfoProperties.getArtifact()).replace("-", "_");
+    var schema = String.format("%s_%s", tenant, buildInfoProperties.getArtifact()).replace("-", "_");
+    if (! SCHEMA_REGEXP.matcher(schema).matches()) {
+      throw new IllegalArgumentException("Illegal character in schema name: " + schema);
+    }
+    return schema;
   }
 
 }

programming_language: Java