If an affected WPCS version scanned untrusted PHP on a self-hosted runner, the investigation must consider repository tokens, cloud credentials, package secrets, writable caches, persistent workspaces, Docker sockets, internal networks, and later jobs. Updating WPCS stops future exposure but does not close a past incident.
Use this for organizations that ran WPCS 0.14.1 through 3.4.0 against forked pull requests, uploaded archives, marketplace submissions, client code, or other untrusted PHP on persistent runners.
Quick answer
Stop assigning jobs to the runner, preserve workflow and host evidence, identify every untrusted scan with the vulnerable sniff, and map the permissions available at that time. Rotate exposed credentials according to evidence and risk, rebuild the runner from a trusted image, separate untrusted workloads onto ephemeral infrastructure, and verify protected systems for unexpected access.
What to check first
- Record runner ID, host, labels, image, workspace retention, service account, network zones, mounted sockets, cloud roles, package tokens, SSH keys, caches, and artifact permissions.
- Identify workflow runs that used affected WPCS, active WordPress or WordPress-Extra rulesets, untrusted commits or archives, custom bootstrap files, and job timestamps.
- Preserve GitHub audit logs, runner logs, shell history where governed, process data, network logs, cloud audit trails, package access, cache writes, artifacts, and host integrity evidence.
- Contain the runner and credentials without deleting evidence, then search for unexpected repository changes, packages, cloud calls, internal requests, persistence, or cross-job artifacts.
- Rebuild from a trusted image, move untrusted scans to ephemeral least-privilege runners, update WPCS, pin actions, isolate caches, and run an adversarial validation.
Diagnostic table
Use this table to keep the work practical. It connects the symptom to evidence and a verification step.
| Action | Evidence to collect | How to verify |
| Quarantine the runner | Record runner ID, host, labels, image, workspace retention, service account, network zones, mounted sockets, cloud roles, package tokens, SSH keys, caches, and artifact permissions. | The runner no longer accepts jobs and its evidence is preserved. |
| Preserve run and host evidence | Identify workflow runs that used affected WPCS, active WordPress or WordPress-Extra rulesets, untrusted commits or archives, custom bootstrap files, and job timestamps. | Every affected run has a source, ruleset, permissions, and investigation outcome. |
| Map exposed permissions and activity | Preserve GitHub audit logs, runner logs, shell history where governed, process data, network logs, cloud audit trails, package access, cache writes, artifacts, and host integrity evidence. | Protected repository, package, cloud, and network audit logs show the reviewed result. |
| Rotate and rebuild from trust | Contain the runner and credentials without deleting evidence, then search for unexpected repository changes, packages, cloud calls, internal requests, persistence, or cross-job artifacts. | A fresh ephemeral job cannot access secrets, trusted caches, persistent storage, or internal services. |
Why this usually happens
- Self-hosted runners retain files and credentials across jobs unless designed otherwise.
- A Docker socket or internal network can expand impact beyond the lint workspace.
- Untrusted pull-request code may influence custom standards or bootstrap behavior.
- Credential rotation without evidence can miss less visible access paths.
Useful command or data shape
Adapt paths, IDs, and privacy handling to the site before running commands or storing data on production.
incident: wpcs-runner-2026-07
runner_id: wp-ci-04
affected_runs: 7
untrusted_sources: 3
secrets_scope: repo-read + package-write
runner_contained: true
credentials_rotated: true
rebuild_digest: sha256:...
ephemeral_validation: pass
Safe fix order
Do the work in a sequence that makes each result easy to prove. Stop if a step produces new evidence that changes the incident scope.
- Quarantine the runner
- Preserve run and host evidence
- Map exposed permissions and activity
- Rotate and rebuild from trust
- Move untrusted scans to ephemeral isolation
Decision rule
Close only when affected runs and reachable resources are scoped, suspicious activity is resolved, credentials are handled according to evidence, the runner is rebuilt, and untrusted scans can no longer persist or reach protected systems.
What to tell the client or owner
Give the owner the affected versions, exact workflow, observed result, business impact, evidence location, temporary control, named owner, and next review time. Remove credentials and personal data from shared screenshots and logs.
Production verification checklist
- The runner no longer accepts jobs and its evidence is preserved.
- Every affected run has a source, ruleset, permissions, and investigation outcome.
- Protected repository, package, cloud, and network audit logs show the reviewed result.
- A fresh ephemeral job cannot access secrets, trusted caches, persistent storage, or internal services.
Mistakes to avoid
- Do not change several plugins, cache rules, or infrastructure settings before preserving a baseline.
- Do not treat one successful test as proof for retries, alternate clients, background work, or mixed-version fleets.
- Do not paste secrets, personal data, complete production payloads, or customer files into tickets or screenshots.
- Do not close the test until the final user-visible state and the server-side evidence agree.
Questions teams ask during testing
Does a successful WPCS update erase the incident risk?
No. It corrects future scans. Review past untrusted runs that executed with the affected version and permissions.
Should the old runner be cleaned and reused?
Rebuilding from a trusted image is easier to verify than cleaning an unknown persistent state in place.
When HandL WP should help
Bring in HandL WP when a production checkout, form, editor, security gate, media pipeline, or paid lead workflow is at risk. We can preserve evidence, isolate the failing layer, make the smallest corrective change, and verify the result across WordPress, connected services, logs, and the user journey.
If this is active on a production site, investigate a WordPress CI exposure.
Related HandL WP guides
Use these related guides when the same issue touches tracking, security, checkout, or crawler visibility.
Helpful references