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

@ -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