This is a spare key hidden inside the admin office, not the front door left open
CVE-2026-3956 is a SQL injection in xierongwkhd/weimai-wetapp affecting builds up to commit 5fe9e8225be4f73f2c5087f134aff657bdf1c6f2, disclosed on 2026-03-11. The vulnerable path is the admin endpoint /admin/auser/getAdmins, where the keyword parameter is passed through the controller, service, and MyBatis mapper chain without proper neutralization, enabling attacker-controlled SQL execution.
The vendor's MEDIUM 4.7 is slightly generous for enterprise prioritization. Yes, SQLi is always ugly and the public issue shows sqlmap working, but the decisive friction is that this is an admin-side endpoint with PR:H, in a niche open-source movie-ticket application with no evidence of broad enterprise exposure, KEV listing, or active exploitation.
4 steps from start to impact.
Reach the admin surface
/admin/auser/getAdmins.- Target organization actually deploys
weimai-wetappbackend - Admin backend is reachable over the network
- Attacker can discover the admin route structure
- This is a niche GitHub project, not a mainstream enterprise platform
- Many deployments will never expose the admin panel to the public internet
- No reliable internet-scale fingerprinting evidence was found
/admin/ paths, but generic vulnerability scanners may miss this without authenticated coverage.Obtain high-privilege application access
- Valid authenticated session to the admin application
- Sufficient privileges to access admin user listing functions
- This is post-initial-access or insider abuse, not true unauthenticated internet exploitation
- MFA, SSO, and admin network restrictions commonly block this stage
- Compromising an admin account is a separate security failure
Weaponize the keyword parameter with sqlmap
sqlmap proof of concept against GET /admin/auser/getAdmins?pageNum=1&limit=10&keyword=.... The researcher reports boolean-based blind and error-based exploitation and retrieval of the current database user.- Backend remains vulnerable at or before commit
5fe9e8225be4f73f2c5087f134aff657bdf1c6f2 - Input reaches the MyBatis query unsafely
- Database error behavior or timing differences remain observable
- Authenticated scanners are uncommon across internally hosted niche apps
- App-layer exception handling may blunt some error-based techniques
- DB permissions may cap what can actually be read or changed
keyword; DB audit logs and app logs can also show malformed search terms and unusual query failures.Abuse database-level access for deeper impact
sqlmap recovered the current DB user as root@%, which suggests some deployments may have overly broad database privileges and therefore higher local blast radius than the CVSS base impact implies.- Injected SQL executes successfully
- Database account has meaningful read/write privileges
- Sensitive admin, user, or ticketing data exists in the schema
- Damage is largely bounded to this application's database tier
- There is no evidence here of direct OS-level code execution
- Blast radius depends heavily on local DB privilege hygiene
The supporting signals.
| In-the-wild status | No evidence found of active exploitation campaigns; not in CISA KEV as checked against the KEV catalog. |
|---|---|
| Proof-of-concept availability | Yes. Public PoC in GitHub Issue #48 uses sqlmap against /admin/auser/getAdmins and reports successful boolean-based blind and error-based exploitation. |
| EPSS | 0.00041 (user-supplied), which is extremely low and aligns with a niche, low-observed-threat profile. |
| KEV status | No; no KEV entry located as of this assessment. |
| CVSS vector | CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:L/I:L/A:L — network reachable, easy to exploit *once logged in*, but requires high privileges and has only low CIA impact in the base model. |
| Affected versions | Vendor/CNA describes affected code as up to commit 5fe9e8225be4f73f2c5087f134aff657bdf1c6f2 in the rolling-release repository. |
| Fixed version | No official fixed release or patched commit was identified. The repo shows no Releases published, and NVD notes the project had not responded. |
| Exposure reality | This appears to be a student/open-source movie-ticket app with a separate admin backend, not a broadly deployed enterprise product. *Inference:* reachable population is likely very small compared with mainstream business software. |
| Internet-scale visibility | No authoritative Shodan/Censys fingerprint or exposure count was found for this product, which itself is a downward pressure on urgency because defender populations appear limited. |
| Disclosure and reporter | Public issue opened on 2026-02-26 by NinjaGPT; CVE published on 2026-03-11 via VulDB. |
noisgate verdict.
The single most important severity reducer is the PR:H authenticated-admin requirement: this is not an initial-access bug, it is a post-auth trust-boundary break inside an admin workflow. Public PoC raises confidence that the flaw is real, but the product's narrow deployment footprint and lack of exploitation evidence keep this out of the patch-now tier for most enterprises.
Why this verdict
- Major downward adjustment: requires high privileges — the CVSS
PR:Hrequirement means the attacker already has authenticated admin-grade access, so this is post-initial-access rather than perimeter compromise. - Population is narrow —
weimai-wetappis a niche GitHub-hosted movie-ticket application, not a common enterprise platform; *inference:* only a tiny fraction of organizations will have this deployed at all. - Admin backend exposure is likely limited — the vulnerable route is in the admin area, and many real deployments will keep that surface internal, behind VPN, or behind SSO/MFA.
- Public PoC prevents IGNORE — the GitHub issue shows
sqlmapexploitation, so if you do run this code, the bug is practical rather than theoretical. - No active exploitation signal — not KEV-listed, no campaign reporting found, and the supplied EPSS is extremely low.
Why not higher?
Because every critical prerequisite narrows the reachable population: the attacker needs network reachability to the admin app, then authenticated high privileges, then a deployment that still runs the vulnerable code. That compounding friction makes this a poor candidate for urgent fleet-wide interruption unless you specifically operate this app.
Why not lower?
It is still a confirmed SQL injection with a public working PoC, not a noisy scanner false positive. If your organization actually runs this backend, a compromised admin account can likely turn this into direct database read/write abuse, so documenting and fixing it is still warranted.
What to do — in priority order.
- Restrict admin reachability — Move the
/admin/backend behind VPN, bastion, or private network controls and keep it off the public internet where possible. For a LOW verdict there is no SLA (treat as backlog hygiene), but if this app is internet-exposed you should do this during the next routine access-control change window. - Enforce strong admin auth — Require SSO and MFA for all admin access because the biggest friction in the exploit chain is authenticated admin possession. For a LOW verdict there is no SLA (treat as backlog hygiene), but this should be part of your standing hardening baseline.
- Add request filtering on
keyword— Apply reverse-proxy or WAF rules to flag or block obvious SQL metacharacters and commonsqlmappatterns on/admin/auser/getAdmins. This is not a perfect fix, but it can reduce opportunistic abuse until a code change lands; for LOW, there is no SLA (treat as backlog hygiene). - Reduce DB account privileges — Ensure the application database user is not effectively privileged beyond what the admin search function needs. The public issue's
root@%result suggests some deployments may be running with dangerous DB permissions; for LOW, there is no SLA (treat as backlog hygiene), but this is a worthwhile cleanup.
- Relying on perimeter AV or endpoint AV alone — this is an application-layer injection through normal HTTP requests.
- Only patching the public mini-program front end — the vulnerable path is in the separate admin backend.
- Assuming obscurity of the route protects you — the path is already public in the CVE and GitHub issue.
- Trusting CVSS impact as a proxy for business urgency — the real limiter here is attacker position, not the theoretical SQLi mechanics.
Crowdsourced verification payload.
Run this on the application host or build workspace that contains the weimai-wetapp source tree or an extracted deployment directory. Invoke it as bash verify-cve-2026-3956.sh /opt/weimai-wetapp with read access only; no root is required unless the app files are permission-restricted.
#!/usr/bin/env bash
# verify-cve-2026-3956.sh
# Checks a local weimai-wetapp source/deployment tree for indicators of CVE-2026-3956.
# Exit codes: 0=PATCHED, 1=VULNERABLE, 2=UNKNOWN, 3=usage/error
set -u
TARGET_DIR="${1:-}"
if [ -z "$TARGET_DIR" ] || [ ! -d "$TARGET_DIR" ]; then
echo "Usage: bash verify-cve-2026-3956.sh /path/to/weimai-wetapp"
echo "UNKNOWN"
exit 3
fi
controller_file="$(find "$TARGET_DIR" -type f -name 'Admin_AdminUserController.java' 2>/dev/null | head -n 1)"
service_file="$(find "$TARGET_DIR" -type f -name 'AdminUserService.java' 2>/dev/null | head -n 1)"
mapper_file="$(find "$TARGET_DIR" -type f \( -name 'AdminUserMapper.xml' -o -name '*AdminUser*Mapper*.xml' \) 2>/dev/null | head -n 1)"
if [ -z "$controller_file" ] && [ -z "$service_file" ] && [ -z "$mapper_file" ]; then
echo "UNKNOWN - could not locate expected weimai-wetapp admin source files"
exit 2
fi
has_controller=0
has_service_chain=0
has_unsafe_mapper=0
has_safe_signal=0
if [ -n "$controller_file" ]; then
if grep -Eq '@GetMapping\(\{"/getAdmins"\}\)|@RequestParam\(value *= *"keyword"' "$controller_file" 2>/dev/null; then
has_controller=1
fi
fi
if [ -n "$service_file" ]; then
if grep -Eq 'getAdmins\(.*keyword\)|getAdminsByKeword\(keyword\)' "$service_file" 2>/dev/null; then
has_service_chain=1
fi
if grep -Eq 'StringUtils|escapeSql|PreparedStatement|sanitize|validator' "$service_file" 2>/dev/null; then
has_safe_signal=1
fi
fi
if [ -n "$mapper_file" ]; then
# MyBatis ${...} is a common unsafe string-substitution signal; #{...} is parameterized.
if grep -Eq '\$\{[^}]*keyword[^}]*\}' "$mapper_file" 2>/dev/null; then
has_unsafe_mapper=1
fi
if grep -Eq '#\{[^}]*keyword[^}]*\}' "$mapper_file" 2>/dev/null; then
has_safe_signal=1
fi
fi
# Decision logic
if [ "$has_controller" -eq 1 ] && [ "$has_service_chain" -eq 1 ] && [ "$has_unsafe_mapper" -eq 1 ]; then
echo "VULNERABLE - admin getAdmins keyword flow with unsafe MyBatis substitution detected"
exit 1
fi
if [ "$has_controller" -eq 1 ] && [ "$has_service_chain" -eq 1 ] && [ "$has_safe_signal" -eq 1 ] && [ "$has_unsafe_mapper" -eq 0 ]; then
echo "PATCHED - keyword flow present but only parameterized/sanitized indicators found"
exit 0
fi
if [ "$has_controller" -eq 1 ] || [ "$has_service_chain" -eq 1 ]; then
echo "UNKNOWN - admin keyword flow detected, but mapper evidence is incomplete"
exit 2
fi
echo "UNKNOWN - insufficient evidence to classify"
exit 2
If you remember one thing.
Sources
What defenders are saying.
Crowdsourced verification outputs.
Results submitted by users who ran the verification payload against their environment.