h3llh0und

Field notes on offensive security, cloud forensics and agentic tooling

Writing

CVE-2026-115700: a redirect from a trusted host could still send hackney to an internal address

hackney refuses a URL whose host is an IP address in disguise, so that an application checking hostnames is not tricked into calling its own internal services. I found two disguises that ...

CVE-2026-116191: an anonymous WebDAV client could write outside the folder rclone was told to serve

A common way to run rclone serve webdav is one process per user, each serving that user's own folder of a shared remote. I found that two requests let a client step out of its folder and ...

CVE-2026-115464: a Poweradmin user allowed only to edit records could rename the zone and slave it to their own server

Poweradmin lets an operator hand someone the records inside a DNS zone without handing over the zone itself. The web interface keeps a zone's type and master server behind a separate perm...

CVE-2026-115373: a certificate locked to one Incus project could read another project's running commands and their secrets

Incus lets an administrator issue a client certificate that only works inside one project. A client holding one could still read any running operation in any other project by asking for i...

Evaluating PHP2Shell reachability and corruptibility in PHP 5.3.15

Every PHP2Shell write-up gives the same floor — PHP 5.4.0 — and none say why, while the official advisories give no lower bound at all. I wanted to know whether PHP 5.3 is actually affect...

CVE-2026-112085: any open tab could talk to the backend behind webpack-dev-server

webpack-dev-server can forward WebSocket connections to the backend a developer is working on. I found that it forwarded them for any web page, not only for the developer's own app: a sit...

PHP2Shell in depth: two PHP engine bugs, the patch that fixed them, and a toolkit to check your servers

On 21 October PHP fixed two engine bugs that let a request with no login run code as the web worker. I did not find them. This post covers how they work, using PHP's own advisories and th...

CVE-2026-113676, CVE-2026-113677 and CVE-2026-113678: the traffic job, a domain delete and an admin lookup in froxlor

froxlor's daily traffic job runs as root and hands each hosting customer their statistics folder. I found that a customer who replaced that folder with a symlink was handed whatever direc...

CVE-2026-111063: aiohttp and the cookies that belonged to no host

aiohttp's client keeps a special place for cookies that have no domain: they belong to no host, so they go to every host. I found that they also went over plain HTTP when marked Secure, b...

CVE-2026-111888 and CVE-2026-111889: NEWS_DELETE to edit, nothing at all to read the dashboard

phpMyFAQ guards its admin area one right at a time: each route names the permission it needs on its first line. Reading those first lines on the 4.1 branch, I found one that named the wro...

CVE-2026-111913 and CVE-2026-111914: two ways to take a list out of Admidio

Admidio lets an operator decide who may see the inventory and who may export a member list. I found that both decisions were enforced only where the list is shown, and that each list had ...

CVE-2026-111919: off the project, still on the webhook

I found that a collaborator removed from a Vikunja project went on receiving every new task through the webhook they had created while still a member. Vikunja already had a routine that c...

CVE-2026-105660: an HTTP/1.1 request can name its host twice

Bandit, the HTTP server new Phoenix applications use by default, checked the Host header against the URI grammar and answered 400 when it failed. It never checked the other place a reques...

CVE-2026-109383: three of the four names on the list were right

In September undici fixed a dispatcher that silently dropped an application's certificate-pinning callback, and the advisory named four other dispatchers as not affected. I checked the fo...

CVE-2026-109162: a form setting read sixteen lines before it was set

TYPO3 v14's form framework read an upload field's destination folder while the field was still being created, before the form's own configuration had been applied. Every form therefore sa...

CVE-2026-108359: number-rows-repeated had no ceiling

An ODS file can tell a reader to repeat one row a few million times. PhpSpreadsheet did exactly that, one real cell object per repeat, with no upper bound — a ~3 KB file that exhausts a w...

CVE-2026-102991: posixpath and ntpath disagree about C:

Mako checks a template URI with one standard-library module and opens the file with another. On Windows those are ntpath and posixpath, and they read C:/../../secret.txt differently: one ...

CVE-2026-107719: the expiry a cache only read when iat was a number

fast-jwt's verifier cache took a token's expiry from exp only inside an if (hasIat) block, so a token without a numeric iat kept verifying after it expired — for ten minutes by default, a...

CVE-2026-107289: every encoding was decoded, and the bypass was not an encoding

Pydantic AI's cloud-metadata blocklist had two published follow-ups, both teaching it to unwrap an IPv4 address hidden inside IPv6. I went looking for a third on the assumption that the n...

