Proxy host override is not respected correctly and mixed with the signing host override
Opened this issue · 0 comments
Scenario
Having a private AWS API Gateway
with IAM auth
and associated with a VPC
and accessible via a VPCE endpoint
and exposed via Cloudflare through Argo Tunnel running in the same VPC (which forwards the external requests).
Problem
Using the signing proxy will set the Host header incorrectly to the signing host override instead of the host override.
See steps to reproduce below.
# 1. Build image
docker build -t aws-sigv4-proxy:latest .
# 2. Run container as
docker run --rm -ti \
-v ~/.aws:/root/.aws \
--network=bridge \
-p 8080:8080 \
-e "AWS_SDK_LOAD_CONFIG=true" \
-e "AWS_PROFILE=my-sso-profile" \
aws-sigv4-proxy:latest \
--verbose \
--log-failed-requests \
--log-signing-process \
--name execute-api \
--region eu-west-1 \
--host external.cloudflare-domain.com \
--sign-host abcd123-vpce-abcd1234cbcdef0987.execute-api.eu-west-1.amazonaws.com
# 3. Invoke the proxy to sign the request and forward
curl -v -d '{"data":"something"}' http://localhost:8080/stage/endpoint
# 4. Proxy request (OBSERVE: Host is the signing host)
proxying request request="POST /stage/endpoint HTTP/1.1\r\nHost: abcd123-vpce-abcd1234cbcdef0987.execute-api.eu-west-1.amazonaws.com\r\nTransfer-Encoding: ....
# 5. Response (FAILED)
request="POST https://external.cloudflare-domain.com/stage/endpoint" status_code=403
Request is rejected "403" because the proxy tries to send an incorrect request. Connect to "host override" then send a request in which the "Host" is the "signing host override".
Solution
After https://github.com/awslabs/aws-sigv4-proxy/blob/master/handler/proxy_client.go#L174 the override
if p.SigningHostOverride != "" {
proxyReq.Host = p.SigningHostOverride
}
and signature generated https://github.com/awslabs/aws-sigv4-proxy/blob/master/handler/proxy_client.go#L186
if err := p.sign(proxyReq, service); err != nil {
return nil, err
}
apply correction according to the host override parameter (this is missing)
if p.HostOverride != "" {
proxyReq.Host = p.HostOverride
}
so the requests will be signed according to the "signing host override" while the request will be sent to the target host as specified in the "host override".