Skip to content

Black October 2026 for Salesforce Teams: PHP2Shell, eMudhra, GitLab, LiteLLM and Where Your Org Credentials Sit

Black October two weeks on: which PHP, eMudhra, GitLab and LiteLLM disclosures reach your Salesforce org, what changed since, and which credentials to rotate.

TL;DR

  • Black October is a label that spread on X around 22 October 2026 for a cluster of disclosures between 19 and 22 October. This post reads it two weeks later, with what has changed since. Forkast points out that nobody has found the original post, and that this was a disclosure wave: several of the problems had existed or been exploited for months.
  • No item is a Salesforce platform vulnerability. Salesforce has three Trust notices: PHP2Shell (no products affected "with the exception of Informatica where expedited patching is in progress"), an unnamed "third-party certificate authority" compromise, where it "may undertake proactive maintenance," and the Node.js and Brotli CVEs.
  • Your exposure is the credentials that sit outside the org. Four places matter:
    • PHP sites and Heroku PHP apps with integration logins (PHP2Shell)
    • Self-managed GitLab with SFDX auth URLs or JWT keys in CI/CD variables (CVE-2026-110264, CVSS 10)
    • Any host that installed litellm==1.107.0, which stole every readable process environment and every *.key file, the default name for a Salesforce JWT private key
    • Zeabur-hosted services, including n8n, whose environment variables were read in bulk
  • The eMudhra compromise is a trust problem, not a credential problem. Check your org's trusted roots at /cacerts.jsp, check whether any endpoint your org calls uses an eMudhra G3 certificate, and if an endpoint you call has moved to eMudhra's G1 root, make sure its certificate was issued before 16 November 2026 or comes from another CA.
  • Order of work: patch or contain the system, then rotate the Salesforce credential it held, then read the integration user's Login History.

What You'll Learn

  • Which Black October items touch a Salesforce org, and which are noise for a Salesforce team
  • Where SFDX auth URLs, JWT private keys and connected app secrets tend to live, and which of those places were exposed that week
  • How to check your org's certificate trust store and the certificate chains of the endpoints you call out to
  • The rotation steps for each kind of Salesforce credential, with the commands
  • A triage table you can hand to whoever owns your integrations

The Problem

The week of 19 October 2026 produced more critical disclosures than most security teams can read, let alone act on. PHP shipped emergency releases for two remote code execution bugs. Mozilla and Chrome blocked eight eMudhra intermediate certificates whose private keys turned out to be integers under 256. GitLab patched a CVSS 10 bug affecting every version since 7.0. A malicious LiteLLM release sat on PyPI and Docker Hub for about two hours. Zeabur disclosed that an attacker had read 3.2 million environment variable records. On top of that came unpatched Linux kernel reports, a Node.js release and a long tail of smaller incidents.

The headlines are written for people who run web servers. A Salesforce admin or architect reading them has a narrower question: which of these can reach my org? The answer for every item is the same shape. Salesforce itself is not the vulnerable system. The vulnerable system is something next to it that holds a key to it: the website with the lead plugin, the GitLab pipeline that deploys metadata, the Python service that calls an LLM and then writes to Salesforce, the integration platform hosting your n8n workflows.

Common questions this article answers:

  • Does anything in Black October affect my Salesforce org directly?
  • Our deployment pipeline runs on GitLab. What do I need to rotate?
  • How do I find out whether my org trusts the eMudhra certificates?

Quick Answer

Nothing in Black October is a flaw in Salesforce's platform. Work through the systems around your org in this order. First, GitLab: if you run self-managed GitLab, upgrade to the 29 October patch releases (19.5.3, 19.4.5, 19.3.7, 19.2.10, 19.1.10, 19.0.11 or 18.11.14), which carry the 21 October fix and also remove trust in the eMudhra intermediates, then rotate every Salesforce credential stored in CI/CD variables (SFDX auth URLs, JWT private keys, consumer keys). Second, LiteLLM: search every Python environment and container for litellm==1.107.0; where you find it, rebuild on a pinned version (LiteLLM's advice is still 1.106.2 or an earlier explicit version) and rotate every secret that was in any process environment on that host, plus any *.key file such as a Salesforce JWT server.key. Third, PHP: upgrade to PHP 8.5.12, 8.4.27, 8.3.36 or 8.2.35, redeploy Heroku PHP apps, and rotate credentials held by any PHP site that was unpatched after 20 October. Fourth, Zeabur: if any Salesforce credential lived in a Zeabur environment variable or a Zeabur-hosted n8n instance, revoke and replace it. Fifth, certificates: open https://<your-domain>.my.salesforce.com/cacerts.jsp, check which roots your org trusts, and check that no endpoint your org calls presents an eMudhra G3 chain, or a G1 certificate issued after 16 November. After each rotation, review the integration user's Login History for unfamiliar IP addresses.

The Black October items, sorted by Salesforce impact

Item What happened Touches Salesforce through Priority
GitLab CVE-2026-110264 Unauthenticated RCE on self-managed GitLab, CVSS 10 CI/CD variables holding SFDX auth URLs, JWT keys High if you self-host GitLab
LiteLLM 1.107.0 Malicious PyPI and Docker release, credential stealer Env vars and *.key files on any host that installed it High if you run Python AI services
PHP2Shell PHP engine RCE, CVE-2026-109618 and CVE-2026-109619 PHP sites, plugins and Heroku apps holding integration logins High if PHP sites connect to your org
Zeabur breach Platform database of env vars read Integration credentials in Zeabur env vars or n8n High for Zeabur users, otherwise none
eMudhra intermediates Eight CA private keys trivially recoverable Outbound callout trust, endpoints with eMudhra certificates Medium, and the G1 cutoff is 16 November
Node.js October release Brotli RCE (CVE-2026-111497) plus eMudhra CA update Salesforce CLI and CI images run on Node Low, update with your normal patching; next release due 11 November
Linux kernel ZDI reports Kernel bugs posted publicly; ksmbd fixes now upstream Not a Salesforce path; Heroku manages its host kernels Watch only

GitLab: your deployment pipeline holds org-wide credentials

GitLab's 21 October patch release fixes CVE-2026-110264, "Integer Overflow issue in Regular Expression Compiler impacts GitLab CE/EE." GitLab rates it CVSS 10.0 and says it "could have allowed an unauthenticated user to execute arbitrary code on the GitLab server." It affects "all versions from 7.0 before 18.11.13" and the 19.x lines before their patch releases. GitLab.com and GitLab Dedicated are already patched; self-managed instances are the exposure. GitLab's advisory does not say whether the bug is being exploited, but it does publish two detections: "Onigmo native worker crash" and "Org mode render error burst."

Do not confuse it with CVE-2026-97229, a different CVSS 10 regex bug in GitLab CI/CD that was fixed on 12 October in 19.4.2, 19.3.5 and 19.2.8. Several news outlets mixed the two up. If you patched on 12 October, you still need the 21 October release. CISA added CVE-2026-97229 to its Known Exploited Vulnerabilities catalogue on 29 October, so the 12 October bug is now confirmed as exploited. CVE-2026-110264 is not on that list as of 4 November.

GitLab shipped another patch release on 29 October (19.5.3, 19.4.5, 19.3.7, 19.2.10, 19.1.10, 19.0.11 and 18.11.14). It fixes CVE-2026-111943: "GitLab has removed trust for eight eMudhra intermediate CA certificates whose private keys have been compromised." It also asks you to update GitLab Runner to 19.5.1 and to "rebuild any CI/CD job images that include their own ca-certificates package." Note too that the 21 October fix is a patch to Ruby, so GitLab says you "must also upgrade Ruby to 3.3.13, 3.4.12, 4.0.9 or later" if you build from source.

Why this matters to a Salesforce team

