External control of database configuration

External control of database configuration

Description

Selecting a database connection’s catalog from unvalidated input can make the application operate on unintended data. Support for java.sql.Connection.setCatalog() and its behavior depend on the driver. Changing the catalog does not itself increase the database account’s permissions, but may direct reads or writes to other data that account can access.

Potential impact

  • Unintended data access: Queries or updates may target the wrong database data.
  • Service disruption: Selecting a nonexistent database may cause requests to fail.
  • Broken access boundaries: If the application account can access several catalogs, user or tenant data may no longer be separated correctly.

Remediation

  1. Use application-controlled database settings.
  2. Select only from a server-owned allow-list, and verify that the current user is authorized to access the selected catalog.
  3. Keep connection configuration fixed when dynamic selection is unnecessary. Otherwise check per-request authorization and connection-pool state reset so settings do not carry into the next request.

Examples

These excerpts use Java 9 or later and the javax.servlet API. The sample allow-list assumes every caller may access both catalogs; add a separate authorization check when permissions differ by user.

Before

java
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import javax.servlet.http.HttpServletRequest;

public class UnsafeDatabaseConfig {
    public void setDatabase(HttpServletRequest request, Connection connection) throws SQLException {
        String catalog = request.getParameter("db"); // Use input directly.
        connection.setCatalog(catalog);
    }
}

After

java
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Set;
import javax.servlet.http.HttpServletRequest;

public class SafeDatabaseConfig {
    private static final Set<String> ALLOWED_CATALOGS = Set.of("main_db", "backup_db");

    public void setDatabase(HttpServletRequest request, Connection connection) throws SQLException {
        String catalog = request.getParameter("db");

        if (catalog == null || !ALLOWED_CATALOGS.contains(catalog)) {
            throw new SecurityException("Invalid database selection");
        }

        connection.setCatalog(catalog);
    }
}

Explanation:

  • Before: Passes input directly to setCatalog(), allowing an unintended selection within the driver’s capabilities and the account’s permissions.
  • After: Defines ALLOWED_CATALOGS and calls setCatalog() only for a non-null value in that set.

References