Leaving a booby-trapped picture in a rarely-visited hallway of a building almost nobody enters
CVE-2026-8195 is a stored cross-site scripting flaw in the SVG file upload handler within CommonController.java in JeecgBoot 3.9.0 and 3.9.1. An attacker uploads a crafted SVG containing embedded JavaScript. When another user — ideally an admin — views or renders that SVG in the application, the script fires in the victim's browser session. The impact is standard stored-XSS fare: session hijacking, CSRF token theft, phishing overlays, or UI manipulation within the JeecgBoot application context. The fix ships in JeecgBoot 3.9.5.
The vendor's MEDIUM / 5.3 rating is *generous* for real-world risk. JeecgBoot is a Chinese-market low-code enterprise scaffolding framework with roughly 47k GitHub stars but vanishingly small Western enterprise adoption. Shodan surfaces approximately 80 internet-facing instances globally. The affected version window is just two point releases (3.9.0–3.9.1). The attack still requires a victim to interact with the malicious SVG — it is not a drive-by. Altogether, the exploitable population and blast radius are far smaller than the CVSS vector suggests.
3 steps from start to impact.
Upload malicious SVG
<script> tag or event handler (e.g., onload). They submit it to the /sys/common/upload endpoint exposed by CommonController.java. The endpoint stores the file without sanitizing embedded JavaScript within SVG markup.- Access to the JeecgBoot upload endpoint (authentication status unclear — endpoint may require a valid session token depending on Shiro/Spring Security configuration)
- Network reachability to the JeecgBoot instance
- Only ~80 instances are internet-exposed per Shodan; the vast majority sit behind corporate firewalls
- JeecgBoot deployments typically enforce Shiro-based authentication — unauthenticated uploads may be blocked in hardened configs
<script or onload= inside SVG MIME types will flag this. No dedicated Nuclei or Nessus plugin identified for this CVE specifically.Victim renders the SVG
- A privileged user (admin or content reviewer) must view or preview the uploaded file
- The application must serve the SVG inline with a
Content-Type: image/svg+xmlheader, not force a download
- Many modern frameworks set
Content-Disposition: attachmenton user-uploaded files, which prevents inline rendering - CSP headers with
script-srcrestrictions would block inline script execution even if the SVG renders
Session hijack or internal action
document.cookie or DOM access and exfiltrates it to an attacker-controlled server. Alternatively, the script performs in-session actions (creating admin accounts, modifying configurations) on behalf of the victim. Impact is bounded to whatever the victim's JeecgBoot role permits.- Session cookies must lack
HttpOnlyflag for cookie theft - No CSP preventing outbound fetch/XHR to attacker domain
- Modern Spring Boot defaults set
HttpOnlyon session cookies, limiting cookie-theft payloads - The attacker must maintain a reachable callback server, adding operational complexity for low-value targets
The supporting signals.
| In-the-wild exploitation | No known active exploitation. Not listed on CISA KEV. No named campaigns or threat actor attribution. |
|---|---|
| Proof-of-concept | Public. PoC is referenced via GHSA-9FGG-WXFC-5325. Exploit code for SVG-based XSS is trivial and well-documented generically. |
| EPSS score | 0.00269 — bottom ~27th percentile. Probability of exploitation in the next 30 days is negligible. |
| KEV status | Not listed. No CISA KEV entry as of 2026-09-10. |
| CVSS 4.0 vector | CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:P/VC:N/VI:L/VA:N/SC:N/SI:N/SA:N/E:P — Network-reachable, low complexity, but requires user interaction. Integrity impact is Low with no confidentiality or availability impact. |
| CVSS 3.1 score | 4.3 (Medium) — consistent with a low-impact stored XSS requiring interaction. |
| Affected versions | JeecgBoot 3.9.0 and 3.9.1 only. |
| Fixed version | JeecgBoot 3.9.5 (3.9.5" target="_blank" rel="noopener">release notes). Patch commit: a2be896f753936956ee6863b632b8e5a0231345c. Versions 3.9.2–3.9.4 status is unclear; 3.9.5 is the confirmed fix. |
| Internet exposure | Approximately ~80 instances globally visible on Shodan. Extremely small attack surface compared to mainstream enterprise software. |
| Disclosure timeline | Vendor (JeecgBoot / jeecg.com) was contacted prior to public disclosure but did not respond. Exploit and advisory published without vendor coordination. |
noisgate verdict.
The single most decisive factor is the negligible exposed population: only ~80 internet-facing JeecgBoot instances exist globally, the affected version window is just two point releases, and the payload requires victim interaction to fire. The blast radius is capped at the individual user's browser session within a line-of-business application — there is no path to fleet compromise, identity-plane takeover, or supply-chain pivot from this XSS alone.
Why this verdict
- Tiny exposure population: ~80 internet-facing instances globally per Shodan. Even accounting for unindexed instances behind corporate networks, JeecgBoot is a niche Chinese-market low-code framework with minimal Western enterprise adoption. The reachable target set is orders of magnitude smaller than mainstream enterprise software.
- Narrow version window: Only JeecgBoot 3.9.0 and 3.9.1 are affected. Version 3.9.5 was released in July 2026 with this fix included. Organizations on 3.8.x or ≤3.7.x are unaffected, further shrinking the vulnerable population.
- User interaction required: The CVSS vector confirms
UI:P— a victim must navigate to and render the malicious SVG. This is not a drive-by or wormable condition. Stored XSS is more dangerous than reflected, but still requires social engineering or workflow-dependent viewing. - Role multiplier: JeecgBoot is a *line-of-business application scaffolding platform*. It does not occupy any high-value-role position (not an IdP, hypervisor, PAM, backup, CI/CD, CA, network edge, or kernel-mode agent). Virtually 0% of installs serve a fleet-critical or identity-critical function. Compromise of a JeecgBoot session yields access to whatever business data the app manages — typically internal forms, dashboards, and workflow data. The blast radius is application-scoped, not domain- or fleet-scoped. The high-value-role floor does not apply.
- Low-impact XSS class: The CVSS vector shows VI:L (low integrity impact) with no confidentiality or availability impact. Even the vendor's own scoring acknowledges this is a minor integrity issue, not a data-breach or RCE vector.
Why not higher?
A MEDIUM rating would require either a larger exposed population, a path to chaining into RCE or privilege escalation, or deployment in a high-value role. JeecgBoot is not infrastructure — it's an application framework. The ~80 exposed instances and two-version window make even the vendor's MEDIUM generous. There is no evidence of active exploitation, no KEV listing, and the EPSS is bottom-quartile.
Why not lower?
An IGNORE rating would require the vulnerability to be purely theoretical or unexploitable. Here, a public PoC exists, the exploit is trivial (SVG with embedded JS), and stored XSS can still cause real harm (admin session hijack, data manipulation) in organizations that do run affected versions. The vendor's non-response to disclosure is also a concern — there's no indication of server-side SVG sanitization being added in the affected versions. It warrants tracking, just not urgency.
What to do — in priority order.
- Set Content-Disposition: attachment on all user-uploaded files — Force the browser to download SVGs rather than render them inline. This completely neutralizes the XSS vector regardless of file content. Deploy via reverse proxy config (nginx
add_header) or Spring Boot response filter. As a LOW-severity issue, no mitigation SLA applies — treat as backlog hygiene. - Deploy Content-Security-Policy headers with strict script-src — A CSP policy like
script-src 'self'blocks inline scripts inside SVGs even if they render. This is a defense-in-depth measure that protects against the entire class of stored XSS, not just this CVE. - Strip or re-encode SVG uploads server-side — Use a library like DOMPurify (JS) or Apache Batik sanitizer (Java) to strip
<script>, event handlers, andxlink:hreffrom uploaded SVGs before storing them. This eliminates the attack at the source. - Upgrade to JeecgBoot 3.9.5 — The definitive fix. Version 3.9.5 addresses this CVE along with multiple other security issues (RCE, SQLi, SSRF). No mitigation SLA — go straight to the remediation window.
- Network-level blocking / firewall rules — the upload uses standard HTTP POST to a legitimate application endpoint; you cannot block it without blocking normal file uploads
- Antivirus scanning of uploads — AV engines do not flag SVGs containing JavaScript as malicious; this is a web-context attack, not a malware delivery vector
- Rate limiting — the attacker only needs a single upload; throttling does not help
Crowdsourced verification payload.
Run this on the JeecgBoot application server or any host with access to the JeecgBoot installation directory. Requires read access to the project's Maven POM or the deployed JAR. Example: bash check_cve_2026_8195.sh /opt/jeecgboot
#!/usr/bin/env bash
# check_cve_2026_8195.sh — Detect JeecgBoot versions vulnerable to SVG XSS (CVE-2026-8195)
# Usage: bash check_cve_2026_8195.sh /path/to/jeecgboot
# Exit codes: 0 = PATCHED, 1 = VULNERABLE, 2 = UNKNOWN
set -euo pipefail
INSTALL_DIR="${1:-}"
if [ -z "$INSTALL_DIR" ]; then
echo "Usage: $0 /path/to/jeecgboot"
exit 2
fi
# Try to find version from pom.xml
POM="$INSTALL_DIR/pom.xml"
if [ -f "$POM" ]; then
VERSION=$(grep -oP '<version>\K[0-9]+\.[0-9]+\.[0-9]+' "$POM" | head -1)
elif ls "$INSTALL_DIR"/lib/jeecg-boot-base-core-*.jar 2>/dev/null 1>&2; then
JAR=$(ls "$INSTALL_DIR"/lib/jeecg-boot-base-core-*.jar | head -1)
VERSION=$(basename "$JAR" | grep -oP '[0-9]+\.[0-9]+\.[0-9]+')
else
echo "UNKNOWN — could not determine JeecgBoot version from $INSTALL_DIR"
exit 2
fi
if [ -z "$VERSION" ]; then
echo "UNKNOWN — version string not found"
exit 2
fi
echo "Detected JeecgBoot version: $VERSION"
# Affected: 3.9.0 and 3.9.1. Fixed in 3.9.5 (3.9.2-3.9.4 status unclear, treat as vulnerable)
MAJOR=$(echo "$VERSION" | cut -d. -f1)
MINOR=$(echo "$VERSION" | cut -d. -f2)
PATCH=$(echo "$VERSION" | cut -d. -f3)
if [ "$MAJOR" -eq 3 ] && [ "$MINOR" -eq 9 ]; then
if [ "$PATCH" -ge 5 ]; then
echo "PATCHED — version $VERSION is >= 3.9.5"
exit 0
elif [ "$PATCH" -ge 0 ] && [ "$PATCH" -le 4 ]; then
echo "VULNERABLE — version $VERSION is in the affected range (3.9.0–3.9.4). Upgrade to 3.9.5+."
exit 1
fi
elif [ "$MAJOR" -gt 3 ] || { [ "$MAJOR" -eq 3 ] && [ "$MINOR" -gt 9 ]; }; then
echo "PATCHED — version $VERSION is newer than 3.9.x"
exit 0
else
echo "PATCHED — version $VERSION predates the affected 3.9.0–3.9.1 range"
exit 0
fi
echo "UNKNOWN"
exit 2If you remember one thing.
Content-Disposition: attachment to kill inline SVG rendering. If you don't run JeecgBoot at all, this CVE requires zero action from your team.Sources
What defenders are saying.
Crowdsourced verification outputs.
Results submitted by users who ran the verification payload against their environment.