Description
The GET /history/search endpoint passes the q query parameter directly to an FTS5 MATCH expression without sanitization. FTS5's MATCH operates on search expression strings (not quoted SQL literals), so characters like ", (, ), *, ^, - can change query semantics, cause syntax errors, or return unintended results.
Steps to Reproduce
- Call
GET /history/search?q=" — the double-quote character causes an FTS5 syntax error
- The endpoint returns HTTP 500 with a traceback, confirming the injection
Expected Behavior
All special FTS5 characters should be escaped or the query should be passed through a safe text-to-FTS5 conversion (e.g., plaintofts5).
Actual Behavior
FTS5 syntax errors propagate as 500 Internal Server Errors, leaking internal implementation details.
Affected Files
backend/app/services/database.py:96 — WHERE fts_history MATCH ? directly uses unsanitized input
backend/app/routers/history.py:52 — q: str = Query(..., min_length=1) with no max_length or escaping
Labels
type:bug, level:intermediate, gssoc2026
Description
The
GET /history/searchendpoint passes theqquery parameter directly to an FTS5MATCHexpression without sanitization. FTS5's MATCH operates on search expression strings (not quoted SQL literals), so characters like",(,),*,^,-can change query semantics, cause syntax errors, or return unintended results.Steps to Reproduce
GET /history/search?q="— the double-quote character causes an FTS5 syntax errorExpected Behavior
All special FTS5 characters should be escaped or the query should be passed through a safe text-to-FTS5 conversion (e.g.,
plaintofts5).Actual Behavior
FTS5 syntax errors propagate as 500 Internal Server Errors, leaking internal implementation details.
Affected Files
backend/app/services/database.py:96—WHERE fts_history MATCH ?directly uses unsanitized inputbackend/app/routers/history.py:52—q: str = Query(..., min_length=1)with no max_length or escapingLabels
type:bug, level:intermediate, gssoc2026