Authentication-Results: mail-b.sr.ht; dkim=pass header.d=josias.dev header.i=@josias.dev Received: from out1.migadu.com (out1.migadu.com [91.121.223.63]) by mail-b.sr.ht (Postfix) with ESMTPS id B6DC011EF31 for <~int80h/public-inbox@lists.sr.ht>; Wed, 16 Feb 2022 16:28:57 +0000 (UTC) X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=josias.dev; s=key1; t=1645028931; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding; bh=I7QiRFeBf7bzeHshVWyuT2ZbM9RAbtuuWXcOrXGtKxs=; b=V0Pdonaoh0hMzvC+rsTJtqKhIo/X1Pn5CL8ke+FbU+OjePmO4v6c0HaR5JcYkf8nBoGLqp KP/nK7lvDkd66/OoIwCeuhU9DtC4rwKj2J8+YeKkfHqxhcUMK/omgV5MXPmg2t9VydPnpC 08SQPAD3JOjTorRoaS7T77H0YZUf2s1gMUPvHqJaSC4hKTdQ+9gBxtezPfUUUgTP37ziIo V4je/l3MAJQ9xLaO5StTNmlYHNiADdk2ITth1a9xD7bemgtj22GzshnOSnL5WVhPguaBYM D6MWDam3VJGHPgF+a9kptYW4WqpZmi+V1qBHgPh5eijJqxwkJE2S0Pf2rgx5Gw== From: Josias To: ~int80h/public-inbox@lists.sr.ht Cc: Josias Subject: [PATCH gemserv v2] Block transversal attacks Date: Wed, 16 Feb 2022 08:27:56 -0800 Message-Id: <20220216162755.12188-1-me@josias.dev> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Migadu-Flow: FLOW_OUT X-Migadu-Auth-User: josias.dev 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 = std::result::Result>; 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