agate

Simple gemini server for static files
git clone https://github.com/mbrubeck/agate.git
Log | Files | Refs | README

commit 7b1e83ec8200a7052fbb867de020336370ac3649
parent 3c38dae5995dcc17c8b201595990ef82d741f811
Author: Matthew Ingwersen <matttpt@gmail.com>
Date:   Mon,  7 Jun 2021 20:52:24 -0400

Add regression test for directory traversal

Diffstat:
Atests/data/directory_traversal.gmi | 1+
Mtests/tests.rs | 35+++++++++++++++++++++++++++++++++++
2 files changed, 36 insertions(+), 0 deletions(-)

diff --git a/tests/data/directory_traversal.gmi b/tests/data/directory_traversal.gmi @@ -0,0 +1 @@ +This is a test file to check for directory traversal vulnerabilities. diff --git a/tests/tests.rs b/tests/tests.rs @@ -2,6 +2,7 @@ use anyhow::anyhow; use gemini_fetch::{Header, Page, Status}; use std::io::{BufRead, BufReader, Read}; use std::net::{SocketAddr, ToSocketAddrs}; +use std::path::PathBuf; use std::process::{Command, Stdio}; use url::Url; @@ -411,6 +412,40 @@ fn serve_secret() { } #[test] +/// - directory traversal attacks using percent-encoded path separators +/// fail (this addresses a previous vulnerability) +fn directory_traversal_regression() { + let base = Url::parse("gemini://localhost/").unwrap(); + + let mut absolute = base.clone(); + absolute + .path_segments_mut() + .unwrap() + .push(&env!("CARGO_MANIFEST_DIR")) // separators will be percent-encoded + .push("tests") + .push("data") + .push("directory_traversal.gmi"); + + let mut relative_escape_path = PathBuf::new(); + relative_escape_path.push("testdir"); + relative_escape_path.push(".."); + relative_escape_path.push(".."); + let mut relative = base.clone(); + relative + .path_segments_mut() + .unwrap() + .push(relative_escape_path.to_str().unwrap()) // separators will be percent-encoded + .push("directory_traversal.gmi"); + + let urls = [absolute, relative]; + for url in urls.iter() { + let page = + get(&["--addr", "[::]:1988"], addr(1988), url.as_str()).expect("could not get page"); + assert_eq!(page.header.status, Status::NotFound); + } +} + +#[test] /// - if TLSv1.3 is selected, does not accept TLSv1.2 connections /// (lower versions do not have to be tested because rustls does not even /// support them, making agate incapable of accepting them)