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:
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)