Security: Fix CWE-89 (SQL Injection) vulnerability in src/main/java/org/owasp/benchmark/testcode/BenchmarkTest02355.java:67#666
Open
appsecai-app[bot] wants to merge 1 commit intomainfrom
Conversation
Replace string concatenation in PASSWORD clause with parameterized placeholder. Bind user-controlled bar variable via setString(2, bar) to prevent SQL injection. Fixes 1 SQL injection vulnerability detected by OpenGrep.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What we found
69c734ebsrc/main/java/org/owasp/benchmark/testcode/BenchmarkTest02355.java:67Description: Detected input from an HTTPServletRequest flowing into a SQL sink without proper parameterization. The PASSWORD clause of a SQL query is constructed via string concatenation with user-controlled input, allowing SQL injection attacks.
Why this matters
Risk if not fixed: An attacker could read, modify, or delete database contents, bypass authentication, execute administrative operations, or in some cases execute operating system commands.
Risk level: High - Direct database access with authentication bypass potential
Attack scenario: An attacker supplies a malicious HTTP parameter name such as
' OR '1'='1which flows through the application logic and is concatenated into the PASSWORD clause. This breaks out of the string literal and alters the query's WHERE clause logic, allowing unauthorized database access.Why we're changing it
Status: Confirmed vulnerability
Data flow analysis:
paramis assigned the HTTP parameter name (not value) fromrequest.getParameterNames()— attacker-controlled input.doSomething): Constructs["safe", param, "moresafe"], removes index 0, returns index 0 — which isparamunchanged. No sanitization occurs.bar(the unmodifiedparam) is concatenated directly into the SQL string:PreparedStatementis created andsetString(1, "foo")binds only theUSERNAMEplaceholder. ThePASSWORDclause is not parameterized — it contains the raw concatenated string.The
PreparedStatementprovides zero protection here because parameterization was applied toUSERNAME=?butPASSWORD='<bar>'is already baked into the SQL string beforeprepareStatement()is called. An attacker supplies a parameter name like' OR '1'='1to break out of the password literal and alter query semantics.Vulnerability Flow Diagram
%%{init: {'theme':'base','themeVariables':{'fontFamily':'ui-sans-serif, Inter, system-ui, sans-serif','primaryColor':'#EDE9FE','primaryTextColor':'#1A1A2E','primaryBorderColor':'#7C3AED','lineColor':'#5B21B6','secondaryColor':'#FEF3C7','tertiaryColor':'#DCFCE7'}}}%% flowchart TD A["HTTP Request Parameter Name<br/>(Attacker-Controlled)"] --> B["param = request.getParameterNames()"] B --> C["doSomething() returns param<br/>(No Sanitization)"] C --> D["bar = param"] D --> E["String Concatenation:<br/>PASSWORD='" + bar + "'"] E --> F["SQL String Built Before<br/>prepareStatement()"] F --> G["❌ PreparedStatement Too Late<br/>Structure Already Compromised"] G --> H["💥 SQL Injection Possible<br/>Query Logic Altered"] style A fill:#EDE9FE,stroke:#7C3AED style E fill:#FFE5E5,stroke:#F65A5A style G fill:#FEF3C7,stroke:#F59E0B style H fill:#FEF3C7,stroke:#F59E0BHow we confirmed
request.getParameterNames()throughdoSomething()which performs no transformationbar(containing the parameter name) is concatenated directly into the SQL string at line 62prepareStatement()is called after string concatenation, making parameterization ineffective for the PASSWORD clausesetString(1, "foo"), leaving PASSWORD unprotectedVulnerability Flow Diagram
See diagram above under "Why we're changing it".
Vulnerable flow: src/main/java/org/owasp/benchmark/testcode/BenchmarkTest02355.java:67
SQL Injection
%%{init: {'theme':'base','themeVariables':{'fontFamily':'ui-sans-serif, Inter, system-ui, sans-serif','primaryColor':'#EDE9FE','primaryTextColor':'#1A1A2E','primaryBorderColor':'#7C3AED','lineColor':'#5B21B6','secondaryColor':'#FEF3C7','tertiaryColor':'#DCFCE7'}}}%% flowchart TD subgraph Vulnerable["❌ Vulnerable Flow"] direction LR A1["Project"] --> A2["SQL string concatenation with user input"] A2 --> A3["💥 Database Compromised"] end Vulnerable ~~~ Fixed subgraph Fixed["✅ Fixed Flow"] direction LR B1["Project"] --> B2["Parameterized queries/ORM used"] B3["🛡️ Attack Blocked"] B2 --> B3 end style A2 fill:#FFE5E5,color:#000 style A3 fill:#ffa94d,color:#000 style B2 fill:#74c0fc,color:#000 style B3 fill:#DCFCE7,color:#000How we fixed it
Root cause: The SQL query used a parameterized placeholder for the USERNAME field but concatenated the user-controlled
barvariable directly into the PASSWORD field via string interpolation.Fix approach: Replacing the string concatenation in the PASSWORD clause with a second parameterized placeholder (
?) and bindingbarviastatement.setString(2, bar)ensures the JDBC driver treats the value as a literal string regardless of its content. Parameterized queries separate SQL structure from data at the protocol level, making SQL injection structurally impossible for bound parameters.Changes made:
Line 62 now reads:
And
statement.setString(2, bar)binds the user-supplied value as data rather than SQL syntax:Alternatives considered:
bar— rejected because it is a secondary defense that does not replace parameterization and would require knowing all valid input valuesVulnerabilities Addressed
CWE-89
Tainted Sql From Http Request
How we validated it
setString()calls' OR '1'='1,; DROP TABLE USERS; --) to ensure they are treated as literal stringsHow to verify
?placeholdersstatement.setString(1, "foo")andstatement.setString(2, bar)are both presentprepareStatement()callRunnable Verification Script (click to expand)
Save this script and run with
bash verify_fix.sh:Before you merge
Learn more
This fix was generated by AppSecAI. Please review before merging.