Skip to content

{Authorization, WwwAuthenticate}::value can construct a non-ASCII HeaderValue through Safe Rust #534

Description

@yilin0518

Hello, I found bugs in http-types 2.12.0 related to Authorization::value and WwwAuthenticate::value

Description

Authorization::value uses HeaderValue::from_bytes_unchecked with the following justification:

// SAFETY: the internal string is validated to be ASCII.

However, Authorization does not actually enforce ASCII on credentials.

Relevant code:

  • Authorization::new accepts any String for credentials
  • Authorization::set_credentials also accepts any String without validation
  • Authorization::value formats scheme + credentials and passes the result into HeaderValue::from_bytes_unchecked

This means Safe Rust can create an Authorization whose value contains non-ASCII UTF-8.

Minimal PoC:

use http_types::auth::Authorization;
use http_types::auth::AuthenticationScheme;
use http_types::auth::WwwAuthenticate;

fn main() {
    // Credentials are accepted without ASCII validation.
    let mut auth = Authorization::new(AuthenticationScheme::Basic, String::new());

    // This injects non-ASCII UTF-8 into the formatted header value.
    auth.set_credentials("α".to_string());

    let header = auth.value();
    println!("{:?}", header.as_str().as_bytes());

    let mut www_auth = WwwAuthenticate::new(AuthenticationScheme::Basic, String::new());
    
    www_auth.set_realm("α".to_string());

    let header = www_auth.value();
    println!("{:?}", header.as_str().as_bytes());
}

Output:

[66, 97, 115, 105, 99, 32, 206, 177]
[66, 97, 115, 105, 99, 32, 114, 101, 97, 108, 109, 61, 34, 206, 177, 34, 44, 32, 99, 104, 97, 114, 115, 101, 116, 61, 34, 85, 84, 70, 45, 56, 34]

The [206, 177] is the representation of "α"

Why this seems wrong:

  • AuthenticationScheme formats to ASCII text.
  • credentials is arbitrary String data.
  • Therefore the formatted output is not guaranteed to be ASCII.
  • But HeaderValue::from_bytes_unchecked is being called under the assumption that the value is ASCII.

Also WwwAuthenticate::set_realm accepts any String without validation, thus WwwAuthenticate::value generates a HeaderValue contains non-ASCII UTF-8.

I did not confirm Undefined Behavior with this Safe Rust PoC under Miri, so I am not reporting this as a confirmed soundness issue. However, the unsafe justification in Authorization::value appears incorrect, and the method can produce a HeaderValue that violates the crate’s documented ASCII invariant.

Suggested fixes:

  • Validate credentials as ASCII in Authorization::new and set_credentials.
  • Or make value return a Result<HeaderValue, Error> and use HeaderValue::from_bytes.

Thank you.

Activity

  1. changed the title [-]Authorization::value can construct a non-ASCII HeaderValue through Safe Rust[/-] [+]Authorization::set_credentials, WwwAuthenticate::set_realm can construct a non-ASCII HeaderValue through Safe Rust[/+] on May 28, 2026
  2. changed the title [-]Authorization::set_credentials, WwwAuthenticate::set_realm can construct a non-ASCII HeaderValue through Safe Rust[/-] [+]{Authorization, WwwAuthenticate}::value can construct a non-ASCII HeaderValue through Safe Rust[/+] on May 28, 2026
  3. djc commented on Jun 1, 2026

    @djc

    @Fishrock123 @jbr any thoughts? Would be nice to move this forward and/or decide that this crate is unmaintained.

  4. jbr commented on Jun 1, 2026

    @jbr
    Member

    I'm of the opinion that all of http-rs should be archived and marked unmaintained, but I think that's @yoshuawuyts' call to make. There has been no activity on any of the crates other than people opening issues. My energy for maintaining a web framework is currently going into https://trillium.rs

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions