diff --git a/crates/factor-outbound-http/tests/factor_test.rs b/crates/factor-outbound-http/tests/factor_test.rs index 2ec4d9e80..8b6d29806 100644 --- a/crates/factor-outbound-http/tests/factor_test.rs +++ b/crates/factor-outbound-http/tests/factor_test.rs @@ -21,7 +21,7 @@ struct TestFactors { #[tokio::test] async fn allowed_host_is_allowed() -> anyhow::Result<()> { - let mut state = test_instance_state("https://*").await?; + let mut state = test_instance_state("https://*", true).await?; let mut wasi_http = OutboundHttpFactor::get_wasi_http_impl(&mut state).unwrap(); // [100::] is an IPv6 "black hole", which should always fail @@ -39,7 +39,7 @@ async fn allowed_host_is_allowed() -> anyhow::Result<()> { #[tokio::test] async fn self_request_smoke_test() -> anyhow::Result<()> { - let mut state = test_instance_state("http://self").await?; + let mut state = test_instance_state("http://self", true).await?; let origin = SelfRequestOrigin::from_uri(&Uri::from_static("http://[100::1]"))?; state.http.set_self_request_origin(origin); @@ -58,7 +58,7 @@ async fn self_request_smoke_test() -> anyhow::Result<()> { #[tokio::test] async fn disallowed_host_fails() -> anyhow::Result<()> { - let mut state = test_instance_state("https://allowed.test").await?; + let mut state = test_instance_state("https://allowed.test", true).await?; let mut wasi_http = OutboundHttpFactor::get_wasi_http_impl(&mut state).unwrap(); let req = Request::get("https://denied.test").body(Default::default())?; @@ -71,13 +71,47 @@ async fn disallowed_host_fails() -> anyhow::Result<()> { Ok(()) } +#[tokio::test] +async fn disallowed_private_ips_fails() -> anyhow::Result<()> { + async fn run_test(allow_private_ips: bool) -> anyhow::Result<()> { + let mut state = test_instance_state("http://*", allow_private_ips).await?; + let mut wasi_http = OutboundHttpFactor::get_wasi_http_impl(&mut state).unwrap(); + let req = Request::get("http://localhost").body(Default::default())?; + let mut future_resp = wasi_http.send_request(req, test_request_config())?; + future_resp.ready().await; + match future_resp.unwrap_ready().unwrap() { + // If we don't allow private IPs, we should not get a response + Ok(_) if !allow_private_ips => bail!("expected Err, got Ok"), + // Otherwise, it's fine if the request happens to succeed + Ok(_) => {} + // If private IPs are disallowed, we should get an error saying the destination is prohibited + Err(err) if !allow_private_ips => { + assert!(matches!(err, ErrorCode::DestinationIpProhibited)) + } + // Otherwise, we should get some non-DestinationIpProhibited error + Err(err) => { + assert!(!matches!(err, ErrorCode::DestinationIpProhibited)) + } + }; + Ok(()) + } + + // Test with private IPs allowed + run_test(true).await?; + // Test with private IPs disallowed + run_test(false).await?; + + Ok(()) +} + async fn test_instance_state( allowed_outbound_hosts: &str, + allow_private_ips: bool, ) -> anyhow::Result { let factors = TestFactors { variables: VariablesFactor::default(), networking: OutboundNetworkingFactor::new(), - http: OutboundHttpFactor::default(), + http: OutboundHttpFactor::new(allow_private_ips), }; let env = TestEnvironment::new(factors).extend_manifest(toml! { [component.test-component] diff --git a/examples/spin-timer/Cargo.lock b/examples/spin-timer/Cargo.lock index 012bd3298..3f71b9d0e 100644 --- a/examples/spin-timer/Cargo.lock +++ b/examples/spin-timer/Cargo.lock @@ -2455,9 +2455,9 @@ checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" [[package]] name = "openssl" -version = "0.10.64" +version = "0.10.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95a0481286a310808298130d22dd1fef0fa571e05a8f44ec801801e84b216b1f" +checksum = "9529f4786b70a3e8c61e11179af17ab6188ad8d0ded78c5529441ed39d4bd9c1" dependencies = [ "bitflags 2.4.2", "cfg-if",