This uses the method described at gemi.dev to block transversal
attacks: it checks to see if the canonical path is within the
boundary of the root directory given in config.
---
src/con_handler.rs | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/src/con_handler.rs b/src/con_handler.rs
index 33cb604..6866a41 100644
--- a/src/con_handler.rs
+++ b/src/con_handler.rs
@@ -13,6 +13,8 @@ use crate::revproxy;
use crate::status::Status;
use crate::util;
+use crate::errors;
+
type Result<T = ()> = std::result::Result<T, Box<dyn std::error::Error + Send + Sync>>;
fn get_mime(path: &Path) -> String {
@@ -260,6 +262,14 @@ pub async fn handle_connection(mut con: conn::Connection, url: url::Url) -> Resu
return Ok(());
}
+ let root = std::fs::canonicalize(&con.srv.server.dir).unwrap();
+ let mut path = std::fs::canonicalize(path).unwrap();
+ if !path.starts_with(root) {
+ logger::logger(con.peer_addr, Status::BadRequest, url.as_str());
+ con.send_status(Status::BadRequest, None).await?;
+ return Err(Box::new(errors::GemError("Blocked transversal".into())));
+ };
+
let mut meta = tokio::fs::metadata(&path).await?;
let mut perm = meta.permissions();
--
2.35.1