| Both sides previous revisionPrevious revision | |
| provenance:programming:crawler:foxhound [2026/08/17 17:50] – Record the third code bug, found after the review rounds by writing an adversarial stress harness against the rewritten reducer, and the one limitation a name heuristic cannot fix. Refresh the self-test output (25 checks) and the byte comparison. Authored karel.kubicek.claude | provenance:programming:crawler:foxhound [2026/08/17 17:56] (current) – Record the figures-and-code re-review: the UTF-16 offset false negative and the iframe.srcdoc gap (both fixed), the confirmed weak needle, the byte-vs-code-point unit error, and a process defect on my side — reviewers were handed files that changed under karel.kubicek.claude |
|---|
| <code> | <code> |
| $ python3 pages/foxhound_flows.py --selftest | $ python3 pages/foxhound_flows.py --selftest |
| selftest: 25 checks passed | selftest: 31 checks passed |
| |
| flows: 1 sites: 1 pages: 1 scripts: 1 | flows: 1 sites: 1 pages: 1 scripts: 1 |
| </code> | </code> |
| |
| The copy embedded in the page's ''<file python>'' block was byte-compared against ''pages/foxhound_flows.py'' before publication (21,889 bytes each, identical), because a published script that has drifted from the one that was tested is worse than no script: | The copy embedded in the page's ''<file python>'' block was byte-compared against ''pages/foxhound_flows.py'' before publication (24,456 bytes each, identical — a real ''wc -c'' byte count, not Python's ''len()'', which counts code points and was what an earlier draft printed), because a published script that has drifted from the one that was tested is worse than no script: |
| |
| <code bash> | <code bash> |
| taintfox.escapeURL, default false, line 116; 0 occurrences of "taintfox" in all.js | netwerk/base/nsStandardURL.cpp and all.js | taintfox.escapeURL, default false, line 116; 0 occurrences of "taintfox" in all.js | netwerk/base/nsStandardURL.cpp and all.js |
| 68 -> 347 confirmed DOM-XSS flows, i.e. 5x | Sabino et al., NDSS 2026, already in section H | 68 -> 347 confirmed DOM-XSS flows, i.e. 5x | Sabino et al., NDSS 2026, already in section H |
| 25 self-test checks, 10 mutations of the documented fixture | python3 pages/foxhound_flows.py --selftest | 31 self-test checks, 13 mutations of the documented fixture | python3 pages/foxhound_flows.py --selftest |
| | UTF-16 code units: 13 for a two-emoji fixture, offsets 4..6 | the utf16_slice self-test in pages/foxhound_flows.py |
| PR #198 touched 36 files | the PR object's changed_files field. A naive GET of /pulls/198/files returns 30 (its default page size) and under-counts; the external-currency reviewer reported 29 for this reason. The probe asks for per_page=50 and prints changed_files beside it. | PR #198 touched 36 files | the PR object's changed_files field. A naive GET of /pulls/198/files returns 30 (its default page size) and under-counts; the external-currency reviewer reported 29 for this reason. The probe asks for per_page=50 and prints changed_files beside it. |
| 12345, TRK-a55bd7c6, 11-16, 22 characters, 5 characters | strings from the documented worked example and from a cited paper — not figures | 12345, TRK-a55bd7c6, 11-16, 22 characters, 5 characters | strings from the documented worked example and from a cited paper — not figures |
| |
| Everything else it checked came back verbatim, including the ''taintfox.escapeURL'' call site and its ''false'' default, the absence of ''taintfox'' from ''all.js'', the 34/61/1 pref counts, both issue states and the maintainer's legacy-IE sentence, all three mozconfigs and the missing unsuffixed one, the PR #350 diff and the trace-versus-tracking reading of it, the 68→347 quintupling and "would not be exploitable in any modern browser", every cell of the bake-off table including the five compatibility and five transparency figures, the "presense" misspelling (confirmed in both renderings, so the ''[sic]'' is right), and the neighbours' published count of 8. It also noted that for the NDSS 2026 paper ''paper.cols.txt'' is the well-ordered rendering and ''paper.txt'' the interleaved one — the opposite of the case flagged in round one, which is a useful reminder that neither rendering is reliably the better one. | Everything else it checked came back verbatim, including the ''taintfox.escapeURL'' call site and its ''false'' default, the absence of ''taintfox'' from ''all.js'', the 34/61/1 pref counts, both issue states and the maintainer's legacy-IE sentence, all three mozconfigs and the missing unsuffixed one, the PR #350 diff and the trace-versus-tracking reading of it, the 68→347 quintupling and "would not be exploitable in any modern browser", every cell of the bake-off table including the five compatibility and five transparency figures, the "presense" misspelling (confirmed in both renderings, so the ''[sic]'' is right), and the neighbours' published count of 8. It also noted that for the NDSS 2026 paper ''paper.cols.txt'' is the well-ordered rendering and ''paper.txt'' the interleaved one — the opposite of the case flagged in round one, which is a useful reminder that neither rendering is reliably the better one. |
| | |
| | The figures-and-code re-review returned last and found **two more real defects in the published script**, both accepted, plus one confirmation and one cosmetic fix: |
| | |
| | ^ # ^ Finding ^ Disposition ^ |
| | | 1 | **''begin''/''end'' are UTF-16 code-unit offsets, and the script sliced with them in Python, which indexes by code point.** One astral character earlier in the string — an emoji, some CJK extensions — shifts every later index, so the wrong substring is read. The reviewer built the case: on ''"\\U0001F600\\U0001F600<>PADDING"'' the engine's offsets 4..6 bound ''"<>"'', while ''value[4:6]'' returns ''"PA"'', and the flow is therefore reported as having held no syntax character. A **false negative on exactly the screen the script exists to provide**. | **Accepted; reproduced first, then fixed.** ''utf16_slice()'' and ''utf16_len()'' do the slicing in the engine's own unit, four regression tests cover it (including one asserting what the naive Python slice //would// have returned, so the bug cannot come back unnoticed), and the content page now states the offsets are UTF-16 and names the languages this bites in. | |
| | | 2 | ''iframe.srcdoc'' was missing from the HTML/JS sink set although its content is parsed as a whole document, so ''no_syntax_chars'' could never fire for it — on the same page that calls out ''iframe.srcdoc'' as a sink a 2024 paper found missing. | **Accepted.** Added, along with ''script.textContent''. The set now also carries an explicit note that navigation sinks (''location.href'', ''a.href'', ''window.open'') are **deliberately excluded**, because they are dangerous through the ''javascript:'' scheme rather than through markup syntax, and a screen that does not model that should stay silent about them rather than look reassuring. A test asserts both behaviours. | |
| | | 3 | The weak ''"13"'' needle in section H, which occurs 26 times in that paper for unrelated reasons. | **Accepted as confirmation** — independently caught and fixed during the same window; see above. | |
| | | 4 | The provenance page said "20,338 bytes each" for the byte-comparison, but that number is Python's ''len()'' — code points. The file has em dashes, so the real ''wc -c'' differs. | **Accepted.** The claim of identity was right; the unit was wrong, and the figure is now a real byte count. | |
| | |
| | **A process defect on my side, recorded because it degraded the review:** this reviewer reported that the files under review changed on disk while it worked, because I was applying the other reviewers' fixes in parallel instead of freezing the tree. It anchored its findings to the snapshot it started from and flagged the drift, which is the right response — but it should not have had to. The next run should copy the artefacts to a frozen directory and point reviewers at that. |
| |
| ===== Rendering check ===== | ===== Rendering check ===== |