04 ORDER BY injection
Retry rescuedSuper · run 2 · AI test + retries · 6668 tokens · 29s
The first test only checked that an unknown column raises ValueError, which is not an injection test, and was rejected. The second attempt used a weaker username-DESC test. The hidden oracle, which tries canary payloads, confirmed the final patch.
Attack test written by the AI
import unittest
from app import make_db, list_users
class TestSQLInjection(unittest.TestCase):
def setUp(self):
# Create an in-memory database for each test.
self.conn = make_db()
def _get_usernames(self, rows):
"""Helper to extract usernames from query result rows."""
return [row[1] for row in rows]
def test_order_by_injection_is_prevented(self):
# If the sort_by parameter is directly concatenated into the ORDER BY clause,
# supplying a value like "username DESC" will change the sort order.
# A fixed implementation should restrict sort_by to a whitelist of safe column
# names (e.g., only "username", "email", "id") and ignore or safely handle
# any other input, thus preserving the default ascending username order.
rows = list_users(self.conn, "username DESC")
usernames = self._get_usernames(rows)
# Expected order when injection is prevented (or input is sanitized):
self.assertEqual(usernames, ["alice", "bob", "carol"])
if __name__ == "__main__":
unittest.main()
Patch
--- vulnerable app.py+++ patched app.py@@ -19,6 +19,9 @@def list_users(conn, sort_by="username"):- # VULNERABLE: sort_by is pasted directly into the ORDER BY clause- query = "SELECT id, username, email FROM users ORDER BY " + sort_by+ # Whitelist allowed column names to prevent SQL injection+ allowed_columns = {"username", "email", "id"}+ if sort_by not in allowed_columns:+ sort_by = "username"+ query = f"SELECT id, username, email FROM users ORDER BY {sort_by}"return conn.execute(query).fetchall()