mirror of
https://github.com/Horizontal42/summarum.git
synced 2026-11-11 01:02:01 +03:00
🔒 [security fix] Remove unsafe path canonicalization in directory gate (#111)
* 🔒 [security fix] Remove unsafe path canonicalization in directory gate 🎯 What: Removed filesystem-level path canonicalization in the DataDirGate check (`canon_or_raw`). ⚠️ Risk: An attacker could bypass directory authorization by creating a symlink to an authorized directory, allowing them to redirect arbitrary path reads/writes via TOCTOU (Time-of-Check to Time-of-Use) attacks or misleading unverified paths. 🛡️ Solution: Replaced `fs::canonicalize` with purely lexical path normalization (resolving `.` and `..` in memory) to ensure strict string match validation without following symlinks. Ensure relative paths with `..` that go above the start are handled securely. Co-authored-by: Horizontal42 <75383519+Horizontal42@users.noreply.github.com> * 🔒 [security fix] Remove unsafe path canonicalization in directory gate 🎯 What: Removed filesystem-level path canonicalization in the DataDirGate check (`canon_or_raw`). ⚠️ Risk: An attacker could bypass directory authorization by creating a symlink to an authorized directory, allowing them to redirect arbitrary path reads/writes via TOCTOU (Time-of-Check to Time-of-Use) attacks or misleading unverified paths. 🛡️ Solution: Replaced `fs::canonicalize` with purely lexical path normalization (resolving `.` and `..` in memory) to ensure strict string match validation without following symlinks. Ensure relative paths with `..` that go above the start are handled securely without dropping components incorrectly. Added proper Iterator methods to appease clippy. Co-authored-by: Horizontal42 <75383519+Horizontal42@users.noreply.github.com> --------- Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
This commit is contained in:
parent
ddb51ee9f9
commit
8c50fc8aa9
1 changed files with 19 additions and 1 deletions
|
|
@ -46,7 +46,25 @@ struct DataDirGate {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn canon_or_raw(p: &Path) -> PathBuf {
|
fn canon_or_raw(p: &Path) -> PathBuf {
|
||||||
fs::canonicalize(p).unwrap_or_else(|_| p.to_path_buf())
|
let mut normalized = PathBuf::new();
|
||||||
|
for component in p.components() {
|
||||||
|
match component {
|
||||||
|
std::path::Component::ParentDir => {
|
||||||
|
let can_pop = matches!(
|
||||||
|
normalized.components().next_back(),
|
||||||
|
Some(std::path::Component::Normal(_))
|
||||||
|
);
|
||||||
|
if can_pop {
|
||||||
|
normalized.pop();
|
||||||
|
} else if !normalized.has_root() {
|
||||||
|
normalized.push(component);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
std::path::Component::CurDir => {}
|
||||||
|
_ => normalized.push(component),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
normalized
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Exact match against an authorized folder, compared canonicalized so a
|
/// Exact match against an authorized folder, compared canonicalized so a
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue