security: fix CodeQL js/xss-through-dom findings [CTO-4840/4841/4842/4843]#302
Open
tech-sushant wants to merge 5 commits into
Open
security: fix CodeQL js/xss-through-dom findings [CTO-4840/4841/4842/4843]#302tech-sushant wants to merge 5 commits into
tech-sushant wants to merge 5 commits into
Conversation
…4843]
Four CodeQL alerts for the same rule (js/xss-through-dom) flagged on
2026-05-19. Each location takes DOM-derived text and routes it into a
sink that interprets it as HTML or as a navigation target. None of
these are remote-exploitable in normal flow — the source values come
from server-rendered Django templates — but a tampered <option value>
or a malicious group name flowing through the URL builder can
escalate to script execution. Cheap fixes, low risk.
templates/global_layout.html (CTO-4840, CTO-4841)
Two <button onclick="javascript:location.href=document.getElementById(...).value">
patterns. Replaced with a helper navigateToSelectedGroup(selectId)
that only navigates if the value is a same-origin relative path
(starts with `/` but not `//`). Blocks `javascript:`/`data:` URIs
and off-origin redirects.
templates/EnigmaOps/allUserAccessList.html (CTO-4842)
title_line.html(title_html) was being fed strings concatenated from
the JS variable `access_type`. Rebuilt the same title with jQuery
element construction APIs (.text() instead of .html()) so
access_type and the username are treated as text, not HTML. Used
{{username|escapejs}} to safely embed the Django value in the JS
literal.
static/files/js/front.js (CTO-4843)
$("#colour").change() concatenated $(this).val() into a CSS path
that was then assigned to a <link href>. A tampered <option value>
could swap the stylesheet for an off-origin URL. Added a regex
allowlist (`^[a-zA-Z0-9_-]+$`) on the theme name before assignment.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…gh-dom Replace the charAt-based path check with a URL parser + same-origin check and reconstruct the navigation target from parsed pathname/search/hash so the taint flow from DOM text into location.assign is broken. CodeQL did not recognize the charAt sanitizer and re-flagged the helper at line 298 on PR #302; the URL-parser pattern is a recognized sanitizer. Refs CTO-4840. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Previous attempt parsed the option value through URL with a same-origin
check, but CodeQL's js/xss-through-dom query treats URL parsing as taint-
preserving and re-flagged the navigation. Cut the DOM-text flow entirely:
emit two JS arrays of `{% url %}` outputs at render time and look up by
the dropdown's selectedIndex (a number, not text). The string passed to
location.assign is now a source-code literal.
Refs CTO-4840.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Bare {% url %} output relies on Django's default HTML autoescape, which
turns `&` into `&` — fine for the current routes but would corrupt
any future URL containing query params when read back by location.assign.
Capture each URL into a Django var and apply |escapejs so the value is
correctly escaped for a JS string literal regardless of what the named
route renders later.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
enigma is a public OSS repo; the inline CTO-* references add no value for external readers. The CodeQL rule name in the comment is enough. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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.
Summary
Closes 4 CodeQL XSS findings raised today (2026-05-19), all of rule `js/xss-through-dom`:
What changed
`templates/global_layout.html` (CTO-4840, CTO-4841)
Two `` patterns. Replaced with a helper that only navigates if the value is a same-origin relative path (starts with `/` but not `//`). Blocks `javascript:`/`data:` URIs and off-origin redirects.
`templates/EnigmaOps/allUserAccessList.html` (CTO-4842)
`title_line.html(title_html)` was being fed strings concatenated from the JS `access_type` variable. Rebuilt the title with jQuery element-creation APIs (`.text()` instead of `.html()`) so `access_type` is treated as text. Used `{{username|escapejs}}` to safely embed the Django value in the JS literal.
`static/files/js/front.js` (CTO-4843)
`$("#colour").change()` concatenated `$(this).val()` into a CSS path and assigned to a ``. Added a regex allowlist (`^[a-zA-Z0-9_-]+$`) on the theme name before any assignment — blocks tampered values pointing to off-origin stylesheets or `javascript:` URIs.
Why this approach
Each is a small, surgical, OSS-friendly fix — no monkey-patches, no environment flags, no surprises for downstream forks. CodeQL alerts close because the data no longer flows from text into an HTML/navigation sink.
Test plan
🤖 Generated with Claude Code