Security: Fix CWE-89 (SQL Injection) vulnerability in src/main/java/org/owasp/benchmark/testcode/BenchmarkTest02632.java:77#679
Open
appsecai-app[bot] wants to merge 1 commit intomainfrom
Conversation
Replace string concatenation in PASSWORD field with parameterized query. Both USERNAME and PASSWORD now use bind parameters, preventing SQL injection attacks via the BenchmarkTest02632 query parameter.
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/BenchmarkTest02632.java:77Description: User-controlled input from an HTTPServletRequest flows directly into a SQL query via string concatenation. The PASSWORD field is constructed by concatenating the attacker-controlled
barvariable into the query string, bypassing parameterized query protection. This allows SQL injection attacks that could read, modify, or delete database contents.Why this matters
Risk if not fixed: An attacker could execute arbitrary SQL commands, including:
Risk level: High — Direct SQL injection via string concatenation into an executed PreparedStatement query. Authentication bypass is trivially achievable (e.g., injecting
' OR '1'='1into the PASSWORD field).Why we're changing it
Status: Confirmed vulnerability
Data Flow Analysis:
request.getQueryString()— attacker-controlled HTTP query stringparamis parsed from the query string and URL-decodeddoSomething()routing (lines 93–111):guess = "ABC",switchTarget = guess.charAt(2)→'C'(compile-time constant). The switch falls throughcase 'C':→bar = param(line 106). Tainted input always propagates tobar.USERNAMEis parameterized;PASSWORDis string-concatenated with attacker-controlledbar.PreparedStatementexecutes the hybrid query.Critical finding: The query is a mixed parameterized/vulnerable construction. The
USERNAMEplaceholder provides no protection for thePASSWORDfield. An attacker supplying' OR '1'='1as the query parameter produces:The switch's
'C'branch is always taken (compile-time constant), sobaralways carries the raw user input — no data-flow escape exists.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 Query Parameter<br/>(attacker-controlled)"] --> B["URLDecoder.decode()<br/>param variable"] B --> C["doSomething() switch<br/>case 'C' - bar = param"] C --> D["SQL String Concatenation<br/>PASSWORD='" + bar + "'"] D --> E["PreparedStatement.execute()<br/>Tainted SQL sent to DB"] E --> F["💥 SQL Injection<br/>Arbitrary query execution"] style A fill:#EDE9FE,stroke:#7C3AED style B fill:#EDE9FE,stroke:#7C3AED style C fill:#EDE9FE,stroke:#7C3AED style D fill:#FFE5E5,stroke:#F65A5A style E fill:#FFE5E5,stroke:#F65A5A style F fill:#FEF3C7,stroke:#F59E0BHow we confirmed
Manual verification steps:
BenchmarkTest02632through the coderequest.getQueryString()is parsed intoparamwithout sanitizationdoSomething()uses a compile-time constant (guess.charAt(2)whereguess="ABC") that always evaluates to'C''C'assignsbar = param, making the tainted value reachable at the SQL sink"PASSWORD='" + bar + "'"setString(1, 'foo')is called, leaving the PASSWORD concatenation unparameterized' OR '1'='1and observe that the query structure is alteredRunnable Verification Script (click to expand)
Save this script and run with
bash verify_fix.sh:Vulnerable flow: src/main/java/org/owasp/benchmark/testcode/BenchmarkTest02632.java:77
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 concatenated user-controlled input (
bar) directly into the PASSWORD field via string interpolation:"SELECT * from USERS where USERNAME=? and PASSWORD='" + bar + "'". Although USERNAME was parameterized, the PASSWORD value was not, allowing an attacker to inject arbitrary SQL by crafting a malicious value for theBenchmarkTest02632query parameter (e.g.,' OR '1'='1). ThedoSomething()switch resolves tobar = paramon case 'C', which is the active branch sinceswitchTarget = 'C', making the user input directly reachable at the SQL sink.Fix approach: Replacing the string-concatenated PASSWORD literal with a second positional parameter (
?) and binding the value viastatement.setString(2, bar)ensures the JDBC driver treatsbaras data, never as executable SQL syntax. Parameterized queries are the canonical defense against SQL injection (OWASP Top 10 A03:2021, CWE-89) because the query structure is fixed at prepare-time, making injection structurally impossible regardless of input content.Code change:
Alternatives considered:
Vulnerabilities Addressed
CWE-89
Tainted Sql From Http Request
How we validated it
The fix was validated by:
setString(2, bar)is called to bind the PASSWORD value as data, not SQL syntax' OR '1'='1) to confirm they are treated as literal strings, not SQL operatorsHow to verify
?)statement.setString(2, bar)is called afterstatement.setString(1, "foo")Before you merge
setString()Learn more
This fix was generated by AppSecAI. Please review before merging.