
The last two years made one thing clear: the fastest way into thousands of companies is through the packages and CI workflows they all share. Self-spreading npm worms stole tokens from maintainers and republished their packages. In May 2026 a mass backdoor campaign touched more than 5,000 GitHub repositories through Actions workflows. Campaigns now hit npm, PyPI and Crates.io at the same time.
On 28 July 2026 GitHub summarised the defaults it changed in response. Most are already live. Here is what each one does, the attack it targets, and what you need to change.

npm: the install step stops running code
npm 12 disables install scripts by default (June 2026)
preinstall, install and postinstall scripts have been the favourite payload hook, because they run the moment someone types npm install, on developer laptops and CI runners full of tokens. GitHub's own words: install-time scripts were "used to exfiltrate credentials instead of waiting for runtime code execution." npm 12 turns them off and lets you approve specific packages' scripts. Git and remote-URL dependencies are also off by default.
What to do: upgrade CI images to npm 12 and run a clean install. Native modules (image libraries, database drivers, esbuild-style binaries) may now need an explicit approval. Approve those few, commit the approval, and treat any new request for script approval in a PR as something to review.
Staged publishing (May 2026) and trusted publishing
Staged publishing means a CI job can upload a release, but it isn't published until a maintainer approves it with 2FA. A stolen CI token can no longer push malware straight to millions of installs. Trusted publishing (OIDC from the CI provider, no long-lived npm token) now also covers CircleCI as well as GitHub Actions and GitLab.
What to do: if you publish packages, delete long-lived NPM_TOKEN secrets, switch to trusted publishing, and turn on staged publishing for anything widely used.
Account protection for high-impact maintainers (June 2026)
If a high-impact account changes its email or uses a 2FA recovery code, npm now puts it in read-only mode for 72 hours. That covers the usual takeover path after a phished maintainer.
GitHub Actions: closing the pwn-request door
Safer checkout in pull_request_target (June 2026)
A "pwn request" is a workflow triggered by pull_request_target (which runs with the base repo's secrets) that then checks out and builds the fork's code. Anyone could open a PR and run code with your secrets. Checkout now refuses untrusted fork code in these commonly exploited triggers unless you explicitly opt out.
What to do: search your workflows for pull_request_target and workflow_run. If something broke, don't just opt out: split the job so the untrusted build runs without secrets under pull_request, and only the trusted step (labelling, commenting) uses pull_request_target.
Workflow execution policies (June 2026)
Enterprises, organisations and repositories can now set who may trigger workflows and which trigger types are allowed. Most teams can ban pull_request_target outright, or limit workflow_dispatch on deploy workflows to a release team.
Read-only cache for untrusted triggers (June 2026)
Cache poisoning let a low-privilege workflow write a cache entry (say, a poisoned node_modules) that a privileged release workflow later restored. Less-trusted workflows now get a read-only cache.
Actions network firewall (technical preview)
Hosted runners can now log every outbound connection from a run, with egress blocking planned. Exfiltration to a random paste site or a new domain becomes visible. Third-party tools such as StepSecurity's Harden-Runner have done this for a while and already support blocking.
Slowing down on purpose
Dependabot version updates now have a three-day default cooldown (July 2026) before opening PRs for a new release. Security updates still arrive immediately. Malicious releases are usually caught and pulled within hours, so a short delay keeps you out of most of them. pnpm, Yarn and Renovate offer similar minimum-release-age settings if you don't use Dependabot.
This week's checklist
1. Move CI and dev machines to npm 12; approve only the install scripts you need.
2. Replace NPM_TOKEN with trusted publishing; enable staged publishing.
3. Audit pull_request_target / workflow_run workflows; set an org execution policy.
4. Pin third-party actions to a full commit SHA, not a tag.
5. Set permissions: to the minimum in every workflow (default contents: read).
6. Turn on runner egress logging (Actions firewall preview or Harden-Runner) and review new domains.
7. Keep the Dependabot cooldown, or add a minimum release age in your package manager.
8. Make sure you can revoke all of a user's credentials quickly. GitHub added self-service enterprise-wide revocation in June 2026.
osec.one publishes practical security write-ups and small tools for teams without a security department. Start with passwordless logins.
See osec.one tools