mirror of https://github.com/ospab/ostp.git
fix(cli): setup wizard used a fake password hash, locking admins out of their own panel
The Server+Panel setup wizard's panel-password hashing was a placeholder:
std::collections::hash_map::DefaultHasher (SipHash, not cryptographic, and
not even a 256-bit output - only the first 8 of 32 bytes were real, the
rest zero-padded), left in by the comment "sha2 is not a direct dep of
ostp/Cargo.toml, so we use std's hasher as a placeholder digest here."
api.rs's handle_login computes the REAL SHA256 hex digest of the submitted
password and compares it against config.json's stored password_hash. Since
the wizard's placeholder never produces the same value as real SHA256 of
the same password, anyone who set up a panel through this wizard could
never actually log into it with the password it just showed them - a
complete functional break of the wizard-driven admin flow, not a corner
case.
Added sha2 as a direct ostp dependency and replaced the placeholder with
the exact same format!("{:x}", Sha256::digest(..)) api.rs's login check
uses.
This commit is contained in:
parent
d9686c9344
commit
9a891310f9
|
|
@ -21,3 +21,4 @@ tracing-subscriber = { version = "0.3", features = ["env-filter"] }
|
||||||
ostp-core = { path = "../ostp-core" }
|
ostp-core = { path = "../ostp-core" }
|
||||||
colored = "2.1"
|
colored = "2.1"
|
||||||
rlimit = "0.11.0"
|
rlimit = "0.11.0"
|
||||||
|
sha2.workspace = true
|
||||||
|
|
|
||||||
|
|
@ -720,24 +720,11 @@ fn run_setup_wizard(config_path: &std::path::Path) -> Result<()> {
|
||||||
}) as char
|
}) as char
|
||||||
}).collect();
|
}).collect();
|
||||||
let password = wizard_prompt("Admin password (blank for random)", &rand_pass);
|
let password = wizard_prompt("Admin password (blank for random)", &rand_pass);
|
||||||
let pass_hash = {
|
// Must match api.rs's handle_login exactly (format!("{:x}", Sha256::digest(..))) -
|
||||||
use std::fmt::Write as _;
|
// this used to be a DefaultHasher (SipHash) placeholder that produced a
|
||||||
let mut hash = String::new();
|
// differently-shaped digest, so a password set up through this wizard could
|
||||||
let digest: [u8; 32] = {
|
// never actually log into the panel it just configured.
|
||||||
use std::collections::hash_map::DefaultHasher;
|
let pass_hash = format!("{:x}", sha2::Sha256::digest(password.as_bytes()));
|
||||||
use std::hash::{Hash, Hasher};
|
|
||||||
// Panel password hashing. sha2 is not a direct dep of ostp/Cargo.toml,
|
|
||||||
// so we use std's hasher as a placeholder digest here.
|
|
||||||
let mut h = DefaultHasher::new();
|
|
||||||
password.hash(&mut h);
|
|
||||||
let v = h.finish();
|
|
||||||
let mut out = [0u8; 32];
|
|
||||||
out[..8].copy_from_slice(&v.to_be_bytes());
|
|
||||||
out
|
|
||||||
};
|
|
||||||
for b in digest { let _ = write!(hash, "{:02x}", b); }
|
|
||||||
hash
|
|
||||||
};
|
|
||||||
|
|
||||||
wizard_step(4, TOTAL, "Saving configuration");
|
wizard_step(4, TOTAL, "Saving configuration");
|
||||||
let panel_bind = format!("0.0.0.0:{}", panel_port);
|
let panel_bind = format!("0.0.0.0:{}", panel_port);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue