T1677 Splunk · SPL

Detect Poisoned Pipeline Execution in Splunk

This detection identifies adversaries attempting to poison CI/CD pipelines through direct modification of CI configuration files, injection of malicious code into pipeline-referenced build artifacts, or exploitation of fork-based pull request workflows that expose pipeline secrets. Detections span three attack vectors: (1) Direct pipeline execution — changes to CI config files (e.g., .github/workflows, .gitlab-ci.yml, Jenkinsfile) containing suspicious commands such as credential exfiltration via curl/wget, base64-encoded payloads, or environment variable dumping; (2) Indirect pipeline execution — modifications to Makefiles, linters, test suites, or build scripts that are invoked by trusted CI configurations; (3) Public pipeline execution — fork-based pull requests targeting pull_request_target workflows or injecting malicious branch names that are processed as trusted inputs by pipeline steps. Detection coverage includes Azure DevOps audit logs, GitHub audit log events, and process telemetry from CI runner hosts.

MITRE ATT&CK

Tactic
Execution
Technique
T1677 Poisoned Pipeline Execution
Canonical reference
https://attack.mitre.org/techniques/T1677/

SPL Detection Query

Splunk (SPL)
spl
index=* (sourcetype="github:audit" OR sourcetype="github_webhook" OR sourcetype="gitlab:audit" OR sourcetype="azure:devops:audit")
| eval ci_config_modified=if(
    match(coalesce(repository_file, file, head_commit.modified{}, ""),
    "(\.github/workflows|\.gitlab-ci\.yml|Jenkinsfile|\.circleci/config|azure-pipelines\.yml|bitbucket-pipelines\.yml|\.travis\.yml|cloudbuild\.yaml)"),
    1, 0)
| eval suspicious_content=if(
    match(coalesce(commit_message, diff, payload, script, command, ""),
    "(curl |wget |base64 -d|base64 --decode|printenv|env \\||\\| base64|ngrok|interactsh|webhook\.site|requestbin|GITHUB_TOKEN|CI_JOB_TOKEN|AWS_SECRET|API_KEY)"),
    1, 0)
| where ci_config_modified=1 OR suspicious_content=1
| eval risk_score=case(
    match(coalesce(diff, script, command, payload, ""), "(base64 -d|base64 --decode|interactsh|ngrok|webhook\.site|burpcollaborator)"), 95,
    match(coalesce(diff, script, command, payload, ""), "(printenv|GITHUB_TOKEN|CI_JOB_TOKEN|AWS_SECRET_ACCESS_KEY)"), 85,
    match(coalesce(diff, script, command, payload, ""), "(curl |wget |\\| base64|API_KEY|SECRET)"), 70,
    50
)
| where risk_score >= 70
| eval actor=coalesce(actor, user, pusher.name, triggering_actor.login)
| eval source_ip=coalesce(actor_location.ip, ip, client_ip)
| eval repo=coalesce(repo, repository.full_name, project_path)
| eval event_action=coalesce(action, event_type, operation)
| table _time, actor, source_ip, repo, event_action, risk_score, ci_config_modified, suspicious_content
| sort - risk_score, - _time
high severity medium confidence

Detects CI/CD pipeline poisoning via audit and webhook events from GitHub, GitLab, and Azure DevOps. Identifies modification of known CI configuration files and suspicious command patterns consistent with credential exfiltration, encoded payload delivery, or use of out-of-band data collection infrastructure (ngrok, interactsh, webhook.site). Risk-scores each event to surface highest-priority pipeline tampering attempts first.

Data Sources

GitHub Audit Logs (Splunk Add-on for GitHub)GitLab Audit EventsAzure DevOps Audit Logs

Required Sourcetypes

github:auditgithub_webhookgitlab:auditazure:devops:audit

False Positives & Tuning

  • Authorized pipeline modifications by DevOps engineers — cross-reference with approved change management system records
  • Legitimate use of curl/wget in build steps for downloading compile-time dependencies from approved artifact registries (Maven, PyPI, npm)
  • Security tooling bots (Renovate, Dependabot, Snyk) that programmatically update workflow files and reference external URLs
  • Developers using base64 encoding for legitimate non-secret data transformation within build scripts
  • Onboarding automation scripts that dump environment details for troubleshooting — should be gated behind a CICD_DEBUG flag
Download portable Sigma rule (.yml)

Other platforms for T1677


Testing Methodology

Validate this detection against 3 adversary techniques from Atomic Red Team. Each test below lists the behaviour to exercise and the telemetry you should expect to see. Executable commands and cleanup steps are available with Pro.

  1. Test 1Direct CI Config Poisoning - GitHub Actions Credential Exfiltration Simulation

    Expected signal: GitHubAuditLog: Action=git.push with repository_file matching .github/workflows path and DataStr containing 'curl' and 'TOKEN'. AzureDevOpsAuditing: OperationName=Git.Push with Data containing workflow file path and suspicious curl command.

  2. Test 2Indirect Pipeline Poisoning - Malicious npm postinstall Script Injection

    Expected signal: DeviceProcessEvents: InitiatingProcessFileName=npm spawning sh/bash with ProcessCommandLine containing 'printenv'. Sysmon Event ID 1: ParentImage=npm, CommandLine matching printenv/grep pattern. linux_secure or auditd: execve syscall for printenv spawned under npm process.

  3. Test 3Public Pipeline Execution - Fork PR with Malicious Branch Name Injection

    Expected signal: GitHubAuditLog: Action=pull_request.opened with pull_request.head.repo.full_name != pull_request.base.repo.full_name (fork indicator). Branch name field containing shell metacharacters triggers IsSuspiciousBranch=true in hunting query.

Unlock Pro Content

Get the full detection package for T1677 including response playbook, investigation guide, and atomic red team tests.

Response PlaybookInvestigation GuideHunting QueriesAtomic Red Team TestsTuning Guidance

Related Detections