Skip to content

fix(security): keep untrusted text analysis linear - #52

Merged
CodeinScrubs merged 1 commit into
mainfrom
agent/harden-codeql-findings
Aug 13, 2026
Merged

fix(security): keep untrusted text analysis linear#52
CodeinScrubs merged 1 commit into
mainfrom
agent/harden-codeql-findings

Conversation

@CodeinScrubs

@CodeinScrubs CodeinScrubs commented Aug 13, 2026

Copy link
Copy Markdown
Owner

What changed - replaces the raw-text math delimiter regex with a single forward scanner for $...$, $$...$$, $$$$, and \(...\) spans - adds adversarial one-line and multi-line unmatched-\( performance regressions - rewrites UTF-16/code-point offset mapping with bounded typed-array fill calls - restricts Unicode downloader writes to the two repository-owned, version-pinned paths after exact SHA-256 verification - updates the security/performance documentation and adds a core patch changeset ## Root cause and security impact CodeQL identified polynomial regex work on library input. A deterministic timing harness reproduced it: repeated unmatched \( input grew from about 1.9 ms at 2,000 UTF-16 units to about 845 ms at 64,000 units, close to quadratic behavior. BidiLens processes untrusted chat/model output, so this can become an application-level denial-of-service path. The typed-array property and Unicode download alerts are defense-in-depth hardening: offsets are already derived from bounded string iteration, and Unicode URLs/paths/checksums are repository constants. The new structure expresses those invariants directly instead of relying on analyzer inference. ## Correctness evidence - differential harness compared the new scanner with the previous regex on 2,396,745 exhaustive inputs over $, \\, parentheses, text, spaces, LF, and CR; outputs were identical - valid math, empty display math, newline boundaries, and later $...$ after an unmatched \( have direct tests - pnpm run check passed on the final compact scanner: 16 files / 401 tests, 932-case corpus, docs, package builds, and bundled Action - the rebased combined branch passed the focused core suite and emits 124,509 bytes under main's unchanged 124 KiB budget - exact Unicode 17.0.0 reproducibility, typecheck, lint, docs, Action bundle, and git diff --check passed ## Performance evidence After the fix, representative local timings were: - 128,000 UTF-16 units of one-line unmatched \(: 12.6 ms - 96,002 units across 32,000 unmatched lines plus a late closer: 19.1 ms - 80,000 mixed unmatched \( and valid $x$ spans: 17.7 ms These are regression measurements, not universal latency promises. ## Review boundary This is intentionally separate from PR #49's natural-language evidence change. The branch is rebased on merged PR #49, including its changelog evidence, and exact hosted CI is rerunning on the final combined commit; the prior JavaScript CodeQL analysis reported zero results for the same security diff. No alert will be dismissed merely to make the dashboard green.

@CodeinScrubs
CodeinScrubs force-pushed the agent/harden-codeql-findings branch 2 times, most recently from 90cc44b to 083ce72 Compare August 13, 2026 12:40
@CodeinScrubs
CodeinScrubs force-pushed the agent/harden-codeql-findings branch from 083ce72 to 179eab1 Compare August 13, 2026 12:43
@CodeinScrubs
CodeinScrubs marked this pull request as ready for review August 13, 2026 13:07
@CodeinScrubs
CodeinScrubs merged commit 35b2ce6 into main Aug 13, 2026
24 checks passed
@CodeinScrubs
CodeinScrubs deleted the agent/harden-codeql-findings branch August 13, 2026 13:07
CodeinScrubs added a commit that referenced this pull request Aug 13, 2026
## What changed

- removes the Unicode generator's network-to-filesystem refresh mode
- keeps `unicode:generate` and `unicode:check` fully offline against the
two vendored Unicode 17 files
- retains exact SHA-256 verification before any generated tables are
produced
- updates the security and Unicode-maintenance documentation

## Why

The default-branch CodeQL run correctly kept one
`js/http-to-file-access` alert open after PR #52: the optional
maintenance command fetched remote response bytes and wrote them to
disk. Paths and checksums were repository constants, so the path was
bounded, but the strongest production posture is to have no
network-to-filesystem path in the generator at all.

The tradeoff is deliberate: a future Unicode-version upgrade requires
maintainers to download and verify the two source files outside the
repository before replacing the vendored copies. Normal users, CI,
builds, and generation remain offline and reproducible.

## Validation

- `pnpm run check`: 16 files / 401 tests, 932-case corpus, docs,
packages, and Action passed
- `pnpm run release:check`: all 12 packed packages, examples, clean
consumer, CLI runtime, and size budgets passed
- Unicode 17 files reproduce both pinned SHA-256 values
- typecheck, lint, docs, and `git diff --check` passed

This PR targets the one remaining medium default-branch CodeQL finding.
No alert will be dismissed as a substitute for a clean scan.
@CodeinScrubs CodeinScrubs mentioned this pull request Aug 13, 2026
9 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant