fix(lexicon,docs): the script-tag row reversed — commons is now the sole diverger
llm-security commit 90f576f (2026-08-10) dropped the closing-</script>-tag requirement from hybrid-xss:script-tag, matching what the guard has always had. Both now agree in shape (no closing tag required), still not byte-identical ([^><] vs [^>]). Commons' own extracted pattern is unchanged under behaviour-preservation, so it is the only one of the three still requiring a closing tag — the opposite of what the divergence doc said when it was written. injection-lexicon.json gains source_fidelity.post_extraction_drift: the existing 83/83-at-b0de0ca claim is untouched (extraction-commit fidelity never decays), and the new 82/83-at-b1ba1fb count carries its own commit and date so it doesn't read as a bare, decaying "vs HEAD" claim. Verified directly against both upstream trees this session, not relayed: llm-security's public remote re-fetched to b1ba1fb, guard read at HEAD 0dce50f.
This commit is contained in:
parent
532d70d5ed
commit
6f79a6ea57
3 changed files with 81 additions and 3 deletions
|
|
@ -94,7 +94,7 @@ Divergence is **not one-directional**. Each side has inputs the other's pattern
|
|||
| `markdown: injection payload in link anchor text` | **guard misses** | `[click ignore this](http://e.com/a(b))` |
|
||||
| `sub-agent: spawn instruction with dangerous capability keywords` | **guard misses** | `create an agent that` + 20 filler words + `execute` |
|
||||
| `sub-agent: delegation with safety bypass instruction` | **guard misses** | `delegate to a new agent` + 200 chars + `bypass` |
|
||||
| `hybrid-xss: <script> tag in content (agent context XSS)` | **commons misses**; span differs | `<script>alert(1)` (unclosed), `<script src=x.js>` |
|
||||
| `hybrid-xss: <script> tag in content (agent context XSS)` | **reversed 2026-08-11, see below** | `<script>alert(1)` (unclosed), `<script src=x.js>` |
|
||||
| `hybrid-xss: iframe with executable src (agent context XSS)` | **guard misses the label, not the attack** | `<iframe data-x="<" src="javascript:alert(1)">` |
|
||||
|
||||
The last row is the one of the 13 that does not reach report level. The guard's
|
||||
|
|
@ -109,6 +109,48 @@ consumer reports offsets or evidence text; it does not change whether a finding
|
|||
The commons-side misses were confirmed in a real JS engine (Node v25.8.2, `RegExp` built from
|
||||
the committed JSON), not only in the Python harness used for the differential.
|
||||
|
||||
### `hybrid-xss:script-tag`: the row reversed, 2026-08-11
|
||||
|
||||
At the time this file was written, `<script>alert(1)` (unclosed) and `<script src=x.js>` were
|
||||
commons misses only in the sense that commons was a byte-identical extraction of
|
||||
`llm-security`, so "commons misses" meant "commons and `llm-security` both miss, the guard
|
||||
does not." That symmetry broke on `llm-security`'s side.
|
||||
|
||||
`llm-security` commit `90f576f` (`fix(llm-security): v8.x-A - close <script> recall hole, add
|
||||
whole-table ReDoS gate`) replaced the source pattern
|
||||
|
||||
```
|
||||
<script\b[^>]*>[\s\S]*?<\/script>
|
||||
```
|
||||
|
||||
with
|
||||
|
||||
```
|
||||
<script\b[^>]*>
|
||||
```
|
||||
|
||||
dropping the closing-tag requirement that produced the recall hole this file first measured.
|
||||
Both witnesses now match on `llm-security`'s side. Verified directly against the module at
|
||||
commit `c67bad3` (2026-08-10, first commit carrying the change) and re-confirmed unmoved at
|
||||
`b1ba1fb` (2026-08-11, current public-remote HEAD as fetched this session) — `git diff
|
||||
c67bad3..b1ba1fb -- scanners/lib/injection-patterns.mjs` is empty, so no later commit touched
|
||||
the pattern a second time.
|
||||
|
||||
The guard's pattern was never the same construct: `<script\b[^><]*>`, negated-class excluding
|
||||
both `>` and `<` (`src/llm_ingestion_guard/injection_lexicon.json:463`, unchanged since
|
||||
`de09711`, re-confirmed unmoved through current guard HEAD `0dce50f`, 2026-08-11). The two
|
||||
patterns now agree on **shape** — both drop the closing-tag requirement, both are a single
|
||||
negated-class run immediately after `<script\b` — but they are still not byte-identical: the
|
||||
guard's excluded-character class also excludes `<`, `llm-security`'s does not. That one-byte
|
||||
difference is unresolved on both sides (see *Open questions* in the coordination thread); it
|
||||
does not reopen the closing-tag question, which is settled.
|
||||
|
||||
Commons still carries the pre-`90f576f` form, unchanged, per this repository's
|
||||
behaviour-preservation invariant — commons does not follow either upstream regex change
|
||||
without an operator decision to re-extract. **Commons is now the sole diverger of the three**
|
||||
on the closing-tag requirement: both `llm-security` and the guard match `<script src=x.js>`
|
||||
and unclosed `<script>alert(1)`; commons' extracted pattern still requires `</script>`.
|
||||
|
||||
## Why they diverge: two different ReDoS mitigations of one table
|
||||
|
||||
This is not drift, and framing it as a bug in either repository would be wrong.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue