← Back to Feed CACHED · 2026-10-02 00:16:33 · CACHE_KEY CVE-2026-13500
CVE-2026-13500 · CWE-74 · Disclosed 2026-06-28

ANTLR4 Grammar Action Block Code Injection via OutputFile.java

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

This is like reporting that a C compiler can compile malicious code and calling it a remote exploit

CVE-2026-13500 targets tool/src/org/antlr/v4/codegen/model/OutputFile.java in ANTLR4 versions 4.13.0 through 4.13.2. ANTLR4 is a parser generator — a *build-time developer tool* that reads .g4 grammar files and emits source code in a target language (Java, Python, C#, etc.). Grammar files support action blocks: inline snippets of target-language code that get embedded verbatim into the generated output. The "vulnerability" is that a malicious .g4 file can contain arbitrary code in these action blocks, which then appears in the generated source. If that generated source is compiled and executed, the injected code runs. Affected versions are 4.13.0, 4.13.1, and 4.13.2. No fix exists or is planned — the ANTLR4 maintainers have stated this is a core design feature that cannot be removed without breaking the tool entirely.

The vendor CVSS 3.1 score of 7.3 HIGH with vector AV:N/AC:L/PR:N/UI:N is grossly misleading. There is no network service, no listener, no unauthenticated remote entry point. The attack requires an adversary to social-engineer a developer into processing a trojanized grammar file, or to compromise a source repository — then the generated code must be compiled and executed. This is functionally identical to a supply-chain trojan (like a malicious Makefile or poisoned dependency), not a remotely exploitable vulnerability. Notably, CVSS 4.0 already corrects downward to 6.9 MEDIUM, and the ANTLR4 maintainers themselves say the practical risk is "close to null." Rundeck, a major downstream consumer, formally assessed this as a false positive because they only ship antlr4-runtime (not the code-generation tool). The 7.3 HIGH label will generate scanner noise across your fleet for a risk that requires a multi-step supply-chain attack against a developer tool.

"ANTLR4 grammar injection is a developer-tool design feature mislabeled as a network vuln"
02 · The Attack Path

4 steps from start to impact.

STEP 01

Craft a trojanized .g4 grammar file

The attacker creates a valid ANTLR4 grammar file (.g4) with malicious target-language code embedded in action blocks (@header, @members, or inline {...} actions). These blocks accept arbitrary code by design — there is no sanitization because that is the intended feature. The malicious grammar must be syntactically valid to pass ANTLR4's own parser.
Conditions required:
  • Attacker must understand ANTLR4 grammar syntax and action block semantics
  • Attacker must know the target language (Java, Python, C#, etc.) of the victim's code generation pipeline
Where this breaks in practice:
  • Crafting a convincing grammar requires domain knowledge of the victim's parser project
  • A grammar with suspicious action blocks is detectable via code review or diff inspection
Detection/coverage: No scanner specifically flags malicious action blocks in .g4 files. Standard SAST tools do not parse ANTLR4 grammars.
STEP 02

Deliver the grammar to the victim's build environment

The malicious .g4 file must reach a location where the ANTLR4 tool will process it. Delivery vectors include: pull request to an open-source grammar repository, typosquatted grammar package, compromised internal repo, or direct social engineering (e.g., 'here is a grammar for your new DSL'). This is a supply-chain insertion step, not a network exploit.
Conditions required:
  • Attacker must have write access to a grammar source the victim trusts, OR must social-engineer a developer into using the file
  • The victim must be using the antlr4-tool (code generator), not just antlr4-runtime
Where this breaks in practice:
  • Most enterprises version-control grammars in private repos with access controls and code review
  • Open-source grammar repos (antlr/grammars-v4) have maintainer review
  • Most ANTLR4 consumers only use antlr4-runtime — the tool is only used at grammar-authoring time
Detection/coverage: SCM audit logs, PR review processes, signed commits. No CVE-specific scanner signature exists.
STEP 03

ANTLR4 tool generates source with injected code

When a developer or CI pipeline invokes antlr4 (via CLI, Maven plugin antlr4-maven-plugin, or Gradle plugin) against the malicious grammar, the tool faithfully transcribes action block content into the generated .java/.py/.cs source files. This step is automatic and produces no warnings — the tool is working as designed.
Conditions required:
  • The antlr4-tool must be invoked against the malicious grammar file
  • The build system must be configured to run ANTLR4 code generation
Where this breaks in practice:
  • Developer reviewing generated source diffs would see injected code
  • CI pipelines that diff generated output against a baseline would flag changes
Detection/coverage: SAST scanning of generated source files *could* catch suspicious code patterns (e.g., Runtime.exec(), os.system()), but this is not standard practice for ANTLR-generated code.
STEP 04

Generated code is compiled and executed

The injected code only runs when the generated source is compiled into the target project and executed — either in a test suite, CI pipeline, or production deployment. At this point the attacker achieves code execution in the context of the build user or application runtime, with whatever privileges that process holds.
Conditions required:
  • Generated source must pass compilation (it will, since action blocks contain valid target-language code)
  • The compiled artifact must be executed — in tests, CI, or production
Where this breaks in practice:
  • Multiple human and automated review gates typically exist between grammar change and production deployment
  • The blast radius is limited to the build environment or the specific application using the generated parser
Detection/coverage: EDR on build hosts would detect anomalous process spawning from a Java/Python process. Runtime application security (RASP) may flag unexpected system calls.
03 · Compensating Control

1
LOW 2.5→IGNORE 0.0
SEVERITY REDUCED
Audit whether your builds use antlr4-tool or only antlr4-runtime — Most Java/Python/.NET projects depend on antlr4-runtime only — the runtime parses input against pre-generated code and is not affected. If your SCA scanner flags antlr4 as a dependency, check whether it's the antlr4-maven-plugin, antlr4-tool jar, or antlr4-runtime. If runtime-only, suppress the finding. No mitigation SLA applies for LOW — treat as backlog hygiene.
2
LOW 2.5→IGNORE 0.0
SEVERITY REDUCED
Pin and review .g4 grammar files in version control — If your builds do invoke the ANTLR4 tool, ensure all .g4 grammar files are committed to your SCM with code-review requirements (CODEOWNERS, branch protection). Never pull grammars from external sources at build time without pinning to a reviewed commit hash. This eliminates the supply-chain delivery vector entirely.
3
LOW 2.5→IGNORE 0.0
SEVERITY REDUCED
Diff generated source output in CI — Add a CI step that diffs ANTLR4-generated source files against a checked-in baseline. Any change to generated code triggers review. This catches injected action-block content even if a malicious grammar slips through. Low-effort to implement with standard git diff --exit-code on generated directories.
4
LOW 2.5→IGNORE 0.0
SEVERITY REDUCED
Run ANTLR4 tool in a sandboxed build container — If you run antlr4 in CI, execute it inside a sandboxed container with no network access and minimal filesystem permissions. Even if malicious code is injected and compiled, it cannot exfiltrate data or pivot. Standard practice for build isolation.
What doesn't work
  • Upgrading ANTLR4 — no fix exists or is planned. The behavior is by design. Upgrading to a hypothetical future version will not change this, as the maintainers have explicitly stated they will not remove action block support.
  • WAF or network-layer controls — there is no network attack surface. ANTLR4 is a local CLI tool. Network controls are completely irrelevant.
  • Vulnerability scanning / SCA suppression alone — suppressing the scanner finding without verifying whether you use antlr4-tool vs antlr4-runtime leaves you uncertain. Verify first, then suppress.
04 · Intelligence Metadata

The supporting signals.

In-the-wild exploitationNone observed. Not listed on CISA KEV. No reports of active campaigns targeting ANTLR4 grammar processing. The ANTLR4 maintainers explicitly state practical risk is "close to null."
Proof-of-conceptA public PoC exists at wooyun123/wooyun#4, demonstrating malicious action block injection. The PoC is trivial — it's literally writing code in a grammar action block, which is the tool's intended function. No weaponized exploit chain exists.
EPSS0.00516 (0.42nd percentile) — in the bottom half of all scored CVEs. FIRST's model considers exploitation extremely unlikely.
KEV statusNot listed. No indication of addition pending.
CVSS vectorsCVSS 3.1: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:L → 7.3 HIGH. CVSS 4.0: 6.9 MEDIUM. The AV:N (Network) and UI:N (No User Interaction) components are factually incorrect — there is no network service and the attack absolutely requires user interaction (processing a malicious grammar file).
Affected versionsANTLR4 4.13.0, 4.13.1, 4.13.2. Only the antlr4-tool component is affected — antlr4-runtime (the library most consumers ship) is not affected.
Fixed versionsNone. No fix planned. ANTLR4 maintainers have stated the behavior is by design and cannot be removed without breaking the core action-block feature. Downstream vendors (Rundeck, etc.) have assessed this as a false positive.
Scanning / exposure dataNo network exposure. ANTLR4 is a build-time tool, not a network service. Shodan/Censys/GreyNoise have zero relevance. Scanner noise will come from SCA tools flagging the antlr4 dependency in Maven/Gradle/pip manifests.
Disclosure timelineDisclosed 2026-06-28 via VulDB (VulDB #374495). Vendor contacted early but "did not respond in any way" per VulDB's disclosure note. ANTLR4 maintainers later clarified their position that this is intended behavior.
ReporterAttributed to wooyun123 via the GitHub issue. No affiliation with a major security research organization disclosed.

Sources.

  1. NVD — CVE-2026-13500
  2. CIRCL Vulnerability Lookup — CVE-2026-13500
  3. Rundeck — CVE-2026-13500 False Positive Assessment
  4. OpenCVE — CVE-2026-13500
  5. GHSA-M64J-M5C8-F58P — GitHub Security Advisory
  6. VulDB — Entry #374495
  7. OSV — DEBIAN-CVE-2026-13500
  8. PoC Reference — wooyun123/wooyun#4
05 · The Call

Final Verdict
↓ DOWNGRADED to LOW (2.5/10)

Why this verdict

  • Misclassified attack vector: The CVSS vector claims AV:N/AC:L/PR:N/UI:N, but there is no network service. The attack requires delivering a malicious .g4 file to a developer's build environment and having them process it — this is a supply-chain/social-engineering prerequisite, not an unauthenticated remote exploit. Correcting to AV:L/AC:H/PR:N/UI:R alone drops the base score below 5.0.
  • Multi-step supply-chain chain with compounding friction: The attack requires (1) crafting a malicious grammar, (2) getting it accepted into a trusted source, (3) having the ANTLR4 *tool* (not runtime) process it, and (4) compiling and executing the output. Each step has independent friction: code review, SCM access controls, build pipeline diffing, and SAST scanning of generated code.
  • Vendor confirms by-design behavior: The ANTLR4 maintainers explicitly state this is a core design feature (action blocks are *supposed* to contain arbitrary target-language code) and will not issue a fix. This is the parser-generator equivalent of saying 'gcc can compile malicious C code.' Multiple downstream vendors (Rundeck) have formally assessed this as a false positive.
  • Role multiplier: ANTLR4 tool is a *build-time developer utility*, not a production service. (a) Dev workstation (primary role, ~70% of installs): local-only impact, blast radius limited to one developer's machine. (b) CI/CD pipeline (~25% of installs): the tool runs in CI to regenerate parsers, but grammars are version-controlled with review gates; blast radius bounded to the CI runner. (c) Production runtime (<5%): only antlr4-runtime ships to production, and the runtime is NOT affected by this CVE. No high-value-role floor applies — the affected component is not an IdP, hypervisor, DC, PAM, backup, edge appliance, or any canonical high-value role. The worst plausible outcome is code execution on a CI runner or developer workstation, which is a local/host-level blast radius.
  • EPSS confirms negligible exploitation likelihood: At 0.00516 (0.42nd percentile), FIRST's empirical model rates this among the least likely CVEs to be exploited. No KEV listing, no campaign reports, no threat intel attributions.

Why not higher?

While the PoC is public and trivial to reproduce, every step of the attack chain requires prior access or social engineering that compounding friction makes impractical at scale. The affected component (antlr4-tool) is a build-time utility, not a production service — it never listens on a network port, never processes untrusted input in normal operation, and the vast majority of ANTLR4 consumers only ship antlr4-runtime (which is unaffected). There is no high-value-role deployment pattern that would floor this above LOW.

Why not lower?

An IGNORE verdict would be inappropriate because the CVE is technically valid — a malicious grammar file *can* inject code into generated output, and CI/CD pipelines that process grammars from semi-trusted sources (e.g., open-source grammar repos pulled at build time) do have a narrow but real attack surface. A 2.5 LOW acknowledges this theoretical supply-chain risk while reflecting the enormous practical friction.

06 · Verification

Crowdsourced verification payload.

Run this script on any build host or CI runner where ANTLR4 may be used. It checks Maven, Gradle, and pip environments for the presence of the affected antlr4-tool component (not the runtime). Requires read access to project directories. Invoke with: bash check_cve_2026_13500.sh /path/to/project

noisgate-verify.sh
BASHREAD-ONLYSAFE
#!/usr/bin/env bash
# CVE-2026-13500 Checker — ANTLR4 Tool (not runtime) presence & version
# Usage: bash check_cve_2026_13500.sh /path/to/project
# Exit codes: 0=PATCHED/NOT_AFFECTED, 1=VULNERABLE, 2=UNKNOWN

set -euo pipefail

PROJECT_DIR="${1:-.}"
VULN_VERSIONS="4\.13\.[012]"
FOUND_TOOL=0
FOUND_VULN=0

echo "[*] CVE-2026-13500: Checking for antlr4-tool in $PROJECT_DIR"

# Check Maven pom.xml for antlr4-maven-plugin
while IFS= read -r -d '' pomfile; do
  if grep -q 'antlr4-maven-plugin' "$pomfile" 2>/dev/null; then
    FOUND_TOOL=1
    ver=$(grep -A5 'antlr4-maven-plugin' "$pomfile" | grep -oP '(?<=<version>)[^<]+' | head -1)
    if [[ -n "$ver" ]] && echo "$ver" | grep -qP "^${VULN_VERSIONS}$"; then
      echo "[!] VULNERABLE: $pomfile uses antlr4-maven-plugin version $ver"
      FOUND_VULN=1
    elif [[ -n "$ver" ]]; then
      echo "[+] $pomfile uses antlr4-maven-plugin version $ver (check manually)"
    else
      echo "[?] $pomfile references antlr4-maven-plugin but version not parsed"
    fi
  fi
done < <(find "$PROJECT_DIR" -name 'pom.xml' -print0 2>/dev/null)

# Check Gradle build files for antlr4 plugin or tool dependency
while IFS= read -r -d '' gradlefile; do
  if grep -qE '(antlr4|org\.antlr.*antlr4.*:4\.)' "$gradlefile" 2>/dev/null; then
    # Skip runtime-only references
    if grep -qE 'antlr4-runtime' "$gradlefile" && ! grep -qE 'antlr4[^-]' "$gradlefile"; then
      echo "[+] $gradlefile uses antlr4-runtime only — NOT AFFECTED"
      continue
    fi
    FOUND_TOOL=1
    ver=$(grep -oP 'antlr4[^-].*?:([0-9.]+)' "$gradlefile" | grep -oP '[0-9]+\.[0-9]+\.[0-9]+' | head -1)
    if [[ -n "$ver" ]] && echo "$ver" | grep -qP "^${VULN_VERSIONS}$"; then
      echo "[!] VULNERABLE: $gradlefile uses antlr4 tool version $ver"
      FOUND_VULN=1
    elif [[ -n "$ver" ]]; then
      echo "[+] $gradlefile uses antlr4 version $ver (check manually)"
    else
      echo "[?] $gradlefile references antlr4 but version not parsed"
    fi
  fi
done < <(find "$PROJECT_DIR" -name '*.gradle' -o -name '*.gradle.kts' -print0 2>/dev/null | tr '\n' '\0')

# Check pip / Python environments
if command -v pip &>/dev/null; then
  pipver=$(pip show antlr4-tools 2>/dev/null | grep -i '^Version:' | awk '{print $2}')
  if [[ -n "$pipver" ]]; then
    FOUND_TOOL=1
    if echo "$pipver" | grep -qP "^${VULN_VERSIONS}$"; then
      echo "[!] VULNERABLE: pip antlr4-tools version $pipver"
      FOUND_VULN=1
    else
      echo "[+] pip antlr4-tools version $pipver (check manually)"
    fi
  fi
fi

# Check for standalone antlr4 jar
while IFS= read -r -d '' jarfile; do
  if [[ "$jarfile" == *antlr4-4.13.[012]* ]] && [[ "$jarfile" != *runtime* ]]; then
    echo "[!] VULNERABLE: Found antlr4-tool jar: $jarfile"
    FOUND_TOOL=1
    FOUND_VULN=1
  fi
done < <(find "$PROJECT_DIR" -name 'antlr4-*.jar' -print0 2>/dev/null)

if [[ $FOUND_VULN -eq 1 ]]; then
  echo ""
  echo "VULNERABLE — antlr4-tool 4.13.0-4.13.2 detected."
  echo "NOTE: No vendor fix exists. Verify grammar files are from trusted, reviewed sources."
  exit 1
elif [[ $FOUND_TOOL -eq 0 ]]; then
  echo ""
  echo "PATCHED — No antlr4-tool dependency found (antlr4-runtime only is NOT affected)."
  exit 0
else
  echo ""
  echo "UNKNOWN — antlr4-tool found but version could not be confirmed as vulnerable."
  exit 2
fi