Flag innerHTML/outerHTML += append sink in security-guidance#76475
Open
winklemad wants to merge 1 commit into
Open
Flag innerHTML/outerHTML += append sink in security-guidance#76475winklemad wants to merge 1 commit into
winklemad wants to merge 1 commit into
Conversation
The innerHTML_xss and outerHTML_xss rules matched by substring
(".innerHTML =" / ".innerHTML="), so `el.innerHTML += userInput` - the most
common DOM XSS append sink - was never flagged, along with tab and
multi-space assignment variants. The same substrings also false-positived on
`==`/`===` comparisons. Replace them with a regex that catches `=` and `+=`
with any whitespace and uses a negative lookahead to skip comparisons.
Adds regression tests (the plugin previously shipped none).
This was referenced Jul 10, 2026
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.
No linked issue — found while reading the security-guidance patterns.
Summary
The
innerHTML_xssandouterHTML_xssrules inplugins/security-guidance/hooks/patterns.pymatch by substring:This misses
el.innerHTML += userInput— the most common DOM-XSS append sink.+=desugars tox = x + …, which re-parses the whole value as HTML, so it's an innerHTML assignment and squarely within the rule's stated scope ("Setting innerHTML with untrusted content can lead to XSS"). Tab- and multi-space-separated assignments (el.innerHTML = x) are missed too. Separately, the substring.innerHTML =also matches.innerHTML ==/===comparisons, which are reads rather than sinks — a false positive.Observed through the shipped
check_patterns:Fix
Replace the two substring lists with a regex, matching the plugin's own regex-rule style (used by ~20 other rules):
\s*absorbs tabs/extra spaces,\+?catches+=, and the(?!=)lookahead skips==/===comparisons (fixing the false positive too). After the change all five cases above behave correctly, and read-only access (const x = el.innerHTML) is still not flagged.innerHTML_xssandouterHTML_xsswere the only two rules using the assignment-substring form[".X =", ".X="], so both are covered here. I also checked the otherregexrules that match=(verify=False,shell=True,weights_only=True, …): those are boolean/kwarg flags with no meaningful+=form, so they don't share this gap.Test
Adds
plugins/security-guidance/hooks/tests/test_innerhtml_patterns.py(the plugin previously shipped no tests). It parametrizes both rules across every sink form — plain=,+=, no-space+=, multi-space, tab, and optional chaining (obj?.innerHTML =) — and every non-sink form that must stay quiet —==,===, and read-only access. 20 cases; it fails on the current code (12 of 20) and passes with the fix.