From b0f259eff213214d08346cfb4789439d526a9790 Mon Sep 17 00:00:00 2001 From: Bryan Newbold Date: Mon, 29 Mar 2021 19:32:54 -0700 Subject: in safe-mode, allow index API methods without trailing slash If we allowed this in `unsafe_all_indices`, then all top-level API methods would be available, which we don't want. --- src/lib.rs | 12 ++++++++++++ tests/files/other_fail/GET_mapping_noslash.txt | 1 + tests/files/other_fail/HEAD_index_exists.txt | 1 + tests/files/other_safe/GET_mapping_noslash.txt | 1 + tests/files/other_safe/HEAD_index_exists.txt | 1 + tests/files/safe_config.toml | 8 ++++++++ tests/parse_es_requests.rs | 17 +++++++++++++++++ 7 files changed, 41 insertions(+) create mode 100644 tests/files/other_fail/GET_mapping_noslash.txt create mode 100644 tests/files/other_fail/HEAD_index_exists.txt create mode 100644 tests/files/other_safe/GET_mapping_noslash.txt create mode 100644 tests/files/other_safe/HEAD_index_exists.txt create mode 100644 tests/files/safe_config.toml diff --git a/src/lib.rs b/src/lib.rs index 4431daa..61aeb83 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -143,6 +143,18 @@ pub async fn filter_request( | (&Method::OPTIONS, [index, ""]) => { filter_read_request(index, path_chunks[1], ¶ms, config)? } + (&Method::GET, [index]) + | (&Method::HEAD, [index]) + | (&Method::OPTIONS, [index]) => { + // only allow operations on index name (no trailing slash) if not "unsafe_all_indices" + // (aka, only if indexes are explicitly enumerated) + // otherwise all top-level API endpoints would be allowed + if config.unsafe_all_indices != Some(true) { + filter_read_request(index, "", ¶ms, config)? + } else { + Err(ProxyError::NotSupported("unknown elasticsearch API endpoint".to_string()))? + } + } (&Method::GET, [index, "_mapping"]) | (&Method::HEAD, [index, "_mapping"]) | (&Method::OPTIONS, [index, "_mapping"]) => { diff --git a/tests/files/other_fail/GET_mapping_noslash.txt b/tests/files/other_fail/GET_mapping_noslash.txt new file mode 100644 index 0000000..30ff58c --- /dev/null +++ b/tests/files/other_fail/GET_mapping_noslash.txt @@ -0,0 +1 @@ +GET /some-index diff --git a/tests/files/other_fail/HEAD_index_exists.txt b/tests/files/other_fail/HEAD_index_exists.txt new file mode 100644 index 0000000..47ab60e --- /dev/null +++ b/tests/files/other_fail/HEAD_index_exists.txt @@ -0,0 +1 @@ +HEAD /some-index diff --git a/tests/files/other_safe/GET_mapping_noslash.txt b/tests/files/other_safe/GET_mapping_noslash.txt new file mode 100644 index 0000000..30ff58c --- /dev/null +++ b/tests/files/other_safe/GET_mapping_noslash.txt @@ -0,0 +1 @@ +GET /some-index diff --git a/tests/files/other_safe/HEAD_index_exists.txt b/tests/files/other_safe/HEAD_index_exists.txt new file mode 100644 index 0000000..47ab60e --- /dev/null +++ b/tests/files/other_safe/HEAD_index_exists.txt @@ -0,0 +1 @@ +HEAD /some-index diff --git a/tests/files/safe_config.toml b/tests/files/safe_config.toml new file mode 100644 index 0000000..3df6acd --- /dev/null +++ b/tests/files/safe_config.toml @@ -0,0 +1,8 @@ + +bind_addr = "127.0.0.1:9292" +upstream_addr = "127.0.0.1:9200" +unsafe_all_indices = false +enable_cors = true + +[[index]] +name = "some-index" diff --git a/tests/parse_es_requests.rs b/tests/parse_es_requests.rs index 53a9889..a654ca3 100644 --- a/tests/parse_es_requests.rs +++ b/tests/parse_es_requests.rs @@ -104,6 +104,23 @@ fn filter_other_requests() { } } +#[test] +fn filter_other_safe_requests() { + let file_paths = fs::read_dir("tests/files/other_safe").unwrap(); + let config: ProxyConfig = toml::from_str(include_str!("files/safe_config.toml")).unwrap(); + let rt = tokio::runtime::Runtime::new().unwrap(); + + for path in file_paths { + let path = path.unwrap().path(); + if path.extension() != Some(OsStr::new("txt")) { + continue; + } + println!(" filtering: {}", path.display()); + let req = common::load_request(&path); + rt.block_on(filter_request(req, &config)).unwrap(); + } +} + #[test] fn filter_failures() { let file_paths = fs::read_dir("tests/files/search_fail").unwrap(); -- cgit v1.2.3