Skip to content

GetToolNamesLike: escape LIKE metacharacters in fragment #18

Description

@detour1999

Follow-up to PR #10.

internal/db/turns.go:325 builds a LIKE query with the user-supplied fragment inserted verbatim between two % wildcards:

```go
rows, err := db.Query(`
SELECT DISTINCT tool_name
FROM tool_uses
WHERE tool_name LIKE '%' || ? || '%'
ORDER BY tool_name
LIMIT ?`, fragment, limit)
```

If `fragment` contains `%` or `_` (SQLite LIKE metacharacters), they leak into the pattern:

  • `tool:foo_bar` → matches `tool_name LIKE '%foo_bar%'` which treats `_` as a single-char wildcard, matching `foolbar`, `fooxbar`, etc.
  • `tool:100%` → `'%100%%'` behaves as `starts with anything containing 100`.

Real tool names in ccvault don't contain these characters today (`Bash`, `Read`, `mcp__foo__bar`, etc.), so the practical exposure is essentially zero. But the hygiene should be there.

Fix

Escape `%`, `_`, and `\` in `fragment` before passing to LIKE, and add `ESCAPE '\\'` clause. Or use `INSTR(tool_name, ?)` which does not interpret metacharacters at all — arguably cleaner for a substring search.

Test

Add a case to `TestDB_GetToolNamesLike` in `internal/db/db_test.go` that seeds `toolX`, `toolY`, `toolZ`, queries with fragment `_`, and asserts zero results.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions