Remediation Guides

JQuery 1.2 < 3.5.0 Multiple XSS: How to Fix CVE-2020-11022 and CVE-2020-11023

26 September 2026 8 min read

JQuery 1.2 < 3.5.0 Multiple XSS means a web server is serving a jQuery library older than 3.5.0, a version range affected by two cross-site scripting bugs, CVE-2020-11022 and CVE-2020-11023. To fix it, replace every copy the scanner reports with jQuery 3.5.0 or later (3.7.1 is the newest 3.x release), purge caches, and rescan.

What the scanner is actually detecting

Both Nessus and Greenbone/OpenVAS detect this remotely. They request JavaScript files from the web server and read the version string that jQuery writes into its own header comment. Nothing is exploited during the scan, so the result tells you that an affected version is reachable, not that your application uses it unsafely.

Scanner ID Finding title CVEs Versions flagged
Nessus 136929 JQuery 1.2 < 3.5.0 Multiple XSS CVE-2020-11022, CVE-2020-11023 1.2 up to 3.5.0
Nessus 182682 jQuery < 3.5.0 XSS CVE-2020-11023 1.0.3 through 3.4.x

Greenbone/OpenVAS reports the same 1.2 to 3.4.x range as a jQuery XSS vulnerability under OID 1.3.6.1.4.1.25623.1.0.143812. Tenable places both Nessus plugins in the CGI abuses: XSS family, and plugin 182682 states that it relied only on the application’s self-reported version number. A single old file usually triggers both Nessus plugins, so one upgrade closes both.

The two underlying bugs, both fixed in jQuery 3.5.0:

  • CVE-2020-11022: jQuery.htmlPrefilter used a regular expression to rewrite self-closing tags. Edge cases in that rewrite meant HTML from an untrusted source could execute code when passed to .html(), .append() and related methods, even after sanitizing. Affects 1.2 up to 3.5.0.
  • CVE-2020-11023: untrusted HTML containing <option> elements could execute code when passed to the same DOM manipulation methods, again even after sanitizing. Affects 1.0.3 up to 3.5.0.

Real-world risk

Tenable rates both plugins Medium (CVSS v3 6.1). The honest reading: the bugs matter only if attacker-influenced HTML reaches jQuery DOM manipulation methods such as .html() or .append(). A page that uses jQuery only for selectors, event handlers and AJAX calls with trusted data is not practically exposed. The difficulty is proving that across an application, its templates and its third-party plugins, which is usually more work than upgrading.

Two facts raise the priority. CISA added CVE-2020-11023 to its Known Exploited Vulnerabilities catalog on 23 January 2025, and Tenable reports that exploit code is available. If the old copy sits in an admin console or an authenticated portal, a working XSS runs with the victim’s session and privileges. It does not, on its own, give an attacker code execution on the server.

How to confirm it on the host

Start from the plugin output, which names the URL where the old script was found. Fetch it and read the banner:

curl -s https://app.example.com/js/jquery.min.js | head -c 200

