← Back to Feed CACHED · 2026-06-30 01:52:38 · CACHE_KEY CVE-2026-13501
CVE-2026-13501 · CWE-74 · Disclosed 2026-06-28

A security vulnerability has been detected in antlr ANTLR4 up to 4

ASSESSED — NOISGATE V0.5
Vendor
Reassessed
Verdict:
Do you agree?
01 · The Real Story

ANTLR's Go code generator hands a grammar-controlled string to `gofmt` and forgets to sanitize it

CVE-2026-13501 lives in tool/src/org/antlr/v4/codegen/target/GoTarget.java of ANTLR4 through 4.13.2. When the Go code generator finishes emitting .go files, it shells out to gofmt and passes path/filename data derived from the grammar file. A crafted grammar can inject shell metacharacters into that invocation, achieving command execution as the user running antlr4 -Dlanguage=Go — typically a developer or a CI build agent. The vector is AV:L because the attacker must convince a victim to compile a malicious .g4 grammar; there is no network surface.

Vendor MEDIUM (5.3) is slightly inflated for the realistic deployment. ANTLR is a build-time tool, not a runtime service, and the impacts (C:L/I:L/A:L) only manifest if you compile attacker-supplied grammars — an unusual workflow outside grammar marketplaces or pull-request CI. For typical enterprise consumers who own their grammars, the practical risk is closer to LOW. The exception is anyone running a hosted grammar-compilation service or accepting third-party .g4 files in CI.

"Local command injection in ANTLR's gofmt invocation — affects developer/CI machines, not production. Vendor MEDIUM is generous."
02 · The Attack Path

4 steps from start to impact.

STEP 01

Attacker crafts a malicious .g4 grammar

The attacker authors an ANTLR grammar file whose options or filename embeds shell metacharacters (backticks, $(...), ;, &&) that will be passed through to the gofmt subprocess invocation in GoTarget.java. Public PoC weaponization is trivial — echo "grammar X; options{...};" > evil.g4 with the injection payload in the offending field.
Conditions required:
  • Knowledge of the GoTarget codegen path
  • Ability to deliver the .g4 file to a victim
Where this breaks in practice:
  • Most enterprises author grammars in-house; they don't ingest third-party .g4 files
Detection/coverage: No scanner rule today; SAST tools won't flag a grammar file
STEP 02

Victim invokes ANTLR with Go target

A developer or CI job runs antlr4 -Dlanguage=Go evil.g4 or equivalent Maven/Gradle plugin invocation. Only Go-target builds reach the vulnerable code path — Java, Python, C#, TypeScript targets are unaffected because the bug is GoTarget-specific.
Conditions required:
  • Victim uses -Dlanguage=Go
  • ANTLR 4.13.2 or older installed
  • gofmt present on PATH
Where this breaks in practice:
  • Go target is a minority of ANTLR users
  • Many shops pin grammars and code-review changes
Detection/coverage: Source-control PR review catches obvious payloads; EDR sees the gofmt child process
STEP 03

Injected command executes under build user

gofmt is launched via a non-quoted shell-style invocation; the injected payload runs with whatever privileges the build user holds. On a dev laptop that's the user. On a Jenkins/GitHub Actions runner it's the runner's service account — often with checkout tokens and registry credentials in scope.
Conditions required:
  • Build agent has secrets in environment
  • No seccomp/sandbox isolation
Where this breaks in practice:
  • Ephemeral GitHub-hosted runners limit blast radius to one job
  • Hardened CI uses OIDC short-lived tokens
Detection/coverage: EDR on the build host flags unexpected child processes spawned from gofmt; CI audit logs show anomalous shell commands
STEP 04

Pivot to supply-chain compromise (worst-case)

If the compromised host is a shared CI runner with persistent credentials, the attacker steals signing keys, registry tokens, or modifies build artifacts downstream. This is the only path that gets past LOW — and it requires the victim to have already accepted attacker-controlled grammar input in their pipeline.
Conditions required:
  • Self-hosted/persistent CI runner
  • Long-lived secrets present
  • Output artifacts published downstream
Where this breaks in practice:
  • Modern CI guidance is ephemeral runners + OIDC
  • Code review on third-party PRs
Detection/coverage: Sigstore/SLSA provenance mismatches; secret-scanner alerts on exfil
03 · Intelligence Metadata

The supporting signals.

In-the-wild exploitationNone observed. No campaign or incident reporting as of 2026-06-30.
Public PoCDisclosure note says exploit is public; trivial to weaponize given a .g4 grammar and -Dlanguage=Go target.
EPSS0.00678 (~0.7%) — bottom decile of exploit-likelihood scoring.
KEV statusNot listed by CISA.
CVSS vectorCVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:L/I:L/A:L — local attack vector, low privilege, partial CIA impact. CVSS v4.0 is 4.8.
Affected versionsANTLR4 up to and including 4.13.2 when invoked with -Dlanguage=Go.
Fixed versionNo vendor patch published. Vendor reportedly did not respond to coordinated disclosure (per Vulnerability-Lookup).
Vulnerable code pathtool/src/org/antlr/v4/codegen/target/GoTarget.java — the gofmt post-processing call.
Exposure dataNot internet-reachable; ANTLR is a build-time CLI. Shodan/GreyNoise N/A.
DisclosurePublished 2026-06-28 via VulDB / Vulnerability-Lookup. CWE-77 also assigned alongside CWE-74.
04 · The Call

noisgate verdict.

Final Verdict
DOWNGRADED to LOW (3.1/10)

Downgraded from MEDIUM to LOW because the single most decisive factor is attacker-controlled grammar input is required at build time — a workflow virtually no enterprise has unless they operate a hosted grammar compiler or accept untrusted .g4 files from external contributors. Exploitation cannot reach this code path through any runtime service or network exposure.

HIGH vulnerability mechanics and version range
HIGH exposure population is negligible outside CI accepting third-party grammars
MEDIUM vendor patch availability — no fix advisory observed as of 2026-06-30

Why this verdict

  • Local-only attack vector (AV:L): no network exposure. Attacker must place a malicious grammar onto a build host and trigger compilation. Removes any internet-scanning population entirely.
  • Go target only: the bug lives in GoTarget.java. Shops using Java/Python/C#/TS code generation — the majority of ANTLR users — are not on the vulnerable code path at all.
  • Build-time tool, not a service: ANTLR4 ships zero runtime daemons. Production servers running compiled parsers cannot be hit by this CVE. The blast radius is limited to whoever runs the antlr4 tool itself.
  • Role multiplier — developer workstation: chain succeeds; outcome is single-user compromise of one laptop. Blast radius: host. Not fleet.
  • Role multiplier — ephemeral CI runner (e.g. GitHub-hosted): chain succeeds; blast radius is one job's secrets, contained by runner lifecycle.
  • Role multiplier — self-hosted persistent CI runner accepting third-party grammar PRs: chain succeeds and reaches supply-chain pivot. This is the worst case but the installed-base share is well under 1% of ANTLR consumers (typical shops compile their own grammars). Insufficient to floor the verdict above LOW.
  • EPSS 0.00678 + no KEV + no observed exploitation corroborates the low real-world urgency.

Why not higher?

MEDIUM would imply the bug can be triggered without attacker-controlled grammar input, or that the tool runs in a service role. Neither is true. CVSS v3.1's local-vector + low-impact scoring already produces 5.3; once you apply the realistic exposure filter (only Go-target users compiling untrusted grammars), the practical risk drops further. HIGH would require either network reachability or a fleet-scale blast radius — this has neither.

Why not lower?

IGNORE is wrong because the chain IS exploitable, public PoC exists, and there is one credible enterprise scenario (self-hosted CI runner ingesting third-party grammar contributions) where it leads to supply-chain compromise. Worth tracking on the backlog and fixing when ANTLR ships a patch.

05 · Compensating Control

What to do — in priority order.

  1. Inventory ANTLR4 usage, filter to Go-target builds — Grep build manifests (pom.xml, build.gradle, Makefile, package.json) for antlr4 invocations with -Dlanguage=Go or the Go runtime dependency. Non-Go users have no exposure. Since verdict is LOW there is no noisgate mitigation SLA — fold this inventory into normal asset hygiene.
  2. Forbid third-party .g4 files in CI without review — Treat grammar files like any other executable code in PRs. Require human review for any .g4 change from external contributors; reject grammars with shell metacharacters in options, headers, or filenames. Implement now on any pipeline that does accept external grammars.
  3. Move grammar compilation to ephemeral runners — If you use self-hosted CI agents that compile ANTLR grammars, migrate those specific jobs to ephemeral GitHub-hosted / GitLab SaaS runners or single-use container runners. Limits blast radius of any successful injection to one job's short-lived credentials.
  4. Strip gofmt from build images you don't need it on — If a build image does not require gofmt for legitimate purposes, remove the Go toolchain entirely. ANTLR's vulnerable code path silently no-ops when gofmt is absent.
  5. Track upstream for a fix release — Vendor did not respond to initial disclosure per the published note. Subscribe to antlr/antlr4 GitHub releases and bump within the noisgate remediation SLA window (365 days) once a fixed version ships.
