Skip to content

RAG-NOJIRA: validate structured SQL fragments - #169

Merged
G4brym merged 6 commits into
mainfrom
G4brym/RAG-NOJIRA-harden-sql-fragments
Jul 24, 2026
Merged

RAG-NOJIRA: validate structured SQL fragments#169
G4brym merged 6 commits into
mainfrom
G4brym/RAG-NOJIRA-harden-sql-fragments

Conversation

@G4brym

@G4brym G4brym commented Jul 24, 2026

Copy link
Copy Markdown
Owner

Summary

  • validate structural identifiers, join/conflict/set-operation enums, ordering, limits, and offsets before generating SQL
  • preserve existing fields SQL expressions without requiring Raw
  • bind ordinary values while inlining explicit Raw values in data, WHERE, and HAVING parameters
  • keep parameter identity consistent across D1, Durable Objects SQLite, and PostgreSQL, including raw SQL containing ? operators
  • add focused injection and placeholder regression coverage

Compatibility

Existing field expressions and all pre-existing tests remain unchanged. Raw is only needed when a value passed through a parameter position should be inlined instead of bound.

Verification

  • npm run lint
  • npm test
  • npm run build
  • npm run docs:build
  • git diff --check

G4brym added 6 commits July 24, 2026 09:01
Reject unsafe identifiers and clause values at runtime while requiring Raw for trusted inline SQL expressions.
Keep existing field SQL strings unchanged while binding ordinary clause values and inlining explicit Raw parameters with dialect-safe placeholder tracking.
@G4brym
G4brym merged commit 5c9bdc0 into main Jul 24, 2026
5 checks passed
@G4brym
G4brym deleted the G4brym/RAG-NOJIRA-harden-sql-fragments branch July 24, 2026 13:14
@github-actions github-actions Bot mentioned this pull request Jul 24, 2026
G4brym pushed a commit that referenced this pull request Jul 24, 2026
This PR was opened by the [Changesets
release](https://github.com/changesets/action) GitHub action. When
you're ready to do a release, you can merge this and the packages will
be published to npm automatically. If you're not ready to do a release
yet, that's fine, whenever you add more changesets to main, this PR will
be updated.


# Releases
## workers-qb@1.15.0

### Minor Changes

- [#169](#169)
[`5c9bdc0`](5c9bdc0)
Thanks [@G4brym](https://github.com/G4brym)! - Harden structured SQL
inputs against injection while preserving existing `fields` expressions.
Table and column identifiers, aliases, CTE names, join types and
conditions, conflict modes, set operations, ordering, limits, and
offsets are now validated before SQL generation.

Bound values now receive unique parameter positions across CTEs,
subqueries, `WHERE`, and `HAVING`. Queries that previously reused the
same numbered position across clauses may consume more bound-parameter
slots; D1 and SQLite-backed Durable Objects allow up to 100 per query.

  ## Upgrade notes

- Existing SQL expressions passed through `fields` continue to work
without changes.
- Plain `groupBy`, `distinct`, and `returning` values must be
identifiers. Plain `orderBy` values must be identifiers with an optional
`ASC` or `DESC` direction, and join conditions must use simple
comparisons joined by `AND` or `OR`. Wrap more complex, trusted
expressions in `Raw`.
- Ordinary `WHERE` and `HAVING` values remain bound parameters. Passing
`Raw` in a parameter position now explicitly inlines trusted SQL and
must never be used with request-controlled input.
- Split or batch D1 and Durable Object queries that can exceed 100
independently supplied bound values.
- Custom database adapters must execute `query.toStatement('sqlite')` or
`query.toStatement('postgres')` instead of `query.query` so nested
parameters retain unique binding positions.

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
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