← Back to Feed CACHED · 2026-05-17 09:42:19 · cache_key CVE-2025-29912
tenable:106657 · CWE-79 · Disclosed 2018-01-18

JQuery 1

ASSESSED — NOISGATE V0.5
Vendor
Reassessed
Verdict:
01 · The Real Story

Like calling a third-party number and blindly trusting whoever picks up

The finding behind tenable:106657 maps to jQuery’s old habit of auto-executing text/javascript returned from a cross-domain Ajax request when developers used $.ajax() / $.get() without an explicit dataType. Tenable flags jQuery 1.x before 1.12.0 and 2.x before 2.2.0, because the jQuery 1.12.0 / 2.2.0 releases added a mitigation for this behavior. The broader CVE record, CVE-2015-9251, was later scoped as affecting jQuery before 3.0.0, which is why this plugin often under-describes the real version story.

Vendor MEDIUM is fair in a lab, but still a bit generous for enterprise patch triage. The bug is only reachable when the application actually makes a vulnerable cross-origin Ajax call to an attacker-controlled or compromised endpoint, and most sites simply do not do that in a way an external attacker can steer on demand. This is real, but it is heavily conditional, highly application-specific, and a terrible candidate for emergency patching across 10,000 hosts.

"This is a risky jQuery behavior, not a reliable internet-scale compromise path."
02 · The Attack Path

4 steps from start to impact.

STEP 01

Find a jQuery page that makes cross-origin Ajax calls

The attacker first needs a page using vulnerable jQuery plus application code that issues $.ajax() / $.get() to a third-party origin without an explicit dataType. The library version alone is not enough; the application has to exercise the bad pattern. The relevant behavior is documented in jQuery issue #2432 and the later mitigation commit f60729f.
Conditions required:
  • Victim browses an application that ships vulnerable jQuery
  • The application makes a cross-domain Ajax request
  • The request omits an explicit dataType
Where this breaks in practice:
  • Many apps never make cross-origin jQuery Ajax calls at all
  • Modern apps often use fetch, back-end proxies, or explicit JSON APIs instead
  • Static library detection does not prove the dangerous code path exists
