You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The documentation states that if the server has received the body and headers, it may not send the "HTTP/1.1 100 CONTINUE" message to the client.
This is a profound misconception on the part of the people writing the standards. They're far removed from programming!
They forgot that packets can be fragmented along the way.
And even if the client sent the body along with the "Expect: 100-continue" header, a situation could still arise where the server first reads from the pending socket (the first recv call) and only then the request body (the second recv call). The standard writers didn't see this coming!
So the server should always send an "HTTP/1.1 100 CONTINUE" response, so as not to violate the standard!
This test simply focus on a simple case when the header is sent with the body with no fragmentation
You don't understand what I'm talking about!
There's a serious error in the standard description!
The creators of the standard forgot that HTTP/1.1 occurs within a TCP stream, which requires explicitly passing some kind of flag between different messages. It's not a datagram (UDP), where requests can be controlled on both sides at the send and recv call level.
Therefore, when receiving a header "Expect: 100-continue", the server must in all cases first respond with "HTTP/1.1 100 CONTINUE" and then send a full response.
Not if you receive the full content from the first stream read, in that case the server already has the whole request and does not need to bother to send a 100 CONTINUE, at all the other times the server should send 100 CONTINUE (no content or incomplete)
a 100, 4xx or 200 should all be acceptable here, maybe 4xx is questionable but I can accept a server doesnt want to deal with 100 bullshit
The purpose of most these tests are not to validate whether a framework follows RFC but to see difference in behavior between frameworks, that is where the true problem and valuable information for an attacker is, the goal of this smuggling category is to create scenarios where frameworks behave very differently, opening attack vectors when they are combined in a reverse proxy
Not if you receive the full content from the first stream read, in that case the server already has the whole request and does not need to bother to send a 100 CONTINUE, at all the other times the server should send 100 CONTINUE (no content or incomplete)
The client can't know in advance whether the server will receive the request headers and body in a single data block!!!
On the way to the server, this data block may be split exactly between the headers and the request body. The server will receive the headers first, and then, after N milliseconds, the request body. In this case, the server (following the standard) will first send "HTTP/1.1 100 CONTINUE" to the client.
But the client doesn't expect "HTTP/1.1 100 CONTINUE" before the response body, since it sent the entire TCP stream as a single block.
I understand what you mean from the beginning and that is not a server issue, the client needs to handle that because from the server perspective it can't guess whether be body is coming or not and needs to send a 100 CONTINUE anyway.
BUT in this test on this suite the client is guaranteed to receive the full request at once, there is no fragmentation possible here, this is a controlled environment scenario, we guarantee the client always sees the full body which means we expect a 200 or a 4xx if he doesn't allow 100 in requests. As I said we can accept a server responding a 100 too as it can happen in the wild that the server doesn't see the body due to fragmentation or other issues.
A server can send both 100 CONTINUE, 200 or 4xx here. this is the update I agree on
Unscored tests means that I am open to change in this case, and in some cases mean that the RFC is too ambiguous and we can't score server based on it so it simply serves as information
Activity
MDA2AV commentedon Apr 6, 2026
Well, in case of fragmentation it is possible that the client sends the body and still receives a 100 continue response.
In this test suite the fragmentation is guaranteed to not happen.
Expect 100 is a known source of request smuggling vectors due to its inherent behavior issues.
This test simply focus on a simple case when the header is sent with the body with no fragmentation
remittor commentedon Apr 6, 2026
You don't understand what I'm talking about!
There's a serious error in the standard description!
The creators of the standard forgot that HTTP/1.1 occurs within a TCP stream, which requires explicitly passing some kind of flag between different messages. It's not a datagram (UDP), where requests can be controlled on both sides at the
sendandrecvcall level.Therefore, when receiving a header "Expect: 100-continue", the server must in all cases first respond with "HTTP/1.1 100 CONTINUE" and then send a full response.
MDA2AV commentedon Apr 6, 2026
Not if you receive the full content from the first stream read, in that case the server already has the whole request and does not need to bother to send a 100 CONTINUE, at all the other times the server should send 100 CONTINUE (no content or incomplete)
a 100, 4xx or 200 should all be acceptable here, maybe 4xx is questionable but I can accept a server doesnt want to deal with 100 bullshit
remittor commentedon Apr 6, 2026
https://support.airship.eu/hc/en-us/articles/5578710286491--Expect-100-Continue-Issues-and-Risks
https://http.dev/100
golang/go#67555
quarkusio/quarkus#13478
MDA2AV commentedon Apr 6, 2026
The purpose of most these tests are not to validate whether a framework follows RFC but to see difference in behavior between frameworks, that is where the true problem and valuable information for an attacker is, the goal of this smuggling category is to create scenarios where frameworks behave very differently, opening attack vectors when they are combined in a reverse proxy
remittor commentedon Apr 6, 2026
The client can't know in advance whether the server will receive the request headers and body in a single data block!!!
On the way to the server, this data block may be split exactly between the headers and the request body. The server will receive the headers first, and then, after N milliseconds, the request body. In this case, the server (following the standard) will first send "HTTP/1.1 100 CONTINUE" to the client.
But the client doesn't expect "HTTP/1.1 100 CONTINUE" before the response body, since it sent the entire TCP stream as a single block.
Now do you understand what I'm talking about?
MDA2AV commentedon Apr 6, 2026
I understand what you mean from the beginning and that is not a server issue, the client needs to handle that because from the server perspective it can't guess whether be body is coming or not and needs to send a 100 CONTINUE anyway.
BUT in this test on this suite the client is guaranteed to receive the full request at once, there is no fragmentation possible here, this is a controlled environment scenario, we guarantee the client always sees the full body which means we expect a 200 or a 4xx if he doesn't allow 100 in requests. As I said we can accept a server responding a 100 too as it can happen in the wild that the server doesn't see the body due to fragmentation or other issues.
A server can send both 100 CONTINUE, 200 or 4xx here. this is the update I agree on
What is your suggestion, only 100?
remittor commentedon Apr 6, 2026
My server always sends 100 and then 200. And this test doesn't like this behavior, because it just stupidly follows the standard with a bug.
remittor commentedon Apr 6, 2026
I just now noticed that this test is unscored ;-)
MDA2AV commentedon Apr 6, 2026
I agree 100 should be accepted :) I will change that
MDA2AV commentedon Apr 6, 2026
Unscored tests means that I am open to change in this case, and in some cases mean that the RFC is too ambiguous and we can't score server based on it so it simply serves as information
MDA2AV commentedon Apr 22, 2026
Fixed with #119