1
0
Fork 0

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:
Kjell Tore Guttormsen 2026-10-31 19:33:51 +01:00
commit eeb7bf07f6
Signed by: ktg
SSH key fingerprint: SHA256:JakMjO6FTBBzN0Bhfj9saOoEjaFxlSdYuZQQpM/lF9Q
13 changed files with 403 additions and 12 deletions

View file

@ -142,9 +142,9 @@ live payload:
python -m llm_ingestion_guard.coverage # exit 0 = all as documented
```
As of `v1.6.0`: **139 / 139 defended classes demonstrated (recall 100%)** and **6 /
As of `v1.6.0`: **140 / 140 defended classes demonstrated (recall 100%)** and **6 /
6 documented gaps still hold** (a *closed* gap fails the test, forcing a doc
update). The matrix is the single source of truth for the test suite (**1142
update). The matrix is the single source of truth for the test suite (**1179
passing**), which also asserts total recall, that every lexicon pattern has a
case (so the matrix cannot fall behind the lexicon), the full LLM02:2026 secret-egress
set, and the container-layer front-end (CSV formula-injection, zip-slip/bomb,

View file

@ -250,6 +250,24 @@ items; this is the full list, each with the mechanism.
is bounded by `log2(length)` at short lengths. Mitigation in depth, not in this
detector: a literal credential in a URL is still caught by the LLM02:2026 egress
patterns in the same `scan_output` pass, whatever severity the carrier gets.
- **A value carried by the order of images is caught only when each symbol is short
and the run shares one URL template.** Since 1.7.0
`active:markdown-image-sequence` (MEDIUM) reports a run of at least 4 ordinary
external images (`IMAGE_SEQUENCE_MIN_RUN`), inline or reference-style, whose URLs
share one template and differ only in tokens of 2 characters or fewer
(`IMAGE_SEQUENCE_SYMBOL_MAX`) or in digit runs, unless those digits count up in
document order. That is CamoLeak's shape (attack A05). Measured 2026-10-31, each
a WARN with only a LOW per image: a dictionary of words (`/alpha.png`,
`/kilo.png`), symbols of 3 characters, a counter whose *increments* carry the
value, a run of 3, and a run whose symbols each change the path depth (every
image its own template). The opposite error is accepted: a table of country
flags (`/w20/no.png`, `/w20/se.png`, …) or figures named `1a`, `1b`, `2a` has the
shape of a symbol alphabet and goes to review. Neither occurs in the six benign
populations measured (the three false-positive corpora, 411 npm READMEs, 166 PyPI
descriptions and the 78 OKF concepts): 0 firings at every run length from 3 to 8.
The three false-positive corpora hold no external markdown image at all, so the
READMEs are the population that tests the rule. Raw `<img>` tags are not
counted: each one is already `active:raw-html` (HIGH).
- **Percent-escapes count as data-carrying — a `%20` in a path is a false positive.**
An ordinary link with an encoded space grades as carrying and reaches
QUARANTINE_REVIEW / FAIL_SECURE on an untrusted upload. Obfuscated encoding is a
@ -632,7 +650,7 @@ items; this is the full list, each with the mechanism.
missed; on one preset it is held for review instead of halted.
- **The ReDoS sweep has a measured sensitivity floor, not a clean bill of
health.** All 161 compiled patterns across all eleven regex-bearing modules are
health.** All 163 compiled patterns across all eleven regex-bearing modules are
swept arm by arm — payloads synthesised per run from each pattern's own
skeleton, so `[`, `[system]` and `[system](` are each probed separately rather
than relying on generic units, and each pattern is timed in the call mode the

View file

@ -269,6 +269,19 @@ tas i økt 2:*
I referansekorpuset står 253 av 254 kommentarer i kode.
- **Økt 6, rekkefølge-bæring:** A05 utgang. Hvert bilde bærer ingen data, men
rekkefølgen gjør det. Det graderes LOW og gir WARN.
*Gjort 31.10 (1.7.0):* A05 fanges, så rad 3 har nå **13 fanget, 1 hull og 5
røde** (A08, A09, A12, A16, A19). `active:markdown-image-sequence` (MEDIUM) melder
minst 4 vanlige eksterne bilder på samme URL-mal der bare korte tokener (2 tegn
eller færre) eller sifre varierer, med unntak for sifre som teller oppover.
Bildene graderes fortsatt hver for seg; funnet står ved siden av. Målt før
bygging: de tre falsk-positiv-korpusene har ikke ett eksternt markdown-bilde, så
de kan ikke prøve regelen. Derfor er den også målt på 411 npm-README-er og 166
PyPI-beskrivelser (312 med eksterne bilder) og OKF-korpuset: 0 treff for alle
lengder fra 3 til 8. Vaktregelen holder: falsk-positiv-tallene og OKF-importen er
identiske. Flaggtabeller og figurer kalt `1a`, `1b` er tvillinger regelen ikke kan
skille fra en symbolkanal. De går til gjennomsyn og står i LIMITATIONS, sammen med
de målte omgåelsene (ordbok med ord, symboler på 3 tegn, en teller der stegene
bærer verdien).
- **Økt 7, instruksjoner i ren prosa:** A08, A09, A12, A16 og A19. Ingen av dem har
en markør. Her er det mest sannsynlig at flere ender som dokumenterte hull fordi
vaktregelen ikke holder. Det skal måles, ikke antas.