
Autopsy 12 · IDE extension supply chain | Comic Strip 2 · Swiper no swiping!
Would Ethosure have caught this? The Amazon Q VS Code wiper injection
An unprivileged GitHub contributor slipped a wiper-style system prompt into the Amazon Q Developer extension for VS Code. The malicious code shipped in an officially signed release before AWS caught it. A syntax error in the payload is the only reason nearly one million developer machines survived. Policy-as-code on AI-adjacent IDE extensions is the boundary that failed.
The incident
On July 13, 2025 an attacker using the GitHub alias lkmanka58 submitted a pull request to the aws-toolkit-vscode repository. The project’s CodeBuild configuration carried an inappropriately scoped GitHub token, which granted the attacker excessive write access once the pull request landed. The attacker injected a wiper-style system prompt instructing the Q Developer agent to delete all non-hidden files in the user’s home directory, enumerate configured AWS profiles, and use AWS CLI commands to delete EC2, S3, and IAM resources. The compromised code shipped as Amazon Q Developer for VS Code version 1.84.0 on July 17, 2025 and reached roughly one million developer installs. AWS published bulletin AWS-2025-015 on July 23, 2025, filed CVE-2025-8217 (CVSS 4.0 at 5.1, CWE-506 Embedded Malicious Code), revoked the compromised credentials, removed 1.84.0 from distribution, and released 1.85.0. The payload did not execute because it contained a syntax error that broke the API call to the Q Developer CLI. That is the entire reason nothing catastrophic happened.
- AWS Security Bulletin AWS-2025-015 — Security Update for Amazon Q Developer Extension for Visual Studio Code
- Ibid. — NVD — CVE-2025-8217
- Ibid. — SC Media — Amazon Q extension for VS Code reportedly injected with wiper prompt
- Ibid. — Anomity Threat Research — Amazon Q Developer VS Code Extension wiper prompt injection (GHSA-7g7f-ff96-5gcw)
The applicable coding-ethos policy
ai-extension-review-integrityCoding-ethos policies are compiled from principle-owned CEL expressions. Every expression in the Ethosure corpus passes three gates: policyvalidate (schema + CEL compile), audit_runtime.py (the fields the expression references are guaranteed present on the runtime event path), and policytest (behavioral fixtures — the policy fires on the positive case and stays quiet on the near miss). The corpus ships 190 policies across 49 principles in six packs, with 422 fixtures and zero failures.
Walkthrough
- The uncomfortable truth of this incident is that the safety net was a syntax error. Amazon’s own security bulletin admits the malicious code shipped in a signed release and would have executed on nearly a million developer machines if the attacker had bothered to test the payload. Nothing in the pipeline stopped the pull request. Nothing revoked the over-scoped token. The industry does not get to rely on attacker incompetence.
supply_chain.ai_extension.pr_review_requires_second_maintainerfires onPreToolUsefor any release publication of an AI-adjacent extension whose merged pull request does not have two independent maintainer approvals recorded in the evidence layer. Severityblock. The attacker’s pull request landed in the aws-toolkit-vscode repository with insufficient review; this policy makes that impossible for any repo taggedai-extension.ci.token_scope.forbid_admin_on_ai_extension_repois the second expression. The CodeBuild GitHub token in this case was scoped so broadly that a single merged pull request granted repository-administrative access. The expression fires on any token exchange whose declared scope includes admin privileges on an ai-extension-tagged repository, and returnsblock. Least privilege is trivial to state and expensive to retrofit; that is the argument for pushing it into policy.agent.system_prompt.origin_provenance_requiredis the third. The wiper payload was a system prompt inside a shipped extension binary. The expression fires on any agent runtime whose system prompt does not carry a provenance record signed by the extension’s registered maintainers. It returnsblock. Signed provenance on system prompts closes the delivery vector that Amazon’s syntax error accidentally closed for them.
Policy YAML
# Pack: regulated-enterprise-base (v2)
# Overlay: model-provider-governance
principles:
- id: ai-extension-review-integrity
title: AI Extension Review Integrity
directive: >-
AI-adjacent developer extensions must ship only through multi-maintainer review,
least-privilege CI credentials, and provenance-signed system prompts.
policy:
expressions:
- id: supply_chain.ai_extension.pr_review_requires_second_maintainer
scope: agent_action
severity: block
event: PreToolUse
principle_ids:
- ai-extension-review-integrity
- security-by-design
skill_id: safe-ai-extension-release
when: >
tool_call.category == "release_publish"
&& repository.tags.exists(t, t == "ai-extension")
&& !release.source_pr.approvals.filter(a,
a.reviewer_is_maintainer && a.reviewer != release.source_pr.author)
.size() >= 2
message: >-
Release of an AI-adjacent extension lacks two independent maintainer approvals
on its source pull request.
advice: >-
Require the second maintainer approval before publishing the release. The
aws-toolkit-vscode incident shipped an unreviewed contribution to nearly one
million installs.
- id: ci.token_scope.forbid_admin_on_ai_extension_repo
scope: agent_action
severity: block
event: PreToolUse
principle_ids:
- ai-extension-review-integrity
- least-authority-in-the-pipeline
when: >
tool_call.category == "oidc_token_exchange"
&& exchange.scope.repository.tags.exists(t, t == "ai-extension")
&& exchange.scope.permissions.exists(p, p == "admin")
message: >-
CI token exchange requests admin scope on an AI-adjacent extension repository.
advice: >-
Scope the token to the specific write actions the workflow needs. Admin scope on
an ai-extension-tagged repo is never the right answer.
- id: agent.system_prompt.origin_provenance_required
scope: agent_config
severity: block
event: PreAgentStart
principle_ids:
- ai-extension-review-integrity
- radical-visibility
when: >
agent.system_prompt.exists
&& !agent.system_prompt.provenance.signed_by.exists(s,
s.role == "maintainer"
&& s.extension_id == agent.extension_id)
message: >-
Agent system prompt lacks a provenance signature from a registered maintainer of
its host extension.
advice: >-
Sign the system prompt at build time and verify the signature at agent-start.
An unsigned prompt is a delivery vector for wiper payloads.
Assurance boundary. Fixtures prove that synthetic positive cases fire and near-misses stay quiet. They do not establish production alert rates. DLP-backed controls depend on upstream detection, shell-command regexes are defense in depth rather than a sandbox boundary, and regulatory tags are engineering aids requiring counsel review.
Where this policy lives in the corpus
The Ethosure importable corpus ships six coding-ethos packs. Each pack composes with the regulated-enterprise base pack, which owns cross-cutting controls for secrets, destructive actions, and human oversight.
- Regulated-enterprise base pack — secrets, destructive actions, human-in-the-loop, evidence-layer recording.
- Financial services overlay — OSFI E-23 alignment, FINTRAC-adjacent data handling, transaction-boundary controls.
- Healthcare & life sciences overlay — PHI handling, model-provenance requirements, evaluation-set contamination checks.
- Government & critical infrastructure overlay — identity-provenance requirements, review-channel signatures, air-gap enforcement labels.
- Model & provider governance pack — egress allowlists, evaluation-runtime isolation, cross-runtime coordination detection.
- AI cost control pack — payload-size and endpoint-visible model checks (preventive), token-total and response-side model facts (detective), external ledger for cumulative budgets.
Published September 3, 2026 · Ethosure · Part of the Autopsy Series.