Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multi-part user agent is joined incorrectly leading to AWS signature failures #1155

Closed
mungojam opened this issue Sep 12, 2024 · 3 comments · Fixed by #1156
Closed

Multi-part user agent is joined incorrectly leading to AWS signature failures #1155

mungojam opened this issue Sep 12, 2024 · 3 comments · Fixed by #1156
Assignees
Labels
bug Something isn't working

Comments

@mungojam
Copy link
Contributor

Describe the bug

When creating a multi-part user-agent header, .net will space separate the different entries, as per the user agent spec. This is also what AWS expects in its canonical header that should be signed.

However, this library always comma delimits multi-part headers by applying this default:

/// <summary>
/// Gets or sets the header value separator. The default value is ", " and it is defined in
/// <see href="https://github.com/dotnet/corefx/blob/master/src/System.Net.Http/src/System/Net/Http/Headers/HttpHeaderParser.cs">
/// HttpHeaderParser</see> in the .NET source code. It is used when serializing a header
/// with multiple values into a HTTP request. For some other languages this separator is
/// plainly ",", but Microsoft has chosen to go with ", ".
/// </summary>
public static string HeaderValueSeparator { get; set; } = ", ";

To Reproduce

                var client= new HttpClient();

                var toolHeader1 = new ProductHeaderValue(
                    "ToolA",
                    "1.2.3",
                );
                var toolUserAgent1 = new ProductInfoHeaderValue(toolHeader1);
                client.DefaultRequestHeaders.UserAgent.Add(toolUserAgent1);

                var toolHeader2 = new ProductHeaderValue(
                    "ToolB",
                    "1.2.3",
                );
                var toolUserAgent2 = new ProductInfoHeaderValue(toolHeader2);
                client.DefaultRequestHeaders.UserAgent.Add(toolUserAgent2);

                await client.UsualCallViaThisLibrary();

This leads to

The request signature we calculated does not match the signature you provided. Check your AWS Secret Access Key and signing method. Consult the service documentation for details. The Canonical String for this request should have been 'POST /something/something host:redacted.execute-api.eu-west-1.amazonaws.com user-agent:ToolA/1.2.3 ToolB/1.2.3 x-amz-date:20240912T171219Z x-amz-security-...

Expected behavior

It's expected to get through the AWS signature checks

Desktop (please complete the following information):

  • OS: Windows 10
  • Version 4.0.5

** Other comments

It can probably be worked around, by manually adding the full user agent as a single entry.

I don't know for sure if any other multi-part headers are also supposed to be space delimited like this. User Agent may be an exception

@mungojam mungojam added the bug Something isn't working label Sep 12, 2024
@mungojam
Copy link
Contributor Author

mungojam commented Sep 12, 2024

A hacky workaround, that only works because I've not got any other multi-part headers:

        var currentHeaderSeparator = CanonicalRequest.HeaderValueSeparator;
        CanonicalRequest.HeaderValueSeparator = " ";

        var response = await MakeAPICall(client, uri, content, credentials);

        CanonicalRequest.HeaderValueSeparator = currentHeaderSeparator;

@mungojam
Copy link
Contributor Author

I'm working on a fix now, should have a PR ready soon

@FantasticFiasco
Copy link
Owner

Hi @mungojam and thanks for reporting the issue! Let me look into the issue and your proposed solution, I'll be back.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
2 participants