feat(active): report a run of images whose order carries a value
Session 6 of the 2026 threat plan (attack row 3): A05 output was red. CamoLeak renders a secret as one image per character from a URL alphabet; each URL is ordinary, so each image graded LOW and the gate WARNed. - active:markdown-image-sequence (MEDIUM): at least 4 ordinary external images, inline or reference-style, on one URL template whose varying tokens are 2 chars or fewer, or digit runs. Digits that count up in document order are a counter and carry nothing. The per-image grade is unchanged; the finding sits beside it. - Accepted twins (flag tables, figures 1a/1b) go to review; measured evasions (word dictionary, 3-char symbols, counter increments, run of 3, a template per symbol) are in LIMITATIONS. Guard rule before/after: FP 106/198, 196/2918, 108/389 identical. Those corpora hold no external markdown image, so the rule was also run on 577 package READMEs (312 with external images): 0 firings at run lengths 3-8. OKF import 47/31 identical. Matrix 140/140, ReDoS 163 patterns 0 flagged, suite 1179 passed + 5 xfailed. Row 3: 13 caught, 1 gap, 5 open.
This commit is contained in:
parent
d00d1b0658
commit
eeb7bf07f6
13 changed files with 403 additions and 12 deletions
10
README.md
10
README.md
|
|
@ -206,18 +206,18 @@ tier + disposition, emitted to `log.md`).
|
|||
Concrete attack classes, grouped by OWASP Top 10 for LLM Applications **2026**
|
||||
anchor. Numbers carry the year, OWASP's own form, because the 2026 edition
|
||||
renumbered the list; a class no entry describes carries no number. Every row is
|
||||
driven by a **live payload** in the coverage matrix — run it to watch all 145 pass
|
||||
driven by a **live payload** in the coverage matrix — run it to watch all 146 pass
|
||||
in your own environment:
|
||||
|
||||
```bash
|
||||
python -m llm_ingestion_guard.coverage # 139/139 classes; exit 0 = all as documented
|
||||
python -m llm_ingestion_guard.coverage # 140/140 classes; exit 0 = all as documented
|
||||
```
|
||||
|
||||
| Anchor | Attack classes it stops (representative) |
|
||||
|---|---|
|
||||
| **LLM01:2026 · prompt injection** | 83 instruction-override lexicon classes (ignore / forget / disregard / suspend-constraints, role-play, jailbreak, …); hidden carriers — every invisible codepoint in Unicode 18.0 (zero-width, BIDI override, Unicode-tag, variation-selector and Sneaky-Bits smuggling, private use; legitimate emoji, CJK, Arabic-script, Indic and right-to-left uses exempt on context), HTML-comment, `data:` URI — stripped on input **and** re-checked at the persist gate (a comment the model leaves in its artifact is reported unless it sits in code); text hidden by styling — a font too small to read, or text coloured like its own background; high-entropy base64/hex blobs; an injection hidden inside a base64 blob (decoded, then re-scanned) |
|
||||
| **LLM02:2026 · sensitive-info disclosure** | Secret egress in output — AWS keys, tokens, private keys, the credential set; a base64-*wrapped* secret (decoded → `decoded:egress:*`) |
|
||||
| **LLM10:2026 · improper output handling** | Zero-click exfil carriers (EchoLeak, CVE-2025-32711) — markdown-image auto-fetch, inline / reference / autolink links, raw active HTML, standalone `data:` URIs |
|
||||
| **LLM10:2026 · improper output handling** | Zero-click exfil carriers (EchoLeak, CVE-2025-32711) — markdown-image auto-fetch, inline / reference / autolink links, raw active HTML, standalone `data:` URIs; a run of images whose *order* carries a value while each URL is ordinary (CamoLeak) |
|
||||
| **LLM03:2026 · excessive agency** | A tool surface on the quarantined transform; credential use beyond the per-stage allowlist; capability isolation (`scoped_env`) |
|
||||
| **Fail-secure** *(the guard's own failure semantics)* | Forced-fallback attack (scan hit + transform failure → halt); compound weak-signal escalation; an un-scannable artifact fails **closed** — never a silent persist |
|
||||
| **OKF structure (T1–T6)** | Body + frontmatter-value injection; YAML anchor / merge / nested / block DoS (parse-safety); non-`https` / active-scheme `resource` URLs and the `resource` allowlist; path traversal / reserved-name shadow; cross-link graph; provenance stamping |
|
||||
|
|
@ -249,7 +249,7 @@ column is the part it does **not** stop. Each one was measured or is a documente
|
|||
| **AML.T0143 · LLM Prompt Propagation** | Instructions that the lexicon or a carrier check sees are caught at the output gate, so they never reach the store that would pass them on | Propagation over a channel the guard does not sit on |
|
||||
| **AML.T0051.001 · LLM Prompt Injection: Indirect** | The **LLM01:2026** row above | Novel phrasings with no lexicon hit; the tool-less transform carries that case |
|
||||
| **AML.T0068 · LLM Prompt Obfuscation** | Invisible characters, HTML comments, a font too small to read, text coloured like the background declared on the same element, base64 and rot13 (decoded, then re-scanned) | White text whose background sits on a parent element or in a stylesheet: a plain-prose instruction hidden that way gives 0 findings |
|
||||
| **AML.T0077 · LLM Response Rendering** | The **LLM10:2026** row above: markdown-image auto-fetch, links, raw active HTML | Pure beaconing to a bare path on a hostile host (a documented gap) |
|
||||
| **AML.T0077 · LLM Response Rendering** | The **LLM10:2026** row above: markdown-image auto-fetch, links, raw active HTML, a run of images whose order spells a value | Pure beaconing to a bare path on a hostile host (a documented gap); an image run whose symbols are words rather than short tokens |
|
||||
| **AML.T0066 · Retrieval Content Crafting** | Only the crafted content that also carries an injection | The crafted content itself — semantic gap |
|
||||
|
||||
**Every catalog the guard cites is on its newest edition, with the date it was
|
||||
|
|
@ -328,7 +328,7 @@ a green scan means safe content. The highest-impact items:
|
|||
two of the three corpora are living, so the cells are not rewritten in place.
|
||||
Method and before/after: [`docs/rawhtml-census.py`](docs/rawhtml-census.py).
|
||||
|
||||
**Full list — 48 items, each with the mechanism, plus the out-of-scope boundary:**
|
||||
**Full list — 49 items, each with the mechanism, plus the out-of-scope boundary:**
|
||||
[`docs/LIMITATIONS.md`](docs/LIMITATIONS.md). Several carry field measurements from
|
||||
consumer corpora, including the false positives the URL-shape rule actually produces.
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue