Skip to content

Commit f260853

Browse files
committed
fixed toctou issue
1 parent 8a7bfb0 commit f260853

File tree

2 files changed

+18
-17
lines changed

2 files changed

+18
-17
lines changed

src/fs/serve_dir.rs

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use crate::{Body, Endpoint, Request, Response, Result, StatusCode};
33

44
use async_std::path::PathBuf as AsyncPathBuf;
55

6-
use std::ffi::OsStr;
6+
use std::{ffi::OsStr, io};
77
use std::path::{Path, PathBuf};
88

99
pub(crate) struct ServeDir {
@@ -43,16 +43,17 @@ where
4343
let file_path = AsyncPathBuf::from(file_path);
4444
if !file_path.starts_with(&self.dir) {
4545
log::warn!("Unauthorized attempt to read: {:?}", file_path);
46-
return Ok(Response::new(StatusCode::Forbidden));
47-
}
48-
if !file_path.exists().await {
49-
log::warn!("File not found: {:?}", file_path);
50-
return Ok(Response::new(StatusCode::NotFound));
46+
Ok(Response::new(StatusCode::Forbidden))
47+
} else {
48+
match Body::from_file(&file_path).await {
49+
Ok(body) => Ok(Response::builder(StatusCode::Ok).body(body).build()),
50+
Err(e) if e.kind() == io::ErrorKind::NotFound => {
51+
log::warn!("File not found: {:?}", &file_path);
52+
Ok(Response::new(StatusCode::NotFound))
53+
}
54+
Err(e) => Err(e)?,
55+
}
5156
}
52-
let body = Body::from_file(&file_path).await?;
53-
let mut res = Response::new(StatusCode::Ok);
54-
res.set_body(body);
55-
Ok(res)
5657
}
5758
}
5859

src/fs/serve_file.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,13 @@ impl ServeFile {
2323
#[async_trait]
2424
impl<State: Clone + Send + Sync + 'static> Endpoint<State> for ServeFile {
2525
async fn call(&self, _: Request<State>) -> Result {
26-
if !self.path.exists().await {
27-
log::warn!("File not found: {:?}", &self.path);
28-
Ok(Response::new(StatusCode::NotFound))
29-
} else {
30-
Ok(Response::builder(StatusCode::Ok)
31-
.body(Body::from_file(&self.path).await?)
32-
.build())
26+
match Body::from_file(&self.path).await {
27+
Ok(body) => Ok(Response::builder(StatusCode::Ok).body(body).build()),
28+
Err(e) if e.kind() == io::ErrorKind::NotFound => {
29+
log::warn!("File not found: {:?}", &self.path);
30+
Ok(Response::new(StatusCode::NotFound))
31+
}
32+
Err(e) => Err(e)?,
3333
}
3434
}
3535
}

0 commit comments

Comments
 (0)