[GH-ISSUE #795] Scripting the request causes the Host header to change #789

Open
opened 2026-03-03 19:21:54 +03:00 by kerem · 4 comments
Owner

Originally created by @nilayp on GitHub (Feb 19, 2021).
Original GitHub issue: https://github.com/ProxymanApp/Proxyman/issues/795

Originally assigned to: @NghiaTranUIT on GitHub.

Proxyman version? (Ex. Proxyman 1.4.3)

2.18

macOS Version? (Ex. mac 10.14)

10.15.7

Steps to reproduce

  1. Start capturing requests with SSL Proxy enabled. Execute the request without scripting enabled. Request is successful and the Host header has no port number.
192_168_125_150_and_aws-v4signature_–___Dropbox_Documents_Backblaze_B2_projects_aws-v4signature_aws-v4signature_py
  1. Enable scripting for the request.
    Scripting_and_192_168_125_150_and_aws-v4signature_–___Dropbox_Documents_Backblaze_B2_projects_aws-v4signature_aws-v4signature_py

  2. Resend the same request. Proxy will fail because Proxyman appended the Host header to include the port number.

192_168_125_150_and_aws-v4signature_–___Dropbox_Documents_Backblaze_B2_projects_aws-v4signature_aws-v4signature_py

The request I'm making is a very basic GET request with an Authorization token and one Query parameter called VersionId. This is executing against AWS S3.

Nothing I can do allows me to remove the port number from Proxyman. I tried to edit the request manually, or use a script to edit it. I tried to toggle the "preserveHostHeader" flag. If the scripting is enabled, a port number is appended. If the script is not enabled, no port number is appended.

I also copied the request as a cUrl command from Proxyman, removed the port number from the Host header and it was successful. I'm 100% confident my request is correct, if the port number isn't present.

The script I used it very basic and does nothing more than log the request content.

function onRequest(context, url, request) {
  console.log(request);
  return request;
}

The logged console output does not include the port number appended to the Host header. It seems the port is appended somewhere after the script execution.

---------------------------------
11:37:27.379: [onRequest] with Request ID=13
{
	"headers": {
		"x-amz-content-sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
		"User-Agent": "python-urllib3/1.26.3",
		"Host": "nilayp-versioned.s3-us-west-1.amazonaws.com",
		"x-amz-date": "20210219T193727Z",
		"Accept-Encoding": "identity",
		"Authorization": [omitted]
	},
	"schema": "https",
	"path": "/mytextfile.txt",
	"port": 443,
	"host": "nilayp-versioned.s3-us-west-1.amazonaws.com",
	"queries": {
		"versionId": [omitted]
	},
	"method": "GET",
	"preserveHostHeader": false
}
11:37:27.380 onRequest() is executed!
----------------------------------
Originally created by @nilayp on GitHub (Feb 19, 2021). Original GitHub issue: https://github.com/ProxymanApp/Proxyman/issues/795 Originally assigned to: @NghiaTranUIT on GitHub. ### Proxyman version? (Ex. Proxyman 1.4.3) 2.18 ### macOS Version? (Ex. mac 10.14) 10.15.7 ### Steps to reproduce 1. Start capturing requests with SSL Proxy enabled. Execute the request without scripting enabled. Request is successful and the Host header has no port number. <img width="1247" alt="192_168_125_150_and_aws-v4signature_–___Dropbox_Documents_Backblaze_B2_projects_aws-v4signature_aws-v4signature_py" src="https://user-images.githubusercontent.com/744246/108552790-a303b980-72a6-11eb-966b-448f00b27cfa.png"> 2. Enable scripting for the request. <img width="1249" alt="Scripting_and_192_168_125_150_and_aws-v4signature_–___Dropbox_Documents_Backblaze_B2_projects_aws-v4signature_aws-v4signature_py" src="https://user-images.githubusercontent.com/744246/108552889-c4fd3c00-72a6-11eb-8083-883d4af8fa5a.png"> 3. Resend the same request. Proxy will fail because Proxyman appended the Host header to include the port number. <img width="1248" alt="192_168_125_150_and_aws-v4signature_–___Dropbox_Documents_Backblaze_B2_projects_aws-v4signature_aws-v4signature_py" src="https://user-images.githubusercontent.com/744246/108553101-0ee62200-72a7-11eb-8df4-f1fada4b4049.png"> The request I'm making is a very basic GET request with an Authorization token and one Query parameter called VersionId. This is executing against AWS S3. Nothing I can do allows me to remove the port number from Proxyman. I tried to edit the request manually, or use a script to edit it. I tried to toggle the "preserveHostHeader" flag. If the scripting is enabled, a port number is appended. If the script is not enabled, no port number is appended. I also copied the request as a cUrl command from Proxyman, removed the port number from the Host header and it was successful. I'm 100% confident my request is correct, if the port number isn't present. The script I used it very basic and does nothing more than log the request content. ``` function onRequest(context, url, request) { console.log(request); return request; } ``` The logged console output does not include the port number appended to the Host header. It seems the port is appended somewhere after the script execution. ``` --------------------------------- 11:37:27.379: [onRequest] with Request ID=13 { "headers": { "x-amz-content-sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", "User-Agent": "python-urllib3/1.26.3", "Host": "nilayp-versioned.s3-us-west-1.amazonaws.com", "x-amz-date": "20210219T193727Z", "Accept-Encoding": "identity", "Authorization": [omitted] }, "schema": "https", "path": "/mytextfile.txt", "port": 443, "host": "nilayp-versioned.s3-us-west-1.amazonaws.com", "queries": { "versionId": [omitted] }, "method": "GET", "preserveHostHeader": false } 11:37:27.380 onRequest() is executed! ---------------------------------- ```
Author
Owner

@NghiaTranUIT commented on GitHub (Feb 20, 2021):

Hi @nilayp, by default, Proxyman will construct the Host header from the Host and port, so it appears as you see.

It's useful if we'd map to different Host and Port (e.g. mydomain.com to localhost:3000).

I suppose that I should omit the port if it's using a default port (80 for HTTP and 443 for HTTPS), so it can resolve your problem 😄

<!-- gh-comment-id:782571787 --> @NghiaTranUIT commented on GitHub (Feb 20, 2021): Hi @nilayp, by default, Proxyman will construct the Host header from the Host and port, so it appears as you see. It's useful if we'd map to different Host and Port (e.g. `mydomain.com` to `localhost:3000`). I suppose that I should omit the port if it's using a default port (80 for HTTP and 443 for HTTPS), so it can resolve your problem 😄
Author
Owner

@NghiaTranUIT commented on GitHub (Feb 20, 2021):

@nilayp Please try this Beta build: https://proxyman.s3.us-east-2.amazonaws.com/beta/Proxyman_2.18.0_Omit_Default_Port_In_Host_Header_Script.dmg

This build will omit the default port: 443 for HTTPS and 80 for HTTP 👍

Screen_Shot_2021-02-20_at_14_25_16
<!-- gh-comment-id:782580847 --> @NghiaTranUIT commented on GitHub (Feb 20, 2021): @nilayp Please try this Beta build: https://proxyman.s3.us-east-2.amazonaws.com/beta/Proxyman_2.18.0_Omit_Default_Port_In_Host_Header_Script.dmg This build will omit the default port: 443 for HTTPS and 80 for HTTP 👍 <img width="1653" alt="Screen_Shot_2021-02-20_at_14_25_16" src="https://user-images.githubusercontent.com/5878421/108588128-25b17500-738a-11eb-88e4-c3d26d65ff2e.png">
Author
Owner

@nilayp commented on GitHub (Feb 20, 2021):

@NghiaTranUIT - Thank you so much. I can confirm this has worked.

Just so you know why this is important - AWS request headers are signed on the client side. When received by AWS (or service that is using AWS compatible requests) - elements of the request are used to compute a signature... if the newly computed signature does not matches the signature provided in the request, the request is rejected by the service.

One of the required headers in the signature calculation is "Host". When it changed, the signatures no longer matched.

Thanks again for the super fast turnaround! It is much appreciated.

<!-- gh-comment-id:782704421 --> @nilayp commented on GitHub (Feb 20, 2021): @NghiaTranUIT - Thank you so much. I can confirm this has worked. Just so you know why this is important - AWS request headers are signed on the client side. When received by AWS (or service that is using AWS compatible requests) - elements of the request are used to compute a signature... if the newly computed signature does not matches the signature provided in the request, the request is rejected by the service. One of the required headers in the signature calculation is "Host". When it changed, the signatures no longer matched. Thanks again for the super fast turnaround! It is much appreciated.
Author
Owner

@NghiaTranUIT commented on GitHub (Feb 21, 2021):

Glad to know that it works for you 🎉

<!-- gh-comment-id:782781906 --> @NghiaTranUIT commented on GitHub (Feb 21, 2021): Glad to know that it works for you 🎉
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/Proxyman#789
No description provided.