Black October: What Happened, What the Numbers Mean, and What Developers Should Do
October’s security headlines span runtime vulnerabilities, compromised certificate keys, and malicious software releases. Here is what the evidence shows, what the numbers mean, and how developers can respond.
- Cybersecurity
- Software Engineering
- Supply Chain
- Node.js
Information checked on October 23, 2026
When PHP, Node.js, certificate authorities, and software packages appear in security headlines together, the immediate question is personal: does this affect something I run?
That was my starting point this October.
I wanted to understand which reports were relevant to my applications, which components needed updates, and whether fixing dependency warnings would be enough.
The investigation quickly became more complicated than a list of outdated packages. The reports described different kinds of problems: vulnerabilities in software runtimes, attempts to exploit those vulnerabilities, compromised cryptographic keys, and a malicious software release.
Some commentators have called this concentration of security events “Black October,” citing its volume and risk. Axios
The name captures the concern. Understanding what happened requires looking beyond the name.
This article examines four representative events, explains why they matter together, and describes how I approached checking my own applications. It is a dated account of developing disclosures, rather than a complete inventory of every incident this month.
First, what does “Black October” actually mean?
In the reporting reviewed for this article, “Black October” is an informal label. It does not identify a single vulnerability, establish a coordinated campaign, or provide a standardized count of victims.
The dates also need care. A disclosure published this week may describe an intrusion that began much earlier. Reporting on the label has highlighted how some incidents circulating together had been underway for months. SecurityToday
There are at least four dates worth separating:
- When a vulnerability was introduced: the software may have contained the flaw for years.
- When exploitation began: attackers may have discovered it independently.
- When defenders learned about it: this may happen privately before public disclosure.
- When a fix became available and was deployed: those are two separate milestones.
A busy disclosure week does not automatically mean every attack started that week.
My interpretation of October’s significance is that several events challenged different assumptions developers rely on every day: that the runtime executes code safely, that certificates establish trustworthy identities, and that software arriving through an established release channel is authentic.
How many attacks happened?
There is no defensible worldwide total in the sources reviewed for this article.
That does not make the incidents less serious. It means the available numbers measure different things.
| Term | What it measures | What it does not establish |
|---|---|---|
| Vulnerability | A security weakness | That anyone exploited it |
| CVE identifier | A publicly identified vulnerability | One attack or one victim |
| Attack attempt | An observed effort to exploit or abuse a system | Successful access |
| Confirmed compromise | Evidence that a security boundary was breached | Every downstream consequence |
| Malicious artifact | A package, image, or file containing malicious content | How many systems executed it |
| Affected installation | A system meeting an advisory’s affected conditions | That the system was attacked |
| Audit finding | A scanner’s match against known advisory data | A forensic finding of compromise |
These categories cannot be added into a meaningful “attack total.”
For example, ten vulnerabilities, eight compromised keys, and one malicious release do not equal nineteen attacks. They describe different units of risk and evidence.
The relationship is better understood like this:
This distinction matters when communicating with users, colleagues, and customers. Saying “we patched an affected component” is a concrete statement. Saying “we were hacked” requires different evidence.
Four events that explain the concern
PHP: a runtime vulnerability with observed exploitation attempts
The PHP disclosures involved CVE-2026-109618 and CVE-2026-109619, collectively called PHP2Shell. Emergency fixes were released on October 21 for two critical remote code execution vulnerabilities in the core runtime. AWS mitigation advisory
AWS reported an exploitation attempt in its MadPot honeypot telemetry dated October 17, four days before public disclosure. That observation establishes attempted exploitation before disclosure; it does not establish a worldwide total of successfully compromised servers. AWS threat intelligence report
For operators, this creates two separate tasks: update the affected runtime and investigate the period during which it was exposed.
The release versions identified as fixing these issues include PHP 8.2.35, 8.3.36, 8.4.27, and 8.5.12. Operators using distribution packages or managed hosting should follow their provider’s advisory, including any backported fixes, rather than judging protection solely from an upstream-looking version string. Plesk advisory
Node.js: multiple vulnerabilities across supported release lines
Node.js published security releases on October 21 addressing ten vulnerabilities, including four rated high severity. The issues include a Brotli decoder memory corruption vulnerability and problems involving DNS and TLS validation.
The corresponding security releases are 22.23.4, 24.22.1, and 26.12.1. Applicability differs between release lines, so the advisory’s affected-version details matter. Node.js security advisory
The count describes vulnerabilities. It does not demonstrate ten successful attacks, nor establish that every Node.js application was compromised.
A practical complication is that “our Node version” can refer to several environments: a developer’s shell, CI, a container used during builds, or the runtime serving production traffic. Updating one does not establish that the others changed.
In my repository, I selected the patched Node 22 release within the existing major version and aligned the development and CI configuration around it.
eMudhra: a problem in the certificate trust system
Mozilla reported receiving notice on October 17 that private keys associated with eight eMudhra intermediate certificates had been compromised. Google also published protective action concerning the affected intermediate CA certificates. Mozilla security notice, Google security notice
Certificate authorities participate in the system clients use to authenticate websites. A compromised intermediate signing key can undermine that trust, subject to certificate constraints and the client’s validation protections.
The number eight refers to keys associated with intermediate certificates. It is not a count of hacked websites or evidence that every connection using HTTPS was intercepted.
Cloudflare documented the incident and protective updates, illustrating how the response extended across software that consumes certificate trust information. Cloudflare incident explanation
There are consequently two operator concerns: whether a service’s certificate chain is affected, and whether its clients and runtimes have current trust protections when connecting to other services.
LiteLLM: malicious code distributed through a software release
LiteLLM’s incident report states that its release pipeline was compromised on October 21 and that malicious version 1.107.0 reached package and container distribution channels. The report described the incident as contained while investigation continued. LiteLLM incident report
Datadog’s analysis identified credential-stealing behavior and a remote-access payload in the malicious release. Datadog Security Labs analysis
This is evidence of a compromised release, rather than merely a newly discovered weakness in otherwise legitimate code.
For an organization that installed or executed affected artifacts, replacing the package is only part of the response. It must also investigate what ran, what credentials were accessible, and whether additional persistence or unauthorized activity exists.
Download figures would not settle the victim count: downloads can include caches, mirrors, repeated builds, and installations that never executed the relevant code.
Why these incidents matter together
The four examples concern different layers of a modern application:
This is a conceptual map of defensive responsibilities, not an assertion that the incidents were connected.
My concern is the operational overlap. The same small team may own application dependencies, runtime updates, deployment pipelines, production credentials, and incident review.
A dependency update cannot solve every problem in that map. A certificate change cannot remove malicious code from a build runner. A successful application build cannot prove that production received the intended runtime.
Each layer needs its own evidence.
Why patching and incident response are different jobs
Patching changes the software’s future behavior. Incident response investigates what happened before and during that change.
Imagine a service that was vulnerable on Monday, exploited on Tuesday, and patched on Wednesday. The Wednesday update might close the original entry point while leaving behind an unauthorized account, a stolen credential, or a modified file.
That example is hypothetical, but it explains why the two workstreams should remain distinct:
Containment, evidence preservation, eradication, and recovery are established incident-response activities. Their order and implementation depend on the incident and the need to stop ongoing harm while retaining useful evidence. CISA incident and vulnerability response playbooks
A team can truthfully report that it has deployed a fix while its investigation remains open.
What I checked in my own applications
My applications live in a monorepo containing Portfolio, Studio, Admin, and Auth.
I began with the software actually present in the repository and development environment. The review found a relevant Node.js and JavaScript dependency surface. It did not identify a PHP application in the reviewed repository.
That scope matters. A repository review does not inventory every external service, vendor, or machine an organization might use.
The resulting changes included:
- Pinning Node.js 22.23.4 and aligning the development and CI configuration.
- Updating the package manager and affected application dependencies.
- Removing an optional CLI dependency that retained vulnerable bundled components.
- Addressing remaining tooling dependencies.
- Adding dependency auditing to CI.
The updates were validated with repository checks, strict type checking, tests, and application builds before shipping. Full and production dependency audits reported zero findings at the time of that validation.
Those are useful results, but their meaning has limits.
They establish that the reviewed dependency graph no longer matched the advisories reported by those audits at that time. They do not establish that the applications had never received malicious traffic, that every possible weakness was absent, or that no credential had ever been exposed.
Determining whether an attack succeeded requires evidence from the relevant operational environment.
Why development dependencies deserve attention
It is tempting to treat a finding in a development dependency as harmless because the package does not ship to the browser or production server.
The better question is: where does this code execute, and what can that environment access?
A build tool may run in CI. A CLI may run on a developer’s machine. Either environment may have access to source code, registry credentials, deployment permissions, or other sensitive resources.
These are possible access paths, not a claim that every dependency has these permissions.
A development-only classification is relevant to prioritization. It is not sufficient to dismiss a finding without understanding the execution path.
A practical response process for developers
The following is the process I would use to turn a headline into a defensible engineering decision.
1. Identify the exact advisory
Start with the maintainer, vendor, certificate program, or organization investigating the incident.
Record the affected component, versions, configurations, available fixes, and any evidence of exploitation.
Keep provisional explanations separate from confirmed findings. Early incident reports can change as investigators learn more.
2. Find every relevant installation
Look beyond the application manifest.
Check production runtimes, container images, CI runners, developer tools, scheduled jobs, staging services, and older deployments that still receive traffic.
For a managed platform, determine what the provider updates and what remains your responsibility.
The output should be a concrete inventory of relevant assets and owners.
3. Establish whether the affected conditions apply
A package name match is a starting point.
Review the installed version, enabled features, reachable inputs, privileges, and advisory prerequisites. If applicability cannot be established promptly, document that uncertainty and choose an appropriately cautious response.
Avoid treating incomplete visibility as evidence of safety.
4. Select and deploy the fix
Use the vendor-recommended fixed release or supported package update. Check whether a distribution has backported the correction.
Review dependency changes, test relevant behavior, and ensure the deployment replaces or restarts affected processes where necessary.
A local version check only proves the version in that local environment.
5. Verify the deployed result
Use deployment records, image identifiers, runtime diagnostics, or provider confirmation to establish what is actually running.
Verify the application’s important flows after the change. Authentication, background jobs, integrations, and error handling can fail even when a homepage still loads.
6. Investigate credible exposure
Where the advisory or incident evidence warrants it, review the period during which affected software was present.
Relevant evidence may include access logs, authentication events, CI job history, package installation records, deployment changes, and outbound network activity.
If compromise is suspected, preserve evidence and contain affected systems using the organization’s incident-response process. Coordinate credential revocation and recovery from a trusted environment. Canadian Centre for Cyber Security response guidance
7. State exactly what was verified
A useful status report distinguishes:
- Which assets were reviewed.
- Which updates were deployed.
- What validation passed.
- What evidence was examined.
- What remains unknown.
That makes the result understandable to someone who did not perform the work.
What a clean audit can and cannot tell you
A dependency audit is valuable because it can repeatedly compare a resolved dependency graph with known advisory information.
Its scope is narrower than an application’s complete security posture.
| Evidence | A reasonable conclusion | An unsupported conclusion |
|---|---|---|
| Clean dependency audit | No matching findings were returned within that audit’s scope | The application has no vulnerabilities |
| Passing tests | The tested behavior passed | Every security boundary is correct |
| Successful deployment | The platform completed the deployment | No attacker accessed the previous deployment |
| Blocked firewall request | That recorded request was blocked | Every malicious request was blocked |
| No suspicious events in reviewed logs | No evidence was found in those logs and that time window | No compromise ever occurred |
Security communication becomes more useful when each statement stays within what its evidence can support.
Changes worth keeping after the headlines fade
Emergency patching is easier when routine engineering already provides visibility.
For my own work, the durable improvements are straightforward:
Make runtime versions explicit. Development, CI, and production should have a deliberate version policy, with a way to verify each environment.
Keep dependency graphs reproducible. Review lockfile changes and understand which artifacts builds consume. Reproducibility helps explain what was installed; it does not prove that an artifact was benign.
Remove tools that no longer justify their presence. Every unnecessary executable dependency adds maintenance work and another place to investigate during an incident.
Limit what build jobs and developer tools can access. Permissions should match the task. A build that does not publish artifacts should not need publishing credentials.
Retain useful operational evidence. Logging and retention decisions made before an incident determine what can be investigated afterward.
Keep ownership clear. Someone should be able to answer who updates the runtime, who controls certificates, who reviews dependency alerts, and who coordinates incident response.
These practices turn an urgent advisory into a tractable set of questions.
The lesson I am taking from October
October’s disclosures prompted me to examine assumptions that are easy to overlook while building features.
What runtime actually serves the application? Which dependencies execute during a build? Which credentials are available to them? Who updates the trust store? What evidence would distinguish a failed attempt from a successful compromise?
Answering those questions is more useful than treating every alarming headline as proof that everything has been hacked.
For my applications, the immediate outcome was a reviewed set of runtime and dependency changes, successful validation, and a clean audit at the time of shipping. The separate question of attack activity requires operational evidence.
That distinction is the standard I want to keep: act quickly on credible exposure, verify what changed, and describe the result with enough precision that another person can trust it.