What doesn't work
  • WAF / network controls — the vector is local file invocation; there is no HTTP request to filter.
  • Runtime application self-protection (RASP) — ANTLR is not in your runtime; it's a build tool. Production parsers generated by ANTLR are not affected.
  • Patching the generated Go parser code — the bug is in the codegen step itself, not in the emitted parser. Regenerating with a fixed ANTLR is the only true fix.
  • Disabling gofmt autoformat in your IDE — unrelated; the call happens inside the antlr4 tool, not your editor.
06 · Verification

Crowdsourced verification payload.

Run this on each build host or CI runner that has ANTLR installed. Invoke as ./check_antlr_cve_2026_13501.sh — no privileges required beyond what the build user already has. Checks the ANTLR jar version and reports VULNERABLE if ≤4.13.2.

noisgate-verify.sh
BASHREAD-ONLYSAFE
#!/usr/bin/env bash
# noisgate verification: CVE-2026-13501 (ANTLR4 GoTarget command injection)
# Exit codes: 0 = PATCHED, 1 = VULNERABLE, 2 = UNKNOWN
set -u

find_antlr() {
  # Common locations + classpath search
  local candidates=()
  while IFS= read -r p; do candidates+=("$p"); done < <(
    { command -v antlr4 antlr 2>/dev/null;
      find / -name 'antlr-*-complete.jar' -o -name 'antlr4-*.jar' 2>/dev/null;
    } | sort -u
  )
  printf '%s\n' "${candidates[@]}"
}

compare_version() {
  # returns 0 if $1 <= $2
  [ "$(printf '%s\n%s\n' "$1" "$2" | sort -V | head -n1)" = "$1" ]
}

status=UNKNOWN
found_any=0

for item in $(find_antlr); do
  found_any=1
  ver=""
  if [ -f "$item" ]; then
    ver=$(echo "$item" | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' | head -n1)
  else
    ver=$("$item" 2>&1 | grep -oE 'Version [0-9]+\.[0-9]+\.[0-9]+' | awk '{print $2}' | head -n1)
  fi
  [ -z "$ver" ] && continue
  echo "Found ANTLR at $item — version $ver"
  if compare_version "$ver" "4.13.2"; then
    echo "  -> VULNERABLE (≤ 4.13.2)"
    status=VULNERABLE
  else
    echo "  -> PATCHED"
    [ "$status" != "VULNERABLE" ] && status=PATCHED
  fi
done

if [ $found_any -eq 0 ]; then
  echo "UNKNOWN: no ANTLR installation located on this host"
  exit 2
fi

echo "Result: $status"
case "$status" in
  PATCHED)    exit 0 ;;
  VULNERABLE) exit 1 ;;
  *)          exit 2 ;;
esac
07 · Bottom Line

If you remember one thing.

TL;DR
Park this one. CVE-2026-13501 is a LOW in any realistic enterprise context — it's a build-time command injection in ANTLR's Go code generator that requires you to compile an attacker-supplied grammar. With verdict LOW there is no noisgate mitigation SLA — go straight to the noisgate remediation SLA of ≤365 days to upgrade ANTLR4 once upstream ships a fix (vendor has not responded to disclosure as of 2026-06-30, so this may sit unfixed for a while). Monday morning: spend 30 minutes grep'ing your build manifests for -Dlanguage=Go ANTLR invocations, then escalate to HIGH only if you operate a self-hosted CI runner that compiles third-party .g4 grammars — in that narrow case, gate external grammar contributions through human review immediately and migrate the job to an ephemeral runner.

Sources

  1. Vulnerability-Lookup: CVE-2026-13501
  2. Vulnerability-Lookup: CVE-2026-13500 (sibling bug, same disclosure batch)
  3. GHSA-Q226-W36V-HHXV (related ANTLR4 advisory)
  4. ANTLR4 GitHub repository
  5. Maven Central: org.antlr:antlr4:4.13.2
  6. CWE-74: Injection
  7. CWE-77: Command Injection
  8. Snyk: antlr4 advisories
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.