CVE-2026-102422: the comment that commented out a quote

The command injection I reported in shell-quote's quote() — the function you call so an untrusted value cannot become shell syntax. A { comment } token emits a #, which comments out the o...

CVE-2026-101913: the address the library couldn't agree with itself about

A classifier in the ip-address library answered isLinkLocal() for fe80::/64 when link-local is fe80::/10 — it recognised one address in every 2^54 of the range it named. I didn't need a s...

CVE-2026-96624: reported as a redirect, fixed as a destination

Fedify delivered activities to whatever inbox a remote actor advertised, without asking where that was. I reached it by following an earlier fix for redirects, filed it as a redirect bug,...

CVE-2026-100419: the checkout that replaced a directory it was still trusting

gitoxide caches which leading path components it has already validated during checkout. On the force-checkout path a collision deletes one of those directories and plants an attacker syml...

CVE-2026-93353: a volume guard enforced one call site at a time

copyparty's xvol option keeps the file server from following symlinks out of a volume. Its SFTP front end runs that check inside one helper — which four handlers call and three do not — s...

CVE-2026-93991: authorizing a namespace selector against the namespace it excludes

Argo Workflows' archive endpoint ran an access review for the namespace named in a metadata.namespace!= field selector, then ran the negated query. One field is read by three components a...

CVE-2026-82672: a function called ignore_until_crlf, and the two points I left on the table

A parser disagreement I reported in Mint, the low-level HTTP client for Elixir: the chunk-size line checked its hexadecimal digits and threw away everything after them. The fix deleted th...

CVE-2026-88932: multer's cleanup fix, and the regression test that could not fail

The incomplete cleanup I reported in multer: the commit that fixed aborted uploads also shipped the test that proves it, and that test aborts while the multipart part is still open — the ...

pwnloop, fifty-one machines

A month after the first root, the autonomous loop has taken fifty-one lab machines from an IP to root and cleared a Pro Lab the platform itself certified. The count is the proof. The meth...

"Not worth a CVE": the mailpit deny-list, and CVE-2026-84697

A maintainer read my report, agreed with every claim in it, shipped the fix in two minutes and declined to request an identifier. I think the decision was defensible and still wrong, and ...

CVE-2026-84207: a good SSRF guard that two WebSocket paths never called

The SSRF I reported in heym: an egress guard that handles NAT64, 6to4, Teredo and DNS rebinding, and two dials that never ask it anything. The predicate was never the problem — the wiring...

CVE-2026-73530: reaching loopback through the IPv6 unspecified address

An SSRF guard bypass I reported in flyto-core: the denylist blocks 0.0.0.0 twice over and its IPv6 twin :: not at all — and the stack routes :: straight to the local host.

CVE-2026-64941: an open redirect in the guard that prevents open redirects

The open redirect I reported in Phoenix LiveView — in validate_local_url!/2, the guard whose entire job is keeping a redirect target on your own origin. It never looked at the three chara...

pwnloop, one week in

Eight days ago it was a container and a 200-line skill file. It has since rooted seventeen machines and taken a Pro Lab end to end — and every path it had to work out on the way is now wr...

pwnloop lab mode: a Pro Lab in four and a half hours

Campaign mode points the loop at a network instead of a box — a frontier, a credential matrix, tunnels that prove themselves. Its first run took HTB's free Puppet mini Pro Lab end to end:...

pwnloop: an autonomous engagement loop for lab machines

Hand it an IP and it runs recon to root to cleanup to report without checking in — then rewrites its own methodology before it is allowed to finish.

I ran a full cloud forensic investigation with an AI agent. It cost $67.

And 99% of that bill was the model re-reading context it had already been given. If you budget for this work by counting what the model writes, you will be wrong by roughly 7×.

Cloud Forensics in the Age of AI Agents: A Field Report

One compromised credential, twenty days, seventeen regions — reconstructed twice from independent sources. What the agent changed, where it was confidently wrong, and what a human still h...

Securing Fintech Apps in 2025: Addressing Modern Threats with Adaptive Defenses

Fintech is at the center of today’s digital transformation, blending finance and technology at a breakneck pace. As attackers get more sophisticated and compliance pressure increases, sec...

Cultivating a Cost-Aware Culture for High-Performance Payment Systems on AWS

In the world of digital payments, businesses must maintain high performance, scalability, and reliability while keeping cloud costs under control. Amazon Web Services (AWS) provides a pow...