Prompt Says No, Configuration Says Yes: Five Detection Layers for AI Coding Agent Hijacking

    This article explains why coding agent configuration hijacking cannot be fixed by a single vendor patch. It breaks down the five-step attack chain, from a web page writing a rules file into the Downloads folder to credential and data exfiltration, and proposes five practical detection layers: session entry checks, configuration integrity monitoring, prompt/execution separation, egress allowlisting, and discovery-driven credential rotation. It also provides a read-only drift-check script, a control mapping table, and a phased rollout plan.

    1. The Uncomfortable Conclusion: There Is No Patch to Apply

    One of the most important takeaways from a public report on coding agent configuration hijacking is not the attack technique itself. It is the root-cause assessment:

    This is not a vulnerability that a single vendor can patch.

    The evidence is not an attempt to excuse any vendor. The authors reproduced the issue across two independent coding agent products with completely different implementation paths. Both attack chains succeeded. In one chain, the proportion of sessions where malicious dependencies were executed exceeded 90%. In the other chain, it was around 50%. The numbers are different, but neither result is occasional. This suggests that the problem is not an implementation flaw in one product. It is embedded in the definition of what counts as a coding agent.

    A more useful analogy for test engineers is browser rendering of a fake bank login page. When a browser renders a forged page, the browser is doing what it is supposed to do. The attack exists in the page, not in the browser. There is no browser-side patch for it.

    Similar issues have existed for years:

    • Email clients correctly render phishing emails.
    • Spreadsheet software correctly calculates malicious formulas inside spreadsheet fields, commonly known as formula injection.

    The common point is this: a data channel is treated as a control channel.

    Coding agents push this contradiction to a new level. Traditional parsers still distinguish between “this is file content” and “this is a command you should execute.” Coding agents, however, work by treating natural-language files as behavioral input. A text file placed in a project root directory, with a name that follows common rules-file conventions such as agents.md, naturally gains instruction-level authority.

    You may disagree with the “no patch” conclusion. But the engineering consequence is unavoidable:

    If the vendor side has nothing to patch, this becomes a check item in your own security gate.

    2. The Attack Chain: Five Actions, Five Detection Points

    The disclosed attack chain can be broken into five actions. Describing them in order is useful because each step corresponds to a detectable location.

    Step 1: A web page writes a rules file into the user’s Downloads directory

    The report emphasizes that, on most systems, the Downloads directory is one of the few folders a web page can write to autonomously. No click is required, no confirmation is required, and both the file name and file content can be specified by the web page. Mechanisms such as automatic downloads, repeated downloads, and attachment-style delivery can all achieve this.

    Operating systems have long blocked the path where “downloaded executables run automatically.” But this file is not executable, so executable-focused guardrails do not apply. This is where the protection gap exists:

    Risk controls target things that can execute, while coding agents turn things that can be understood into things that can execute.

    Step 2: The user starts the agent inside the Downloads directory

    The report cites its own telemetry: about half of customers have run coding agents in the Downloads directory, and about one quarter of sessions open a real browser. These numbers explain why the path is viable. It is not a coincidence. It is habit.

    Security designers often assume that “users will not work in the Downloads directory.” Real-world data says otherwise.

    Step 3: The agent reads the file, treats it as project rules, and changes its global configuration

    This is the key transition in the entire chain: the impact expands from “this current session” to “all future sessions.”

    A project-level file obtains global-level authority. The model does not have the ability to determine which file is allowed to modify its configuration, because for the model, this is text semantics, not permission metadata.

    Step 4 and Step 5: Malicious dependencies are introduced, and credentials or code are carried out

    In a general environment, these two steps usually appear as:

    • Installing a third-party package that contains lifecycle scripts, such as postinstall.
    • Sending tokens, source code, or environment variables back through outbound network requests.

    Once the global configuration has been rewritten, defaults such as automatic installation and automatic execution can be enabled. Later actions no longer require human confirmation.

    The core takeaway

    Model output is untrusted. Only the policy layer is enforceable.

    All permission decisions must move from model output to deterministic policy. The model may request an action. It must not be able to authorize itself.

    3. Five Executable Detections

    3.1 Entry Detection: Where the Session Starts Matters More Than What the File Looks Like

    The detection target is not “whether there are suspicious files in the Downloads directory.” There are too many legitimate files there, and false positives will drown out the signal.

    The target should be the startup location and directory origin of the agent session.

    Checkable items:

    • Whether the session working directory is under a path that a web page can write to or whose origin is untrusted, such as the Downloads directory, temporary directory, extracted temporary area, or mounted shared drive.
    • Whether the working directory contains a rules file whose origin cannot be traced, for example:
      • No version repository.
      • No commit history.
      • File creation time closely matches the timestamp of a download event.
    • There is also a commonly overlooked risk inside the Downloads directory: a web page can create a folder, place a rules file inside it, and then the user may extract or open it. Once the user enters that directory, the current directory becomes the “project root directory.”

    Implementation recommendation: perform path checks at the session startup hook or command-line entry point. If the path matches a risk condition, refuse to start the session and provide clear guidance, such as moving the project into a controlled workspace. Do not merely warn and allow the session to continue.

    3.2 Configuration Integrity: Global Configuration Must Be Watched by an External Control Point

    This is the highest-value layer in the entire chain. The core principle is:

    Do not rely on the agent itself to report whether its own configuration has been modified.

    Self-auditing is ineffective in this scenario. Supervision must be performed by host-side probes, CI jobs, or centralized configuration management.

    Check dimension Risk signal Why it matters
    Owner and permissions Global configuration files are writable by group or other users Any local process can modify them, so baseline hashes can be “legitimately” updated
    Content hash Differs from the baseline manifest Freeze the baseline first, then compare. Comparison results must be reported externally, not only written to local logs
    Auto-execution switches Defaults such as automatic dependency installation, automatic script execution, or automatic patch application change from off to on These are the keys attackers most want to modify, and they have higher priority than text-only configuration
    Allowed-directory and allowed-command lists Wildcard allowances outside the workspace appear A wildcard allowlist is equivalent to no allowlist
    Rules-file load priority Project-level files can override global-level policy If they can override, any directory can become a privilege-escalation entry point

    3.3 Separate Prompts From Execution: Text Must Never Escalate Into Permission

    This layer is architectural. It cannot be solved by adding “do not execute” to a prompt. The prompt layer is untrusted. Putting security constraints in the untrusted layer is like hanging the door lock on a piece of paper outside the door.

    Possible layering approaches:

    1. Expose risky actions as tool calls with parameter validation.
      Writing to the global configuration directory, installing dependencies, executing lifecycle scripts, and accessing credential stores should all be defined as high-risk actions that require explicit approval.

    2. Approval must be given by a human.
      The approval interface should show which file will be modified and what scope the change will affect. It should not show only a model-generated summary.

    3. The prompt layer must not carry security responsibilities.
      System prompts, project rules files, code comments, dependency package READMEs, and web content should all be treated at the same level: untrusted.

    4. Default deny, not default allow.
      Directory writes, command execution, and outbound network access that are not explicitly listed in the allowlist should be blocked directly.

    3.4 Egress Allowlisting: Treat the Exfiltration Channel as Part of the Attack Chain

    Credential theft and result exfiltration require outbound network access. This is the hardest part of the attack chain to bypass and the easiest to control centrally.

    Recommended policy:

    • Default deny. Allow by exact domain. Avoid broad wildcards.
    • After DNS resolution, validate the resolved target address again. Block requests pointing to private network ranges, loopback addresses, and cloud environment metadata service addresses, which are typically link-local addresses. This covers bypasses where a domain resolves to an internal address.
    • Try to converge coding-agent traffic to a unified egress proxy. Proxy logs should at least retain time, process, target domain, request byte count, and session identifier.
    • Alert on changes such as “a new domain suddenly appears in the middle of a session.” This has more signal value than “a certain domain was accessed.”
    • In centralized environments, egress access logs and anomalous outbound connection alerts can be handled by general cloud logging and monitoring/alerting capabilities. The key point is to make proxy logs queryable and correlatable, rather than leaving them in local files on a single host.

    3.5 Discover-and-Rotate: Define the Response Before It Happens

    Once global configuration tampering is confirmed and dependencies have been executed, the response must be handled as “credentials are assumed compromised,” not as “one file was modified.”

    Recommended response order:

    1. Isolate first, then collect evidence.
      Stop the session and disconnect sensitive credentials, but preserve host snapshots, configuration copies, and proxy logs first. Cleaning up too early destroys evidence needed for tracing.

    2. Assume compromise is real and rotate credentials.
      Invalidate and reissue static tokens, session credentials, cloud access keys, private repository credentials, and signing keys. Rolling back the configuration alone does not mean the risk is resolved.

    3. Roll back and verify.
      Restore the configuration baseline. Check whether installed dependencies or lifecycle scripts left behind files, scheduled tasks, or startup items.

    4. Align the messaging.
      Internally and externally, make it clear that this is a trust-boundary issue caused by the agent working as designed, not a crash in a specific product. Avoid reducing the conclusion to “wait for the vendor to fix it,” which delays building your own gate controls.

    4. Read-Only Configuration Drift Check Script

    The following script turns the checks in sections 3.1 and 3.2 into executable logic. It is read-only and does not modify any configuration. A non-zero exit code indicates that risk was detected.

    Placeholder variables should be adjusted for your environment. Configuration file paths and key names differ across products. The script uses generic placeholders and does not assume a specific schema.

    1. #!/usr/bin/env bash
    2. # agent-drift-check.sh - Read-only drift and entry-cleanliness check for coding agent configuration
    3. set -uo pipefail
    4. DL="${DOWNLOAD_DIR:-$HOME/Downloads}" # Download directory
    5. AGENT_HOME="${AGENT_CONFIG_HOME:-$HOME/.agent}" # Global configuration root
    6. MANIFEST="${CONFIG_BASELINE:-/etc/agent-config-baseline.sha256}"
    7. RULE_FILES='agents.md .agent.md *rules*.md'
    8. hits=0
    9. hit() { printf '[RISK] %s\n' "$*"; hits=$((hits+1)); }
    10. ok() { printf '[ OK ] %s\n' "$*"; }
    11. # 1) Entry cleanliness: detect coding-agent rule files in the download directory tree
    12. while IFS= read -r f; do
    13. [ -n "$f" ] && hit "Rule file found in download directory; it may be treated as project instructions: $f"
    14. done < <(find "$DL" -maxdepth 3 -type f \( -iname 'agents.md' -o -iname '.agent.md' \) 2>/dev/null)
    15. [ "$hits" -eq 0 ] && ok "No rule files found in the download directory"
    16. # 2) Ownership and writability of global configuration: any locally writable file is untrusted
    17. while IFS= read -r f; do
    18. [ -n "$f" ] && hit "Global configuration file is writable by group or other users: $f"
    19. done < <(find "$AGENT_HOME" -type f -perm /0022 2>/dev/null)
    20. # 3) Content hash drift (freeze the baseline first: find "$AGENT_HOME" -type f -exec sha256sum {} \; > "$MANIFEST")
    21. if [ -r "$MANIFEST" ]; then
    22. out="$(cd / && sha256sum -c "$MANIFEST" 2>&1 | grep -v ': OK')"
    23. [ -n "$out" ] && hit "Configuration baseline differs from current content:" "$out" || ok "Configuration baseline matches current content"
    24. else
    25. printf '[WARN] Baseline manifest not found; cannot determine content drift: %s\n' "$MANIFEST"
    26. fi
    27. # 4) High-risk auto-execution switches (key names depend on the actual configuration; this uses generic keyword matching)
    28. for cfg in "$AGENT_HOME"/settings.json "$AGENT_HOME"/config.json; do
    29. [ -r "$cfg" ] || continue
    30. if grep -Eiq '"(autoInstall|allowScripts|autoApprove|bypass[A-Za-z]*)[[:space:]]*:[[:space:]]*true' "$cfg"; then
    31. hit "Auto-install, auto-execute, or auto-approve switch detected as true: $cfg"
    32. fi
    33. done
    34. # 5) Whether allowed-directory whitelists degrade into wildcards
    35. for cfg in "$AGENT_HOME"/settings.json "$AGENT_HOME"/config.json; do
    36. [ -r "$cfg" ] || continue
    37. grep -Eq '"(allow[A-Za-z]*Dir|writableRoots)"[[:space:]]*:[[:space:]]*\[[^]]*("/\*"|"~"|"\$HOME")' "$cfg" \
    38. && hit "Write allowlist contains wildcard entries, effectively removing directory boundaries: $cfg"
    39. done
    40. # 6) Whether egress is routed through a unified proxy
    41. if [ -z "${HTTPS_PROXY:-${https_proxy:-}}" ]; then
    42. printf '[WARN] No egress proxy configured; cannot enforce an egress allowlist or retain logs\n'
    43. else
    44. ok "Egress proxy configured: ${HTTPS_PROXY:-$https_proxy}"
    45. fi
    46. printf '\nCheck complete. Risk items: %d\n' "$hits"
    47. exit $(( hits > 0 ))

    Usage recommendations:

    • Attach the script to three places: the session startup hook, a scheduled task, and a pre-check in CI.
    • Store the baseline manifest in a location the agent itself cannot write to.
    • Report check results to centralized logging rather than local files.

    Using only one of these places is easy to bypass. Only when all three are combined can the script cover the case where “the configuration is changed and the baseline is changed as well.”

    5. Control Mapping Table

    Attack stage Detection layer Risk signal Response Primary owner
    Web page writes a rules file Entry detection Rules file appears in Downloads directory; no version history Warn before session start and block work in that directory Endpoint / workspace policy
    User starts the agent in Downloads Entry detection Session working directory belongs to an untrusted path list Hard block and guide migration to a controlled workspace Platform-side entry policy
    Agent reads the rules file Prompt and execution separation Project-level rules file attempts to modify global configuration High-risk actions require human approval; reject self-authorization Architecture and product policy
    Global configuration is rewritten Configuration integrity Permissions loosen, hash drift, auto-execution switches become true Automatically roll back baseline, alert, and freeze the session Host-side supervision / CI
    Malicious dependency is installed Configuration integrity + egress Lifecycle scripts execute; package source or version is abnormal Block script execution and isolate the dependency cache Supply-chain controls
    Credentials and data are exfiltrated Egress allowlist New target domain appears mid-session; access to internal or metadata addresses Default deny and trace through proxy logs Network policy
    Hijacking is confirmed Discover and rotate Configuration tampered and dependencies executed Isolate and preserve evidence, rotate all credentials, and perform retroactive investigation Incident response

    6. Common Objections and Responses

    “Users should not start agents in the Downloads directory.”

    The conclusion is correct, but it is insufficient as a defense. Telemetry shows that about half of users have done it. This is an existing habit, not an edge case. Building security on “users will not do this” sets the baseline at the most optimistic scenario.

    “This is a model-capability issue. The next model version will recognize it.”

    Recognizing “this is a malicious instruction” and being unauthorized to execute the action are two different things.

    The first is probabilistic. The second is deterministic. Security controls should rely on the second.

    “We already wrote a system prompt prohibiting the agent from modifying its own configuration.”

    In this scenario, the prompt layer is exactly the position under attack. The effectiveness of a project-level rules file comes from the loading mechanism, not from whether it is polite.

    Any constraint that can be overridden by content cannot count as a security control.

    7. Phased Rollout

    Do not try to deploy all five layers at once.

    A practical progression is:

    1. First, gain visibility.
      Enable logging and checks only. Collect three types of signals: entry-point hits, configuration drift, and anomalous outbound connections. Use them to establish the real baseline for your organization.

    2. Then, enforce blocking.
      Turn configuration integrity monitoring into automatic rollback. Change session startup in the Downloads directory from a warning to a hard block.

    3. Finally, automate response.
      Connect egress allowlisting and credential rotation processes to incident response plans, and run exercises.

    The essence of this work is to translate a design property for which “there is no patch” into a set of deterministic checks that can run in your security gate.

    Vendors do not need to change code. Your pipeline needs to change configuration.