Skip to content

fix(security): escape SQL identifiers in migrate.ts and searchDocs.ts#104

Open
xiaolai wants to merge 1 commit into
timescale:mainfrom
xiaolai:fix/nlpm-sql-identifier-escaping
Open

fix(security): escape SQL identifiers in migrate.ts and searchDocs.ts#104
xiaolai wants to merge 1 commit into
timescale:mainfrom
xiaolai:fix/nlpm-sql-identifier-escaping

Conversation

@xiaolai
Copy link
Copy Markdown

@xiaolai xiaolai commented Apr 20, 2026

Automated audit: This PR was generated by NLPM, a natural language programming linter, running via claude-code-action. Please evaluate the diff on its merits.

Bug

DB_SCHEMA (sourced from process.env.DB_SCHEMA) and schema/entityPrefix (in searchDocs.ts) were interpolated directly into SQL template literals as unquoted identifiers. If a schema name contains double-quote characters or other SQL metacharacters, the generated SQL can break or behave unexpectedly.

Affected lines (before this PR):

  • src/migrate.ts lines 37, 42, 51: CREATE SCHEMA IF NOT EXISTS ${schema}, CREATE TABLE IF NOT EXISTS ${schema}.migrations, SELECT set FROM ${schema}.migrations
  • src/apis/searchDocs.ts lines 149–155: FROM ${schema}.${entityPrefix}_chunks, JOIN ${schema}.${entityPrefix}_pages

Fix

  • src/migrate.ts: Call client.escapeIdentifier(schema) once at the top of the load method and use the result throughout (the pg Client class provides this method).
  • src/apis/searchDocs.ts: Add a minimal inline helper escId = (name) => '"' + name.replace(/"/g, '""') + '"' (the standard SQL identifier quoting rule) and use it for both schema and entityPrefix in the FROM/JOIN clauses.

entityPrefix is already constrained to an enum-derived set of safe values, so the practical injection risk is low — but quoting both identifiers consistently is good defence-in-depth.

Why it matters

The DB_SCHEMA value is operator-supplied configuration. A schema name like public" CASCADE; DROP TABLE migrations; -- would produce malformed SQL without quoting. The fix is a one-liner using the standard pg escaping API.

DB_SCHEMA (migrate.ts) and schema/entityPrefix (searchDocs.ts) were
interpolated directly into SQL as unquoted identifiers. Use
client.escapeIdentifier() in migrate.ts and a local escId() helper
in searchDocs.ts so names containing SQL metacharacters cannot break
queries.

Co-Authored-By: Claude Code <noreply@anthropic.com>
@CLAassistant
Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

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.

3 participants