fix(security): keep untrusted text analysis linear - #52
Merged
Conversation
CodeinScrubs
force-pushed
the
agent/harden-codeql-findings
branch
2 times, most recently
from
August 13, 2026 12:40
90cc44b to
083ce72
Compare
CodeinScrubs
force-pushed
the
agent/harden-codeql-findings
branch
from
August 13, 2026 12:43
083ce72 to
179eab1
Compare
CodeinScrubs
marked this pull request as ready for review
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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-arrayfillcalls - 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 checkpassed 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, andgit diff --checkpassed ## 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.