Like finding a loaded gun inside a bank vault — devastating if reached, but the vault door is the real constraint
CVE-2026-110812 is an unsafe Java deserialization flaw in Amazon Neptune's Gremlin graph-import path, rooted in Apache TinkerPop's Gryo serializer (tracked upstream as TINKERPOP-3278). The Gryo format registers TraversalStrategy types with Kryo's JavaSerializer, which wraps attacker-controlled bytes in ObjectInputStream.readObject() — the classic Java deser sink. An authenticated principal with Neptune data-plane query permissions can submit a crafted Gryo payload through the graph-import API, achieving arbitrary code execution in the Neptune engine environment. The secondary CWE-918 (SSRF) tag indicates the code-execution primitive can reach the AWS Instance Metadata Service (IMDS), leaking internal service-role credentials and enabling lateral pivot to other AWS services (S3, DynamoDB, IAM). Affected engine versions span 1.2.0.0 through all releases before 1.5.0.0, with backport fixes in 1.4.8.1 and 1.4.7.1.
AWS scored this CRITICAL 9.9 with a Scope-Changed vector (S:C), and on paper the CVSS math checks out — network-reachable, low complexity, low privilege, full CIA impact across trust boundaries. But the 9.9 dramatically overstates real-world exploitability. Neptune clusters live inside a VPC by default and have zero internet exposure unless the operator explicitly enables public endpoints (available only since engine 1.4.6.0), which in turn mandates IAM SigV4 authentication. For the vast majority of deployments, an attacker must already hold a foothold inside the VPC — meaning this is a post-initial-access privilege-escalation and lateral-movement vector, not a drive-by RCE. The EPSS score of 0.365% (28th percentile) agrees: the model sees minimal near-term exploitation probability. The vendor severity is defensible as a worst-case ceiling but misleading as an operational priority signal.
5 steps from start to impact.
Establish VPC foothold
- Target Neptune cluster is reachable from attacker-controlled VPC resource
- Attacker has achieved initial access to the AWS account or VPC
- Neptune is VPC-only by default; public endpoints require explicit opt-in (engine ≥1.4.6.0) and force IAM auth on
- Most production deployments follow AWS Well-Architected guidance and keep Neptune in private subnets
Authenticate to Neptune endpoint
neptune-db:* data-plane permissions and must SigV4-sign every request. If IAM auth is disabled (the default for non-public clusters), any entity with TCP access to port 8182 can issue queries with no credentials at all. AWS documentation confirms: *anyone with network access to port 8182 can query, modify, or delete all graph data with no credentials required* when IAM auth is off.- Network path to Neptune port 8182
- Valid IAM credentials with neptune-db permissions (if IAM auth enabled)
- IAM auth with least-privilege policies blocks opportunistic insiders
- Organizations following AWS security best practices have IAM auth enabled
Craft and submit malicious Gryo payload
JavaSerializer.read() calls ObjectInputStream.readObject() on attacker-controlled bytes before any graph-level validation.- Knowledge of Neptune engine classpath to select viable gadget chain
- Ability to submit Gremlin graph-import requests
- No public PoC or weaponized tooling exists as of 2026-10-20
- Attacker must identify which gadget chain libraries are on Neptune's internal classpath — this is opaque in a managed service
- Neptune's managed runtime may have a stripped classpath compared to open-source TinkerPop
Achieve code execution in Neptune engine
- Viable gadget chain executed successfully
- Neptune engine process has sufficient OS-level permissions for next steps
- AWS may have hardened the Neptune runtime with Java Security Manager, module restrictions, or seccomp profiles — specifics are opaque
- Managed-service sandboxing may limit syscall surface
SSRF to IMDS for credential theft and lateral pivot
- IMDS v1 reachable (no IMDSv2 enforcement) or ability to obtain IMDSv2 token
- Neptune service role has permissions to other AWS resources
- AWS has been rolling out IMDSv2-only enforcement across managed services, which requires a PUT-based token hop that complicates SSRF
- Neptune service-linked role permissions may be narrowly scoped
- AWS internal monitoring detects anomalous IMDS access patterns from managed-service containers
UnauthorizedAccess:IAMUser/InstanceCredentialExfiltration finding fires if credentials are used from outside the expected networkneptune-db:* permissions. Enable via aws neptune modify-db-cluster --db-cluster-identifier <id> --enable-iam-database-authentication. Per the noisgate mitigation SLA for HIGH, deploy within 30 days — but given that this is a configuration toggle with no downtime, aim for days not weeks.aws neptune modify-db-cluster --db-cluster-identifier <id> --engine-version 1.5.0.0 --apply-immediately. Expect 20–30 seconds to several minutes of downtime during the restart. Per noisgate remediation SLA for HIGH, complete within 180 days — but given the fix is already available and deployment is a single API call, aim for 30 days.aws neptune describe-db-instances and check AutoMinorVersionUpgrade: true. This does not fix currently vulnerable clusters but prevents future exposure windows from manual upgrade delays.- AWS WAF — Neptune is a database service accessed via direct TCP/WebSocket connections to port 8182, not through API Gateway or ALB. WAF rules cannot inspect or block Gremlin protocol traffic.
- VPC Flow Logs alone — Flow logs capture IP/port/byte-count metadata but cannot inspect Gremlin protocol payloads. You'll see that a connection to port 8182 occurred, but not whether it contained a malicious Gryo payload. Useful for forensics, useless for prevention.
- Encryption at rest — Protects data on the underlying storage volumes. Completely irrelevant to a deserialization attack that operates in the query engine's memory at request-processing time.
- Neptune parameter group tuning — There is no Neptune parameter to disable Gryo deserialization or restrict the graph-import API. The only fix is the engine upgrade.
The supporting signals.
| In-the-wild exploitation | None confirmed. No campaigns, no threat-actor attribution, no CISA KEV listing. AWS bulletin 2026-136-AWS does not mention active exploitation. |
|---|---|
| Proof-of-concept | None public. Checked pocindex.io, GitHub, ExploitDB — no repos or exploits for CVE-2026-110812. The upstream TinkerPop issue TINKERPOP-3278 (reported by Guian Gumpac, 2026-07-28) documents the deserialization sink in GryoReader/JavaSerializer but provides no weaponized payload. Gadget-chain selection requires classpath knowledge of Neptune's managed runtime, which is opaque. |
| EPSS | 0.00365 (0.365%), 28.8th percentile — bottom third. The model predicts very low probability of exploitation within 30 days. |
| CISA KEV | Not listed as of 2026-10-20. |
| CVSS vector | CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H — the S:C (scope change) is the critical element, reflecting escape from Neptune data plane to AWS service plane via IMDS SSRF. PR:L maps to Neptune query permissions, which may require zero credentials if IAM auth is disabled. CVSS v4.0 score is 9.4. |
| Affected versions | Amazon Neptune Engine ≥1.2.0.0 through all releases <1.5.0.0. This spans the entire 1.2.x, 1.3.x, and 1.4.x release families. Note: 1.2.x series reaches end of security support on 2026-12-04. |
| Fixed versions | 1.5.0.0 (primary), 1.4.8.1, 1.4.7.1 (backports). Clusters enrolled in Auto Minor Version Upgrade receive fixes during their next maintenance window. AWS released backports on 2026-09-16 (1.4.7.1) and 2026-09-30 (1.4.8.1) — ahead of the public advisory date. |
| Scanning & exposure | Neptune is a managed VPC-only service — it does not appear in Shodan, Censys, or GreyNoise scans. Public endpoints (since engine 1.4.6.0) mandate IAM auth and are gated by security groups. AWS recommends public endpoints only for non-production environments. There is no external scanning surface for this CVE. |
| Disclosure timeline | Upstream TinkerPop TINKERPOP-3278 reported 2026-07-28 → backport fixes released 2026-09-16/2026-09-30 → AWS bulletin 2026-136-AWS published 2026-10-15 → CVE published same day. |
| Researcher | Guian Gumpac (TINKERPOP-3278 reporter). AWS security team credited for Neptune-specific advisory coordination. |
Sources.
- AWS Security Bulletin 2026-136-AWS
- SecurityOnline — AWS Patches Critical Neptune Vulnerability
- Strix AI — CVE-2026-110812 Analysis
- ThreatInt CVE Database — CVE-2026-110812
- TINKERPOP-3278 — Gryo IO Unsafe Java Deserialization
- AWS Docs — Neptune Security Pillar (Well-Architected)
- AWS Blog — Neptune Public Endpoints
- Neptune Security Card — Attack Vectors & Defense Guide
Why this verdict
- VPC confinement eliminates drive-by exploitation: Neptune clusters are VPC-only by default. Public endpoints exist only on engine ≥1.4.6.0, are opt-in, and force IAM SigV4 authentication. The attacker's first prerequisite is a foothold *inside* the VPC — this is a post-initial-access scenario, not an internet-facing RCE. This alone invalidates the AV:N assumption for the majority of deployments.
- IAM-off default is a double-edged sword but still gated by VPC: When IAM database auth is disabled (the default for non-public clusters), PR:L effectively means 'network access to port 8182.' This is concerning for lateral movement — but the VPC boundary is the real gate. The CVSS score treats PR:L as a single credential step; in practice it's 'break into VPC first, then optionally present credentials.'
- No PoC, no tooling, opaque classpath: Exploiting Java deserialization requires a viable gadget chain on the target classpath. Neptune's managed runtime is opaque — the attacker cannot enumerate available libraries without prior code execution. No public PoC exists, and the TinkerPop advisory provides only the sink description, not a weaponized chain. This raises AC above the L the vendor claims.
- EPSS confirms low near-term risk: At 0.365% (28th percentile), the EPSS model — which incorporates exploit availability, attacker interest, and attack-surface factors — places this firmly in the low-exploitation-probability tier.
- AWS managed-service auto-update compresses the exposure window: Clusters enrolled in Auto Minor Version Upgrade receive patches during the next maintenance window without operator action. AWS pre-positioned backport fixes (1.4.7.1 on 2026-09-16, 1.4.8.1 on 2026-09-30) weeks before the public advisory, meaning many clusters were already patched at disclosure.
- Role multiplier: Neptune is a production database engine and appears in the high-value-role catalog. In its canonical production deployment — storing fraud-detection graphs, identity-resolution data, or compliance relationship maps — the chain succeeds: deserialization → RCE → IMDS SSRF → service-role credential theft → potential S3/DynamoDB/IAM pivot. Blast radius is tenant-to-account (not fleet or domain, since each Neptune cluster's service role is scoped to a single AWS account). Well over 1% of Neptune deployments serve production data tiers, so the verdict floor is HIGH. The floor is not CRITICAL because Neptune is not in the explicit canonical-CRITICAL category (hypervisor, IdP, PAM, CA, network edge, DC role software), and the scope change is bounded to AWS account-level pivot rather than fleet or supply-chain compromise.
Why not higher?
The CRITICAL floor requires the affected component to be canonically high-value-role software where ≥10% of installs define the trust boundary (hypervisors, IdPs, DCs, PAM, CAs, network edge). Neptune is a production database but does not define infrastructure trust boundaries the way a domain controller or hypervisor does. The scope change reaches AWS account-level credentials, not fleet or supply-chain compromise. Additionally, the complete absence of public exploit tooling, the VPC confinement requirement, and the managed-service auto-update mechanism all create meaningful friction that distinguishes this from a true CRITICAL-urgency scenario.
Why not lower?
The scope change (S:C) is real and verified — code execution in the Neptune engine can reach IMDS and steal service-role credentials, enabling pivot to other AWS services within the account. This is not a contained database-only impact. Neptune stores production graph data in regulated and sensitive contexts (fraud detection, identity resolution), making data exfiltration a material concern. The IAM-auth-off default for non-public clusters means that any compromised VPC entity with a network path to port 8182 can exploit this without any credentials. MEDIUM would understate the post-compromise escalation value of this vulnerability.
Crowdsourced verification payload.
Run from any workstation or CI runner with AWS CLI v2 installed and IAM permission neptune:DescribeDBClusters. Usage: bash check_cve_2026_110812.sh [AWS_REGION] — e.g., bash check_cve_2026_110812.sh us-east-1. No elevated OS privileges required; only AWS IAM read permissions.
#!/usr/bin/env bash
# CVE-2026-110812 — Amazon Neptune Gremlin Deserialization Check
# Reports whether each Neptune cluster runs a vulnerable engine version
# and whether IAM database authentication is enabled.
#
# EXIT CODES:
# 0 — PATCHED (all clusters on fixed versions)
# 1 — VULNERABLE (one or more clusters affected)
# 2 — UNKNOWN (query failed or no clusters found)
set -euo pipefail
REGION="${1:-}"
AWS_ARGS=()
[[ -n "$REGION" ]] && AWS_ARGS+=(--region "$REGION")
# Patched engine versions
PATCHED=("1.5.0.0" "1.4.8.1" "1.4.7.1")
VULN_FLOOR="1.2.0.0"
found_vuln=0
found_any=0
# Compare two dotted version strings; returns 0 if $1 >= $2
ver_gte() {
printf '%s\n%s\n' "$1" "$2" | sort -V | head -n1 | grep -qFx "$2"
}
is_patched_ver() {
local v="$1"
for pv in "${PATCHED[@]}"; do
[[ "$v" == "$pv" ]] && return 0
done
ver_gte "$v" "1.5.0.0" && return 0
return 1
}
output=$(aws neptune describe-db-clusters "${AWS_ARGS[@]}" \
--query 'DBClusters[*].[DBClusterIdentifier,EngineVersion,IAMDatabaseAuthenticationEnabled]' \
--output text 2>&1) || {
echo "UNKNOWN — AWS CLI query failed: $output"
exit 2
}
if [[ -z "$output" || "$output" == "None" ]]; then
echo "UNKNOWN — no Neptune clusters found in this region"
exit 2
fi
echo "=== CVE-2026-110812 Neptune Engine Check ==="
echo ""
while IFS=$'\t' read -r cid ver iam; do
[[ -z "$cid" ]] && continue
found_any=1
iam_status="IAM_AUTH_OFF"
[[ "$iam" == "True" || "$iam" == "true" ]] && iam_status="IAM_AUTH_ON"
if is_patched_ver "$ver"; then
echo "PATCHED — cluster=$cid engine=$ver $iam_status"
elif ver_gte "$ver" "$VULN_FLOOR"; then
echo "VULNERABLE — cluster=$cid engine=$ver $iam_status [upgrade to >=1.5.0.0 or backport]"
found_vuln=1
else
echo "PATCHED — cluster=$cid engine=$ver (below affected range)"
fi
done <<< "$output"
echo ""
if [[ $found_any -eq 0 ]]; then
echo "UNKNOWN — no Neptune clusters parsed"
exit 2
elif [[ $found_vuln -eq 1 ]]; then
echo "VULNERABLE — one or more Neptune clusters require patching for CVE-2026-110812"
exit 1
else
echo "PATCHED — all Neptune clusters are on fixed engine versions"
exit 0
fi