Salesforce DevOps Center supports GitHub and Bitbucket Cloud. GitLab support is an open item on Salesforce's public DevOps Center roadmap, marked for the second half of 2026. So a GitLab-based Salesforce pipeline is one your team built: sf CLI commands in .gitlab-ci.yml, with credentials in CI/CD variables. The usual ones are:

  • an SFDX auth URL (the force://... string from sf org display --verbose), which contains a refresh token
  • a JWT private key (often server.key, stored as a file variable) plus the consumer key of the connected app or external client app it signs for
  • sometimes a username, so the pipeline knows which user to log in as

Code execution on the GitLab server is code execution next to all of those. The advisory does not mention CI/CD variables, so this is an inference, but a sound one: the variables are stored by the GitLab instance, and the instance is what the attacker controls.

What to do

  1. Upgrade self-managed GitLab to the 29 October release for your line and GitLab Runner to 19.5.1, rebuild CI images that carry their own CA bundle, and check the two detections in your logs back to at least 21 October.

  2. List every CI/CD variable that holds a Salesforce credential, across projects, groups and the instance level.

  3. For each SFDX auth URL: revoke the refresh token it contains. In Setup, open Connected Apps OAuth Usage, find the app the CLI authorised through, and revoke the deployment user's token there (or open the user record and revoke under OAuth Connected Apps). Then authorise again from a clean machine and store the new URL:

    sf org login web --alias deploy-prod --instance-url https://yourdomain.my.salesforce.com
    sf org display --target-org deploy-prod --verbose --json
    

    The sfdxAuthUrl value in the output is the new secret. Paste it into the CI/CD variable and mark the variable as masked and protected.

  4. For each JWT key: generate a new key pair away from the GitLab server, upload the new certificate to the connected app or external client app, update the CI/CD variable, run one deployment to prove it works, then remove the old certificate.

    openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 \
      -keyout server.key -out server.crt -subj "/CN=ci-deploy"
    
  5. Read the deployment user's Login History since 20 October and compare source IPs with your runners' egress addresses.

LiteLLM 1.107.0: a stealer that collects *.key files

LiteLLM is a popular Python library and proxy that puts one OpenAI-style API in front of many model providers. On 21 October 2026, a malicious litellm==1.107.0 was published to PyPI (11:39 to 13:23 UTC) and to Docker Hub and GHCR under the tags v1.107.0, latest, main-latest and main-stable (from 11:46 UTC until removed by 13:51 on GHCR and 14:20 on Docker Hub). LiteLLM's incident post says the attacker used stolen GitHub CLI OAuth tokens to point the release workflow at a lookalike repository, Berri-AI/litellm. The git tag itself is clean; 1.106.2 and earlier are safe; enterprise private registry customers were not affected.

LiteLLM published a fuller account on 23 October that corrects its first post. An admin key for an internal LiteLLM service had been committed to a public repository on 27 May, and "nobody followed through on revoking" it. The attacker used it on 10 October to get an organisation owner's GitHub CLI token. LiteLLM rotated its cosign image signing key on 23 October, and every release from 24 October onwards (starting with v1.103.8, v1.104.6, v1.105.4 and v1.106.3) is signed with the new key. 1.107.0 is no longer on PyPI. A prerelease tagged v1.107.0-rc.3 was published on 5 November, so a version scan that matches on 1.107.0 will flag it too.

The researcher who reported it decoded the payload in GitHub issue #47826. It runs on every Python start and collects, among other things:

  • ".env* files, *.pem, *.key and *.pfx"
  • "the environment variables of every readable process (/proc/*/environ)"
  • ~/.ssh, shell histories, cloud CLI credentials, gitlab-runner and Jenkins credentials
  • AI tool configs, including VS Code MCP and Copilot configs
  • every upstream provider key stored in a LiteLLM proxy database, if DATABASE_URL is set

Data is encrypted and posted to http://www.litellm.dev/healthcheck, a domain registered on 13 October that is not the project's own.

Where this meets Salesforce

  • JWT private keys. Salesforce's own JWT bearer flow setup has you create a key called server.key. A stealer that collects *.key from the filesystem collects that file if it sits anywhere the process can read.
  • Credentials in environment variables. Python services that write to Salesforce commonly read a consumer key and secret, or a username, password and security token, from environment variables. Salesforce AI Research's CRMArena benchmark, for example, reads SALESFORCE_USERNAME, SALESFORCE_PASSWORD and SALESFORCE_SECURITY_TOKEN from the environment (it pins an older, safe LiteLLM, 1.67.2). The stealer reads the environment of every readable process, not just its own.
  • Heroku Managed Inference. Heroku documents LiteLLM as an integration for its inference add-on, using INFERENCE_KEY and INFERENCE_URL. The doc does not pin a LiteLLM version, so an app that installed the latest release during the window would have pulled 1.107.0.
  • LLM gateways behind Agentforce. The Einstein LLM Open Connector is based on the OpenAI API, so a self-hosted OpenAI-compatible proxy such as LiteLLM can sit behind a Bring Your Own LLM setup. If yours does, its database holds your upstream provider keys and the payload dumps them.
  • Unpinned research code. Salesforce AI Research's promptomatix lists litellm without a version pin, so a fresh install during the window would have pulled the bad release.

What to do

  1. Find it. Check every virtual environment, container image and CI cache:

    pip show litellm 2>/dev/null | grep -i '^version'
    find / -name 'litellm-1.107.0.dist-info' -o -name 'cook.pth' 2>/dev/null
    ls -la /tmp/remote_code_loader.lock /tmp/.pc_once_* 2>/dev/null
    

    For Docker, check whether any image was pulled from the four tags during the window.

  2. Do not run pip install first on an affected host. Every Python start, including pip, runs the payload again. Follow the clean-up order in LiteLLM's post and issue: remove the files, kill the daemon holding /tmp/remote_code_loader.lock, rebuild from a clean image pinned to an explicit version. LiteLLM's written advice is still 1.106.2; if you take a later release, verify the image against the new cosign key.

  3. Assume exfiltration if the host had outbound internet. The issue notes that a missing marker file proves nothing, because containers and tmp cleanup remove it.

  4. Rotate what LiteLLM lists (IAM role, provider keys, master and virtual keys, DATABASE_URL password, any secret in any process environment), plus any Salesforce credential that was in an environment variable or a *.key file on that host.

PHP2Shell: websites and plugins that hold integration logins

PHP2Shell (CVE-2026-109618 and CVE-2026-109619) is two critical bugs in the PHP engine that allow unauthenticated code execution before any application code runs. The fix is PHP 8.5.12, 8.4.27, 8.3.36 or 8.2.35. Salesforce updated its Trust notice on 27 October: no Salesforce products are affected "with the exception of Informatica where expedited patching is in progress," and it has "seen no evidence of compromise of Salesforce customers or data." Heroku has shipped patched runtimes that apps pick up on redeploy. CISA added both CVEs to its Known Exploited Vulnerabilities catalogue on 26 October, so an unpatched PHP site should be treated as compromised, not just exposed.

For a Salesforce team, the exposure is WordPress, Drupal, Magento and custom PHP sites that hold a connected app secret, a refresh token, a JWT key or an integration password. The full walkthrough, including the plugins and connectors to look for and a credential rotation checklist, is in PHP2Shell (CVE-2026-109618 and CVE-2026-109619): What Broke, How to Fix It, and What It Means for Salesforce.

Zeabur: integration platforms are credential stores

Zeabur, a developer hosting platform, published a preliminary incident report on 19 October. Its own root-cause summary: "long-lived admin credentials were stored in plaintext and could be used from the public internet." An attacker active from 14 to 15 October read the platform database, which held 3,218,965 environment variable records for 321,810 accounts. Zeabur also reports running commands on 865 shared cluster database services, 736 of them n8n, and found that 602 of 607 n8n instances it checked kept their encryption key in an environment variable. Zeabur is shutting down on 31 December 2026.

n8n has a Salesforce node, and its stored credentials are encrypted with that encryption key. If a team in your organisation ran an n8n workflow or any other integration on Zeabur that connected to Salesforce, treat that credential as read. Zeabur's instruction to all users is to revoke and replace every credential in environment variables. For n8n specifically, it says to replace the encryption key and recreate all third-party credentials. A follow-up on 28 October adds that Zeabur is "unable to pay for third-party service charges arising from the October 2026 security incident," so any API spend run up with a stolen key is yours.

Railway, another hosting platform, also disclosed on 21 October that an unauthorised party may have accessed encrypted customer environment variables, and obtained the decrypted contents of some of them. Railway's preliminary report, last updated 26 October, says the incident "is resolved for existing users," recommends that "all customers who signed up prior to October 21 rotate their keys stored on Railway," and says Railway "is unable to refund customers for spend performed with compromised API keys." Its final forensic report is not out yet. If you host integrations there, apply the same logic as for Zeabur.

eMudhra: check what your org trusts and what it calls

Mozilla's notice to the oss-security list says "the private keys corresponding to 8 eMudhra Intermediate certificates have been compromised": six TLS intermediates (EM EV, OV and DV TLS CA, generations G3B and G3C) and two code-signing intermediates. Sectigo had cross-signed all eight under its AAA Certificate Services root. eMudhra revoked them on 18 October and Sectigo revoked its cross-signs on 19 October. Mozilla's bug tracker records that the keys "all used integers less than 256," so anyone could compute them.

Mozilla's first notice said Certificate Transparency logs "do not show any issued certificates from the compromised intermediates," and warned that "abuse of the compromised private keys is likely in the near future." That warning came true within a day. A later comment in the Mozilla bug reports that between 20 and 21 October, "107,107 certificates signed with six of the eight keys were logged" to one CT log operator, and "every signature verifies under the corresponding CA key." Most were proof-of-concept certificates for google.com, but the list includes precertificates for emudhra.salesforce.com. Nobody has reported these being used in an attack, but they show that anyone could sign with the keys.

Firefox and Chrome block the intermediates through OneCRL and CRLSets. Mozilla removed emSign ECC Root CA - G3 from NSS on 20 October, and Chromium's root store removed it the same day.

The story then widened to eMudhra's other root. On 5 November, Mozilla and Chromium both set a TLS distrust-after date of 16 November 2026, 23:59:59 UTC for emSign Root CA - G1. Mozilla's bug says "TLS certificates issued after the cutoff will be rejected, with SCT checking to prevent circumvention through backdating." eMudhra's own update lists Apple removing G1 on 30 November; I have not found an Apple source for that date. eMudhra has said its full incident report will follow on 9 November.

What Salesforce has said

Trust message 20000266, "Proactive Maintenance: Third-Party Certificate Authority Issue," reads: "Salesforce is aware of a publicly reported compromise of intermediate certificates issued by a third-party certificate authority. Salesforce is continuing to monitor the situation and may undertake proactive maintenance." It does not name eMudhra, and as of 7 November it has not been updated since it was posted on 21 October.

Two checks for your org

1. What your org trusts. Salesforce's help article on certificate trust says you can see the trusted root CAs for your org by appending /cacerts.jsp to your org hostname, and that Salesforce uses trust stores such as the Mozilla Root Store as a baseline. Open:

https://yourdomain.my.salesforce.com/cacerts.jsp

Search the page for AAA Certificate Services, emSign and eMudhra. If AAA Certificate Services is there (it is a long-standing, widely trusted Sectigo root), then until Salesforce's "proactive maintenance" lands, your org's outbound callouts could accept a certificate chaining through the cross-signed intermediates if someone minted one, unless revocation is checked. There is nothing for you to switch off in the org; the action is to know the exposure and watch Trust message 20000266 for changes. If you have added custom roots, Salesforce's certificate trust store and private CAs covers how those are managed.

2. Which endpoints you call. List the hosts behind your named credentials, remote site settings, outbound messages and Apex callouts. For each, look at the issuer chain:

openssl s_client -connect api.example.com:443 -servername api.example.com -showcerts </dev/null 2>/dev/null | grep -E '^ *[0-9] s:|i:'

If any line shows an EM ... TLS CA - G3B or G3C issuer, or an emSign ... G3 root, that endpoint's owner needs to move to a new certificate. eMudhra says about 30,800 certificates were issued under the affected G3 hierarchies, nearly all to one client ecosystem in the United States, and that those customers moved to its G1 RSA root. With G1 now facing its own cutoff, check G1 certificates too: one issued after 16 November will fail in Chrome and Firefox, and the endpoint owner should move to another CA. If Salesforce removes the G3 roots from its trust store, callouts to an unmigrated endpoint will start failing TLS handshakes, and the error will look like an integration outage, not a security event.

The smaller items

Node.js. The 21 October Node.js security releases (22.23.4, 24.22.1 and 26.12.1) include a CA certificate update for the eMudhra compromise and fix a high-severity Brotli decoder bug, CVE-2026-111497, credited to OpenAI Codex Security. Salesforce posted Trust message 20000268 on 28 October covering CVE-2026-111497 and another October Node.js CVE, again with "no evidence of exploitation affecting Salesforce or customer data." Node.js has pre-announced another security release for 26.x, 24.x and 22.x on or shortly after 11 November. The Salesforce CLI runs on Node, so update the Node in your CI images and admin laptops with your normal patching.

Linux kernel. Trend Micro's Zero Day Initiative posted kernel bug reports to public lists on 21 and 22 October, including two rated CVSS 9.0 in the in-kernel SMB server (ksmbd). Fixes for both ksmbd bugs are now in mainline (7.4-rc1) and queued for the stable kernels, but neither has a CVE yet. This is not a path into Salesforce. Heroku manages the host kernels its dynos run on.

Frequently Asked Questions

Is Salesforce affected by Black October?

Not as a platform vulnerability. Salesforce's PHP2Shell notice reports no evidence of exploitation affecting Salesforce or customer data, and its certificate notice says it is monitoring and may do proactive maintenance. The exposure is in systems you run next to Salesforce that hold credentials to it.

Which Salesforce credentials should I rotate first?

Rotate the credentials that sat on a system you know was exposed. In practice that means the CI/CD credentials on self-managed GitLab instances that were unpatched after 21 October, then anything on a host that installed litellm 1.107.0, then PHP sites unpatched after 20 October, then anything on Zeabur. A credential on a system that was never exposed does not need emergency rotation.

Does DevOps Center use GitLab?

No. DevOps Center supports GitHub and Bitbucket Cloud. GitLab integration is an open item on Salesforce's public DevOps Center roadmap, so GitLab exposure only applies to pipelines you built yourself.

Do I need to do anything about eMudhra if I never bought an eMudhra certificate?

Check the endpoints your org calls out to, because their owners might have. If none of them chain to an eMudhra G3 intermediate, and none use a G1 certificate issued after 16 November, there is nothing to migrate. Keep an eye on Salesforce's Trust message 20000266 in case Salesforce changes its trust store.

How do I know whether a stolen credential was used?

Read Login History for the integration or deployment user from 20 October onwards. Integration users log in from a small, predictable set of IP addresses, so an unfamiliar source IP or client application stands out. If you have Event Monitoring, the API and login event log files show what was queried.

Key Takeaways

  • Black October is a disclosure wave, and none of it is a Salesforce platform vulnerability.
  • The real exposure is credentials stored outside the org: CI/CD variables, environment variables, *.key files, plugin settings and integration platforms.
  • Self-managed GitLab (CVE-2026-110264) and litellm 1.107.0 are the two items most likely to have exposed Salesforce deployment and integration credentials.
  • For eMudhra, check /cacerts.jsp and the certificate chains of the endpoints you call, including G1 chains, then watch Trust message 20000266.
  • After every rotation, read the affected user's Login History.

What's Next?

Recommended reading:

Action items:

  1. List every system outside Salesforce that holds a credential to your org, with the credential type and who owns it.
  2. Patch self-managed GitLab and rotate the Salesforce credentials in its CI/CD variables.
  3. Search Python environments and images for litellm 1.107.0, and pin LiteLLM to an explicit version everywhere.
  4. Open /cacerts.jsp in each production org and check your callout endpoints' certificate chains before the 16 November G1 cutoff.
  5. Set login IP ranges on integration and deployment users' profiles, so a stolen credential cannot be used from anywhere else.

Resources & References

Responses

Checking your session.

Loading responses.