7ce0ba7 docs(carriers): the third verdict exists, and publishing an alias is what takes it away 302625e fix(conformance): the tag carrier has no output: label, and our blocker claimed it did fe5e6b2 docs(conventions): the merge button is off for a reason, and the reason now lives in the repo 2d86151 fix(divergence): our own iframe number read 3x low, and the reported cause was not the cause daa7ba4 release(0.4.0): two values moved by two mechanisms, and the difference is the release 2eee7e1 feat(lexicon): both unbounded rows narrow to [^><]*, and the mechanism is new here d467324 feat(signatures): the staleness we disclosed is closed by reading the module, not the message 4187715 docs(divergence): our own form has a number now, and it is quadratic 0e765a0 docs(security): the attack surface here is data, so the report route had to say where a wrong entry gets fixed d96fbbf docs(divergence): the span row had one witness; llm-security measured five more git-subtree-dir: scanners/commons git-subtree-split: 7ce0ba706cadd032ec3c16622dcfdb5ce4dc32d6
133 lines
7.2 KiB
Markdown
133 lines
7.2 KiB
Markdown
# Security policy
|
|
|
|
This repository ships **no runnable code** — no package, no build, no dependency tree,
|
|
nothing that executes on your machine. So the usual question, *can this be exploited*,
|
|
has an unusual answer here: the attack surface is the **data**.
|
|
|
|
Seven data files here carry the detection material — pattern tables, code-point carriers,
|
|
calibration thresholds, an OWASP mapping — and several independent runtimes read them at the
|
|
same time. A wrong code point, a mis-escaped regex, a fixture that expects a miss: none of that
|
|
crashes anything. It produces a detector that looks like it works and is not looking. That
|
|
is the vulnerability class this policy is about, and a report of one is welcome even though
|
|
no code changes as a result.
|
|
|
|
## Reporting
|
|
|
|
**Do not open a public issue.** A report here usually names an input that gets *past* a
|
|
detector, and that is a working bypass against every consumer until it is closed.
|
|
|
|
Report privately by email:
|
|
|
|
- **hello@fromaitochitta.com**, with `SECURITY` at the start of the subject.
|
|
|
|
Pull requests are not the channel either — they are switched off on the canonical
|
|
repository, and not as an oversight. This repository is vendored into independent runtimes
|
|
that pin a tag; a change to detection data changes what those runtimes *find*. Such a change
|
|
has to be coordinated with each consumer before it exists, which a merge button does not do.
|
|
Fork-and-own is the supported path.
|
|
|
|
Please include:
|
|
|
|
- the file and the entry — its `name`, `order` or `id`, whichever that file uses;
|
|
- the tag you read (`v0.3.0`, not "main");
|
|
- the input that should have matched and does not, or the input that matches and should not;
|
|
- what a consuming runtime actually does today, if you have measured it.
|
|
|
|
**Obfuscate live payloads.** Do not send a working credential or a live carrier. Spell
|
|
invisible characters as code points the way the tables do (`"U+200B"`), and use placeholder
|
|
key material — a report should not itself be a delivery mechanism.
|
|
|
|
## What counts as a vulnerability here
|
|
|
|
In scope — all of these are real reports:
|
|
|
|
1. **A detection entry that is a silent false negative.** A wrong code point, a regex whose
|
|
escaping is wrong for the declared dialect, missing or wrong flags, a pattern that fails
|
|
to compile in a documented engine and gets skipped rather than reported.
|
|
2. **A conformance fixture that sanctions a miss.** `expected.json` is ground truth: a
|
|
runtime that disagrees with it is deemed wrong. A fixture that expects too little makes
|
|
every conforming runtime wrong identically, and the corpus will not catch it.
|
|
3. **A normative clause that mandates unsafe behaviour.** The `spec/` files bind the
|
|
implementations that consume them, so a weak rule propagates to all of them.
|
|
4. **A real secret or personal data in the repository or its history.** The history is
|
|
public in full.
|
|
5. **Data that has gone stale against its declared source in a way that under-detects.**
|
|
Each data file names its source in a `provenance` block. If that source has since added
|
|
or corrected an entry, the copy here under-matches, and a consumer vendoring it is less
|
|
protected than the runtime it was taken from.
|
|
|
|
Out of scope — documented boundaries, not vulnerabilities. See **Known limitations** and
|
|
**Non-goals** in [README.md](README.md):
|
|
|
|
- a detection class absent from the tables entirely (coverage is the union of what the seed
|
|
implementations detected, not of what exists);
|
|
- a table implemented by only one runtime, and cases marked `not-applicable` for the others;
|
|
- disagreement about a `calibration.json` threshold — the thresholds are published, the
|
|
policy built on them belongs to the consumer;
|
|
- a divergence already recorded in [`docs/lexicon-port-divergence.md`](docs/lexicon-port-divergence.md);
|
|
- the five data files no fixture constrains, and the finite homoglyph map.
|
|
|
|
If you are unsure which side something falls on, report it privately anyway.
|
|
|
|
## Why a confirmed defect is usually not fixed here first
|
|
|
|
This is the part that differs from an ordinary repository, and it is worth reading before
|
|
you conclude that a fix is being stalled.
|
|
|
|
Most data here is an **extraction**: a copy of a table that lives in a runtime, kept
|
|
behaviour-identical to it on purpose. Correcting an entry here — even a genuinely wrong one
|
|
— would make the copy disagree with the implementation it was taken from. Two implementations
|
|
answering differently on the same input is precisely the failure this repository exists to
|
|
prevent, so producing one as a *fix* would be self-defeating.
|
|
|
|
A confirmed defect in extracted data therefore travels:
|
|
|
|
1. the report reaches the maintainer here, privately;
|
|
2. the owning runtime is identified — every data file names it in `provenance.source_repo`
|
|
— and the report is routed there;
|
|
3. the decision is taken **there**, where the pattern is under test against a real suite;
|
|
4. once the source has moved, this repository **re-extracts** from a pinned public commit
|
|
and tags a release;
|
|
5. consumers pull that tag on their own schedule.
|
|
|
|
Stated plainly, because it affects you: fix latency is bounded by the owning runtime's
|
|
schedule and by each consumer's pull, not by this repository's. If you need protection
|
|
sooner than that, the fix belongs in your own runtime; this repository is where it becomes
|
|
shared, not where it becomes real.
|
|
|
|
Two things do **not** take that route:
|
|
|
|
- **A real secret in the repository or its history** (class 4) is handled here, immediately.
|
|
- **Data authored in this repository** rather than extracted — it is flagged as such where
|
|
it occurs, for example `authored_payloads` in `conformance/manifest.json` — is this
|
|
repository's own to correct.
|
|
|
|
The precedent is on the record. In `v0.3.0` a detection pattern changed value here for the
|
|
first time, and it changed because the owning runtime had changed its own and this
|
|
repository re-read the source — not because a reviewer here judged the old value wrong.
|
|
`docs/lexicon-port-divergence.md` records a row where two runtimes still disagree and this
|
|
repository deliberately did *not* pick a winner. Provenance is the ground for moving a
|
|
value. Merit is not, and the day it becomes the ground, the guarantee is gone.
|
|
|
|
## Supported versions
|
|
|
|
Pre-1.0. Only the latest tag is fixed; there are no back-ported branches.
|
|
|
|
Consumers vendor this repository (`git subtree`, or a pinned copy) rather than installing
|
|
it, so a fix reaches a consumer only when that consumer pulls the new tag. There is no CI in
|
|
this organisation and nothing polls for updates. When a fix changes detection data, the
|
|
maintainer notifies the known consumers directly — but their upgrade is their own action, on
|
|
their own schedule.
|
|
|
|
Read the `CHANGELOG.md` entry before upgrading rather than the version number: in 0.x, a
|
|
change to what a conforming runtime *finds* is still a minor bump.
|
|
|
|
## Disclosure
|
|
|
|
There is no formal embargo SLA here. The maintainer will acknowledge the report, agree a fix
|
|
and disclosure timeline with the reporter, and credit the reporter in the `CHANGELOG.md`
|
|
entry unless they prefer to remain anonymous.
|
|
|
|
If the report is a false negative in a table that has already shipped, the changelog entry
|
|
will say what slipped through, in enough detail that a consumer still pinned to the older
|
|
tag can judge whether it is exposed. Naming it is the point of fixing it.
|