From bb0b2886e907d15fb804c8942e86c72b2f3ce550 Mon Sep 17 00:00:00 2001 From: Albert S Date: Mon, 14 Sep 2020 19:38:13 +0200 Subject: [PATCH] Fix embarassing, basic path traversal attack Fix the most embarassing kind of path traversal vulnerability imaginable for such a tool. You could simply run raou ../../../../tmp/evil_entry The C version contained various check on the config dir and its entries which would have prevented this attack. In this port, the checking functions were deemed unnecessary, as they did lots of redundant checks too. Unfortunately, I missed this trivial attack when I decided not to port them. At the plus side, I found this now myself while sleep-deprived, so there may be some hope for me after all. Also, you should not use some non-released software from some guys git ;-) --- src/main.rs | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/main.rs b/src/main.rs index 1186a82..bc36a93 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,6 +5,7 @@ use std::fs::File; use std::io::BufRead; use std::io::BufReader; use std::io::{Error, ErrorKind}; +use std::fs; extern crate libc; use libc::passwd; @@ -240,9 +241,16 @@ fn create_execv_args(entry: &Entry, cmdargs: &Vec) -> Vec<*const libc::c return args; } fn exec(entryname: &str, cmdargs: &Vec) -> std::io::Result<()> { - let mut filepath: String = String::from("/etc/raou.d/"); - filepath = filepath + entryname; + let basedir: String = String::from("/etc/raou.d/"); + let filepath: String = basedir.to_string() + entryname; + let realpath = fs::canonicalize(&filepath)?; + if !realpath.starts_with(basedir) { + return Err(std::io::Error::new( + ErrorKind::InvalidInput, + "Specified entry is outside base directory", + )); + } if !std::path::Path::new(&filepath).exists() { return Err(std::io::Error::new( ErrorKind::NotFound,