-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Description
I have found these related issues/pull requests
N/A
Description
sqlx-postgres/src/connection/sasl.rs comments the SCRAM step as:
// SaltedPassword := Hi(Normalize(password), salt, i)but the implementation currently passes options.password directly into hi(...) and hi(...) hashes s.as_bytes() unchanged.
In fact, SQLx already applies saslprep() to the username in the same file, but not to the password.
However, this is not a security issue, as it doesn't allow authentication bypass in any way.
Reproduction steps
1. Use a PostgreSQL server with SCRAM enabled
Create a role whose password contains U+00A0 (the NO-BREAK SPACE char), which SASLprep maps to a normal ASCII space:
DROP ROLE IF EXISTS saslprep_user;
CREATE ROLE saslprep_user LOGIN PASSWORD U&'pass\00A0word';2. Try two logically equivalent passwords from SQLx
use sqlx::{postgres::PgConnectOptions, ConnectOptions};
#[tokio::main]
async fn main() {
let raw_password = "pass\u{00A0}word"; // U+00A0 NO-BREAK SPACE
let normalized_password = "pass word"; // SASLprep result
let base = PgConnectOptions::new()
.host("127.0.0.1")
.port(5432)
.database("postgres")
.username("saslprep_user");
let raw = base.clone().password(raw_password);
let normalized = base.clone().password(normalized_password);
println!("raw: {:?}", raw.connect().await);
println!("normalized: {:?}", normalized.connect().await);
}Expected behavior
Both connection attempts should succeed.
Per SCRAM, the client-side proof should be computed from Hi(Normalize(password), salt, i), so both "pass\u{00A0}word" and "pass word" should produce the same SCRAM proof.
Actual behavior
The raw password form fails with 28P01 / password authentication failed, while the normalized form succeeds.
This happens because SQLx computes the SCRAM proof from the raw Rust UTF-8 bytes of the password instead of the SASLprep-normalized password.
SQLx version
main branch
Enabled SQLx features
default
Database server and version
Postgres
Operating system
MacOS
Rust version
1.94.0 (4a4ef493e 2026-03-02)