Outdated jQuery Library Allows Malicious Scripts to Run in Users' Browsers
Your website uses an outdated version of jQuery (3.3.1), a common tool that helps web pages work smoothly. This version has a known flaw that could allow an attacker to sneak malicious code into your pages if your site processes any content from outside sources — like user-submitted text or third-party data. The fix is straightforward: update jQuery to the latest version.
Business Impact And Actions
medium urgencyBusiness Impact
If your site accepts and displays content from users or external sources, this flaw could be exploited to run unwanted scripts in your visitors' browsers — potentially exposing their session data or redirecting them to harmful pages. This could affect customer trust, create liability under data protection regulations, and flag as a finding in security audits or compliance reviews (such as PCI-DSS or SOC 2).
What To Do
- Ask your developer to upgrade jQuery to version 3.5.0 or later — this is the official fix and is typically a 1–2 hour task.
- If your site allows users to submit or display any kind of text or HTML content, ask your developer to review those areas specifically to ensure user input is never passed directly into jQuery's page-update functions.
- After the upgrade, ask your developer to run a quick smoke test to confirm existing features still work correctly, as the update changes some internal HTML handling behaviour.
- If an immediate upgrade isn't possible, ask your developer about a short-term workaround (overriding the affected function) while the full update is scheduled.
jQuery < 3.5.0 XSS via htmlPrefilter Regex Bypass (CVE-2020-11022)
medium severity CVSS 6.1Vulnerability Explanation
In jQuery versions >= 1.2.0 and < 3.5.0, the `jQuery.htmlPrefilter()` method uses a regex (`rxhtmlTag`) to convert self-closing tags into XHTML-compliant open/close pairs before passing HTML to DOM manipulation methods such as `.html()`, `.append()`, and related functions. This regex transformation can inadvertently restructure attacker-controlled HTML in a way that moves content out of safe contexts (e.g., inside a `<style>` element or an attribute value) and into an executable position in the DOM — causing script execution even when the input was previously sanitized. Public proof-of-concept payloads exist and the vulnerability is remotely exploitable with user interaction (the victim must visit a page that processes attacker-influenced HTML).
Root Cause
The root cause is jQuery's `htmlPrefilter` function relying on a regex substitution to normalise self-closing HTML tags. The regex does not account for all HTML parsing edge cases, meaning certain crafted strings — which appear safe to a sanitiser — are transformed into executable markup when jQuery processes them and assigns the result to `innerHTML`.
Technical Impact
An attacker who can influence HTML content passed to jQuery's DOM manipulation methods (`.html()`, `.append()`, etc.) can execute arbitrary JavaScript in the context of the victim's browser session. This can lead to session token theft, credential harvesting, defacement, or use of the victim's browser as a pivot for further attacks.
Severity Justification
CVSS v3.1 Base Score 6.1 (AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N). Network-accessible, no privileges required, but requires user interaction. Exploitability is conditional on the application passing untrusted HTML through jQuery DOM methods — not all jQuery deployments do this.
Affected Components
jQuery >= 1.2.0 and < 3.5.0
Remediation Steps
- Upgrade jQuery to version 3.5.0 or later. This is the primary and complete fix — the `htmlPrefilter` method was rewritten to eliminate the vulnerable regex transformation.
- Update your `package.json` (or equivalent) and lock file: run `npm install jquery@latest` (or `yarn upgrade jquery`) and commit the updated lock file.
- If an immediate upgrade is not feasible, apply the official temporary workaround by overriding `htmlPrefilter` to a no-op identity function. Note: this removes the XHTML self-closing tag normalisation and requires you to ensure all HTML passed to jQuery DOM methods is independently sanitised (e.g., via DOMPurify).
- Audit all code paths where HTML from user input, API responses, or third-party sources is passed to `.html()`, `.append()`, `.prepend()`, `.after()`, `.before()`, `.replaceWith()`, or `.wrap()`. These are the only paths where this vulnerability is reachable.
- For any such code paths, add server-side or client-side sanitisation using DOMPurify with the `SAFE_FOR_JQUERY` option enabled, as an additional defence-in-depth layer even after upgrading.
Verification Steps
- After upgrading, confirm the version in use: open your browser's developer console on any page that loads jQuery and run `jQuery.fn.jquery` — it should return `3.5.0` or higher.
- Check your built/deployed asset: run `grep -r 'jQuery v' ./public` (or your static assets directory) and verify no pre-3.5.0 version strings remain.
- If you use a CDN-hosted jQuery, verify the `<script>` tag `src` attribute references version 3.5.0 or later.
- Run your existing test suite or perform a manual smoke test of key UI interactions after the upgrade, as the `htmlPrefilter` change may affect edge cases with self-closing tags in dynamically inserted HTML.
Code Examples (javascript)
// jQuery 3.3.1 — vulnerable htmlPrefilter regex
// Internally, jQuery transforms HTML like this before DOM insertion:
// rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)((\w[^/\0>\x20\t\r\n\f]*)[^>]*)\/>/gi
// jQuery.htmlPrefilter = function(html) {
// return html.replace(rxhtmlTag, '<$1></$2>');
// };
// Attacker-influenced payload that bypasses sanitisation:
$('#target').html('<style><style /><img src=x onerror=alert(1)>');
// Option 1 (preferred): Upgrade to jQuery >= 3.5.0
// The htmlPrefilter method is rewritten — no regex transformation.
// No code change required beyond the version bump.
// Option 2 (temporary workaround for jQuery >= 1.12 / 2.2 only):
// Override htmlPrefilter to bypass the vulnerable regex.
// You MUST independently sanitise all HTML before passing to DOM methods.
jQuery.htmlPrefilter = function(html) {
return html;
};
// Option 3 (defence-in-depth, use alongside upgrade):
// Sanitise untrusted HTML with DOMPurify before passing to jQuery.
const clean = DOMPurify.sanitize(dirtyHtml, { SAFE_FOR_JQUERY: true });
$('#target').html(clean);
Best Practices
- Never pass unsanitised user-supplied or third-party HTML directly to jQuery DOM manipulation methods — sanitise it first with a dedicated library such as DOMPurify.
- Pin and regularly audit your JavaScript dependency versions; use `npm audit` or a software composition analysis (SCA) tool in your CI pipeline to catch known-vulnerable libraries before they reach production.
- Prefer DOM-safe jQuery methods (`.text()` instead of `.html()`) when inserting plain text content — this eliminates the HTML parsing attack surface entirely.
- Implement a Content Security Policy (CSP) as a defence-in-depth control; even if XSS occurs, a well-configured CSP can block inline script execution.
Found this in your infrastructure?
VulWall scans for this and dozens of other issues automatically.
Scan Your Domain Free