Skip to content

Comments

Potential fix for code scanning alert no. 2: DOM text reinterpreted as HTML#34

Open
niyazialpay wants to merge 1 commit intomainfrom
alert-autofix-2
Open

Potential fix for code scanning alert no. 2: DOM text reinterpreted as HTML#34
niyazialpay wants to merge 1 commit intomainfrom
alert-autofix-2

Conversation

@niyazialpay
Copy link
Owner

Potential fix for https://github.com/niyazialpay/AlphaBlog/security/code-scanning/2

In general, the problem arises because a string taken from the DOM (data-target / href) is passed directly into a(...)/$(...). jQuery interprets this parameter as either a selector or an HTML fragment, which can allow HTML injection / XSS when the string is attacker-controlled. To fix this, we must ensure that the string is only ever treated as a selector (and only of the allowed, safe form), and never as arbitrary HTML. This can be done by validating it against a whitelist (e.g., allow only simple ID selectors like #something) and then using a context that does not reinterpret it as HTML.

For this specific code, the simplest safe adjustment that preserves existing functionality is:

  1. Validate f before using it.
  2. If f is not of a safe form (e.g., not a simple #id selector), ignore it and fall back to e.closest(".alert"), which is the current fallback.
  3. When resolved, continue to use a(f) as a selector—Bootstrap expects selectors here—but only after ensuring it is just a selector, not arbitrary HTML.

We can add a small helper inside this IIFE to check that f is a simple ID selector (/^#[A-Za-z][A-Za-z0-9\-_:.]*$/). If the string fails validation, we set f to null and let the following g.length || (g = e.closest(".alert")) logic choose the closest .alert instead. This preserves behavior for all normal Bootstrap usage (where data-target="#myAlert" or href="#myAlert"), but prevents harmful HTML/selector strings from being used directly.

Concretely:

  • Inside the +function(a) { ... }(jQuery) that defines the alert plugin, define a local function isSafeSelector(sel) before d.prototype.close.
  • In d.prototype.close, after computing f from data-target/href, validate f. If !isSafeSelector(f), set f = null.
  • Change the line var g = a("#" === f ? [] : f); to safely handle null/unsafe values: if f is falsy, initialize g as an empty jQuery object, so the later g.length || (g = e.closest(".alert")) fallback kicks in.

No external dependencies or imports are needed; everything is self-contained within this file and closure.


Suggested fixes powered by Copilot Autofix. Review carefully before merging.

…s HTML

Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
@secure-code-warrior-for-github

Micro-Learning Topic: DOM text reinterpreted as HTML (Detected by phrase)

Matched on "DOM text reinterpreted as HTML"

What is this? (2min video)

Reinterpreting text from the DOM as HTML can lead to a cross-site scripting vulnerability.

Try a challenge in Secure Code Warrior

Micro-Learning Topic: HTML injection (Detected by phrase)

Matched on "HTML injection"

XSS flaws occur whenever an application includes untrusted data in a new web page without proper validation or escaping, or updates an existing web page with user-supplied data using a browser API that can create HTML or JavaScript. XSS allows attackers to execute scripts in the victim’s browser which can hijack user sessions, deface web sites, or redirect the user to malicious sites. Source: https://www.owasp.org/index.php/Category:OWASP_Top_Ten_Project

Try a challenge in Secure Code Warrior

Helpful references

Micro-Learning Topic: Cross-site scripting (Detected by phrase)

Matched on "XSS"

Cross-site scripting vulnerabilities occur when unescaped input is rendered into a page displayed to the user. When HTML or script is included in the input, it will be processed by a user's browser as HTML or script and can alter the appearance of the page or execute malicious scripts in their user context.

Try a challenge in Secure Code Warrior

Helpful references

@niyazialpay niyazialpay marked this pull request as ready for review January 16, 2026 20:53
f = f && f.replace(/.*(?=#[^\s]*$)/, ""));
var g = a("#" === f ? [] : f);
d._isSafeSelector(f) || (f = null);
var g = f ? a("#" === f ? [] : f) : a();

Check failure

Code scanning / CodeQL

DOM text reinterpreted as HTML High

DOM text
is reinterpreted as HTML without escaping meta-characters.

Copilot Autofix

AI about 1 month ago

In general, the fix is to ensure that untrusted text taken from the DOM (here, data-target / href) is not passed directly to a(...) (jQuery) in a way that could be interpreted as HTML. Instead, we should either (1) validate that it is a safe, restricted selector pattern before using it in $(), or (2) use APIs that only ever interpret it as a selector and never as HTML, or (3) fall back to a safe default (like the closest .alert) when the selector is unsafe.

The best fix, preserving existing behavior, is to validate f against a strict pattern for allowed selectors and discard it when it doesn’t match. You already have a helper d._isSafeSelector (lines 67–71) that allows only simple ID selectors like #my-alert. The minimal, targeted change is to ensure that any unsafe selector results in no element being selected (so jQuery is never invoked with potentially HTML-looking strings). Currently we already have:

81:                 d._isSafeSelector(f) || (f = null);
82:                 var g = f ? a("#" === f ? [] : f) : a();

However, this still uses the slightly odd "#" === f ? [] : f expression, which is unnecessary when f is either null or a validated ID selector (it will always start with # and have more than one character if valid). We can simplify and make the intent clearer by:

  • Keeping d._isSafeSelector(f) as the gatekeeper.
  • After that, using f ? a(f) : a(); instead of "#" === f ? [] : f, since f will be null for unsafe or empty values and a valid #id string for safe ones.
  • This prevents any possibility of jQuery interpreting HTML-like text, because only validated #id selectors reach it.

Concretely, in public/themes/Default/js/bootstrap.js within d.prototype.close, we will:

  1. Leave the _isSafeSelector helper as-is.
  2. Replace line 82 to remove the "#" === f ? [] : f ternary and rely solely on the safe/unsafe guard on line 81.

No new methods or imports are required; we only adjust the use of f when constructing the jQuery object.


Suggested changeset 1
public/themes/Default/js/bootstrap.js

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/public/themes/Default/js/bootstrap.js b/public/themes/Default/js/bootstrap.js
--- a/public/themes/Default/js/bootstrap.js
+++ b/public/themes/Default/js/bootstrap.js
@@ -79,7 +79,7 @@
                 f || (f = e.attr("href"),
                     f = f && f.replace(/.*(?=#[^\s]*$)/, ""));
                 d._isSafeSelector(f) || (f = null);
-                var g = f ? a("#" === f ? [] : f) : a();
+                var g = f ? a(f) : a();
                 b && b.preventDefault(),
                 g.length || (g = e.closest(".alert")),
                     g.trigger(b = a.Event("close.bs.alert")),
EOF
@@ -79,7 +79,7 @@
f || (f = e.attr("href"),
f = f && f.replace(/.*(?=#[^\s]*$)/, ""));
d._isSafeSelector(f) || (f = null);
var g = f ? a("#" === f ? [] : f) : a();
var g = f ? a(f) : a();
b && b.preventDefault(),
g.length || (g = e.closest(".alert")),
g.trigger(b = a.Event("close.bs.alert")),
Copilot is powered by AI and may make mistakes. Always verify output.
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