From Vulnerability Finding to Verified Patch
Storefront API endpoint, exploitable SQL injection vulnerability, and complete verification test evidence.
Finding & Exploit Evidence
Category filter bypassed via SQL injection vulnerability.
The API directly concatenates the category parameter into the raw SQL query. A crafted input payload alters query semantics, bypassing the filter and returning all records in the fixture.
src/api/products.ts:6GET /api/products?category=books'%20OR%20'1'%3D'1
category = "books' OR '1'='1"Filter bypass reproduced (vulnerability confirmed).
Input handled as bound literal (exploit neutralized).
Root Cause Analysis
String concatenation mixes untrusted user input directly with executable SQL syntax. Quoting input is ineffective: an injected apostrophe terminates the literal string, and the appended OR clause evaluates to true for all rows. The correct fix decouples SQL statement structure from bound parameter values.
Synthesized Fix
The concatenated query was replaced with a parameterized prepared statement. The API response contract and legitimate category filtering behavior remain unchanged.
Before
const query = `SELECT * FROM products WHERE category = '${category}'`;
const products = await database.query(query);After
const query = 'SELECT * FROM products WHERE category = ?';
const products = await database.query(query, [category]);Regression Test Results
Executed in an isolated, in-memory SQLite test fixture. The exploit was reproduced prior to patching, and the modified query passed all four regression checks below.
- Injection payload treated as literal data
0 rows - Standard category query returns expected records
1 rows - Category with apostrophe filters correctly
1 rows - Nonexistent category returns empty array
0 rows
Verified scope: this query and its four regression cases. This is not a whole-project security certification.
Branch Handoff
Dedicated Git branch prepared for this fix. Review the diff and test results before merging into main.
main → rehabilty/fix-product-queryExample branch name for illustration; no remote customer repository was modified.