Detection/coverage: Version scanners like Nessus/RetireJS catch the library, not the vulnerable runtime call path. SAST/grep for $.ajax(, $.get(, and cross-domain URLs is better for applicability.
STEP 02

Gain control of the remote response

Next the attacker must control the third-party server, compromise it, abuse DNS/redirect behavior, or otherwise influence the response body and Content-Type. The original report demonstrates a malicious endpoint returning text/javascript, which jQuery then treated as executable content.
Conditions required:
  • Attacker controls or can tamper with the cross-origin endpoint
  • Browser can reach that endpoint from the victim context
Where this breaks in practice:
  • This usually requires compromise of a partner API, CDN-like endpoint, or app configuration weakness
  • TLS, pinned destinations, and allowlisted domains make this much less reachable in mature environments
  • If the third-party endpoint is stable and trusted, the attacker has no path
Detection/coverage: Network telemetry may show unexpected third-party requests, but few orgs instrument browser-side Ajax flows well enough to tie them back to this CVE.
STEP 03

Trigger jQuery script auto-execution

On vulnerable versions, jQuery could pass the returned body into jQuery.globalEval() even when the caller did not request script execution. The mitigation commit explicitly added a prefilter to disable auto-execution for crossDomain requests unless dataType: "script" is set.
Conditions required:
  • Returned response is treated as script-capable content
  • The request remains cross-domain in jQuery’s logic
Where this breaks in practice:
  • The exact behavior depends on request options and response headers
  • Applications already using dataType safely or sanitizing flows are not meaningfully exposed
Detection/coverage: Browser DevTools, CSP violation telemetry in some cases, and front-end security testing can expose this. Most infrastructure scanners cannot.
STEP 04

Abuse the victim session in-browser

If execution lands, impact is classic browser-context abuse: session riding, data theft visible to that user, DOM modification, or credential/token capture from the app context. The blast radius is the current user session, not direct server takeover.
Conditions required:
  • Victim must load the affected page and trigger the request
  • The application session has something worth stealing or abusing
Where this breaks in practice:
  • Impact stays inside the browser session unless chained further
  • HttpOnly cookies, strong CSP, and short-lived tokens can reduce practical payoff
Detection/coverage: RUM/browser telemetry or CSP reports can help; EDR on endpoints generally has poor visibility into front-end JavaScript misuse.
03 · Intelligence Metadata

The supporting signals.

Mapped issueCVE-2015-9251; Tenable plugin 106657 specifically keys on the 1.12.0 / 2.2.0 mitigation milestone rather than the broader CVE scope.
In-the-wild statusNo CISA KEV listing and I found no authoritative evidence of active exploitation campaigns tied to this CVE in the sources reviewed.
PoC / weaponizationA public demo exists in jQuery issue #2432 and Packet Storm/RetireJS references are attached from NVD. That makes reproduction easy for testers, but not the same as broad offensive use.
EPSSCurrent public telemetry is elevated for a medium bug: Bitsight shows 18.01% probability over 30 days at the 95th percentile. Tenable’s CVE page also shows FIRST EPSS on the record, which confirms this CVE stays visible in exploit-likelihood feeds.
KEV statusNot present in CISA’s Known Exploited Vulnerabilities Catalog. No due date exists because it is not KEV-listed.
CVSS and meaningNVD scores it 6.1 / MEDIUM with CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N: network reachable, but user interaction is required and impact is browser-session level.
Affected versionsAuthoritative CVE language says jQuery before 3.0.0. The Tenable plugin title is narrower: 1.x < 1.12.0 / 2.x < 2.2.0.
Fixed versionsUpstream mitigation appears in 1.12.0 and 2.2.0 release notes, but Debian notes only 3.0 was fixed upstream for the full CVE because backporting was considered too invasive. Treat 3.0.0+ as the clean answer.
Exposure dataBitsight Groma currently shows about 2,023,513 observations tied to this CVE over the prior 30 days, with 39.02% of observations in the US. That says the library is common, not that each instance is exploitable.
Timeline / attributionThe dangerous behavior was publicly discussed in jQuery issue #2432 on 2015-06-26; the mitigation shipped in the 2016-01-08 jQuery 1.12.0 / 2.2.0 release; NVD published the CVE on 2018-01-18. The GitHub issue was opened by homakov.
04 · The Call

noisgate verdict.

Final Verdict
DOWNGRADED to LOW (3.4/10)

The decisive downgrade factor is attacker reachability: this is not a generic 'load page, get popped' library bug. An attacker needs a very specific application behavior—unsafe cross-origin jQuery Ajax to an attacker-influenced endpoint—which sharply narrows the exposed population even though vulnerable jQuery versions are widespread.

HIGH Version-only scanners overstate real exploitability for this finding
MEDIUM Applicability to any single web app without code-path review

Why this verdict

  • Downgrade for prerequisite chain: the attacker does not get value from the library version alone; they need a live cross-origin $.ajax() / $.get() call with no explicit dataType.
  • Downgrade for attacker position: requiring control of a third-party response path implies either compromise of an external service, misrouting, or application-specific endpoint abuse. That is much narrower than unauthenticated direct exploitation.
  • Downgrade for blast radius: successful exploitation lands in the victim browser session, not as direct server-side code execution or broad host compromise.
  • Slight upward pressure: public demos exist and EPSS is higher than many medium-severity bugs, so this is not noise-only.

Why not higher?

There is no direct pre-auth server compromise path here. The exploit chain depends on a fragile combination of front-end coding pattern, cross-origin request behavior, and attacker control of the response source; that is too much real-world friction for MEDIUM-or-higher patch urgency across a large fleet.

Why not lower?

This is still a real client-side execution issue with public repro steps, and some legacy apps absolutely do make unsafe jQuery cross-domain calls. If one of your internet-facing portals relies on this pattern, the result can still be credential theft or session abuse for active users.

05 · Compensating Control

What to do — in priority order.

  1. Inventory the code path — Within backlog hygiene timing for a LOW issue, confirm whether the app actually performs cross-origin jQuery Ajax without explicit dataType. This is the single fastest way to separate real exposure from scanner noise.
  2. Eliminate browser-to-third-party Ajax where possible — Move third-party API calls server-side or through a same-origin proxy so the browser is not executing trust decisions on remote content. For this LOW verdict, fold this into normal engineering backlog rather than emergency change windows.
  3. Set explicit dataType on legacy jQuery requests — Where legacy code must stay, force dataType: 'json' or another expected type so script auto-execution is not inferred from response headers. Do this during the next planned maintenance cycle.
  4. Harden CSP — Use a stricter script-src and eliminate unnecessary execution allowances to reduce the payoff of browser-side script injection. CSP is not a perfect fix here, but it can reduce downstream abuse while you clean up old front-end code.
What doesn't work
  • A WAF does not reliably help because the bad decision happens inside legitimate browser-side JavaScript after the page loads.
  • Blindly trusting the library version finding does not prove exploitability; this CVE is highly dependent on application behavior.
  • EDR on user endpoints usually has poor visibility into a browser executing allowed JavaScript from an application origin.
06 · Verification

Crowdsourced verification payload.

Run this on the target web server, build artifact directory, or unpacked static-content repo that actually hosts front-end assets. Invoke it as python3 verify_jquery_106657.py /var/www/html or point it at your CI artifact root; no admin rights are required beyond read access to the files.

noisgate-verify.py
PYTHONREAD-ONLYSAFE
#!/usr/bin/env python3
# verify_jquery_106657.py
# Purpose: validate whether local jQuery assets match Tenable plugin 106657 conditions.
# Exit codes: 0=PATCHED, 1=VULNERABLE, 2=UNKNOWN/usage error

import os
import re
import sys
from typing import Optional, Tuple

VERSION_RE = re.compile(r"jQuery v?(\d+)\.(\d+)\.(\d+)", re.I)
FILENAME_RE = re.compile(r"jquery(?:[-.]min)?[-.]?(\d+)\.(\d+)\.(\d+)", re.I)
JS_EXT = (".js", ".jsp", ".html", ".htm", ".cshtml", ".php", ".twig")


def parse_version(text: str) -> Optional[Tuple[int, int, int]]:
    m = VERSION_RE.search(text)
    if m:
        return tuple(map(int, m.groups()))
    m = FILENAME_RE.search(text)
    if m:
        return tuple(map(int, m.groups()))
    return None


def classify(ver: Tuple[int, int, int]) -> str:
    major, minor, patch = ver
    # Tenable plugin 106657 logic
    if major == 1 and ver < (1, 12, 0):
        return "VULNERABLE"
    if major == 2 and ver < (2, 2, 0):
        return "VULNERABLE"

    # Important nuance: broader CVE-2015-9251 language says < 3.0.0.
    # Versions 1.12.x and 2.2.x contain the mitigation Tenable is looking for,
    # but may still be treated as affected by broader CVE records.
    if major in (1, 2) and ver >= ((1, 12, 0) if major == 1 else (2, 2, 0)):
        return "UNKNOWN"

    if major >= 3:
        return "PATCHED"

    return "UNKNOWN"


def inspect_file(path: str) -> Optional[Tuple[Tuple[int, int, int], str]]:
    # First try filename
    ver = parse_version(os.path.basename(path))
    if ver:
        return ver, classify(ver)

    # Then read a small chunk from the file body for the jQuery banner
    try:
        with open(path, "r", encoding="utf-8", errors="ignore") as f:
            chunk = f.read(65536)
        ver = parse_version(chunk)
        if ver:
            return ver, classify(ver)
    except Exception:
        return None
    return None


def main() -> int:
    if len(sys.argv) != 2:
        print("UNKNOWN - usage: python3 verify_jquery_106657.py <webroot-or-artifact-dir>")
        return 2

    root = sys.argv[1]
    if not os.path.exists(root):
        print(f"UNKNOWN - path does not exist: {root}")
        return 2

    findings = []
    for base, _, files in os.walk(root):
        for name in files:
            if not name.lower().endswith(JS_EXT):
                continue
            path = os.path.join(base, name)
            result = inspect_file(path)
            if result:
                ver, state = result
                findings.append((path, ver, state))

    if not findings:
        print("UNKNOWN - no identifiable jQuery assets found")
        return 2

    vulnerable = [f for f in findings if f[2] == "VULNERABLE"]
    unknown = [f for f in findings if f[2] == "UNKNOWN"]
    patched = [f for f in findings if f[2] == "PATCHED"]

    if vulnerable:
        path, ver, _ = vulnerable[0]
        print(f"VULNERABLE - found jQuery {ver[0]}.{ver[1]}.{ver[2]} at {path}")
        return 1

    if unknown:
        sample = unknown[0]
        path, ver, _ = sample
        print(f"UNKNOWN - found jQuery {ver[0]}.{ver[1]}.{ver[2]} at {path}; Tenable plugin condition may be mitigated, but broader CVE-2015-9251 scope should be reviewed")
        return 2

    path, ver, _ = patched[0]
    print(f"PATCHED - found jQuery {ver[0]}.{ver[1]}.{ver[2]} at {path}")
    return 0


if __name__ == "__main__":
    sys.exit(main())
07 · Bottom Line

If you remember one thing.

TL;DR
Monday morning: do not treat this as a fleet-wide fire drill. First, have AppSec or the app owners validate whether affected sites actually make cross-origin jQuery Ajax calls without explicit dataType; for a LOW verdict there is no noisgate mitigation SLA and no noisgate remediation SLA—treat it as backlog hygiene. If the unsafe pattern exists on a sensitive external app, fix the code path and move the jQuery upgrade into the next normal release train; if it is only a library-version hit with no reachable pattern, document the exception and move on.

Sources

  1. Tenable plugin 106657
  2. Official jQuery 1.12.0 / 2.2.0 release notes
  3. jQuery issue #2432
  4. jQuery mitigation commit f60729f
  5. NVD CVE-2015-9251
  6. CISA Known Exploited Vulnerabilities Catalog
  7. Bitsight CVE-2015-9251 observation footprint
  8. Debian security tracker for CVE-2015-9251
Peer Review

What defenders are saying.

Submit a review attribution: handle + country only
0 flags selected · stored anonymously
Validation Results

Crowdsourced verification outputs.

Results submitted by users who ran the verification payload against their environment.