fix(#2391): drop "." entirely from credential/snapshot name charset
Per mara: "i would have even disallowed ., we are making up the rules here lets go strict". validate_credential_name now restricts to [A-Za-z0-9_-] (no dot at all) instead of [A-Za-z0-9_.-] + a separate ".." substring check — simpler rule, and there's no legitimate need for a dot in either a systemd credential id or a hive- prefixed snapshot label. Matching hivectl client-side check + wire-proto doc comments updated.
This commit is contained in:
parent
720ac81235
commit
2c079afd65
3 changed files with 25 additions and 22 deletions
|
|
@ -445,25 +445,21 @@ fn validate_snapshot_name(name: &str) -> Result<()> {
|
|||
}
|
||||
|
||||
/// A systemd credential id must be a short token — restrict to
|
||||
/// `[A-Za-z0-9_.-]` so it can't inject extra `--load-credential` argv or
|
||||
/// break the `name:path` shape.
|
||||
/// `[A-Za-z0-9_-]` (no `.`) so it can't inject extra `--load-credential`
|
||||
/// argv or break the `name:path` shape. `.` is deliberately excluded, not
|
||||
/// just a bare `..`: this name gets interpolated into filesystem paths
|
||||
/// (snapshot labels) and there's no legitimate need for a dot in either a
|
||||
/// systemd credential id or a `hive-`-prefixed snapshot label — we're
|
||||
/// defining this token format from scratch, so keep it maximally strict
|
||||
/// rather than allow-then-patch each traversal-adjacent character
|
||||
/// (mara: "we are making up the rules here, lets go strict").
|
||||
fn validate_credential_name(name: &str) -> Result<()> {
|
||||
if name.is_empty()
|
||||
|| !name
|
||||
.bytes()
|
||||
.all(|b| b.is_ascii_alphanumeric() || matches!(b, b'_' | b'.' | b'-'))
|
||||
.all(|b| b.is_ascii_alphanumeric() || matches!(b, b'_' | b'-'))
|
||||
{
|
||||
bail!("invalid credential name {name:?}: must be non-empty [A-Za-z0-9_.-]");
|
||||
}
|
||||
// `.` is in the allowed charset (systemd credential ids and snapshot
|
||||
// labels both legitimately use dots), but a bare `..` reads as a
|
||||
// directory-traversal token to anyone auditing this path — and a
|
||||
// caller that builds a path via `PathBuf::from(name)` instead of the
|
||||
// current `format!("...{name}...")` embedding would actually be
|
||||
// exploitable. Reject it outright rather than relying on every future
|
||||
// caller getting the embedding right.
|
||||
if name.contains("..") {
|
||||
bail!("invalid credential name {name:?}: must not contain \"..\"");
|
||||
bail!("invalid credential name {name:?}: must be non-empty [A-Za-z0-9_-]");
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue