From: Christian Ebner <c.ebner@proxmox.com>
To: pbs-devel@lists.proxmox.com
Subject: [PATCH proxmox 1/3] s3-client: fix header and query parameter sorting during aws sign v4
Date: Wed, 7 Oct 2026 14:34:04 +0200 [thread overview]
Message-ID: <20261007123406.429342-2-c.ebner@proxmox.com> (raw)
In-Reply-To: <20261007123406.429342-1-c.ebner@proxmox.com>
Currently, canonical headers and query parameters are incorrectly
sorted by combined `key:value` or `key=value` strings respectively,
instead of by key only. This could result in signature mismatches
with the S3 API.
Fixes: 7c6ef846 ("s3 client: implement AWS signature v4 request authentication")
Signed-off-by: Christian Ebner <c.ebner@proxmox.com>
---
proxmox-s3-client/src/aws_sign_v4.rs | 30 +++++++++++++++++++---------
1 file changed, 21 insertions(+), 9 deletions(-)
diff --git a/proxmox-s3-client/src/aws_sign_v4.rs b/proxmox-s3-client/src/aws_sign_v4.rs
index f172b4b4..54f4e54e 100644
--- a/proxmox-s3-client/src/aws_sign_v4.rs
+++ b/proxmox-s3-client/src/aws_sign_v4.rs
@@ -31,11 +31,11 @@ pub(crate) fn aws_sign_v4_signature(
// headers are required. however, in order to prevent data tampering, you should consider
// including all the headers in the signature calculation."
// See https://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-header-based-auth.html
- let mut canonical_headers = Vec::new();
- let mut signed_headers = Vec::new();
- for (key, value) in request.headers() {
- canonical_headers.push(format!(
- "{}:{}",
+ let req_headers = request.headers();
+ let mut headers = Vec::with_capacity(req_headers.len());
+
+ for (key, value) in req_headers {
+ headers.push((
// Header name has to be lower case, key.as_str() does guarantee that, see
// https://docs.rs/http/0.2.0/http/header/struct.HeaderName.html
key.as_str(),
@@ -43,14 +43,27 @@ pub(crate) fn aws_sign_v4_signature(
// https://docs.rs/http/0.2.0/http/header/struct.HeaderValue.html
value.to_str()?,
));
- signed_headers.push(key.as_str());
}
- canonical_headers.sort();
- signed_headers.sort();
+
+ headers.sort_unstable_by(|a, b| a.0.cmp(b.0));
+
+ let mut canonical_headers = Vec::with_capacity(headers.len());
+ let mut signed_headers = Vec::with_capacity(headers.len());
+ for (key, value) in headers {
+ canonical_headers.push(format!("{key}:{value}"));
+ signed_headers.push(key);
+ }
let signed_headers_string = signed_headers.join(";");
let mut canonical_queries = Url::parse(&request.uri().to_string())?
.query_pairs()
+ .map(|(key, value)| (key.to_string(), value.to_string()))
+ .collect::<Vec<(String, String)>>();
+
+ canonical_queries.sort_unstable_by(|a, b| a.0.cmp(&b.0));
+
+ let canonical_queries = canonical_queries
+ .into_iter()
.map(|(key, value)| {
format!(
"{}={}",
@@ -59,7 +72,6 @@ pub(crate) fn aws_sign_v4_signature(
)
})
.collect::<Vec<String>>();
- canonical_queries.sort();
let canonical_request = format!(
"{}\n{}\n{}\n{}\n\n{}\n{}",
--
2.47.3
next prev parent reply other threads:[~2026-10-07 12:34 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-07 12:34 [PATCH proxmox 0/3] s3-client: fix request signing and update request time on retry Christian Ebner
2026-10-07 12:34 ` Christian Ebner [this message]
2026-10-07 12:34 ` [PATCH proxmox 2/3] s3-client: factor out request signing and related header updates Christian Ebner
2026-10-07 12:34 ` [PATCH proxmox 3/3] s3-client: update request time and signature on retries Christian Ebner
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261007123406.429342-2-c.ebner@proxmox.com \
--to=c.ebner@proxmox.com \
--cc=pbs-devel@lists.proxmox.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox