Squashed 'scanners/commons/' changes from 4641a7b..7ce0ba7
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
This commit is contained in:
parent
bbd03f9b52
commit
bc23b07cf9
8 changed files with 844 additions and 41 deletions
133
SECURITY.md
Normal file
133
SECURITY.md
Normal file
|
|
@ -0,0 +1,133 @@
|
|||
# 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.
|
||||
Loading…
Add table
Add a link
Reference in a new issue