Squashed 'scanners/commons/' changes from 0ffee85..532d70d
532d70d release(0.2.0): the contract gained a MUST, so the tag has to move 946f51d fix(active-content,conformance): cite line numbers per commit — they do not resolve at the pin bdcb1f1 feat(conformance): ship the six active-content cases; the id space already existed 807c0d4 feat(spec): add not-applicable, so a single-runtime table stops reading as 7 defects a1578e6 fix(conformance): record the guard's internal-surface position on _LEX_PAYLOADS 4d351d2 fix(mapping): state that three of four OWASP maps have no production consumer f082a91 fix(lexicon,docs): retract the claim that the guard's port cites severity.mjs git-subtree-dir: scanners/commons git-subtree-split: 532d70d5ed2f9b23a8efad760ef490356cf52ada
This commit is contained in:
parent
a640f43d73
commit
9b95fc607e
20 changed files with 533 additions and 37 deletions
|
|
@ -1,11 +1,59 @@
|
|||
{
|
||||
"version": "0.1.0",
|
||||
"version": "0.2.0",
|
||||
"id": "active-content",
|
||||
"description": "Active content in persisted text: constructs that fetch, render or execute on their own when a renderer touches them. The EchoLeak class (CVE-2025-32711). Report-only data: no construct here is defined as something to remove.",
|
||||
"owasp": "LLM05",
|
||||
"detector": "active_content",
|
||||
"label_format": "active:{class}",
|
||||
|
||||
"pattern_id_space": {
|
||||
"$comment": "Stable, commons-owned identifier for each construct, so that a conformance fixture can name an active-content finding. Unlike the injection lexicon's id space, nothing was constructed here: `label_format` and the `constructs` keys were already extracted verbatim from the seed runtime, and their concatenation IS what that runtime emits. This block states an id space that the file already had implicitly rather than introducing one.",
|
||||
"field": "\"active:\" + the key of the entry in `constructs`",
|
||||
"ids": [
|
||||
"active:autolink",
|
||||
"active:data-uri",
|
||||
"active:markdown-image",
|
||||
"active:markdown-link",
|
||||
"active:raw-html",
|
||||
"active:reference-link"
|
||||
],
|
||||
"verified": {
|
||||
"method": "The six `constructs` keys were compared to the six class strings the seed runtime passes to its finding emitter: the `_flag(cls, …)` call sites in active_content.py, whose emitter builds `label=f\"active:{cls}\"`. Set-equal, exact strings, no normalisation applied.",
|
||||
"line_numbers": {
|
||||
"$comment": "Given per commit rather than once, because the two differ and a reader checking against this file's provenance pin would otherwise land on the wrong lines. The 23-line insert between the two commits shifts everything below it by 21.",
|
||||
"de09711": "_flag call sites at 337, 341, 345, 349, 363, 369; emitter at 309 — where the comparison was run",
|
||||
"0bf0729": "the same six call sites at 316, 320, 324, 328, 342, 348; emitter at 288 — the commit `provenance` pins",
|
||||
"symbols": "`_flag` and the `label=f\"active:{cls}\"` assignment inside it — stable across both, unlike the line numbers"
|
||||
},
|
||||
"date": "2026-08-10",
|
||||
"at_commit": "de09711",
|
||||
"at_commit_note": "Named because that is where the comparison was actually run, which is NOT the commit this file's provenance pins (0bf0729). active_content.py did change over that range: `git diff 0bf0729..de09711` adds 23 lines. Measured, not assumed - the change is a self-safety length cap (a new `max_scan_chars` parameter, and an `active:oversize-input` finding when the input exceeds it). It adds no construct, removes none, and leaves every `_flag` call site and every construct pattern untouched, so the six-way comparison above holds at both commits. The drift is recorded rather than smoothed over: a reader checking this file against 0bf0729 will see a different active_content.py and is entitled to know why that does not invalidate the check."
|
||||
},
|
||||
"not_every_active_label": {
|
||||
"$comment": "The seed runtime emits at least one `active:`-prefixed label that is NOT in this id space, and a consumer that matches by prefix rather than by membership will mis-scope it.",
|
||||
"known_example": "active:oversize-input",
|
||||
"what_it_is": "A self-safety flag (OWASP LLM10) raised when the input exceeds the runtime's scan cap, announcing that the tail went unread. It reports the detector's own coverage, not a construct found in the text, which is why it is not a member of this table.",
|
||||
"rule": "Membership in this id space is by presence in `ids`, never by the `active:` prefix. A finding carrying that prefix but absent from `ids` does not belong to this data file, and is therefore OUT of scope for a conformance case scoped here - see spec/conformance-corpus.md section 4.",
|
||||
"introduced": "Between 0bf0729 and de09711; absent at the commit this file's provenance pins."
|
||||
},
|
||||
"stability": "An id is a stable identifier. Changing one is a BREAKING change for any consumer matching on it, and requires a major bump of this file.",
|
||||
"single_runtime": {
|
||||
"$comment": "This id space is ratified by ONE runtime, not two, and that is a weaker status than the injection lexicon's - stated here rather than left to be discovered by a consumer who assumes the two files carry equal weight.",
|
||||
"implemented_by": [
|
||||
"llm_ingestion_guard"
|
||||
],
|
||||
"not_implemented_by": [
|
||||
"llm_security"
|
||||
],
|
||||
"absence_evidence": "Measured in llm-security at b0de0ca, not assumed: a case-insensitive tree-wide search for an active-content detector, class table or emitted `active:` label returns no implementation - only prose in `knowledge/` and an entropy-scanner test that mentions the markdown-image construct. `git log -S 'active_content'` and `git log -S 'active:markdown'` over `--all` return zero commits, so the table was never present and later removed either.",
|
||||
"not_a_coverage_claim": "That runtime having no active-content TABLE is not the same as it being blind to these constructs. Its entropy scanner reaches markdown-image URLs from a different angle (rule E18, host- and query-aware). What is absent is this table, which is all `not_implemented_by` asserts.",
|
||||
"conformance_consequence": "Under spec/conformance-corpus.md section 1.1, a runtime that does not declare this file reports cases scoped to it as `not-applicable` - neither pass nor error."
|
||||
},
|
||||
"aliases": {
|
||||
"$comment": "No `aliases` object is carried per construct, and the omission is deliberate rather than pending. The lexicon needs aliases because two runtimes name the same pattern differently; here the sole implementing runtime's emitted label IS the id, so an alias would be a copy of the key. A second runtime adopting this table registers its alias then - see the lexicon's aliases block for the shape."
|
||||
}
|
||||
},
|
||||
|
||||
"$comment": "Extracted verbatim, without behaviour change, from llm-ingestion-pipeline-security v0.3.4 (commit 0bf0729, 2026-08-03): src/llm_ingestion_guard/active_content.py (pattern table, pass order, URL-shape analysis, defang) and src/llm_ingestion_guard/calibration.py (per-construct severities and opacity floors). That module documents itself as the canonical home of this table with the Node port sharing its severities, which is why the guard is the seed source here rather than llm-security.",
|
||||
|
||||
"provenance": {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue