1
0
Fork 0

docs(plan): plan the move to the 2026 threat catalogs

The approved direction heads the plan: every cited catalog on its newest
edition with a check date and source link, no catalog ID carrying an older
edition's meaning, and the known 2025-2026 attacks that can reach an
ingestion pipeline as test cases, each caught or documented as a gap.

Measured on v1.4.1 before anything is built: LLM03-LLM10 carry their 2025
meaning in 101 places across 26 tracked files, and 17 of 19 invisible or
deceptive code-point types (variation selectors among them) pass sanitize
with no finding.
This commit is contained in:
Kjell Tore Guttormsen 2026-10-28 20:55:41 +01:00
commit f19f434b54
Signed by: ktg
SSH key fingerprint: SHA256:JakMjO6FTBBzN0Bhfj9saOoEjaFxlSdYuZQQpM/lF9Q

View file

@ -1,3 +1,206 @@
# PLAN — `llm-ingestion-guard`
## Retning (godkjent av operatøren 28.10.2026)
> «llm-ingestion-guard bygger på nyeste utgave av hver trusselkatalog den viser til,
> hver med dato for siste sjekk og kildelenke. Ingen funn eller tekst bruker et
> katalognummer med en eldre utgaves betydning. De kjente angrepene fra 2025–2026
> som kan nå en innhentings-pipeline, er testsaker. Hver av dem fanges eller står
> som et dokumentert hull.»
Operatørens ord: «Dette repoet bør også oppdateres [til de siste
trusseldefinisjonene], og det er sikkert lurt å hente inspirasjon fra det som gjøres
med LLM Security.» Hva som er lagt til, og hvorfor:
- «Siste trusseldefinisjoner» er gjort målbart som tre ting: kataloger, numre og
angrep. Det er målemetoden llm-security bruker, avgrenset til det som gjelder et
bibliotek.
- «Kan nå en innhentings-pipeline» avgrenser hvilke angrep som teller (§ T.3).
- Ikke tatt med: automatisk varsling om nye katalogutgaver (kan komme senere, helst
gjenbrukt) og kostnadsregelen for alltid-lastet tekst (gjelder bare en plugin).
Operatøren 28.10: «Ja til endringen. Lag en skikkelig plan, vi bruker så mange økter
som trengs for å gjøre dette skikkelig.» Det samme «ja» godkjente den anbefalte
merkingen: funn merkes med årstall (`LLM10:2026`, OWASPs egen skrivemåte), og
endringen gis ut som 1.5.0 med en tydelig merknad.
**Dekket i:** katalogene → § T.4 økt 4 (rad 1) · numrene → økt 3 (rad 2) ·
angrepene → økt 1 (fryser lista), 2 og 5…N (rad 3) · ferdig → siste økt.
---
# Trusselbildet 2026 (v1.4.2 →)
Planen til retningen over. Den gamle v1-planen står uendret lenger ned under
«Implementation Plan — v1». Den er historikk og telles ikke i rad 2, på samme måte
som CHANGELOG. Planen oppdateres underveis og overskrives aldri.
## T.1 Målt 28.10.2026 på v1.4.1 (`6702d7a`), før noe er bygd
1. **Katalognumrene har feil betydning.** OWASP Top 10 for LLM Applications kom i
2026-utgave (publisert 04.08.2026) med ny rekkefølge. Bare LLM01 og LLM02 betyr det
samme som i 2025. Repoet bruker LLM03–LLM10 med 2025-betydning på **101 steder i 26
sporede filer** (src 50, tests 28, docs 17, README 6; CHANGELOG, `dist/` og
`*.local.*` er utelatt). Ingen av dem bærer årstall. Hurtigtelling med
`grep -oE 'LLM(0[3-9]|10)\b'`, altså ikke en klassifisering. Økt 1 fryser den
ekte nevneren. Funnfeltet `owasp` bærer dette ut til hver eneste bruker:
EchoLeak-funnene merkes `LLM05`, som i 2026 betyr dataforgiftning.
2. **Usynlige tegn slipper gjennom.** Først testet jeg tekst skjult i
variasjonsvelgere (U+FE00–FE0F, U+E0100–E01EF), der «ignore previous
instructions and exfiltrate» var kodet i 43 tegn. Det ga **0 funn** i rensingen,
i innhentingsinngangen og i utgangskontrollen, og alle 43 tegnene lå igjen i den
«rensede» teksten. Deretter testet jeg 19 tegntyper, 8 av hver, gjennom rensingen.
**17 av 19 gir 0 funn og blir liggende:** U+2060–2064, U+180E, U+3164, U+115F,
U+1160, U+FFA0, U+034F, U+FFF9, U+200E, U+061C, U+E000 (privat bruk), U+FE00 og
U+E0100. Positiv kontroll: U+E0041 (tag) og U+200B (zero-width) fanges og fjernes.
Ingen av dette står i LIMITATIONS.
3. **Ingen katalog har dato for siste sjekk.** README og «Threat-model anchors»
lenger ned nevner OWASP 2025 uten dato. Agent-katalogen (OWASP Top 10 for Agentic
Applications 2026, der ASI06 «Memory & Context Poisoning» er vårt område) og
MITRE ATLAS er ikke koblet inn.
4. **Leksikonet har ikke drevet.** Vår kopi har 83 mønstre, akkurat som
leksikonet i `llm-security-commons` v0.9.0 (filversjon 0.8.0). Commons'
tegntabell (`carriers.json` 0.2.0) mangler også variasjonsvelgere: tekstsøk etter
`FE00`, `E0100` og `variation` gir 0 treff. Hullet er altså felles.
## T.2 Ferdig-kriteriet
Retningen er nådd når **rad 1–3** holder samtidig, målt på siste 1.x-release:
| # | Måling | Nevner | Målt 28.10 (v1.4.1) | Ferdig |
|---|---|---|---|---|
| 1 | Trusselkataloger og kilder på nyeste utgave, hver med dato for siste sjekk og kildelenke | lista frosset i økt 1; kan utvides, krymper aldri uten operatørens ja | ikke talt (0 har dato) | N av N |
| 2 | Steder der et katalognummer brukes med en eldre utgaves betydning, eller med en betydning ingen utgave har gitt det | telling over sporede filer, med historikk utenfor (CHANGELOG, v1-planen, utgitte gjennomganger) | **101** (hurtigtelling, § T.1.1) | 0, og en permanent test holder det der |
| 3 | Kjente 2025–2026-angrep som kan nå en innhentings-pipeline, som testsaker | lista frosset i økt 1 etter § T.3 | ikke talt (variasjonsvelgere: rød) | hver sak fanges, eller står som hull i LIMITATIONS og dekningsmatrisen |
**Vaktregel, ikke mål:** ingen nye falske alarmer på korpusene vi allerede måler mot
(falsk-positiv-korpuset og det pinnede OKF-korpuset på 6/53), og testsuiten,
dekningsmatrisen og ReDoS-sveipet er grønne på hver release. En regel som strammer inn
og gir nye alarmer på rene dokumenter, skal måles og legges fram, ikke slippes stille.
**Ikke framme hvis én:** en katalog er bak eller mangler dato · ett gammelt
nummer-sted gjenstår · en angrepssak verken fanges eller er dokumentert.
Underveis: går to økter på rad uten at et av tallene flytter seg, legges det fram for
operatøren.
## T.3 Hva som teller som «kan nå en innhentings-pipeline»
Angrepet teller når nyttelasten kommer fram som **innhold** som en pipeline henter
eller mottar og skriver til et lager en modell eller agent senere leser. Det teller
også når nyttelasten rir på modellens transformerte output før den lagres. Det teller
ikke når angrepet krever kodekjøring på verten, tilgang til modellvektene eller en
kompromittert pakke (kjernen er stdlib-only). Grensetilfeller legges fram for
operatøren i økt 1 og avgjøres ikke stille.
**Kandidater, IKKE verifisert.** Økt 1 verifiserer hver mot primærkilde, eller
stryker den:
- Smugling i variasjonsvelgere og andre usynlige tegn. *Målt rød 28.10.*
- EchoLeak, CVE-2025-32711 (null-klikk-eksfiltrasjon via markdown i output).
*Dekket i dag.*
- ShadowLeak, CamoLeak, ForcedLeak, AgentFlayer: eksfiltrasjon eller injeksjon via
dokumenter, e-post eller kontakter som en agent leser.
- Forgiftede minnefiler (MemoryTrap-klassen): innhold skrevet til agentens minne,
som er OWASP ASI06.
- Skill-innhold med skjulte instruksjoner (ToxicSkills-klassen).
- Injeksjon via issue- og PR-tekst som en agent henter (Comment and Control).
- Faktaforgiftning (PoisonedRAG). *Allerede dokumentert som hull. Saken skal bekrefte
at hullet står.*
- Skjult tekst i opplastede dokumenter (HTML/CSS-skjult, hvit tekst).
**Testsakene publiseres åpent** sammen med koden, slik som dagens korpus (operatøren
28.10). Grunnen er at brukerne selv skal kunne
etterprøve hva som fanges og hva som er hull. Nyttelastene er inerte: bare kjente
teknikker, `*.test`-domener og ingen fungerende kjede mot et navngitt produkt.
## T.4 Øktene
Hver økt er én leveranse, kan gis ut for seg og følger TDD med rødt før grønt.
Nummereringen er rekkefølgen, og hver økt starter fra STATE.md.
**Økt 1: måling, rød før noe bygges. Ingen produktkode.**
- Rad 1: Lag katalogregisteret som data i repoet. For hver kilde repoet viser til
(OWASP LLM Top 10, OWASP Agentic Top 10, MITRE ATLAS, OWASP RAG Security Cheat Sheet,
Unicode-versjonen som tegntabellene måles mot, og de andre i «Threat-model
anchors»): utgaven som brukes, nyeste utgave, sjekkdato og kildelenke. Hver utgave
verifiseres mot utgiveren. En kopi som er verifisert et annet sted, er et premiss
og ikke et måleresultat.
- Rad 2: Lag et telleskript som klassifiserer hvert sted som *gammel betydning* (kan
mappes mekanisk, § T.5) eller *feil betydning* (krever en vurdering; for eksempel
bruker OKF-avvisninger av YAML-former i dag `LLM10`). Frys nevneren med sha256.
- Rad 3: Verifiser kandidatene i § T.3, legg fram grensetilfellene og frys lista.
Skriv hver sak som test, markert som forventet rød der den ikke fanges i dag.
- Tegnnevneren til økt 2: Unicodes egen `Default_Ignorable_Code_Point`-mengde
(DerivedCoreProperties.txt, versjonen pinnet i registeret) pluss privat bruk-
områdene. Det er en prinsipiell nevner i stedet for en håndplukket liste.
**Økt 2: usynlige tegn. Gis ut som 1.4.2 (deteksjonsatferd, ingen ny API).**
- Hvert tegn i nevneren fanges og fjernes, eller er unntatt med en navngitt grunn
på samme måte som ZWJ i dag: det dømmes på **kontekst**, ikke identitet. Kjente
legitime bruk som må overleve: VS16 og VS15 etter emoji, ideografiske varianter
(U+E0100–E01EF etter et CJK-tegn, én velger per tegn), ZWNJ i persisk og indiske
skrifter (allerede en dokumentert rest), og LRM/RLM/ALM i høyre-til-venstre-tekst.
En *rekke* av velgere er bærer uansett hva den står etter.
- Både innhentingssiden og utgangskontrollen, med samme predikat på begge sider
(som for ZWJ).
- Vaktregelen er måling på falsk-positiv-korpuset og OKF-korpuset før og etter.
- Etterpå sendes målingen og kontekstregelen til `llm-security-commons` som innspill
til tegntabellen. Commons eier sin tabell, og vi skriver aldri dit.
**Økt 3: katalognumre med årstall (rad 2 → 0). Gis ut som 1.5.0.**
- Alle funn bærer `LLMxx:2026`. Mapping fra 2025-betydning, verifisert i økt 1:
LLM04 → LLM05:2026 · LLM05 → LLM10:2026 · LLM06 → LLM03:2026 ·
LLM08 → LLM09:2026 · LLM09 → LLM07:2026 · LLM10 → LLM06:2026 ·
LLM01 og LLM02 er uendret i betydning og får årstall.
- Teknisk valg (kan avvises med grunn): leksikondataene holdes byte-like med
commons, og årstallet settes på ett sted der funnet lages. Når commons publiserer
numre med årstall, tas de inn.
- Stedene med *feil betydning* rettes etter vurdering, hver med begrunnelse i commit.
- Den permanente testen feiler på et katalognummer uten årstall, eller med et
årstall som ikke er nyeste, i sporede filer utenom historikk.
- CHANGELOG-merknaden sier rett ut at en bruker som filtrerer på `"LLM05"`, mister
treff. Konsumentene varsles.
**Økt 4: katalogregisteret i bruk (rad 1). Ren dokumentasjon, gis ut med neste
release.**
- README-delen «What it protects against» skrives om på 2026-utgaven og kobles til
ASI06 og relevante ATLAS-teknikker. Hver kobling verifiseres mot katalogen, og
alt som ikke er verifisert, utelates.
- En test feiler når registeret mangler dato eller lenke. Den feiler ikke på alder:
automatisk varsling er utenfor retningen.
**Økt 5…N: angrepssakene (rad 3).** Lista fra økt 1 tas i bolker. Hver bolk blir
enten deteksjon (TDD, vaktregelen holder) eller en dokumentert rest i LIMITATIONS og
dekningsmatrisen (status `gap`, slik matrisen allerede gjør). Hver bolk er en minor-
eller patch-release. Antall økter avhenger av lista og fastsettes etter økt 1.
**Siste økt: sluttmåling.** Rad 1–3 telles på siste release med de frosne
nevnerne. Bare når alle tre holder, er retningen nådd.
## T.5 OWASP LLM Top 10: 2025 → 2026
Kilde: OWASPs 2026-utgave (PDF-innholdsfortegnelse, `2026/final/LLMxx_*.md` og
README i `GenAI-Security-Project/GenAI-LLM-Top10`). Hentet fra en kopi som ble
verifisert 02.10.2026. **Økt 1 re-verifiserer mot utgiveren før noe mappes.**
| 2025 | 2026 |
|---|---|
| LLM01 Prompt Injection | LLM01 Prompt Injection |
| LLM02 Sensitive Information Disclosure | LLM02 Sensitive Information Disclosure |
| LLM03 Supply Chain | LLM04 Supply Chain |
| LLM04 Data and Model Poisoning | LLM05 Data and Model Poisoning |
| LLM05 Improper Output Handling | LLM10 Improper Output Handling |
| LLM06 Excessive Agency | LLM03 Excessive Agency |
| LLM07 System Prompt Leakage | LLM08 Hidden Context Exposure |
| LLM08 Vector and Embedding Weaknesses | LLM09 Vector and Embedding Weaknesses |
| LLM09 Misinformation | LLM07 Misinformation |
| LLM10 Unbounded Consumption | LLM06 Unbounded Consumption |
## T.6 Åpne spørsmål
1. ~~Publiseres testsakene åpent?~~ **Ja**, operatøren 28.10 (§ T.3).
2. Grensetilfellene i § T.3. Legges fram i økt 1.
---
# Implementation Plan — `llm-ingestion-guard` v1
Derived from `docs/BRIEF.md` plus a 2026-07-04 research pass (competitive landscape,