Skip to content

Escape user search filters#404

Open
jsdavid278-cyber wants to merge 2 commits into
profullstack:masterfrom
jsdavid278-cyber:codex/users-search-escape
Open

Escape user search filters#404
jsdavid278-cyber wants to merge 2 commits into
profullstack:masterfrom
jsdavid278-cyber:codex/users-search-escape

Conversation

@jsdavid278-cyber
Copy link
Copy Markdown
Contributor

Fixes /api/users/search treating %, _, comma, and dot characters in username prefixes as PostgREST/LIKE syntax. The endpoint now escapes the query before passing it to ilike so usernames are matched literally while preserving the existing prefix-search behavior.

Validation:

  • vitest run src/app/api/users/search/route.test.ts
  • tsc --noEmit

@greptile-apps
Copy link
Copy Markdown

greptile-apps Bot commented Jun 4, 2026

Greptile Summary

This PR closes a wildcard-injection gap in /api/users/search by adding * (PostgREST's % alias) to the characters escaped by escapePostgrestSearchValue, and wires that function into the route before it builds the ilike pattern.

  • sanitize.ts: Regex updated from /[\\%_,().]/g to /[\\%*_,().]/g; JSDoc extended to document the * alias. All other callers (/api/search, /api/skills, /api/affiliates/offers) benefit automatically.
  • route.ts: query is now run through escapePostgrestSearchValue before being appended with % for the prefix search.
  • route.test.ts: New test verifies end-to-end escaping of %, *, _, ,, and . against the mocked Supabase ilike call. The sanitize.test.ts unit test was not updated to include *, leaving a small coverage gap there.

Confidence Score: 5/5

Safe to merge — the change is a one-character addition to a regex that is already well-guarded by the surrounding escaping logic and has end-to-end test coverage.

The fix is minimal and correct: adding * to the single-pass escape regex plugs the only remaining wildcard gap without touching any other behavior. The route integration test now exercises all five previously-problematic characters, and all other callers of the shared function gain the fix automatically.

No files require special attention. The only follow-up worth doing is updating the sanitize.test.ts unit test to cover * directly on the escape function.

Important Files Changed

Filename Overview
src/lib/security/sanitize.ts Adds * to the escape regex in escapePostgrestSearchValue; all other escaped characters are unchanged and the single-pass regex replacement is correct.
src/app/api/users/search/route.ts Wires in escapePostgrestSearchValue before the ilike call; no other logic changes.
src/app/api/users/search/route.test.ts New test exercises %, *, _, ,, and . escaping end-to-end through the route; test URL and expected value are correct.

Sequence Diagram

sequenceDiagram
    participant Client
    participant Route as GET /api/users/search
    participant Escape as escapePostgrestSearchValue
    participant Supabase

    Client->>Route: "?q=user%*input_,v1.2"
    Route->>Route: "URL-decode → "user%*input_,v1.2""
    Route->>Escape: "escapePostgrestSearchValue("user%*input_,v1.2")"
    Escape-->>Route: "user\%\*input\_\,v1\.2"
    Route->>Supabase: ".ilike("username", "user\%\*input\_\,v1\.2%")"
    Supabase-->>Route: matching rows (literal prefix only)
    Route-->>Client: "{ users: [...] }"
Loading

Reviews (2): Last reviewed commit: "Escape user search wildcard aliases" | Re-trigger Greptile

Comment thread src/app/api/users/search/route.test.ts
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant