CalvinKirs opened a new issue, #66152: URL: https://github.com/apache/doris/issues/66152
### Description Doris stores local account passwords using MySQL's two-stage SHA-1 scheme (`mysql_native_password`): - `fe/fe-core/src/main/java/org/apache/doris/mysql/MysqlPassword.java` — `makeScrambledPassword()` computes `SHA1(SHA1(password))` and stores it as a `*HEX` string - `fe/fe-core/src/main/java/org/apache/doris/mysql/privilege/Auth.java` — the same scheme is used for the initial root password No salt, no key stretching, one SHA-1 round per stage. Upstream has moved off it. MySQL deprecated `mysql_native_password` in 8.4 and **removed it entirely in 9.0**, replacing it with `caching_sha2_password` (SHA-256, per-account salt, 5000 iterations). MariaDB still ships the old plugin but discourages it: > It is not recommended to use the mysql_native_password authentication plugin for new installations that require high password security. If someone is able to both listen to the connection protocol and get a copy of the mysql.user table, then the person would be able to use this information to connect to the MariaDB server. That last sentence is the actual threat model, and both halves of it are reachable in a default Doris deployment: 1. **The stored hash.** `SHA1(SHA1(pw))` is unsalted, so identical passwords produce identical hashes across accounts and across clusters, and double-SHA-1 is among the cheapest hashes to attack on commodity GPUs. Anyone who can read FE metadata — the `doris-meta` directory, an image file, a metadata backup, a copy of the edit log — gets every account's hash. 2. **The handshake.** `enable_ssl` defaults to `false`, so the challenge-response exchange is observable on the wire by default. Combined with the stored stage-2 hash, an observer can recover the stage-1 value `SHA1(pw)`, which is permanently sufficient to authenticate as that account — no cracking required. Neither half alone is fatal, but the combination is realistic and there is currently no defence in depth against it. In OWASP terms this is A02:2021 Cryptographic Failures. There is also a plain compatibility angle: as MySQL 9.x clients drop `mysql_native_password`, Doris authentication becomes the thing that has to be worked around. ### Current state in the codebase The plugin groundwork already exists, which makes this cheaper than it might look: - `fe/fe-authentication/fe-authentication-api` defines `CredentialType`, currently only `MYSQL_NATIVE_PASSWORD` - `fe/fe-authentication/fe-authentication-plugins/fe-authentication-plugin-password` implements the local password plugin - `fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/` has `AuthenticateType`, `AuthenticatorFactory`, and the LDAP / integration / plugin authenticators What's missing: - **No strong local credential type.** `caching_sha2_password` and `sha256_password` appear nowhere in FE or BE; the only reference is a comment in `NativePasswordResolver`. - **No per-user plugin selection.** The grammar only supports `IDENTIFIED BY PASSWORD? <string>` (`DorisParser.g4`) — there is no `IDENTIFIED WITH <plugin>`. The authentication method is a cluster-level config (`authenticate_type`), not a per-account property. Noted independently in #66115: *"No per-user authentication plugins in Doris."* - **LDAP does not close the gap.** The LDAP authenticator falls back to native password authentication, so the weak path stays reachable in LDAP deployments too. ### Proposed solution **Phase 1 — implement `caching_sha2_password` as an additional local credential type behind the existing SPI.** Add it as a new `CredentialType` in `fe-authentication-plugin-password`. This means SHA-256 with a per-account salt and 5000 iterations for storage, plus the fast-auth / full-auth handshake so standard MySQL clients work unchanged. The storage format needs a per-account marker so both schemes can coexist in `Password` and in the FE image. No behaviour change for existing accounts. Choosing `caching_sha2_password` over a Doris-specific scheme is deliberate: it is what current MySQL clients already speak, so it costs users nothing on the client side and it is the direction the ecosystem has already committed to. **Phase 2 — make it selectable per account.** - `IDENTIFIED WITH <plugin> BY '<password>'` on `CREATE USER` and `ALTER USER`, matching MySQL syntax - Expose the plugin per account in `SHOW GRANTS` / `information_schema`, so operators can audit which accounts are still on the legacy scheme - A config for the default plugin used by `CREATE USER` and by the initial root account — defaulting to native for compatibility, flippable to `caching_sha2_password` **Migration.** Existing accounts keep working unchanged. Hashes cannot be converted without the plaintext, so migration is `ALTER USER ... IDENTIFIED WITH caching_sha2_password BY '<password>'` at the operator's own pace. Worth noting that #66115 (dual password / `RETAIN CURRENT PASSWORD`), if it lands, provides exactly the overlap window this migration needs — the two features complement each other well. **Interim hardening**, independent of the above and much cheaper: - Document the `enable_ssl` recommendation prominently for any deployment on an untrusted network — it removes the "listen to the protocol" half of the threat - Document that FE metadata (`doris-meta`, images, backups) has to be treated as credential material ### Use case - Deployments with password-strength or credential-storage requirements (financial, public sector, anything under an internal crypto standard) that currently cannot pass review on unsalted double-SHA-1. - Users on MySQL 9.x clients and tooling, where `mysql_native_password` no longer exists. - Operators who want to audit and migrate off the legacy scheme account by account rather than all at once. ### Out of scope - Changing the default authentication plugin — a separate compatibility decision once Phase 1 exists - BE-side and Arrow Flight changes beyond what the new credential type requires ### Related issues - #66115 (dual password support — provides the rotation window Phase 2 migration would use) -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected] --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
