Skip to content

[pulse][taint] add java.sql.Connection SQL injection sinks - #2108

Open
jeremydubreil wants to merge 1 commit into
facebook:mainfrom
jeremydubreil:pulse-jdbc-sql-injection-tests
Open

[pulse][taint] add java.sql.Connection SQL injection sinks#2108
jeremydubreil wants to merge 1 commit into
facebook:mainfrom
jeremydubreil:pulse-jdbc-sql-injection-tests

Conversation

@jeremydubreil

@jeremydubreil jeremydubreil commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

The Java taint test config declares java.sql.Statement.{addBatch, execute, executeQuery, executeUpdate, executeLargeUpdate} as SQL sinks, but nothing on java.sql.Connection. Preparing a statement or a call from a user-controlled string is already an injection, even though the resulting PreparedStatement would be safe if the query were a constant. This kind of taint flow happen surprisingly often in practice. This PR adds prepareStatement and prepareCall as SQLInjection sinks.

The new taint/Jdbc.java exercises them alongside two patterns the Java taint tests did not cover at all:

  • reaching a SQL sink through string concatenation. Services.java passes an endpoint parameter straight to the sink, whereas real injections are almost always built with '+', which javac compiles to Object.makeConcatWithConstants. That is a sanitizer for StringConcatenation only, a kind that no SQL policy lists, so these flows are reported as expected.

  • binding the user-controlled value as a parameter of a constant query, which is the recommended mitigation and must not be reported.

The sinks are pinned to ArgumentPositions [0] rather than left to default to AllArguments so that prepareStatementWithOptionsBad reports once, on the query, and not also on the two int result-set options.

The Java taint test config declares java.sql.Statement.{addBatch, execute,
executeQuery, executeUpdate, executeLargeUpdate} as SQL sinks, but nothing on
java.sql.Connection. Preparing a statement or a call from a user-controlled
string is already an injection, even though the resulting PreparedStatement
would be safe if the query were a constant, so add prepareStatement and
prepareCall as SQLInjection sinks.

The new taint/Jdbc.java exercises them alongside two patterns the Java taint
tests did not cover at all:

  - reaching a SQL sink through string concatenation. Services.java passes an
    endpoint parameter straight to the sink, whereas real injections are
    almost always built with '+', which javac compiles to
    Object.makeConcatWithConstants. That is a sanitizer for
    StringConcatenation only, a kind that no SQL policy lists, so these flows
    are reported as expected.

  - binding the user-controlled value as a parameter of a constant query,
    which is the recommended mitigation and must not be reported.

The sinks are pinned to ArgumentPositions [0] rather than left to default to
AllArguments so that prepareStatementWithOptionsBad reports once, on the query,
and not also on the two int result-set options.
@meta-cla meta-cla Bot added the CLA Signed label Aug 31, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant