mygit

[UNMAINTAINED] A cgit/webgit alternative, written in Rust
Log | Files | Refs | README | LICENSE

commit b3cb0f229a403d6e18b0cab4505a52123f88efac
parent dd5f1b6e61ffb015370da757b43751b7b7127d18
Author: Johann150 <johann@qwertqwefsday.eu>
Date:   Wed, 24 Mar 2021 21:38:22 +0100

clean up repo_from_request

Check for the export file and also improve path traversal protection:
Do not just check if the path contains .. but instead check that the
resulting path does not leave the project root directory.

Diffstat:
Msrc/main.rs | 30+++++++++++++++++++++++-------
1 file changed, 23 insertions(+), 7 deletions(-)

diff --git a/src/main.rs b/src/main.rs @@ -133,18 +133,34 @@ fn repo_from_request(repo_name: &str) -> Result<Repository, tide::Error> { let repo_name = percent_encoding::percent_decode_str(repo_name) .decode_utf8_lossy() .into_owned(); - if repo_name.contains("..") { - // Prevent path traversal - return Err(tide::Error::from_str(400, "Invalid name")); - } - // TODO: check for export_ok file + let repo_path = Path::new(&CONFIG.projectroot).join(repo_name); - Repository::open(repo_path).or_else(|_| { + + // prevent path traversal + if !repo_path.starts_with(&CONFIG.projectroot) { + return Err(tide::Error::from_str( + 403, + "You do not have access to this resource.", + )); + } + + let repo = Repository::open(repo_path).or_else(|_| { + Err(tide::Error::from_str( + 404, + "This repository does not exist.", + )) + })?; + + if !repo.path().join(&CONFIG.export_ok).exists() { + // outside users should not be able to tell the difference between + // nonexistent and existing but forbidden repos, so not using 403 Err(tide::Error::from_str( 404, "This repository does not exist.", )) - }) + } else { + Ok(repo) + } } async fn repo_home(req: Request<()>) -> tide::Result {