Please do not open a public issue.
Use GitHub's private vulnerability reporting — the Security tab of this repository, then Report a vulnerability. That opens a private thread visible only to the maintainer.
If that is unavailable to you, email sain.abdallah@gmail.com with siftql security in the subject.
Please include a runnable repro: the query, the input it runs against, the options passed, and what happens. For anything resource-related, the input size and the observed time or memory matter — a report saying "this is slow" without a measurement is hard to act on.
I will acknowledge a report and say whether it is in scope. This is a personal project, not a funded one, so I cannot promise a response time; I can promise that I will not quietly ignore it.
Fixes land on the latest 0.x release. There is no back-porting to earlier
0.x versions — while the API is still settling, the supported version is the
most recent one.
siftql parses untrusted query text and evaluates it against untrusted data, so input-driven failures are the interesting ones:
- Denial of service — any input, query or record, that causes runaway time
or memory, with
regexGuardleft at its default. The regex engine is a Thompson NFA rather than a backtracking matcher specifically so a user-supplied pattern cannot blow up; a pattern that defeats that is in scope, as is any query that gets past the structural limits insrc/limits.ts. - Prototype pollution or any write to an object the caller did not hand in.
- Escaping the failure boundary — a raw
RangeError, a stack overflow, or any error that is not aSiftQLErrorreaching the caller. - Cross-engine leakage — one
createEngine()instance observing or altering another's registry or options. - A silently wrong answer driven by crafted input: a record that matches when it should not, or a permissive clause surviving a filter that should have dropped it. This package exists to avoid quiet wrongness, so treat it with the same seriousness as a crash.
- Backtracking under
regexGuard: false. That option runs patterns this matcher refuses onRegExpinstead, so catastrophic backtracking comes back with it — a 17-character pattern can take seconds. The default refuses those patterns; turning the guard off is an explicit acceptance ofRegExp's cost model, not a defect. spans()reporting no ranges on a pattern that matches everywhere. A step budget caps that walk, so its measured cost is linear; past the budget it returns no positions and the highlight names the field without underlining inside it. Recorded under Known limitations in CHANGELOG.md. Bounded-but-degraded is a limitation; unbounded is a vulnerability, and the line between them is whether the work has a ceiling.- A crash from an AST you hand-built that
parse()would never produce. Malformed input to the AST-in path is a programming error and is refused loudly by design. - Anything requiring the attacker to already control the calling application.
- Issues in dev dependencies that do not ship. The published package has zero runtime dependencies, so its supply-chain surface is its own source.
If you would like credit, say so and I will name you in the changelog entry for the fix. If you would rather not be named, that is fine too.