From 15de46da7b293f71c1ad5d839ed1301ad5c59ea3 Mon Sep 17 00:00:00 2001 From: epi Date: Fri, 12 Feb 2021 06:26:45 -0600 Subject: [PATCH] fixed existing tests --- src/banner/tests.rs | 9 ++++++--- src/scan_manager/scan.rs | 3 --- src/scan_manager/tests.rs | 14 +++++++++++++- src/scanner/utils.rs | 15 +++++++++------ src/statistics/container.rs | 10 ++++++++-- tests/test_scanner.rs | 6 +++++- 6 files changed, 41 insertions(+), 16 deletions(-) diff --git a/src/banner/tests.rs b/src/banner/tests.rs index 0f997df..4106ba4 100644 --- a/src/banner/tests.rs +++ b/src/banner/tests.rs @@ -1,6 +1,6 @@ use super::container::UpdateStatus; use super::*; -use crate::{config::Configuration, event_handlers::Handles}; +use crate::{config::Configuration, event_handlers::Handles, scan_manager::FeroxScans}; use httpmock::Method::GET; use httpmock::MockServer; use std::{io::stderr, sync::Arc, time::Duration}; @@ -73,8 +73,9 @@ async fn banner_needs_update_returns_up_to_date() { when.method(GET).path("/latest"); then.status(200).body("{\"tag_name\":\"v1.1.0\"}"); }); + let scans = Arc::new(FeroxScans::default()); - let handles = Arc::new(Handles::for_testing(None, None).0); + let handles = Arc::new(Handles::for_testing(Some(scans), None).0); let mut banner = Banner::new(&[srv.url("")], &Configuration::new().unwrap()); banner.version = String::from("1.1.0"); @@ -95,7 +96,9 @@ async fn banner_needs_update_returns_out_of_date() { then.status(200).body("{\"tag_name\":\"v1.1.0\"}"); }); - let handles = Arc::new(Handles::for_testing(None, None).0); + let scans = Arc::new(FeroxScans::default()); + + let handles = Arc::new(Handles::for_testing(Some(scans), None).0); let mut banner = Banner::new(&[srv.url("")], &Configuration::new().unwrap()); banner.version = String::from("1.0.1"); diff --git a/src/scan_manager/scan.rs b/src/scan_manager/scan.rs index 49cd8f6..3f14733 100644 --- a/src/scan_manager/scan.rs +++ b/src/scan_manager/scan.rs @@ -90,10 +90,7 @@ impl FeroxScan { /// Stop a currently running scan pub async fn abort(&self) -> Result<()> { let mut guard = self.task.lock().await; - log::error!("got the guard for {}", self); // todo remove or debug - if guard.is_some() { - log::error!("guard is some {}", self); // todo remove or debug if let Some(task) = std::mem::replace(&mut *guard, None) { task.abort(); self.set_status(ScanStatus::Cancelled)?; diff --git a/src/scan_manager/tests.rs b/src/scan_manager/tests.rs index 5160a57..5ced99e 100644 --- a/src/scan_manager/tests.rs +++ b/src/scan_manager/tests.rs @@ -382,7 +382,7 @@ fn feroxstates_feroxserialize_implementation() { let json_state = ferox_state.as_json().unwrap(); let expected = format!( - r#"{{"scans":[{{"id":"{}","url":"https://spiritanimal.com","scan_type":"Directory","status":"NotStarted","num_requests":0}}],"config":{{"type":"configuration","wordlist":"/usr/share/seclists/Discovery/Web-Content/raft-medium-directories.txt","config":"","proxy":"","replay_proxy":"","target_url":"","status_codes":[200,204,301,302,307,308,401,403,405],"replay_codes":[200,204,301,302,307,308,401,403,405],"filter_status":[],"threads":50,"timeout":7,"verbosity":0,"silent":false,"quiet":false,"json":false,"output":"","debug_log":"","user_agent":"feroxbuster/{}","redirects":false,"insecure":false,"extensions":[],"headers":{{}},"queries":[],"no_recursion":false,"extract_links":false,"add_slash":false,"stdin":false,"depth":4,"scan_limit":0,"rate_limit":0,"filter_size":[],"filter_line_count":[],"filter_word_count":[],"filter_regex":[],"dont_filter":false,"resumed":false,"resume_from":"","save_state":false,"time_limit":"","filter_similar":[]}},"responses":[{{"type":"response","url":"https://nerdcore.com/css","path":"/css","wildcard":true,"status":301,"content_length":173,"line_count":10,"word_count":16,"headers":{{"server":"nginx/1.16.1"}}}}]"#, + r#"{{"scans":[{{"id":"{}","url":"https://spiritanimal.com","scan_type":"Directory","status":"NotStarted","num_requests":0}}],"config":{{"type":"configuration","wordlist":"/usr/share/seclists/Discovery/Web-Content/raft-medium-directories.txt","config":"","proxy":"","replay_proxy":"","target_url":"","status_codes":[200,204,301,302,307,308,401,403,405],"replay_codes":[200,204,301,302,307,308,401,403,405],"filter_status":[],"threads":50,"timeout":7,"verbosity":0,"silent":false,"quiet":false,"auto_bail":false,"auto_tune":false,"json":false,"output":"","debug_log":"","user_agent":"feroxbuster/{}","redirects":false,"insecure":false,"extensions":[],"headers":{{}},"queries":[],"no_recursion":false,"extract_links":false,"add_slash":false,"stdin":false,"depth":4,"scan_limit":0,"rate_limit":0,"filter_size":[],"filter_line_count":[],"filter_word_count":[],"filter_regex":[],"dont_filter":false,"resumed":false,"resume_from":"","save_state":false,"time_limit":"","filter_similar":[]}},"responses":[{{"type":"response","url":"https://nerdcore.com/css","path":"/css","wildcard":true,"status":301,"content_length":173,"line_count":10,"word_count":16,"headers":{{"server":"nginx/1.16.1"}}}}]"#, saved_id, VERSION ); println!("{}\n{}", expected, json_state); @@ -561,3 +561,15 @@ fn get_base_scan_by_url_finds_correct_scan() { scan3.id ); } + +#[test] +/// given a shallow url, find the correct scan +fn get_base_scan_by_url_finds_correct_shallow_scan() { + let urls = FeroxScans::default(); + let url = "http://localhost"; + let (_, scan) = urls.add_scan(url, ScanType::Directory, ScanOrder::Latest); + assert_eq!( + urls.get_base_scan_by_url("http://localhost/").unwrap().id, + scan.id + ); +} diff --git a/src/scanner/utils.rs b/src/scanner/utils.rs index abddc2c..a1c0480 100644 --- a/src/scanner/utils.rs +++ b/src/scanner/utils.rs @@ -432,8 +432,13 @@ mod tests { /// helper to stay DRY async fn increment_scan_errors(handles: Arc, url: &str, num_errors: usize) { let scans = handles.ferox_scans().unwrap(); + for _ in 0..num_errors { - scans.increment_error(url); + if !url.ends_with('/') { + scans.increment_error(format!("{}/", url).as_str()); + } else { + scans.increment_error(url); + }; } } @@ -602,13 +607,11 @@ mod tests { } #[tokio::test(flavor = "multi_thread", worker_threads = 1)] - /// bail should return call abort on the scan with the most errors + /// bail should call abort on the scan with the most errors async fn bail_calls_abort_on_highest_errored_feroxscan() { - let url = "http://one"; - let (handles, _) = setup_requester_test(None).await; - let scan_one = create_scan(handles.clone(), url, 10, PolicyTrigger::Errors).await; + let scan_one = create_scan(handles.clone(), "http://one", 10, PolicyTrigger::Errors).await; let scan_two = create_scan(handles.clone(), "http://two", 14, PolicyTrigger::Errors).await; let scan_three = create_scan(handles.clone(), "http://three", 4, PolicyTrigger::Errors).await; @@ -628,7 +631,7 @@ mod tests { let requester = Requester { handles, - target_url: url.to_string(), + target_url: "http://one/one/stuff.php".to_string(), rate_limiter: None, policy_data: Default::default(), }; diff --git a/src/statistics/container.rs b/src/statistics/container.rs index b07ae39..7dd5db7 100644 --- a/src/statistics/container.rs +++ b/src/statistics/container.rs @@ -401,6 +401,9 @@ impl Stats { atomic_increment!(self.client_errors, atomic_load!(d_stats.client_errors)); atomic_increment!(self.server_errors, atomic_load!(d_stats.server_errors)); atomic_increment!(self.links_extracted, atomic_load!(d_stats.links_extracted)); + atomic_increment!(self.enforced_errors, atomic_load!(d_stats.enforced_errors)); + atomic_increment!(self.enforced_403s, atomic_load!(d_stats.enforced_403s)); + atomic_increment!(self.enforced_429s, atomic_load!(d_stats.enforced_429s)); atomic_increment!(self.status_200s, atomic_load!(d_stats.status_200s)); atomic_increment!(self.status_301s, atomic_load!(d_stats.status_301s)); atomic_increment!(self.status_302s, atomic_load!(d_stats.status_302s)); @@ -571,7 +574,7 @@ mod tests { #[test] /// Stats::merge_from should properly increment expected fields and ignore others fn stats_merge_from_alters_correct_fields() { - let contents = r#"{"statistics":{"type":"statistics","timeouts":1,"requests":9207,"expected_per_scan":707,"total_expected":9191,"errors":3,"successes":720,"redirects":13,"client_errors":8474,"server_errors":2,"total_scans":13,"initial_targets":1,"links_extracted":51,"status_403s":3,"status_200s":720,"status_301s":12,"status_302s":1,"status_401s":4,"status_429s":2,"status_500s":5,"status_503s":9,"status_504s":6,"status_508s":7,"wildcards_filtered":707,"responses_filtered":707,"resources_discovered":27,"directory_scan_times":[2.211973078,1.989015505,1.898675839,3.9714468910000003,4.938152838,5.256073528,6.021986595,6.065740734,6.42633762,7.095142125,7.336982137,5.319785619,4.843649778],"total_runtime":[11.556575456000001],"url_format_errors":17,"redirection_errors":12,"connection_errors":21,"request_errors":4}}"#; + let contents = r#"{"statistics":{"type":"statistics","timeouts":1,"requests":9207,"expected_per_scan":707,"total_expected":9191,"errors":3,"successes":720,"enforced_errors":41,"enforced_429s":42,"enforced_403s":43,"redirects":13,"client_errors":8474,"server_errors":2,"total_scans":13,"initial_targets":1,"links_extracted":51,"status_403s":3,"status_200s":720,"status_301s":12,"status_302s":1,"status_401s":4,"status_429s":2,"status_500s":5,"status_503s":9,"status_504s":6,"status_508s":7,"wildcards_filtered":707,"responses_filtered":707,"resources_discovered":27,"directory_scan_times":[2.211973078,1.989015505,1.898675839,3.9714468910000003,4.938152838,5.256073528,6.021986595,6.065740734,6.42633762,7.095142125,7.336982137,5.319785619,4.843649778],"total_runtime":[11.556575456000001],"url_format_errors":17,"redirection_errors":12,"connection_errors":21,"request_errors":4}}"#; let config = Configuration::new().unwrap(); let stats = Stats::new(config.extensions.len(), config.json); @@ -580,7 +583,7 @@ mod tests { stats.merge_from(tfile.path().to_str().unwrap()).unwrap(); - // as of 1.11.1; all Stats fields are accounted for whether they're updated in merge_from + // as of 2.1.0; all Stats fields are accounted for whether they're updated in merge_from // or not assert_eq!(atomic_load!(stats.timeouts), 1); assert_eq!(atomic_load!(stats.requests), 9207); @@ -611,6 +614,9 @@ mod tests { assert_eq!(atomic_load!(stats.redirection_errors), 12); assert_eq!(atomic_load!(stats.connection_errors), 21); assert_eq!(atomic_load!(stats.request_errors), 4); + assert_eq!(atomic_load!(stats.enforced_errors), 41); + assert_eq!(atomic_load!(stats.enforced_429s), 42); + assert_eq!(atomic_load!(stats.enforced_403s), 43); assert_eq!(stats.directory_scan_times.lock().unwrap().len(), 13); for scan in stats.directory_scan_times.lock().unwrap().iter() { assert!(scan.max(0.0) > 0.0); // all scans are non-zero diff --git a/tests/test_scanner.rs b/tests/test_scanner.rs index 4c686f5..21a38ae 100644 --- a/tests/test_scanner.rs +++ b/tests/test_scanner.rs @@ -496,7 +496,11 @@ fn scanner_single_request_scan_with_debug_logging_as_json() { assert!(contents.contains("\"level\":\"DEBUG\"")); assert!(contents.contains("\"level\":\"INFO\"")); assert!(contents.contains("time_offset")); - assert!(contents.contains("\"module\":\"feroxbuster::scanner\"")); + assert!(contents.contains("exit: main")); + assert!(contents.contains(&srv.url("/LICENSE"))); + assert!(contents.contains("\"module\":\"feroxbuster::response\"")); + assert!(contents.contains("\"module\":\"feroxbuster::extractor::container\"")); + assert!(contents.contains("\"module\":\"feroxbuster::url\"")); assert!(contents.contains("\"module\":\"feroxbuster::event_handlers::inputs\"")); assert!(contents.contains("exit: start_enter_handler")); assert!(contents.contains("All scans complete!"));