wasmtime-wasi-http forbids guests to set the Host header, and then synthesizes it from the authority part of the URI, with a default port number added if none was already present.
I've run into a case where this presents a problem for a guest component. The AWS SDK includes the host header (or maybe what it assumes the HTTP connector will set it to — it actually looked like it was not even attempting to set when I was debugging this) in a digest that it sends with API requests to AWS servers. Because wasmtime-wasi-http inserts the port number into the host header, this means that the digest will never match, and AWS servers return an opaque auth error. I formed this belief because in my testing, if I replicate the same request using curl it fails in the same way, but if I remove the port number from the Host header then it succeeds.
Now, I don't understand what the port number insertion is for, so I'm not confident in suggesting any specific change here. Instead, I'll ask a few questions:
Instead of forbidding the Host header, could it be allowed as long as it is set to something that is "compatible" with the authority part of the URL — i.e. same host, and also port if one was specified in the authority part of the URI? This option if possible seems most flexible.
Instead of including the port number in the synthesized Host header, could it just be the authority part of the URI without the port number added? This option would at least let the AWS SDK work.
What is the port number added for here? Is it some correctness/security concern, or is it just a convenient place to store it so it can be plucked out later when the actual connection is made? Or is it not even deliberate?
Thanks in advance for any thoughts on this! :sparkling_heart::man_bowing:
I can confirm this problem, which is caused by AWS's request signing mechanism which includes the exact host header value in its signature payload. I think a close reading of the http/1.1 spec suggests that wasmtime-wasi-http's behavior is incorrect (here): https://httpwg.org/http-core/draft-ietf-httpbis-messaging-latest.html#request.target
If the target URI includes an authority component, then a client MUST send a field value for Host that is identical to that authority component
Made an issue to track: https://github.com/bytecodealliance/wasmtime/issues/8430
As a workaround you might be able to force the AWS SDK to include the default port number by setting it explicitly in the endpoint, e.g. s3.us-east-2.amazonaws.com:443
?
Last updated: Dec 23 2024 at 14:03 UTC