Join our Newsletter — 33% off our NHI Course
Home› Guides› MITRE ATT&CK T1677 Poisoned Pipeline Execution: Detecting Malicious…
Guide Identity Visibility, Posture & Threat Detection

MITRE ATT&CK T1677 Poisoned Pipeline Execution: Detecting Malicious Execution

← All guides
By NHI Mgmt Group, edited by Lalit Choda Updated 12 November 2026 13 min read
On this page

A CI/CD pipeline runs whatever code reaches it with whatever credentials it holds, so an attacker who can influence that code gets the pipeline's identity for free. MITRE ATT&CK T1677 Poisoned Pipeline Execution sits under the Execution tactic on the SaaS platform and describes adversaries injecting malicious code into the build process to steal credentials, move laterally or push malicious components further down the pipeline. This guide takes the ATT&CK technique view: the procedure examples recorded in ATT&CK v20, the detection strategy and data components MITRE publishes, the two mitigations, and how to test that your controls hold. It is written for platform engineering, AppSec and SOC teams. For the OWASP risk framing, requirements and evidence, see the OWASP CI/CD Top 10 CICD-SEC-4 Poisoned Pipeline Execution Guide; this page does not repeat it.

Key takeaways

  • The target is the pipeline's credentials. ATT&CK describes poisoned builds exfiltrating secrets to a remote server or exporting them as workflow artifacts, and every recent case on this page turned a stolen token into the next compromise.
  • Three routes, one root cause. Direct (edit the CI file), indirect (edit files the CI file calls) and public (a fork pull request) all succeed because unreviewed code runs with privileged access.
  • Some triggers and inputs are the attack surface. In GitHub Actions, pull_request_target with a checkout of the pull request head, and branch names or titles interpolated into run steps, recur across the cases.
  • Detection lives in SaaS audit logs. ATT&CK DET0533 correlates fork-triggered workflows, secret access, encoded artifacts and changes to build configuration files.
  • Two mitigations carry the weight. M1054 Software Configuration (isolate unreviewed code from secrets) and M1018 User Account Management (minimum pipeline permissions, fewer writers).

What the technique covers

ATT&CK v20 lists T1677 with no sub-techniques. Its description follows the OWASP CICD-SEC-4 taxonomy and adds GitHub-specific detail. The table maps each route to the access the adversary needs and the first control that breaks it.

RouteWhat the adversary changesAccess neededControl that breaks it
Direct pipeline executionThe CI configuration itself, for example .gitlab-ci.yml or a file under .github/workflows/Push or pull request rights on a branch that triggers the pipelineBranch protection and code owner review on CI files
Indirect pipeline executionFiles the CI configuration references: makefiles, scripts, unit tests, linters, package.json scriptsWrite access to referenced files, or a dependency they installReview of build scripts as code, no secrets in jobs that run untrusted code
Public pipeline executionA pull request from a fork, or crafted inputs such as a branch nameNone beyond a public accountFork workflows without secrets, approval before running, no self-hosted runners on public repositories

The outcome is often a MITRE ATT&CK T1195 Supply Chain Compromise: the poisoned pipeline signs, publishes or deploys something your customers trust. Keep the two separate in your threat model: T1677 is the execution inside your pipeline; T1195 is what happens to everyone downstream.

How adversaries use it: cases from ATT&CK and incident reporting

  • TeamPCP (G1056): ATT&CK records the group compromising trusted CI/CD pipelines by injecting credential-stealing payloads into legitimate workflows and packages, including the Trivy and KICS security tools and the LiteLLM AI gateway. In the Trivy case, a pull_request_target workflow ran code from an outside pull request with the repository's privileges, a personal access token was stolen, and after an incomplete rotation the attacker poisoned a release and force-pushed trivy-action tags in March 2026. The stealer read secrets from runner memory. See the Trivy supply chain attack analysis and the downstream LiteLLM PyPI package breach.
  • Shai-Hulud (S9008): ATT&CK records the worm using GitHub Actions from stolen accounts to create a malicious workflow at .github/workflows/discussion.yaml. The first wave in September 2025 pushed a workflow that dumped repository secrets; the November wave registered infected hosts as self-hosted runners for later command execution. One entry point in that wave was a pull_request_target workflow that checked out pull request code and leaked a bot token. See the Shai-Hulud npm worm analysis.
  • Mini Shai-Hulud (S9043) and CanisterWorm (S9042): ATT&CK records Mini Shai-Hulud propagating through triggered workflows, and CanisterWorm using tokens stolen from Trivy users to publish itself across more than 46 npm packages. See the Mini Shai-Hulud 2026 analysis.
  • APT38 (G0082): ATT&CK records poisoned npm packages with fake runtime dependencies that execute during install or update on developer endpoints or CI/CD systems. This is the indirect route: the CI file is untouched, but npm install runs attacker code.
  • Branch name injection (Ultralytics, December 2024): Wiz reported that a workflow treated github.head_ref as a trusted string, so a crafted branch name in a pull request executed as shell code. Versions 8.3.41 and 8.3.42 published to PyPI carried the XMRig cryptominer.
  • Self-hosted runners (PyTorch research, 2023): researchers reported to Meta's bug bounty programme that fork pull requests from previous contributors ran on self-hosted runners without approval, which gave them root on runners, GITHUB_TOKENs with write permission, personal access tokens and AWS keys able to write to release buckets.

Where identity fits

Every case above is a non-human identity problem. The pipeline holds a workflow token, publishing tokens, cloud keys and often a bot account's personal access token, and the poisoned code inherits all of them. The questions that decide the blast radius are identity questions: which secrets are visible to the job that runs untrusted code, how long they live, whether a bot token can push to protected branches, and whether rotation after an incident reaches every credential. The Trivy case turned on an incomplete rotation that left a service account valid. See the CI/CD Pipeline Identity Security Guide and How to Audit CI/CD Secrets Scope.

What to detect and where

ATT&CK publishes one detection strategy, DET0533, with analytic AN1473 for SaaS. It looks for workflows triggered from forks with suspicious pull request metadata, insecure triggers such as pull_request_target, unusual secret use, and artifacts or network destinations that suggest exfiltration. The data components and log sources it names:

ATT&CK data componentWhat AN1473 looks forPractical source
DC0069 Cloud Service ModificationWorkflow triggered via pull_request_target from a forked repositoryGitHub organisation audit log, workflow run events
DC0070 Cloud Service MetadataCI/CD secret accessed or exportedAudit log secret events, cloud provider logs for the identities the secrets map to
DC0025 Cloud Storage AccessArtifact containing base64 or encoded payloads or URLsArtifact uploads, artifact contents scanned after run
DC0059 File MetadataNew or modified build configuration in a pull request (.github/workflows/*.yml, .gitlab-ci.yml, build.gradle, pom.xml)Repository push and pull request events
DC0064 Command ExecutionCommit message or branch name containing encoded strings or payload indicatorsPull request metadata, runner step logs

The analytic exposes tunable elements: a time window, user context, a trigger type allowlist, an artifact entropy threshold and a secret access rate threshold. Set the allowlist from an inventory of the triggers you actually use, and baseline secret access per workflow before alerting on rate.

NHI Mgmt Group recommends adding three signals that sit outside the CI system and catch the cases above after the pipeline has already run:

  • Token use from the wrong place: a publishing or cloud credential that normally appears only from runner IP ranges or an OIDC federation used from elsewhere.
  • Unexpected releases and tag moves: releases, package versions or force-pushed tags outside the release workflow, the pattern in the Trivy case.
  • New runners and new workflows: self-hosted runner registrations and new workflow files not made through reviewed pull requests, the patterns Shai-Hulud used.

For the general method of turning ATT&CK analytics into rules, see the ATT&CK Detection Strategies and Analytics Guide.

Mitigations

ATT&CK v20 maps two mitigations to T1677. Under each, the specific settings come from GitHub's secure use reference and GitHub Security Lab guidance; equivalent controls exist in other CI systems.

M1054 Software Configuration

  • Do not run unreviewed code with secrets: where unreviewed code must run, use isolated nodes without access to secrets, as ATT&CK states.
  • Avoid pull_request_target: use pull_request for building and testing fork code with a read-only token. Where a privileged step is needed, GitHub Security Lab recommends splitting it into a workflow_run workflow and treating anything the first workflow produced as untrusted. Label gating is racy and only a temporary measure.
  • Treat inputs as data: never interpolate attacker-controllable fields such as github.head_ref, pull request titles, issue bodies or commit messages into a run script. Pass them through an intermediate environment variable and quote it.
  • Self-hosted runners: GitHub's guidance is that self-hosted runners should almost never be used for public repositories. For private repositories, use ephemeral runners in separate runner groups.
  • Pin third-party actions to a full-length commit SHA, or a lockfile where adopted. See How to Pin GitHub Actions to Commit SHAs.
  • Block install scripts in jobs that hold secrets, for example npm ci --ignore-scripts, to break the APT38 pattern.

M1018 User Account Management

  • Minimum workflow token: set the default GITHUB_TOKEN permission to read and grant per job with the permissions key.
  • Fewer writers: limit who can write to repositories and who can change workflow files; add .github/workflows to CODEOWNERS.
  • Short-lived credentials: replace stored cloud keys with OIDC federation (see the GitHub Actions OIDC Federation Hardening Guide) and publishing tokens with trusted publishing where the registry supports it.
  • Gate secrets by environment: put release secrets in an environment with required reviewers so a poisoned job on another branch cannot read them.

How to put it in place

  1. Inventory triggers and runners. List every workflow using pull_request_target, workflow_run or issue_comment, every self-hosted runner group and which repositories can use it.
  2. Inventory secrets per job. Map each secret to the jobs that can read it and the identity it represents. Flag secrets reachable by any job that runs fork code or installs third-party packages.
  3. Fix the high-risk patterns first. Remove checkouts of pull request heads under privileged triggers, move inline ${{ }} expressions into environment variables, and take self-hosted runners off public repositories. Change one repository first and confirm builds still pass before rolling the pattern out with a shared reusable workflow.
  4. Reduce token scope. Set organisation default token permissions to read, then raise per job. Roll back by restoring a job's explicit permissions if a build fails, not by reverting the default.
  5. Move to federation. Replace long-lived cloud keys with OIDC; keep the old key disabled, not deleted, for one release cycle so you can roll back.
  6. Turn on detection. Stream the SCM audit log to your SIEM and build the DET0533 correlations plus the three external signals above.
  7. Prepare the response. Write down which tokens to revoke together and how to verify old credentials fail. See the CI/CD Pipeline Compromise Playbook.

How to test

  • Static review: scan workflow files for privileged triggers combined with pull request checkouts, for ${{ github.event.* }} inside run blocks and for unpinned actions.
  • Harmless fork test: in an authorised test repository, open a fork pull request whose build step only writes a marker value and attempts to read a canary secret. Confirm the secret is absent and an alert fires on the fork-triggered run.
  • Canary credential: place a honeytoken in a secret that no legitimate job uses and alert on any use of it.
  • Rotation drill: rotate all pipeline credentials for one repository and verify every old one fails.

Decision guidance

  • Public open source projects: assume every pull request is hostile. GitHub-hosted runners only, no secrets on fork builds, approval for outside collaborators, and publishing from a separate protected workflow.
  • Private repositories in large organisations: the threat is a compromised developer or bot account. Prioritise code owner review on CI files, environment protection on release secrets and token use monitoring.
  • Small teams: start with read-only default tokens, SHA pinning and OIDC. These are configuration changes with little operational cost.
  • Self-hosted versus hosted runners: self-hosted runners reach your network, which ATT&CK names as a route to code execution inside the organisation. Use them only with ephemeral instances, private repositories and dedicated runner groups.

Measurement

  • Number of workflows combining a privileged trigger with a pull request checkout (target: zero).
  • Percentage of third-party actions pinned to a commit SHA.
  • Percentage of cloud access from pipelines using OIDC rather than stored keys.
  • Number of secrets readable by jobs that run untrusted code or install packages.
  • Mean time from a credential exposure alert to verified revocation of every related token.

Common failure patterns

  • Fixing the trigger, keeping the token: a workflow moved off pull_request_target still runs with a write token and broad secrets because default permissions were never lowered.
  • Partial rotation: rotating the token you know about and missing a bot or service account, which the Trivy timeline shows reopened the door.
  • Trusting artifacts: a privileged workflow_run job executes a binary or script built from the pull request.
  • Movable tags: referencing actions by version tag, which an attacker with publishing rights can repoint, as in the tj-actions/changed-files compromise.
  • Persistent self-hosted runners: long-lived runners that keep state between jobs, so one poisoned job leaves something behind for the next.

Framework mapping

FrameworkItemsRelevance
MITRE ATT&CK v20T1677; M1054, M1018; DET0533; related T1195.002 Compromise Software Supply ChainTechnique, mitigations and detection strategy
NIST SP 800-53 Rev 5CM-3, CM-5, SA-10, AC-6, IA-5, SI-7, AU-6Change control on CI files, developer configuration management, least privilege, credential management, integrity, log review
NIST CSF 2.0PR.PS-01, PR.PS-06, PR.AA-05, DE.CM-09Configuration management, secure development, least privilege, monitoring of runtime environments
CIS Controls v8.1Control 16 Application Software SecuritySecure build and release processes
ISO/IEC 27001:2022 Annex A8.25 Secure development life cycle, 8.31 Separation of development, test and production environments, 8.32 Change managementGovernance of pipelines and build environments
OWASP Top 10 CI/CD Security RisksCICD-SEC-4The same risk in OWASP terms

Practitioner checklist

  • No workflow combines pull_request_target or workflow_run with a checkout or execution of pull request code.
  • No attacker-controllable context field is interpolated into a run script.
  • Default GITHUB_TOKEN permission is read; jobs request more explicitly.
  • Third-party actions are pinned to full commit SHAs.
  • Self-hosted runners are ephemeral, grouped and never used by public repositories.
  • Release and publishing secrets sit behind protected environments; cloud access uses OIDC.
  • CI files are under code owner review and branch protection.
  • SCM audit logs feed the SIEM with DET0533 correlations, token use monitoring and runner registration alerts.
  • A tested runbook revokes every pipeline credential together and verifies the old ones fail.

Standards and references

Related NHI Mgmt Group resources: GitHub and GitHub Actions Security Guide, Self-hosted CI/CD Runners and Build Agents, ATT&CK Execution Tactic Guide, CI/CD Security Guide.

Free weekly newsletter

Subscribe to the NHI & AI Identity Journal

The latest on NHI and Agentic AI security – articles, research, breaches, news and events every week.

Bonus 33% off our NHI Course when you subscribe.

NHIMG Editorial Note
Researched and written by the NHI Mgmt Group editorial team using AI tools, under the editorial direction of Lalit Choda. Facts are drawn from the sources listed on this page and checked by our automated quality process. Last updated 12 November 2026. Spotted an error? Use our contact page.
NHI Mgmt Group, the independent authority on Non-Human Identity, IAM and Agentic AI security. nhimg.org