Detecting malicious pull requests at scale with LLMs | Datadog (opens in new tab)
Malicious pull requests can turn routine code review and CI workflows into supply-chain attack vectors. The post explains how attackers abuse automated builds—especially when workflows expose repository secrets or elevated GitHub permissions—and recommends treating all pull-request code as untrusted. Strong isolation, least privilege, careful workflow design, and monitoring are essential to prevent credential theft and unauthorized access.
How Malicious Pull Requests Work
- Attackers submit seemingly harmless changes that alter:
- GitHub Actions workflows
- Build or test scripts
- Dependency configuration
- Developer tooling
- The malicious code executes automatically when CI runs the pull request.
- Its goal may be to:
- Exfiltrate repository or cloud credentials
- Modify artifacts
- Access internal systems
- Establish persistence in the development pipeline
Why CI Workflows Are Vulnerable
- Pull-request jobs often execute attacker-controlled code through tests, package installation, or build commands.
- Using privileged workflow events such as
pull_request_targetcan expose secrets while checking out untrusted contributor code. - Broad
GITHUB_TOKENpermissions increase the impact of a compromised job. - Secrets may leak through logs, environment variables, artifacts, or outbound network requests.
Defensive Engineering Practices
- Treat code from forks and external contributors as untrusted.
- Avoid making secrets available to pull-request jobs.
- Use minimal
GITHUB_TOKENpermissions and separate privileged workflows from validation workflows. - Pin third-party GitHub Actions and dependencies to trusted commits or versions.
- Require explicit approval before running workflows from untrusted contributors.
- Isolate CI jobs with ephemeral runners, restricted network access, and limited filesystem permissions.
- Review changes to workflow files with heightened scrutiny.
Detection and Response
- Monitor workflow behavior for unexpected network connections, credential access, or modified build outputs.
- Audit repository and CI permissions regularly.
- Use short-lived credentials and OIDC-based cloud access instead of long-lived static secrets.
- Preserve workflow logs and artifacts to support investigation.
- Revoke credentials immediately if a pull request or CI job is suspected of compromise.
The practical recommendation is to design CI as though every pull request could be hostile: validate untrusted code in a restricted environment, keep secrets and write permissions out of those jobs, and require deliberate promotion into trusted workflows.