MySQL: a user without a password is refused when the server switches the auth plugin (empty password scrambled)

Chiusa Adatta ai principianti
#4,482 0 commenti 0 reazioni 0 assegnatari Vedi su GitHub

I maintainer di solito rispondono entro 4 giorni

Una pull request collegata è già stata integrata.

  • #4493 di @lmont19 — integrata

Valutazione

Difficoltà
2/5
Tempo stimato
1-3 ore
Idoneità per principianti
80/100
Tipo di issue
Bug
Chiarezza
Specificata chiaramente
Stato di attività
Attiva
Stack tecnologico
mysql, rust
Ambito
databases

Direzione di ricerca

Inizia in sqlx-mysql/src/connection/establish.rs, nella gestione del cambio di autenticazione 0xfe, poi leggi AuthPlugin::scramble per vedere come vengono gestite le password vuote. Riproduci il problema con i passaggi Docker per MySQL 8.4 nell’issue e verifica che, dopo la modifica, un utente senza password possa connettersi. L’issue non indica un test specifico; aggiungi o esegui test per il caso di cambio di autenticazione con password vuota.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

I have found these related issues/pull requests

#3484 (closed): people kept reporting "Access denied … (using password: YES)" for users without a password; this is a reproduction on a clean database, with the cause.

Description

A MySQL user with no password can't log in with sqlx-mysql 0.9.0 when the server switches the auth plugin during the handshake (an AuthSwitchRequest): sqlx answers with a scramble of the empty string instead of an empty response, so the server sees a wrong password. The mysql client logs in fine.

In sqlx-mysql/src/connection/establish.rs, the 0xfe (auth switch) arm calls

switch.plugin.scramble(&mut stream, options.password.as_deref().unwrap_or_default(), &nonce)

and AuthPlugin::scramble turns "" into 20 (native) or 32 (caching_sha2) bytes. libmysqlclient sends an empty auth response for an empty password.

Reproduction steps
docker run -d --name sqlx-repro -e MYSQL_ROOT_PASSWORD=root -p 127.0.0.1:53390:3306 mysql:8.4 --mysql-native-password=ON
docker exec sqlx-repro mysql -uroot -proot -e "CREATE USER 'nopw'@'%' IDENTIFIED WITH mysql_native_password BY ''"
docker exec sqlx-repro mysql -h127.0.0.1 -unopw -e "select 1"     # the mysql client: works
// sqlx = { version = "=0.9.0", default-features = false, features = ["mysql", "runtime-tokio"] }
use sqlx::mysql::MySqlConnectOptions;
use sqlx::ConnectOptions;

#[tokio::main]
async fn main() {
    // No `.password()`: the user has none.
    let options = MySqlConnectOptions::new().host("127.0.0.1").port(53390).username("nopw");
    match options.connect().await {
        Ok(_) => println!("connected"),
        Err(e) => println!("error: {e}"),
    }
}

Prints error: error returned from database: 1045 (28000): Access denied for user 'nopw'@'172.17.0.1' (using password: YES).

The same happens on public servers that use such users, e.g. EBI's Rfam (mysql://[email protected]:4497/Rfam).

A fix

Answer with an empty response when the password is empty, for the plugins that scramble it. In AuthPlugin::scramble:

AuthPlugin::CachingSha2Password | AuthPlugin::MySqlNativePassword if password.is_empty() => Ok(Vec::new()),

With that, the program above prints connected (checked against the same container), and Rfam connects. Happy to send it as a pull request.

SQLx version

0.9.0

Enabled SQLx features

mysql, runtime-tokio

Database server and version

MySQL 8.4.11 (Docker mysql:8.4), and EBI's public Rfam server

Operating system

macOS 26

Rust version

1.99

Lingua principale
Rust
Stelle
17.5k
Fork
1.7k
Merge medio
1g 17h
PR unite (30g)
7

Preparare l'ambiente

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di transact-rs/sqlx

Tutte le issue di transact-rs/sqlx

Issue simili

Altre issue su Rust

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.