Skip to content

Fix for DML queries - #685

Open
vikasrathee-cs wants to merge 2 commits into
data-integrations:developfrom
cloudsufi:sql-injection-fix
Open

vikasrathee-cs wants to merge 2 commits into
data-integrations:developfrom
cloudsufi:sql-injection-fix

Conversation

@vikasrathee-cs

Copy link
Copy Markdown
Contributor

Fix for DML queries

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request enhances security and robustness across multiple database connectors by implementing SQL identifier quoting and escaping using SqlIdentifierUtils to prevent SQL injection. It also introduces read-only connection wrapping for data sampling operations and adds metadata-based table validation before query execution. Feedback on these changes highlights a potential connection leak in AbstractDBSpecificConnector.getConnection if wrapping the connection fails, as well as potential validation failures in validateTable for databases that do not support catalogs or have mismatched database names.

Comment on lines +160 to +169
protected Connection getConnection(String connectionString, Properties connectionArguments) {
Connection connection = super.getConnection(connectionString, connectionArguments);
try {
return ReadOnlyConnection.wrap(connection);
} catch (SQLException e) {
throw new IllegalArgumentException(String.format(
"Failed to open a read-only connection to database via connection string: %s. Error: %s.",
connectionString, ExceptionUtils.getRootCauseMessage(e)), e);
}
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

If ReadOnlyConnection.wrap(connection) throws a SQLException, the connection opened by super.getConnection(connectionString, connectionArguments) is leaked because it is not closed before throwing the IllegalArgumentException. We should close the connection in the catch block to prevent resource leaks.

  @Override
  protected Connection getConnection(String connectionString, Properties connectionArguments) {
    Connection connection = super.getConnection(connectionString, connectionArguments);
    try {
      return ReadOnlyConnection.wrap(connection);
    } catch (SQLException e) {
      if (connection != null) {
        try {
          connection.close();
        } catch (SQLException closeEx) {
          e.addSuppressed(closeEx);
        }
      }
      throw new IllegalArgumentException(String.format(
        "Failed to open a read-only connection to database via connection string: %s. Error: %s.",
        connectionString, ExceptionUtils.getRootCauseMessage(e)), e);
    }
  }

Comment on lines +179 to +188
protected void validateTable(Connection connection, @Nullable String database, @Nullable String schema,
String table) throws SQLException {
try (ResultSet tables = connection.getMetaData().getTables(database, schema, table, null)) {
if (!tables.next()) {
throw new IllegalArgumentException(
schema == null ? String.format("Table '%s' does not exist.", table)
: String.format("Table '%s' does not exist in schema '%s'.", table, schema));
}
}
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

Passing the database parameter to connection.getMetaData().getTables(...) can cause validation to fail on databases that do not support catalogs (such as Oracle) or when the database name in the path does not match the physical database catalog name (such as in PostgreSQL/Redshift where cross-database queries are not supported and the database name is omitted from the table name).

Consider overriding validateTable in those specific connectors (e.g., OracleConnector, PostgresConnector, RedshiftConnector) to pass null for the database parameter, or handle it generically.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant