Node.js+MySQL环境下ProductSearch接口SQL注入演示失败问题求助
/api/productsearch Endpoint Let's walk through why your initial attempt didn't work, then break down how to successfully exploit this vulnerability, and even touch on how to fix it (since that's always good practice for anyone working with databases).
Why Your TRUNCATE Attempt Failed
Your injected string '%'Songs'; TRUNCATE TABLE demo --%' created a syntactically invalid SQL query when spliced into your code. Here's what the final query looked like:
SELECT * FROM products WHERE booktitle like '%'Songs'; TRUNCATE TABLE demo --%'
Notice the mismatched single quotes: after like '%', you have Songs' which leaves an unclosed quote. MySQL throws a syntax error immediately, so the TRUNCATE statement never gets executed. Additionally, by default, Node.js's mysql library disables multi-statement execution (via the multipleStatements flag), so even if your syntax was correct, stacking queries like that would fail out of the box.
How to Successfully Exploit the Vulnerability
Your code uses unvalidated string concatenation to build SQL queries—this is a classic injection vector. Here's how to target it properly:
1. Verify the Vulnerability First
Start with a simple injection to confirm the endpoint is vulnerable. Send this as the booktitle value:
' OR 1=1 --
When spliced into your query, it becomes:
SELECT * FROM products WHERE booktitle like '%' OR 1=1 --%'
- The
%'closes the original single quote from thelikeclause. OR 1=1makes theWHEREcondition always true, so the query returns all rows from theproductstable.--comments out the remaining%'to avoid syntax errors.
If you get all products back, you've confirmed the vulnerability.
2. Execute TRUNCATE TABLE demo (If Multi-Statements Are Enabled)
If your MySQL connection has the multipleStatements: true flag set (uncommon by default), you can use a stacked query. Send this as the booktitle value:
'; TRUNCATE TABLE demo; --
The resulting query becomes:
SELECT * FROM products WHERE booktitle like '%'; TRUNCATE TABLE demo; --%'
%'closes the initiallikequote.- The semicolon ends the
SELECTstatement, then executesTRUNCATE TABLE demo. - The final
--comments out the leftover%'.
3. Workarounds for Default Multi-Statement Disabled
If multipleStatements is off (the default), you can't execute stacked queries directly. But you can still perform other malicious actions:
- UNION Injection: If the
productstable anddemotable have the same number of columns, you can steal data fromdemousing:' UNION SELECT * FROM demo -- - Error-Based Injection: Force MySQL to leak information about the database structure using invalid functions or syntax (e.g.,
' AND (SELECT COUNT(*) FROM information_schema.tables) > 0 --).
Fixing the Vulnerability (Critical!)
To stop this vulnerability entirely, use parameterized queries instead of string concatenation. Here's how to rewrite your endpoint safely:
app.post("/api/productsearch", (req, res) => { const searchTerm = req.body.searchData.booktitle; // Use a placeholder (?) and pass parameters as an array db.query( "SELECT * FROM products WHERE booktitle LIKE ?", [`%${searchTerm}%`], // The library handles escaping automatically (err, result) => { if (err) { console.log(err); } else { res.json(result); } } ); });
Parameterized queries ensure user input is treated as data, not executable SQL, eliminating injection risks entirely.
内容的提问来源于stack exchange,提问作者Nat

