펜리젠트 헤더

GitHub Actions Security Audit: Respond to the wfx Credential Stealer

A clean default branch is not enough to close a GitHub Actions credential-exposure investigation. The wfx campaign illustrates why a reverted workflow change, a completed runner job and a surviving cloud identity are three different records. An audit should establish which code executed, which authority that execution received and what access remains afterward.

What the original wfx research establishes

In its November 12 investigation, SafeDep describes stolen GitHub tokens used to introduce a stealer through workflows or npm installation hooks, often followed by commits reverting the change. The research also describes attempts to create cloud access that can survive replacement of the initially exposed secret. These are researcher observations, not results of a Penligent investigation.

SafeDep’s repository count is a dated search snapshot covering November 10 through early November 12. Do not use a public count as an inventory of your own affected repositories. This article’s response method uses your authorized organization history, workflow executions and cloud audit records. It does not fetch payloads, execute suspicious packages or visit exfiltration destinations.

An audit correlates suspicious commit history with Actions execution and subsequent cloud-state evidence.
Each arrow is an investigation question, not a completed chain

Preserve execution history before interpreting the latest tree

Record the repository, suspicious commit range, actor, workflow revision, trigger, job time and run identifiers. Preserve available evidence according to the organization’s incident process. Inspect the workflow that ran at that commit, including referenced scripts and dependency-install changes. Comparing only the current YAML with a baseline can miss code that executed and was subsequently removed.

Keep developer exposure separate from hosted-runner exposure. An installation hook can execute outside Actions when a developer or another build system installs the affected package. Map the package version and installation window to the machines that actually consumed it. The existence of an unfamiliar commit does not by itself prove that every environment ran the code.

Evidence plane질문Closure limit
Repository historyWas a workflow or install hook introduced, changed and reverted?A clean current tree does not erase historical execution.
Runner executionWhich job ran that revision, under which trigger and environment?A commit alone does not prove a runner executed it.
Credential authorityWhich secrets, variables and identity tokens were available?Masking log output is not a restriction on code using a secret.
Cloud stateDid that identity create or modify continuing access?Rotating the original key does not remove a separate principal or trust change.

Audit the authority granted to each job

GitHub’s security hardening guidance recommends least privilege for the GITHUB_TOKEN and addresses untrusted input, third-party actions, secrets and OIDC. Apply those controls to the workflow’s actual data flow. Record repository defaults and job-level overrides; do not assume an apparently read-only step makes the whole job read-only.

Review which jobs need secrets and which can run without them. Inspect third-party action references and the process for accepting updates. Pinning an action to a full commit identifies the selected revision; it does not make that revision trustworthy. Keep provenance review, revision pinning and runtime permissions as separate evidence fields.

For OIDC, review both sides: a job’s permission to request an identity token and the cloud role’s trust policy for accepting it. Bind the trust decision to the intended repository and deployment context according to the provider’s documented claims. A short-lived token limits one credential’s lifetime; it does not prevent an overly privileged session from making lasting changes.

GitHub job permission, cloud trust conditions and role resource privileges are separate security controls.
Short token lifetime does not limit every action of the assumed role

Contain the exposed authority and verify what remains

Coordinate token revocation, secret replacement and cloud response with the relevant owners. Avoid putting replacement credentials into a workflow or runner that is still under investigation. Review access changes, newly created identities and trust-policy changes in the appropriate cloud records. Retain visibility gaps and unavailable retention periods instead of treating missing events as proof of no activity.

A self-hosted runner needs its own host assessment because it can retain state between jobs. A repository fix does not establish that the runner’s filesystem, credentials or scheduled processes are clean. Use the organization’s rebuild and incident procedures where warranted; this guide does not prescribe deleting artifacts before evidence collection.

Make a CI/CD security testing engagement measurable

Use a disposable repository and synthetic credentials for control validation. Define four safe acceptance cases: an untrusted change cannot reach a protected deployment secret; a minimal job cannot obtain an unrelated write permission; an identity token from the wrong approved fixture cannot assume the deployment role; and the audit record ties the allowed deployment to its reviewed revision. Do not run the stealer as a test.

Workflow / revision: exact reviewed commit
Trigger and trust level: owned test fixture
Job permissions: required vs observed
Secret access: synthetic canary only
Cloud role: intended subject and trust constraints
Run evidence: job ID, time, redacted decision logs
Residual state: principals, trust changes, runner status
Outcome: passed / failed / inconclusive / not tested

Ask an auditor to demonstrate the enforcement point and the negative control, then provide a repair retest. The useful deliverable is a traceable boundary decision, not a screenshot of a green pipeline. Keep incident closure and future control assurance as separate conclusions even when the same engagement supports both.

When evaluating 펜리전트 for a subsequent authorized application assessment, keep its scope and findings separate from the repository-history and cloud-identity incident work above.

The official Penligent 3.0 video below demonstrates the general product workflow. It illustrates product use; the article’s assessment proposals and source findings are evaluated separately.

Method: AI-assisted review of the linked primary sources, checked November 12, 2026, with an original assessment framework. No exploit, production target or customer environment was tested for this article.

게시물을 공유하세요:
관련 게시물
ko_KRKorean