From d06025e934c16a8c19b6d0587d8878417058cd63 Mon Sep 17 00:00:00 2001 From: Iain Shigeoka Date: Wed, 11 May 2022 20:33:24 -0700 Subject: [PATCH 1/2] Support host header overrides and updated README --- AWSSignature4DynamicValue.js | 8 +++++++- README.md | 12 +++++++++--- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/AWSSignature4DynamicValue.js b/AWSSignature4DynamicValue.js index 20a5525..39a8d53 100644 --- a/AWSSignature4DynamicValue.js +++ b/AWSSignature4DynamicValue.js @@ -253,7 +253,13 @@ var AWSSignature4DynamicValue = function() { }) } - headers['host'] = uri.host.toLowerCase(); + if (headers.host) { + // Use the host header if set + headers.host = headers.host.toLowerCase(); + } else { + // Otherwise, extract it from the target uri + headers.host = uri.host.toLowerCase(); + } if (!headers['x-amz-date']) { headers['x-amz-date'] = daytime; diff --git a/README.md b/README.md index 54abd47..50dd78b 100644 --- a/README.md +++ b/README.md @@ -6,14 +6,18 @@ A [Paw Extension][extensions] to compute AWS Signature version 4 authentication To install AWS Signature 4 authentication go to the [Paw Extension page][extension] and click the "Install Extension" button. -For each request, add a header `Authorization` and set the value to this extension (start typing "AWS" and select AWS Signature 4 or right-click on the value and choose **Extensions > AWS Signature 4**). Enter your credentials by clicking on the dynamic value extension. The AWS Access and Secret keys are required. If you leave the other fields blank they will use defaults. - +For each request, add a header `Authorization` and set the value to this extension (start typing "AWS" and select AWS Signature 4 or right-click on the value and choose **Extensions > AWS Signature 4**). Enter your credentials by clicking on the dynamic value extension. The AWS Access and Secret keys are required. If you leave the other fields blank they will use the defaults indicated. + +The `Use X-Amz-Content-Sha256 header?` option allows you to override the default content hashing behavior (primarily for binary payloads). Due to a limitation of the Paw extension API, the content of a request is always returned as a string to the extension. However, sha-256 hashing for the AWS API must be done on the binary data. In these cases, set the header and check this option so the header value is used for the content hash. Implementation thanks to [@jimdelois](https://github.com/jimdelois). + screen shot of Paw with extension open Add a second header `X-Amz-Date`. Set the value to custom timestamp (start typing "timestamp" and select the Custom formatting timestamp option or right click the value and select **Timestamp > Custom formatting**). Enter a custom timestamp format by clicking on the dynamic value extension, and selecting `Custom formatting` from the format. Enter the value `%G%m%dT%H%M%SZ` for the format. Make sure `Now` is checked, delta is 0, and `local time` is unchecked. AWS requires the time be within a few seconds of server time in UTC (not local time). screen shot of Paw with custom date configured +Optionally, you can set a `Host` header to set the "host" value used in the signature calculation if it differs from the host used in the request URI. This use-case can occur when tunneling requests to the AWS API endpoints. + If you don't have something to test against, follow the [Getting Started][start] guide for the API Gateway service to create a basic "hello world" API. Make sure that the API is [protected by IAM security][protect] by choosing "authorization type" of `AWS IAM` in the console when configuring the method. This extension was developed to test in-house API Gateway REST APIs. However, AWS Signature 4 is used to protect all the standard AWS service endpoints. By ensuring you have the correct `aws service` setting for the extension you can manually call any of the AWS service endpoints using Paw. @@ -24,6 +28,8 @@ This extension was developed to test in-house API Gateway REST APIs. However, AW * Freeze dynamic values to obtain X-Amz-Date as generated and sent to client (will help with debugging and eliminates an edge case where the AWS signature can be generated in a different second than the X-Amz-Date). * Need binary a version of HMAC SHA256 crypto function. Currently, the extension uses CryptJS which is fairly slow. +* If the Paw extension API supports it, correctly hash binary payloads and remove the `Use X-Amz-Content-Sha256 header?` option. +* Update Makefile to support installing to both the standard and the Setapp versions of Paw. ## Development @@ -45,6 +51,6 @@ See [Contributors][contributors]. [extensions]: http://luckymarmot.com/paw/extensions/ [extension]: https://paw.cloud/extensions/AWSSignature4DynamicValue -[contributors]: https://github.com/luckymarmot/Paw-AWSSignature4DynamicValue/graphs/contributors +[contributors]: https://github.com/badslug/Paw-AWSSignature4DynamicValue/graphs/contributors [start]: http://docs.aws.amazon.com/apigateway/latest/developerguide/getting-started.html [protect]: http://docs.aws.amazon.com/apigateway/latest/developerguide/how-to-method-settings-callers-console.html From cf65cc9f732180ba81bf9c1ce6c977893f8a6550 Mon Sep 17 00:00:00 2001 From: "Rias A. Sherzad" Date: Fri, 13 May 2022 20:04:38 +0200 Subject: [PATCH 2/2] Support Host header overriding URI --- AWSSignature4DynamicValue.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/AWSSignature4DynamicValue.js b/AWSSignature4DynamicValue.js index 39a8d53..ed47762 100644 --- a/AWSSignature4DynamicValue.js +++ b/AWSSignature4DynamicValue.js @@ -247,7 +247,7 @@ var AWSSignature4DynamicValue = function() { if (headersArray) { headersArray.forEach(function(header) { var lower = header.name.getEvaluatedString().toLowerCase() - if (lower.startsWith('x-amz-')) { + if (lower.startsWith('x-amz-') || lower === 'host') { headers[lower] = header.value.getEvaluatedString(); } }) @@ -275,7 +275,6 @@ var AWSSignature4DynamicValue = function() { // AWS wants the URI normalized (except for s3 which is not normalized) path URL encoded according to RFC 3986. // Each path segment should be URI-encoded **twice** except for s3 which only gets URI-encoded once. - var target = uri.pathname; var canonicalURI = encodeComponents(uri.pathname, service === 's3' || service === 'execute-api'); // Step 1