From e926d6ddfd8763a701ee11aa33fc0c5f2bebce75 Mon Sep 17 00:00:00 2001 From: Alon Date: Tue, 10 May 2022 14:36:24 +0300 Subject: [PATCH 1/3] Add allow_signing_user_agent_header setting option. for verification signed request --- .../aws-sigv4/src/http_request/canonical_request.rs | 5 ++++- aws/rust-runtime/aws-sigv4/src/http_request/settings.rs | 4 ++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/aws/rust-runtime/aws-sigv4/src/http_request/canonical_request.rs b/aws/rust-runtime/aws-sigv4/src/http_request/canonical_request.rs index 444ff9afd8..9632171b53 100644 --- a/aws/rust-runtime/aws-sigv4/src/http_request/canonical_request.rs +++ b/aws/rust-runtime/aws-sigv4/src/http_request/canonical_request.rs @@ -220,8 +220,11 @@ impl<'a> CanonicalRequest<'a> { for (name, _) in &canonical_headers { // The user agent header should not be signed because it may be altered by proxies if name == USER_AGENT { - continue; + if !params.settings.allow_signing_user_agent_header { + continue; + } } + if params.settings.signature_location == SignatureLocation::QueryParams { // The X-Amz-User-Agent header should not be signed if this is for a presigned URL if name == HeaderName::from_static(header::X_AMZ_USER_AGENT) { diff --git a/aws/rust-runtime/aws-sigv4/src/http_request/settings.rs b/aws/rust-runtime/aws-sigv4/src/http_request/settings.rs index 508f5c4ea0..7020dc62dd 100644 --- a/aws/rust-runtime/aws-sigv4/src/http_request/settings.rs +++ b/aws/rust-runtime/aws-sigv4/src/http_request/settings.rs @@ -25,6 +25,9 @@ pub struct SigningSettings { /// For presigned requests, how long the presigned request is valid for pub expires_in: Option, + + /// For signed requests, which already signed the user-agent header + pub allow_signing_user_agent_header: bool, } /// HTTP payload checksum type @@ -64,6 +67,7 @@ impl Default for SigningSettings { payload_checksum_kind: PayloadChecksumKind::NoHeader, signature_location: SignatureLocation::Headers, expires_in: None, + allow_signing_user_agent_header: false, } } } From 8ff1d2bff74791725fd678885e5cd6082a46bbbe Mon Sep 17 00:00:00 2001 From: Alon Date: Thu, 12 May 2022 12:05:46 +0300 Subject: [PATCH 2/3] Change the user-agent bool setting to exluced headers list --- .../aws-sigv4/src/http_request/canonical_request.rs | 7 +++---- .../aws-sigv4/src/http_request/settings.rs | 10 +++++++--- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/aws/rust-runtime/aws-sigv4/src/http_request/canonical_request.rs b/aws/rust-runtime/aws-sigv4/src/http_request/canonical_request.rs index 9632171b53..9eee68f8da 100644 --- a/aws/rust-runtime/aws-sigv4/src/http_request/canonical_request.rs +++ b/aws/rust-runtime/aws-sigv4/src/http_request/canonical_request.rs @@ -10,7 +10,7 @@ use crate::http_request::sign::SignableRequest; use crate::http_request::url_escape::percent_encode_path; use crate::http_request::PercentEncodingMode; use crate::sign::sha256_hex_string; -use http::header::{HeaderName, HOST, USER_AGENT}; +use http::header::{HeaderName, HOST}; use http::{HeaderMap, HeaderValue, Method, Uri}; use std::borrow::Cow; use std::cmp::Ordering; @@ -218,9 +218,8 @@ impl<'a> CanonicalRequest<'a> { let mut signed_headers = Vec::with_capacity(canonical_headers.len()); for (name, _) in &canonical_headers { - // The user agent header should not be signed because it may be altered by proxies - if name == USER_AGENT { - if !params.settings.allow_signing_user_agent_header { + if let Some(excluded_headers) = params.settings.excluded_headers.as_ref() { + if excluded_headers.contains(name) { continue; } } diff --git a/aws/rust-runtime/aws-sigv4/src/http_request/settings.rs b/aws/rust-runtime/aws-sigv4/src/http_request/settings.rs index 7020dc62dd..e78ef7d4a9 100644 --- a/aws/rust-runtime/aws-sigv4/src/http_request/settings.rs +++ b/aws/rust-runtime/aws-sigv4/src/http_request/settings.rs @@ -3,6 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ +use http::header::{HeaderName, USER_AGENT}; use std::time::Duration; /// HTTP signing parameters @@ -26,8 +27,8 @@ pub struct SigningSettings { /// For presigned requests, how long the presigned request is valid for pub expires_in: Option, - /// For signed requests, which already signed the user-agent header - pub allow_signing_user_agent_header: bool, + /// Headers that should be excluded from the signing process + pub excluded_headers: Option>, } /// HTTP payload checksum type @@ -62,12 +63,15 @@ pub enum PercentEncodingMode { impl Default for SigningSettings { fn default() -> Self { + // The user agent header should not be signed because it may be altered by proxies + const EXCLUDED_HEADERS: [HeaderName; 1] = [USER_AGENT]; + Self { percent_encoding_mode: PercentEncodingMode::Double, payload_checksum_kind: PayloadChecksumKind::NoHeader, signature_location: SignatureLocation::Headers, expires_in: None, - allow_signing_user_agent_header: false, + excluded_headers: Some(EXCLUDED_HEADERS.to_vec()), } } } From c9cd0795fa28d729070621ea81911b01a4295156 Mon Sep 17 00:00:00 2001 From: John DiSanti Date: Mon, 16 May 2022 12:54:44 -0700 Subject: [PATCH 3/3] Update changelog --- CHANGELOG.next.toml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.next.toml b/CHANGELOG.next.toml index 1dffbf7f63..00426832ae 100644 --- a/CHANGELOG.next.toml +++ b/CHANGELOG.next.toml @@ -9,4 +9,10 @@ # message = "Fix typos in module documentation for generated crates" # references = ["smithy-rs#920"] # meta = { "breaking" = false, "tada" = false, "bug" = false } -# author = "rcoh" \ No newline at end of file +# author = "rcoh" + +[[smithy-rs]] +message = "Add ability to sign a request with all headers, or to change which headers are excluded from signing" +references = ["smithy-rs#1381"] +meta = { "breaking" = false, "tada" = true, "bug" = false } +author = "alonlud"