Coding Agent Directory Poisoning: Five Detections for Defense in Depth

    When coding agents follow instructions from untrusted project files, a plain-text document can become a real execution path. This article breaks down a directory-poisoning attack chain and presents five practical checks—launch-directory controls, configuration integrity verification, data/instruction separation, egress allowlisting, and immediate credential rotation—that teams can enforce in their own pipelines. It also includes a baseline hash drift-check script.

    Why This Is a “No-Patch” Problem

    A point that may seem counterintuitive is worth stating up front: in this class of incidents, the tool provider often has nothing to patch directly.

    The reason is not to excuse anyone. The behavior reproduced across two independent product forms: two mainstream coding agents were both successfully exploited along the same attack chain. When the same defect pattern appears reliably across different implementations, it looks less like a bug in one product and more like an inherent property of agent-based systems.

    A useful analogy for test engineers is the browser rendering a spoofed bank login page. The browser is doing what it is supposed to do: parsing and displaying page content according to the specification. The attack is in the page, not in the browser, so there is no browser patch to issue. In the same way, a coding agent that strictly follows “project rules” or “project convention” files in its working directory is behaving as designed.

    You may disagree with the analogy, but it leads to an unavoidable conclusion for a testing team: if the risk cannot be solved by an upstream patch, it must become a gate check in your own pipeline.

    Attack Chain: Every Step Maps to a Checkable Point

    The disclosed real-world chain contains five actions. Breaking them down in order is useful because each step naturally maps to a detection point.

    Step 1: A web page writes a file into the download directory.
    The download directory is almost the only folder a web page can write to autonomously—no click, no confirmation, and both the filename and content are controlled by the page. Operating systems have long blocked automatic execution of downloaded executables, but instruction files are not executables. Guards designed around executable files do not apply to them, so this step may look harmless on its own.

    Step 2: The user launches the coding agent from the download directory.
    The key here is not coincidence; it is habit. According to the vendor’s own telemetry, about half of customers have run a coding agent from the download directory, and about one-quarter of sessions involve opening a real browser. Together, those behaviors create the conditions for this attack path.

    Step 3: The agent reads the file and rewrites its global configuration.
    The malicious sample usually appears as “project conventions,” instructing the agent to change tool behavior, loosen restrictions, or add external dependencies. At this point, the configuration is no longer what the user originally set, yet it is still treated as a trusted baseline.

    Step 4: The modified configuration leads the agent to install a malicious dependency.
    The danger is that, from the agent’s point of view, it is simply “setting up the environment according to the rules.” Every step seems reasonable.

    Step 5: The malicious dependency executes during build or runtime.
    Once execution occurs, it can read local credentials, make outbound connections, and exfiltrate data. The attack has now moved from “a plain text file” to “actual code execution.”

    Five Practical Detection Controls

    Since you cannot rely on an upstream fix, you need to build controls on your own side. The following five controls tighten the defense from entry point to response.

    1. Entry control: restrict the agent launch directory

    The root cause is the default behavior of “launch the agent from any directory.” Practical measures include:

    • Require agents to start only from trusted project roots, and reject startup from untrusted writable areas such as download directories or temporary directories.
    • Check the current working directory in the launch script, and abort if it matches a denylist.
    • Monitor file creation in the download directory, and raise an alert immediately when instruction-like files—such as .md, rules, or config—land there.

    2. Configuration integrity: baseline the global configuration

    Put global configuration under version control and baseline validation. The core idea is that any runtime modification to global configuration should be treated as abnormal, not normal. A hash baseline plus periodic comparison is sufficient. For stronger protection, make the global configuration read-only for the agent process, so any change must go through a manual review process.

    3. Prompt/execution separation: keep data and instructions apart

    The key is to distinguish data from instructions. Instruction files inside a project directory should be treated as untrusted data, not as directly executable instructions. In engineering terms:

    • Tag instruction files that come from a project directory as “external content,” and clearly mark their data nature when injecting them into context.
    • Require secondary confirmation for high-impact actions such as rewriting global configuration, installing dependencies, or making network requests, rather than allowing a single text file to drive them directly.
    • Scan instruction files with content heuristics to detect high-risk intents such as “overwrite configuration,” “install package,” or “read credentials,” and raise alerts.

    4. Egress allowlist

    Even if earlier layers are bypassed, egress control remains the last gate. Apply a least-privilege outbound policy to the agent runtime: allow only the package sources and endpoints required for building, and deny everything else by default. Malicious dependencies usually need outbound access to download payloads or exfiltrate data, so an allowlist can significantly raise the attacker’s cost. At the same time, log and audit all outbound connections so that “detect and rotate” can be triggered in real time.

    5. “Detect and rotate” response policy

    Once configuration drift or anomalous egress is detected, assume credentials have been exposed and immediately rotate all tokens, keys, and cloud credentials accessible to the agent—do not wait to investigate before deciding. The logic is the same as the “no patch” problem: when the attack surface is an agent that is “working as designed,” time equals loss. Rotation should be an automated default response, not an option that requires repeated debate.

    Configuration Drift Check Script

    The script below demonstrates how to baseline-hash a coding agent’s global configuration. It can be integrated as a gate check or a scheduled task.

    1. #!/usr/bin/env bash
    2. # Configuration drift check: compare agent global configuration files against baseline hashes
    3. set -euo pipefail
    4. # Configuration files to monitor (examples; adjust paths as needed)
    5. WATCH_FILES=(
    6. "$HOME/.config/agent/settings.json"
    7. "$HOME/.config/agent/rules.md"
    8. )
    9. BASELINE_FILE="$HOME/.config/agent/.baseline.sha256"
    10. # Generate/update baseline
    11. if [[ "${1:-}" == "--init" ]]; then
    12. : > "$BASELINE_FILE"
    13. for f in "${WATCH_FILES[@]}"; do
    14. [[ -f "$f" ]] && sha256sum "$f" >> "$BASELINE_FILE"
    15. done
    16. echo "Baseline generated: $BASELINE_FILE"
    17. exit 0
    18. fi
    19. # Check for drift
    20. drift=0
    21. for f in "${WATCH_FILES[@]}"; do
    22. [[ -f "$f" ]] || continue
    23. now=$(sha256sum "$f" | awk '{print $1}')
    24. base=$(grep -F "$f" "$BASELINE_FILE" 2>/dev/null | awk '{print $1}' || true)
    25. if [[ "$now" != "$base" ]]; then
    26. echo "[Alert] Configuration drift detected: $f"
    27. drift=1
    28. fi
    29. done
    30. [[ $drift -eq 0 ]] && echo "Configuration intact. No drift detected."
    31. exit $drift

    Usage is simple: run with --init for the first time to generate the baseline, then run it in a CI pipeline or scheduled task. If a hash mismatch is found, the script exits with a non-zero status, which blocks subsequent steps and triggers an alert.

    Control Matrix

    Detection Category Control Point What to Check Where to Implement
    Entry control Launch directory allowlist Reject agent startup from download/temporary directories; alert when instruction files land in watched locations Launch scripts, EDR/file monitoring
    Configuration integrity Baseline hash comparison Treat runtime modification of global configuration as abnormal Gate scripts, scheduled tasks
    Prompt/execution separation Data/instruction isolation Mark external instruction files as untrusted data; require confirmation for high-impact actions Context injection layer, approval workflow
    Egress allowlist Least-privilege outbound policy Allow only required package sources and endpoints; deny everything else by default Network policy, proxy gateway
    Detect and rotate Automatic credential rotation Rotate tokens and keys after drift or anomalous outbound connections are detected Secret management, incident response process

    Conclusion

    What makes this class of risk unusual is that there is no single “vendor hotfix” exit. When an agent strictly follows the instruction file in its working directory, it is not doing anything wrong—the problem is that “working as designed” itself becomes the attack surface. For testing and platform teams, the actionable conclusion is to shift the defense from “wait for a patch” to “build gates.” Entry controls narrow the startup surface, configuration integrity protects the baseline, separation reduces instruction contamination, egress allowlisting cuts off outbound connections, and automatic rotation limits damage. Only with these five layers combined can a seemingly harmless text file be kept away from actual code execution.