Skip to content

Fix the two regex defects CodeQL flags in the build script - #17

Merged
erseco merged 2 commits into
mainfrom
fix/jakefile-regex-findings
Sep 19, 2026
Merged

erseco merged 2 commits into
mainfrom
fix/jakefile-regex-findings

Conversation

@erseco

@erseco erseco commented Sep 19, 2026

Copy link
Copy Markdown

Summary

CodeQL's first scan of main raised ten alerts. Eight are in the vendored docs/node-jsdoc-toolkit/ documentation generator; the two in our own build script are addressed here.

js/incomplete-sanitization (Jakefile.js:110) — a real bug. The exclude-pattern builder escaped only dots, leaving + ? ^ $ { } ( ) | [ ] \ live in patterns compiled straight into a RegExp. It also passed "g" as a third argument to String.prototype.replace, which takes two and ignores the rest, so with a string pattern only the first * was converted. *foo* compiled to .*foo* — that is .*fo followed by zero or more o, not the intended wildcard.

js/bad-tag-filter (Jakefile.js:17) — the script-tag regex accepted only a bare </script>. It now accepts every browser-tolerated end-tag form via [^>]*, so a tag written as </script > or </script/> can no longer be dropped from the bundle in silence.

Note that CodeQL still reports the line 17 regex. The rule targets HTML sanitizers fed untrusted input; this is a build-time extractor over our own src/index.html, and the regex requires an opening tag, so it can never match a bare </script > no matter how the end-tag part is written. The change is a robustness improvement, not a security fix, and the remaining alert looks like a false positive for this code shape.

The build output does not change

Both defects are latent against today's inputs, verified rather than assumed:

  • All 56 real inputs (the 11 literal exclude entries, index.html, and the 44 script paths in the JS:LIB section) produce a byte-identical pattern under the old and new escaping.
  • The old and new tag regexes extract the same 44 script names from src/index.html.
  • 25 of 26 files in dist/ are byte-identical before and after. The 26th is cache.appcache, which embeds Date.now() at Jakefile.js:149 and so differs between any two builds; stripped of its timestamp line it hashes identically too.
  • dist/js/script.js stays at a3a26210ce5e662136417e436b5e75ba36a80e68bcd0e90f34602d378faedd26, so the hash eXeLearning pins is untouched and no PINNED_REVISION bump is implied.

npm test passes (13 assertions).

Scope

Build script only. No dependency, application-source or CI changes. These files are identical to drichard/mindmaps:master, so this could become a later upstream candidate if the maintainer wants it.

The script-tag regex missed end tags written as `</script >`, so such a
tag would have been dropped from the bundle without warning.

The exclude-pattern builder escaped only dots, leaving every other regex
metacharacter live, and passed "g" as a third argument to String.replace,
where it is ignored -- only the first `*` of a pattern became `.*`, so
`*foo*` compiled to `.*foo*`, which matches `.*fo` followed by zero or
more `o`. Escape the full metacharacter set and make the wildcard
substitution global.

Both are latent: the current exclude list and index.html produce byte
-identical output before and after.
Comment thread Jakefile.js Fixed
\s* covered whitespace but not </script/> or </script bar>, both of
which browsers accept, so CodeQL still reported the regex as incomplete.
[^>]* covers all of them. The build output is unchanged either way.
Comment thread Jakefile.js Dismissed
@erseco
erseco merged commit 96b32d0 into main Sep 19, 2026
5 of 6 checks passed
@erseco
erseco deleted the fix/jakefile-regex-findings branch September 19, 2026 10:09
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.

2 participants