CI/CD pipeline abuse: the problem no one is watching
Attackers are increasingly targeting CI/CD pipelines to harvest secrets and pivot to production environments using techniques like workflow modification and privileged trigger exploitation. Elastic has released an open-source tool, cicd-abuse-detector, which leverages regex-based signal extraction and LLM analysis to detect suspicious pipeline changes during the pull request phase.
Authors: Elastic Security Labs
Source:Elastic Security Labs
Detection / Hunter
What Happened
Cyber attackers are increasingly targeting the automated systems (CI/CD pipelines) that developers use to build and deploy software, rather than attacking the final servers directly. Anyone using platforms like GitHub Actions, GitLab CI, or Azure DevOps is potentially at risk if their developer credentials are stolen. This matters because a single compromised automation file can give attackers access to highly sensitive passwords, cloud keys, and code-signing certificates. Organizations should implement strict security controls on their automation pipelines, such as pinning dependencies to specific versions and using tools like Elastic's new open-source CI/CD abuse detector to review code changes for malicious activity.
Key Takeaways
- Attackers are shifting focus from production servers to CI/CD automation to harvest cloud credentials and tokens.
- Elastic open-sourced cicd-abuse-detector, combining regex signal extraction and Claude LLM to analyze pull request diffs.
- Common attack vectors include pull_request_target exploitation, GITHUB_ENV injection, and IDE config poisoning.
- Defenders should pin actions to SHAs, scope secrets tightly, and avoid persisting credentials in checkout actions.
Affected Systems
- GitHub Actions
- GitLab CI
- Azure DevOps
- CI/CD Pipelines
Vulnerabilities (CVEs)
- CVE-2025-30066
Attack Chain
Attackers gain initial access via stolen developer credentials and modify CI/CD workflow files or IDE configurations. They exploit privileged triggers like pull_request_target or inject malicious environment variables such as LD_PRELOAD to execute arbitrary code. The automation runners then execute the malicious instructions, harvesting sensitive secrets, cloud credentials, and tokens from the environment. Finally, the attackers exfiltrate these secrets, often using double base64 encoding to evade log masking, and use them to pivot laterally into production cloud environments or conduct supply chain attacks.
Detection Availability
- YARA Rules: No
- Sigma Rules: No
- Snort/Suricata Rules: No
- KQL Queries: No
- Splunk SPL Queries: No
- EQL Queries: Yes
- Other Detection Logic: Yes
- Platforms: Elastic cicd-abuse-detector, Elasticsearch ES|QL
The article provides an ES|QL query to hunt for malicious or suspicious CI/CD verdicts in Elasticsearch, as well as several regex patterns used by the cicd-abuse-detector tool to identify dangerous pipeline configurations.
Detection Engineering Assessment
EDR Visibility: Low — EDR typically does not run on ephemeral GitHub-hosted or GitLab-hosted runners, and the malicious activity occurs within the CI/CD platform's control plane (YAML files, API calls). Network Visibility: Medium — Network monitoring might catch exfiltration from self-hosted runners to known malicious IPs, but traffic from cloud-hosted runners is often encrypted and blends with legitimate API traffic. Detection Difficulty: Moderate — Detecting these attacks requires specialized parsing of CI/CD configuration files (YAML) and understanding platform-specific context, which traditional SIEMs struggle with without dedicated tools like the provided detector.
Required Log Sources
- CI/CD Pipeline Logs
- GitHub Audit Logs
- GitLab Audit Events
- Elasticsearch logs-cicd.abuse-*
Hunting Hypotheses
| Hypothesis | Telemetry | ATT&CK Stage | FP Risk |
|---|---|---|---|
| Attackers are modifying workflow files to include double base64 encoding to exfiltrate secrets while bypassing log masking. | CI/CD pipeline logs and pull request diffs | Exfiltration | Low |
| Untrusted pull requests are exploiting the pull_request_target trigger to access repository secrets. | GitHub Actions workflow configurations | Privilege Escalation | Medium |
| Developers' IDE configurations (.vscode/tasks.json) are being modified to execute hidden tasks upon folder opening. | Source control commit history and file diffs | Execution | Low |
Control Gaps
- Traditional Code Review
- EDR on ephemeral cloud runners
- Static Application Security Testing (SAST) for CI/CD logic
Key Behavioral Indicators
- Use of pull_request_target trigger
- Direct secret interpolation (${{ secrets. }})
- Modifications to GITHUB_ENV or GITHUB_PATH
- Presence of LD_PRELOAD in workflow steps
- Double base64 encoding commands
False Positive Assessment
- Medium
Recommendations
Immediate Mitigation
- Deploy the cicd-abuse-detector to monitor pull requests for suspicious workflow changes.
- Audit existing repositories for the use of the pull_request_target trigger and remove it if not strictly necessary.
Infrastructure Hardening
- Pin all GitHub Actions to specific SHAs rather than tags or branches.
- Scope secrets to individual steps rather than using job-level environment variables.
- Set explicit permissions (permissions: {}) at the workflow level and add specific permissions per job.
- Enable persist-credentials: false on checkout actions to prevent GITHUB_TOKEN leakage.
User Protection
- Use short-lived, ephemeral tokens for developer access to reduce the attack surface of stolen credentials.
Security Awareness
- Train developers on the risks of CI/CD pipeline modifications and the dangers of executing untrusted code in privileged contexts.
- Educate teams on the Contagious Interview campaign and the risks of opening untrusted repositories in IDEs.
MITRE ATT&CK Mapping
- T1552 - Unsecured Credentials
- T1195.002 - Compromise Software Supply Chain
- T1059 - Command and Scripting Interpreter
- T1070.006 - Timestomp
- T1098 - Account Manipulation
- T1078 - Valid Accounts
Additional IOCs
- File Paths:
.vscode/tasks.json- IDE configuration file targeted for initial access via auto-execution.git/config- Git configuration file often leaked in artifact race condition attacks
- Command Lines:
- Purpose: Extract and encode secrets from environment variables to evade log masking | Tools:
env,awk,base64| Stage: Exfiltration |awk -v RS='0' '/^secret_/ {print $0}' | base64 - Purpose: Extract Azure access tokens and encode them for exfiltration | Tools:
az,base64| Stage: Exfiltration |az account get-access-token | base64 - Purpose: Remote script execution for IDE config poisoning | Tools:
curl,node| Stage: Execution |curl | node
- Purpose: Extract and encode secrets from environment variables to evade log masking | Tools: