Improves RPC path sanitation (#29931)

This commit is contained in:
Brooks 2023-01-26 23:49:02 -05:00 committed by GitHub
parent 3bd389149c
commit daea6722f6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 64 additions and 6 deletions

View File

@ -122,6 +122,10 @@ impl RpcRequestMiddleware {
.unwrap()
}
fn strip_leading_slash(path: &str) -> Option<&str> {
path.strip_prefix('/')
}
fn is_file_get_path(&self, path: &str) -> bool {
if path == DEFAULT_GENESIS_DOWNLOAD_PATH {
return true;
@ -131,12 +135,9 @@ impl RpcRequestMiddleware {
return false;
}
let starting_character = '/';
if !path.starts_with(starting_character) {
let Some(path) = Self::strip_leading_slash(path) else {
return false;
}
let path = path.trim_start_matches(starting_character);
};
self.full_snapshot_archive_path_regex.is_match(path)
|| self.incremental_snapshot_archive_path_regex.is_match(path)
@ -189,8 +190,8 @@ impl RpcRequestMiddleware {
}
fn process_file_get(&self, path: &str) -> RequestMiddlewareAction {
let stem = path.split_at(1).1; // Drop leading '/' from path
let filename = {
let stem = Self::strip_leading_slash(path).expect("path already verified");
match path {
DEFAULT_GENESIS_DOWNLOAD_PATH => {
inc_new_counter_info!("rpc-get_genesis", 1);
@ -681,6 +682,35 @@ mod tests {
);
}
#[test]
fn test_strip_prefix() {
assert_eq!(RpcRequestMiddleware::strip_leading_slash("/"), Some(""));
assert_eq!(RpcRequestMiddleware::strip_leading_slash("//"), Some("/"));
assert_eq!(
RpcRequestMiddleware::strip_leading_slash("/abc"),
Some("abc")
);
assert_eq!(
RpcRequestMiddleware::strip_leading_slash("//abc"),
Some("/abc")
);
assert_eq!(
RpcRequestMiddleware::strip_leading_slash("/./abc"),
Some("./abc")
);
assert_eq!(
RpcRequestMiddleware::strip_leading_slash("/../abc"),
Some("../abc")
);
assert_eq!(RpcRequestMiddleware::strip_leading_slash(""), None);
assert_eq!(RpcRequestMiddleware::strip_leading_slash("./"), None);
assert_eq!(RpcRequestMiddleware::strip_leading_slash("../"), None);
assert_eq!(RpcRequestMiddleware::strip_leading_slash("."), None);
assert_eq!(RpcRequestMiddleware::strip_leading_slash(".."), None);
assert_eq!(RpcRequestMiddleware::strip_leading_slash("abc"), None);
}
#[test]
fn test_is_file_get_path() {
let bank_forks = create_bank_forks();
@ -699,6 +729,8 @@ mod tests {
assert!(rrm.is_file_get_path(DEFAULT_GENESIS_DOWNLOAD_PATH));
assert!(!rrm.is_file_get_path(DEFAULT_GENESIS_ARCHIVE));
assert!(!rrm.is_file_get_path("//genesis.tar.bz2"));
assert!(!rrm.is_file_get_path("/../genesis.tar.bz2"));
assert!(!rrm.is_file_get_path("/snapshot.tar.bz2")); // This is a redirect
@ -748,8 +780,34 @@ mod tests {
.is_file_get_path("../../../test/incremental-snapshot-123-456-xxx.tar"));
assert!(!rrm.is_file_get_path("/"));
assert!(!rrm.is_file_get_path("//"));
assert!(!rrm.is_file_get_path("/."));
assert!(!rrm.is_file_get_path("/./"));
assert!(!rrm.is_file_get_path("/.."));
assert!(!rrm.is_file_get_path("/../"));
assert!(!rrm.is_file_get_path("."));
assert!(!rrm.is_file_get_path("./"));
assert!(!rrm.is_file_get_path(".//"));
assert!(!rrm.is_file_get_path(".."));
assert!(!rrm.is_file_get_path("../"));
assert!(!rrm.is_file_get_path("..//"));
assert!(!rrm.is_file_get_path("🎣"));
assert!(!rrm_with_snapshot_config
.is_file_get_path("//snapshot-100-AvFf9oS8A8U78HdjT9YG2sTTThLHJZmhaMn2g8vkWYnr.tar"));
assert!(!rrm_with_snapshot_config
.is_file_get_path("/./snapshot-100-AvFf9oS8A8U78HdjT9YG2sTTThLHJZmhaMn2g8vkWYnr.tar"));
assert!(!rrm_with_snapshot_config
.is_file_get_path("/../snapshot-100-AvFf9oS8A8U78HdjT9YG2sTTThLHJZmhaMn2g8vkWYnr.tar"));
assert!(!rrm_with_snapshot_config.is_file_get_path(
"//incremental-snapshot-100-200-AvFf9oS8A8U78HdjT9YG2sTTThLHJZmhaMn2g8vkWYnr.tar"
));
assert!(!rrm_with_snapshot_config.is_file_get_path(
"/./incremental-snapshot-100-200-AvFf9oS8A8U78HdjT9YG2sTTThLHJZmhaMn2g8vkWYnr.tar"
));
assert!(!rrm_with_snapshot_config.is_file_get_path(
"/../incremental-snapshot-100-200-AvFf9oS8A8U78HdjT9YG2sTTThLHJZmhaMn2g8vkWYnr.tar"
));
}
#[test]