Skip to content

JITSU-27: fix(ingest): sanitize __sql_type hint values on s2s ingest - #1473

Merged
absorbb merged 3 commits into
newjitsufrom
fix/s2s-sql-type-sanitize
Aug 19, 2026
Merged

JITSU-27: fix(ingest): sanitize __sql_type hint values on s2s ingest#1473
absorbb merged 3 commits into
newjitsufrom
fix/s2s-sql-type-sanitize

Conversation

@absorbb

@absorbb absorbb commented Aug 19, 2026

Copy link
Copy Markdown
Contributor

Summary

Implements the s2s action item of JITSU-27 (browser sanitization was already done; the Bulker-side defense-in-depth items moved to JITSU-179).

The s2s ingest path passed __sql_type* type hints through verbatim, and hint values end up interpolated into SQL DDL by bulker. The feature stays available to authenticated s2s callers — prod events_log shows one active customer relying on \"__sql_type_\": \"JSON\" — but hints are now restricted at ingest to their supported use case, mapping a (nested) object to a JSON- or string-typed column:

  • A hint survives only if its value is a single string from a case-insensitive allowlist of bare object/string type names: json, jsonb, string, text, varchar, variant, object, super. Original casing is passed through (ClickHouse types are case-sensitive, e.g. String).
  • No parameters, commas, or expressions — there is no grammar left to abuse in generated DDL.
  • The [castType, ddlType] array form accepted by bulkerlib's extractSQLTypesHints is not allowed through ingest.
  • Malformed hints are dropped silently; the event itself always lands — a bad hint never stalls a pipeline. This also removes a pre-existing s2s crash vector ([] hint → val[0] index-out-of-range panic in processor.go).
  • Browser paths are unchanged (FilterEvent still drops all hints); filterEvent is refactored to a shared predicate walk with identical browser semantics.
  • Wired into both s2s patch sites: patchEvent (modern/batch/pixel/funcs handlers — now a catch-all else so it fails closed) and the classic handler.
  • Richer hints (parameterized types, arrays) can still be produced by transformation functions downstream; JITSU-179 tracks bulker-side filtering/whitelisting as defense in depth for those paths.

Tests

New unit tests in jitsubase/types: sanitizer walk (real customer shape + injection payloads) and validator table (allowlist across casings; rejects for parameterized types, quotes/semicolons/comments, comma injection, arrays, non-strings). go test ./ingest/... ./jitsubase/types/... passes.

🤖 Generated with Claude Code

Browser ingest already drops __sql_type* keys entirely (FilterEvent).
The s2s path kept passing them through verbatim, and hint values end up
in SQL DDL in bulker. Keep the feature for authenticated s2s callers but
allow only type-shaped values: a string (or 1-2 element string array)
matching ^[A-Za-z][A-Za-z0-9 _,()<>]{0,127}$ — no quotes, semicolons,
dashes or slashes, so a hint cannot break out of the type position.
Malformed hints are dropped; the event itself is never rejected.

JITSU-27 (s2s action item; bulker-side expression filter and per-driver
type whitelist remain)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
jitsu-code-review[bot]
jitsu-code-review Bot previously approved these changes Aug 19, 2026

@jitsu-code-review jitsu-code-review Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed the ingest/sql-hint sanitization changes in router.go, router_classic_handler.go, and jitsubase/types/json.go (+ tests). The direction looks good and tests pass locally for touched packages. I left one inline security concern about the current hint regex still permitting DDL breakout tokens in some cases.

Comment thread bulker/jitsubase/types/json.go Outdated
…hints

A separate ddlType is a wider DDL surface (the review bot noted it can
carry a payload independently of the cast type) and has no known
external user — only string hints pass s2s ingest now.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
jitsu-code-review[bot]
jitsu-code-review Bot previously approved these changes Aug 19, 2026

@jitsu-code-review jitsu-code-review Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed the ingest SQL-type sanitization and routing changes in this PR. I found one potential compatibility regression called out inline.

Comment thread bulker/jitsubase/types/json.go Outdated
Replace the type-shape regex with a case-insensitive allowlist of bare
object/string type names (json, jsonb, string, text, varchar, variant,
object, super). The hint's only supported use at ingest is mapping a
nested object to a JSON- or string-typed column; an allowlist leaves no
grammar to abuse in generated DDL (no parameters, commas or
expressions). Original casing is passed through for case-sensitive
drivers like ClickHouse. Richer hints can still be produced by
transformation functions downstream.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

@jitsu-code-review jitsu-code-review Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed bulker/ingest/router.go, bulker/ingest/router_classic_handler.go, and bulker/jitsubase/types/json* for SQL-hint sanitization, ingest-path behavior, and test coverage.

Security hardening direction looks good overall. I left one inline question about a potential silent compatibility regression when invalid hints are now dropped without surfacing an error/warning.

Comment thread bulker/jitsubase/types/json.go

@jitsu-code-review jitsu-code-review Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed the diff in bulker/ingest/router.go, bulker/ingest/router_classic_handler.go, and bulker/jitsubase/types/json*.go with focus on security/correctness regressions around __sql_type* handling.

I also ran go test ./ingest/... ./jitsubase/types/... under bulker/ and both packages passed.

I did not find additional actionable issues beyond the already existing discussion threads.

@absorbb
absorbb merged commit bf20a88 into newjitsu Aug 19, 2026
13 checks passed
@absorbb
absorbb deleted the fix/s2s-sql-type-sanitize branch August 19, 2026 07:35
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