http-rs / http-rs/http-types

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

Open
#534 2 comments 0 reactions 0 assignees View on GitHub
Dominant language
Rust
Stars
209
Forks
91
PR merge metrics
No merged PRs in 30d

Description

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:
```rust
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:

```text
[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 and use HeaderValue::from_bytes.

Thank you.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.