This is a misplaced office key behind the receptionist desk, not a front-door master key
CVE-2025-0227 is a remote file disclosure bug in Tsinghua Unigroup Electronic Archives System affecting version 3.2.210802(62532). The vulnerable component is the /Logs/Annals/downLoad.html handler, where a user-controlled path argument can be manipulated to retrieve unintended files readable by the application, yielding confidentiality impact without stated integrity or availability impact.
The vendor's MEDIUM 4.3 baseline is already restrained, and in enterprise reality it trends slightly lower. The decisive friction is PR:L: the attacker must already hold a valid low-privilege account or equivalent session, which makes this mostly a post-initial-access or post-credential-theft problem in a niche product with no KEV listing, very low EPSS, no public evidence of broad exploitation, and only partial impact.
4 steps from start to impact.
Land a valid application session
- Network reachability to the application
- A valid low-privilege user account or reusable authenticated session
- The target runs the affected
3.2.210802(62532)build
- MFA, SSO, or VPN gating can materially reduce reachable population
- Many deployments of this product are likely internal-only, not internet-facing
- Without credentials, the CVSS
PR:Lprerequisite blocks first-hop abuse
Probe the vulnerable download handler
Burp Suite, curl, or the PoC path referenced in the CVE record, the attacker sends requests to /Logs/Annals/downLoad.html while tampering with the path parameter. The goal is to coerce the handler into returning a file outside the intended access scope.- Authenticated access to the application
- The vulnerable endpoint is deployed and reachable
- Request parameter handling is unchanged from the affected release
- Endpoint paths can vary across reverse proxies or customized deployments
- WAF or reverse-proxy normalization may block obvious traversal-style payloads
- Some deployments may remove or restrict the module entirely
downLoad.html with anomalous path values; off-the-shelf external scanners have weak coverage unless they understand the app and authenticate.Read files the app account can access
- The server-side process has read access to useful files
- Requested files are not separately access-controlled by the application
- Returned content is not redacted or blocked by the server
- The impact is capped at confidentiality and only what the app account can read
- OS permissions and containerization can sharply limit what is obtainable
- There is no stated write, code execution, or service-crash path
Use disclosed data for follow-on abuse
- The disclosed files contain sensitive data or reusable secrets
- The attacker can operationalize the information elsewhere
- Many accessible files may be low-value operational artifacts
- No direct integrity or availability impact is built into this CVE
- Blast radius is usually limited to one application dataset or host context
The supporting signals.
| In-the-wild status | No reliable public evidence of active exploitation found in the sources reviewed; CISA ADP SSVC marks Exploitation: none. |
|---|---|
| Proof-of-concept availability | The CVE record references a public GitHub PoC at BxYQ/ld/file_read1/poc.py; the original repo path appears unavailable now, but the CVE/OpenCVE record still documents it as public exploit material. |
| EPSS | 0.00123 from your intel block, which is extremely low and consistent with a niche, auth-required issue. |
| KEV status | No as of this assessment; not present in the CISA KEV catalog. |
| CVSS vector reality check | CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:N maps to *remote but authenticated* with *low confidentiality-only* impact. That is a built-in downward pressure compared with unauthenticated edge bugs. |
| Affected versions | CVE/OpenCVE lists Tsinghua Unigroup Electronic Archives System 3.2.210802(62532) as affected. No broader version range was published in the record I reviewed. |
| Fixed version | No vendor-fixed version or workaround was published in the cited record; treat patched_version as unknown and verify with the vendor or maintainer. |
| Disclosure timeline | Reserved 2025-01-04, published 2025-01-05, and CISA ADP enrichment updated 2025-01-06. |
| Reporter / assigning authority | Assigned by VulDB per the CVE metadata surfaced in OpenCVE. |
| Exposure / scanning data | I found no trustworthy public Shodan/Censys/FOFA count for this specific product+endpoint combination in the reviewed sources. That absence itself argues against assuming broad internet exposure. |
noisgate verdict.
The single most important reason this lands in LOW is the PR:L requirement: an attacker must already be authenticated, which makes this a follow-on weakness rather than a clean initial-access path. The impact is also bounded to low confidentiality loss with no published integrity, availability, or code-execution angle.
Why this verdict
- Requires authenticated remote access:
PR:Lmeans the attacker needs a valid user account or stolen session first, which implies prior compromise, insider access, or successful credential abuse. - Narrow blast radius: the published impact is file disclosure within the application's readable scope, not host takeover, not arbitrary write, and not service outage.
- Low public threat signal: no KEV listing, extremely low EPSS, and no solid evidence of active campaigns reduce urgency despite the PoC reference.
- Likely niche exposure population: this is not a commodity internet edge product with massive U.S. enterprise footprint, so the vendor score slightly overstates typical fleet-wide urgency for a 10,000-host program.
Why not higher?
This is not an unauthenticated edge compromise and there is no published RCE, auth bypass, mass exploitation evidence, or destructive outcome. Even if reachable over the network, the attacker must already be inside the trust boundary of the application and the documented effect is only low confidentiality loss.
Why not lower?
It is still a real remote application flaw with a disclosed exploit reference, and once an attacker has credentials the path to abuse is straightforward. Archives platforms often hold sensitive documents, so even a low-impact disclosure bug can matter if this app stores HR, legal, or regulated records.
What to do — in priority order.
- Force the app behind trusted access paths — If this system is internet-exposed, move it behind VPN, ZTNA, or source-IP restrictions so the
PR:Lprerequisite cannot be exercised from the open internet. For a LOW verdict there is no formal SLA; treat this as backlog hygiene and complete it in normal hardening work if exposure exists. - Tighten low-privilege account hygiene — Review dormant users, weak local passwords, and shared service accounts because this CVE only matters after authentication. For LOW, there is no mitigation SLA; fold this into routine IAM cleanup and prioritize any account class that can sign into the archives app.
- Log and alert on anomalous
downLoad.htmlaccess — Add reverse-proxy or application logging for repeated requests to/Logs/Annals/downLoad.htmlwith unusualpathvalues, then alert on spikes or off-hours access. For LOW, deploy as backlog hygiene rather than emergency change, unless the system holds highly sensitive records. - Restrict filesystem readability of the app account — Constrain the service account and webroot so successful abuse exposes as little as possible beyond intended archives content. There is no SLA for LOW, but this is one of the few controls that directly shrinks the blast radius even before a vendor patch exists.
- EDR alone does not solve this because the application can read files through normal process behavior; nothing about a successful read necessarily looks malicious at the OS level.
- Network segmentation by itself is weak if the attacker already has internal access or a valid app session; the bug lives in the authenticated web workflow.
- Password rotation without MFA or session controls is incomplete if session cookies can be stolen or reused.
Crowdsourced verification payload.
Run this on the application server or on a mounted application image, not from a random auditor workstation, because it performs an offline install check rather than active exploitation. Invoke it with python3 check_cve_2025_0227.py --root /opt/earchives and supply read access to the installation directory; no admin rights are required beyond filesystem read permissions.
#!/usr/bin/env python3
# check_cve_2025_0227.py
# Offline checker for CVE-2025-0227 in Tsinghua Unigroup Electronic Archives System
# Exit codes: 0=PATCHED, 1=VULNERABLE, 2=UNKNOWN, 3=usage/runtime error
import argparse
import os
import re
import sys
from pathlib import Path
AFFECTED_VERSION = "3.2.210802(62532)"
ENDPOINT_SUFFIX = Path("Logs") / "Annals" / "downLoad.html"
PRODUCT_HINTS = [
"Electronic Archives System",
"Tsinghua Unigroup",
"Archives",
"电子档案",
]
VERSION_FILE_CANDIDATES = [
"version.txt",
"VERSION",
"build.txt",
"manifest.mf",
"pom.properties",
"application.properties",
]
MAX_SCAN_FILES = 4000
MAX_READ_BYTES = 2 * 1024 * 1024
def read_text_safely(path: Path):
try:
if path.stat().st_size > MAX_READ_BYTES:
return None
return path.read_text(encoding="utf-8", errors="ignore")
except Exception:
return None
def find_endpoint(root: Path):
matches = []
for p in root.rglob("downLoad.html"):
try:
rel = p.relative_to(root)
except Exception:
rel = p
if str(rel).replace('\\', '/').endswith(str(ENDPOINT_SUFFIX).replace('\\', '/')):
matches.append(p)
return matches
def scan_for_version_and_product(root: Path):
version_match = False
product_hint = False
scanned = 0
preferred = []
for name in VERSION_FILE_CANDIDATES:
preferred.extend(root.rglob(name))
seen = set()
ordered_paths = []
for p in preferred:
if p.is_file() and p not in seen:
ordered_paths.append(p)
seen.add(p)
for p in root.rglob("*"):
if scanned >= MAX_SCAN_FILES:
break
if p.is_file() and p not in seen:
ordered_paths.append(p)
seen.add(p)
scanned += 1
for p in ordered_paths:
text = read_text_safely(p)
if not text:
continue
if AFFECTED_VERSION in text:
version_match = True
for hint in PRODUCT_HINTS:
if hint.lower() in text.lower():
product_hint = True
break
if version_match and product_hint:
break
return version_match, product_hint
def main():
parser = argparse.ArgumentParser(description="Offline check for CVE-2025-0227")
parser.add_argument("--root", required=True, help="Application installation root")
args = parser.parse_args()
root = Path(args.root)
if not root.exists() or not root.is_dir():
print("UNKNOWN - installation root not found or not a directory")
return 2
endpoint_hits = find_endpoint(root)
version_match, product_hint = scan_for_version_and_product(root)
if endpoint_hits and version_match:
print("VULNERABLE - found affected version '{}' and endpoint '{}'".format(
AFFECTED_VERSION, ENDPOINT_SUFFIX.as_posix()
))
return 1
if product_hint and not endpoint_hits:
print("PATCHED - product indicators found but vulnerable endpoint '{}' not present".format(
ENDPOINT_SUFFIX.as_posix()
))
return 0
if endpoint_hits and not version_match:
print("UNKNOWN - vulnerable endpoint exists but affected version string '{}' was not confirmed".format(
AFFECTED_VERSION
))
return 2
if version_match and not endpoint_hits:
print("UNKNOWN - affected version string found but endpoint '{}' was not located".format(
ENDPOINT_SUFFIX.as_posix()
))
return 2
print("UNKNOWN - insufficient evidence to confirm product, version, or endpoint")
return 2
if __name__ == "__main__":
try:
sys.exit(main())
except KeyboardInterrupt:
print("UNKNOWN - interrupted")
sys.exit(2)
except Exception as exc:
print(f"UNKNOWN - runtime error: {exc}")
sys.exit(3)
If you remember one thing.
3.2.210802(62532). Because this is LOW, there is no noisgate mitigation SLA and no noisgate remediation SLA—treat it as backlog hygiene, document the auth-required exposure, restrict access if any instance is externally reachable, and track the vendor for a real fixed version before folding remediation into routine maintenance.Sources
What defenders are saying.
Crowdsourced verification outputs.
Results submitted by users who ran the verification payload against their environment.