Minified builds begin with a comment such as /*! jQuery v1.12.4 |, while unminified builds contain jQuery JavaScript Library v3.4.1. Next, find every copy on disk, because the scanner only reports the URLs it happened to crawl. On Linux:

grep -rIoE --include='*.js' 'jQuery (JavaScript Library )?v[0-9]+.[0-9]+.[0-9]+' /var/www

On Windows with IIS:

Get-ChildItem -Path C:inetpub -Recurse -Include *.js |
  Select-String -Pattern 'jQuery (JavaScript Library )?vd+.d+.d+' -List |
  Select-Object Path, @{n='Version';e={$_.Matches[0].Value}}

In the browser, open the affected page, then run jQuery.fn.jquery in the developer console to see the version the page is actually using. The console shows only the copy bound to the global jQuery, so also check the Network tab for every jQuery request. For Node.js projects, list every installed copy in the dependency tree:

npm ls jquery --all

How to fix it

A file you host yourself

Download the current 3.x release under a versioned filename, point your templates at it, and delete the old file so it is no longer reachable:

curl -fsSL -o /var/www/app/js/jquery-3.7.1.min.js https://code.jquery.com/jquery-3.7.1.min.js

A new filename also sidesteps stale browser caches, since clients request a URL they have never cached.

Pages that load jQuery from a CDN

Change the script tag and keep Subresource Integrity so the browser rejects a tampered file:

<script src="https://code.jquery.com/jquery-3.7.1.min.js"
        integrity="sha256-/JqT3SQfawRcv/BIHPThkBvs0OEvtFFmqPF/lYI/Cxo="
        crossorigin="anonymous"></script>

npm, NuGet and WebJars builds

Update the dependency, rebuild, and redeploy the build output. The scanner sees the deployed file, not your manifest.

npm install jquery@3.7.1

If jQuery arrives as a transitive dependency, force the version with an overrides block in the root package.json and test the parent package afterwards:

{
  "overrides": {
    "jquery": "3.7.1"
  }
}

In Visual Studio, the NuGet Package Manager Console equivalent is Update-Package jQuery -Version 3.7.1. Java projects using WebJars should move org.webjars:jquery to 3.7.1. Catching old libraries at build time is the job of software composition analysis, which this comparison of SAST, DAST and SCA explains in more detail.

CMS sites, vendor consoles and third-party products

For a CMS, update core, themes and plugins through the normal update mechanism instead of replacing files by hand; plugins and themes often bundle their own jQuery copy, so check each path the scanner lists. For appliances and commercial products (management consoles, embedded web UIs), apply the vendor update that ships a newer jQuery. Hand-edited files in a vendor product are unsupported and get overwritten on the next upgrade. If no update exists, restrict access to the management interface and record a formal exception.

Legacy code: bridge with jQuery Migrate

The jQuery Migrate project states that upgrading to 3.x requires starting from 1.12.x or 2.2.x; older code should first move there using Migrate 1.x. Then load Migrate 3.x after jQuery:

<script src="https://code.jquery.com/jquery-3.7.1.js"></script>
<script src="https://code.jquery.com/jquery-migrate-3.6.0.js"></script>

The development build logs a JQMIGRATE console warning for each removed or deprecated API your code touches. Fix those, switch to jquery-migrate-3.6.0.min.js for production, and remove Migrate once the warnings stop.

How to verify the fix and rescan

  1. Request the old URL from the plugin output with curl. It should return 404, or a banner showing 3.5.0 or later.
  2. Purge the path on any CDN, reverse proxy or cache layer, and confirm every load-balanced node received the deployment.
  3. Run jQuery.fn.jquery in the browser console after a hard reload and confirm it returns the new version.
  4. Repeat the grep or PowerShell search and confirm no pre-3.5.0 banners remain.
  5. Rescan with the same policy. Nessus 136929 and 182682 and the OpenVAS check should no longer report the host; if one persists, its output names the remaining URL.

What can break and how to roll back

The fix itself changes behavior. From 3.5.0, jQuery.htmlPrefilter returns HTML unchanged, so self-closing tags for elements that can hold content are no longer expanded:

// Before 3.5.0 this produced <div></div><span></span>
jQuery( "<div/><span/>" );
// Write explicit closing tags instead
jQuery( "<div></div><span></span>" );

Code jumping from 1.x hits older removals too: .live() is gone, and jQuery 3.0 removed .size() (use .length), .andSelf() (use .addBack()) and the .load(), .unload() and .error() event shorthands (use .on( "load", fn )). Old third-party plugins are the most common source of breakage.

To roll back, keep the previous file in your deployment artifacts (not in the web root) and revert the script tag or package version. Avoid the shortcuts: the upgrade guide shows how to reinstate the old prefilter, and Migrate offers jQuery.migrateEnablePatches( "self-closed-tags" ), but both restore the vulnerable behavior while the version string looks clean. Use them only as a short, documented bridge.

Common false positive reasons

  • Version-only detection. The file is flagged whether or not any code path feeds it untrusted HTML. That is a risk-acceptance question, not a false positive.
  • Stale caches. A CDN, reverse proxy or a node that missed the deployment keeps serving the old file after you upgraded.
  • Orphaned copies. Backup folders, bundled documentation and sample apps still serve old files. They are reachable, so remove them rather than suppress the finding.
  • Vendor-patched builds. Some products patch the flaw but keep the old version banner. Get a written vendor statement before closing the finding.
  • Excluded platforms. Tenable notes that 136929 does not flag Palo Alto PAN-OS (no security impact per Tenable) or Cisco WLC devices, so a hit there deserves a second look.

For a broader checklist, see these common causes of vulnerability scanner false positives.

FAQ

Does jQuery 3.5.0 fix both CVE-2020-11022 and CVE-2020-11023?

Yes. The jQuery security advisories for both CVEs list 3.5.0 as the patched version. Any later 3.x or 4.x release also includes the fix.

Should I upgrade straight to jQuery 4?

jQuery 4.0.0 is the current release and also clears the finding, but the Migrate project says code must reach 3.x first. For legacy applications, 3.7.1 closes the finding with fewer breaking changes.

Is there a workaround if I cannot upgrade yet?

The CVE-2020-11022 advisory suggests overriding jQuery.htmlPrefilter to return its input unchanged (jQuery 1.12 or 2.2 and later), and the CVE-2020-11023 advisory suggests sanitizing with DOMPurify using its SAFE_FOR_JQUERY option. Scanners still see the old version, so treat these as temporary compensating controls.

My site takes no user input. Is it still vulnerable?

If no attacker-influenced HTML ever reaches jQuery DOM methods, practical risk is low. Scanners will keep reporting the file, though, and upgrading is usually cheaper than proving that claim.

Tracking this finding across many hosts

An old jQuery copy tends to appear on dozens of web servers at once, often through the same template or vendor product. SITEY, a self-hosted vulnerability management platform, imports Nessus results (as uploaded .nessus files) and OpenVAS results among its 16 scanner integrations, and it merges duplicates within each scanner, so a Nessus and an OpenVAS record for the same host stay separate items. For Nessus findings it can re-test an individual finding after you replace the file, so closure rests on a fresh check rather than a ticket status.

Sources

SITEY closes the loop, not just the report.Discover, validate, fix and verify in your own infrastructure.

See pricing