Skip to content

docs+feat: query schema sanitization contract and skipSanitize option - #3696

Merged
marshallswain merged 6 commits into
dovefrom
docs/query-schema-sanitize-contract
Aug 10, 2026
Merged

marshallswain merged 6 commits into
dovefrom
docs/query-schema-sanitize-contract

Conversation

@marshallswain

@marshallswain marshallswain commented Aug 10, 2026

Copy link
Copy Markdown
Member

Summary

Documents the intentional dual-mode design for restricting external queries, and adds an opt-in to keep both layers when desired.

Design (unchanged by default)

  • Without validateQuery: adapters use the built-in operator/filter allowlist (sanitizeQuery).
  • With validateQuery (default skipSanitize: true): the query schema is the full allowlist; the adapter skips built-in $ operator sanitization for validated queries.

New option

schemaHooks.validateQuery(messageQueryValidator, {
  skipSanitize: false // also run adapter sanitizeQuery
})
  • Default skipSanitize: true preserves current behavior.
  • When false, the query is validated by the schema but not stamped VALIDATED, so the adapter allowlist still runs (defense in depth).
  • Operators allowed in the schema must still be listed on the service operators / filters when using this option.

Docs

  • Dual-mode contract under validateQuery
  • TypeBox footgun: plain Type.Object({ ... }) is permissive under Ajv without additionalProperties: false
  • Security guide, common adapter API, querying, schema helpers

Tests

  • Unit tests for VALIDATED stamping with default and skipSanitize: false
  • Adapter-level test: pass-through schema + skipSanitize: false still rejects $regex
  • Default path: non-standard operators can reach the adapter when sanitization is skipped
  • Mongo flaky-test isolation for validated query coverage

Test plan

  • @feathersjs/schema tests including new skipSanitize integration cases
  • Docs wording consistent with dual-layer opt-in
  • Preview docs anchors for validateQuery / how-queries-are-restricted
  • Confirm default behavior unchanged for generated apps

Clarify that validateQuery and the built-in adapter operator allowlist
are alternative paths: a validated query schema is the full allowlist
and skips sanitizeQuery. Point this out from validators, adapter common
API, querying, schema helpers, and the security guide.
Allow opting into defense in depth: with replaceSanitization: false,
schema validation still runs but the query is not marked VALIDATED, so
adapters continue to enforce their built-in operator and filter allowlist.
Default remains true for backward compatibility.
@marshallswain marshallswain changed the title docs: document query schema vs adapter sanitization contract docs+feat: query schema sanitization contract and replaceSanitization option Aug 10, 2026
Reset shared service options (multi, disableObjectify, paginate) so
earlier suite mutations cannot leave create/find in a bad state, and
assert create actually returned a document before checking $regex.
Shorter option name that matches the behavior: when true (default),
adapter sanitizeQuery is skipped after validateQuery succeeds.
Plain Type.Object without additionalProperties: false omits the keyword,
so Ajv accepts unknown query keys. Call that out for validateQuery
allowlists, querySyntax guidance, and the security guide.
Soften dual-path wording so skipSanitize: false is not contradictory,
clarify validateQuery default options, fix the TypeBox docs link label,
and add adapter-level coverage that skipSanitize: false still rejects
non-allowlisted operators.
@marshallswain marshallswain changed the title docs+feat: query schema sanitization contract and replaceSanitization option docs+feat: query schema sanitization contract and skipSanitize option Aug 10, 2026
@marshallswain
marshallswain merged commit 775ed00 into dove Aug 10, 2026
4 checks passed
@marshallswain
marshallswain deleted the docs/query-schema-sanitize-contract branch August 10, 2026 20:18
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