fix: improve path traversal check
The previous implementation would falsely detect a path traversal in a filename such as "foo... bar". This patch changes the check function so that it inspects `PathBuf` components instead of substrings.
This commit is contained in:
parent
1307148a05
commit
f020673032
1 changed files with 13 additions and 7 deletions
|
|
@ -3,7 +3,7 @@ use std::{
|
||||||
collections::{HashMap, HashSet},
|
collections::{HashMap, HashSet},
|
||||||
io::Read,
|
io::Read,
|
||||||
net::SocketAddr,
|
net::SocketAddr,
|
||||||
path::{Path, PathBuf},
|
path::{Component, Path, PathBuf},
|
||||||
sync::{atomic::AtomicUsize, Arc},
|
sync::{atomic::AtomicUsize, Arc},
|
||||||
time::Duration,
|
time::Duration,
|
||||||
};
|
};
|
||||||
|
|
@ -994,8 +994,12 @@ impl Session {
|
||||||
if files.len() < 2 {
|
if files.len() < 2 {
|
||||||
return Ok(None);
|
return Ok(None);
|
||||||
}
|
}
|
||||||
fn check_valid(name: &str) -> anyhow::Result<()> {
|
|
||||||
if name.contains("/") || name.contains("\\") || name.contains("..") {
|
fn check_valid(pb: &PathBuf) -> anyhow::Result<()> {
|
||||||
|
if pb.components().into_iter().any(|x| match x {
|
||||||
|
Component::Normal(_) => false,
|
||||||
|
_ => true,
|
||||||
|
}) {
|
||||||
bail!("path traversal in torrent name detected")
|
bail!("path traversal in torrent name detected")
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
@ -1004,12 +1008,14 @@ impl Session {
|
||||||
if let Some(name) = &info.name {
|
if let Some(name) = &info.name {
|
||||||
let s =
|
let s =
|
||||||
std::str::from_utf8(name.as_slice()).context("invalid UTF-8 in torrent name")?;
|
std::str::from_utf8(name.as_slice()).context("invalid UTF-8 in torrent name")?;
|
||||||
check_valid(s)?;
|
let pb = PathBuf::from(s);
|
||||||
return Ok(Some(PathBuf::from(s)));
|
check_valid(&pb)?;
|
||||||
|
return Ok(Some(pb));
|
||||||
};
|
};
|
||||||
if let Some(name) = magnet_name {
|
if let Some(name) = magnet_name {
|
||||||
check_valid(name)?;
|
let pb = PathBuf::from(name);
|
||||||
return Ok(Some(PathBuf::from(name)));
|
check_valid(&pb)?;
|
||||||
|
return Ok(Some(pb));
|
||||||
}
|
}
|
||||||
// Let the subfolder name be the longest filename
|
// Let the subfolder name be the longest filename
|
||||||
let longest = files
|
let longest = files
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue