diff --git a/aikido_zen/helpers/get_ip_from_request.py b/aikido_zen/helpers/get_ip_from_request.py index 73de267ab..308c66015 100644 --- a/aikido_zen/helpers/get_ip_from_request.py +++ b/aikido_zen/helpers/get_ip_from_request.py @@ -48,11 +48,11 @@ def get_client_ip_from_header(value): def trust_proxy(): """ - Checks the environment variables for `AIKIDO_TRUST_PROXY`, Defaults to true. + Checks the environment variables for `AIKIDO_TRUST_PROXY`, Defaults to false. """ trust_proxy_env = os.getenv("AIKIDO_TRUST_PROXY") if not trust_proxy_env: - return True # default to trusting proxy + return False # default to not trusting proxy headers for security if trust_proxy_env.lower() in ["0", "false"]: return False diff --git a/aikido_zen/helpers/get_ip_from_request_test.py b/aikido_zen/helpers/get_ip_from_request_test.py index d34404ddc..aeef8a42b 100644 --- a/aikido_zen/helpers/get_ip_from_request_test.py +++ b/aikido_zen/helpers/get_ip_from_request_test.py @@ -48,50 +48,67 @@ def test_x_forwarded_for_without_trust_proxy_ipv6(monkeypatch): ) -def test_x_forwarded_for_with_trust_proxy_invalid_ip(): +def test_x_forwarded_for_default_does_not_trust_proxy(monkeypatch): + # Test case: Default behavior (no AIKIDO_TRUST_PROXY set) should not trust proxy headers + # This is the secure default to prevent IP spoofing + monkeypatch.delenv("AIKIDO_TRUST_PROXY", raising=False) + headers = Headers() + headers.store_header("x-forwarded-for", "9.9.9.9") + # Should return the actual remote address, not the forwarded header + assert get_ip_from_request("1.2.3.4", headers) == "1.2.3.4" + + +def test_x_forwarded_for_with_trust_proxy_invalid_ip(monkeypatch): # Test case 4: x-forwarded-for with trust proxy and invalid IP + monkeypatch.setenv("AIKIDO_TRUST_PROXY", "true") headers = Headers() headers.store_header("x-forwarded-for", "invalid") assert get_ip_from_request("1.2.3.4", headers) == "1.2.3.4" -def test_x_forwarded_for_with_trust_proxy_ip_with_port(): +def test_x_forwarded_for_with_trust_proxy_ip_with_port(monkeypatch): # Test case 5: x-forwarded-for with trust proxy and IP contains port + monkeypatch.setenv("AIKIDO_TRUST_PROXY", "true") headers = Headers() headers.store_header("x-forwarded-for", "9.9.9.9:8080") assert get_ip_from_request("1.2.3.4", headers) == "9.9.9.9" -def test_x_forwarded_for_with_trust_proxy_and_trailing_comma(): +def test_x_forwarded_for_with_trust_proxy_and_trailing_comma(monkeypatch): # Test case 6: x-forwarded-for with trailing comma + monkeypatch.setenv("AIKIDO_TRUST_PROXY", "true") headers = Headers() headers.store_header("x-forwarded-for", "9.9.9.9,") assert get_ip_from_request("1.2.3.4", headers) == "9.9.9.9" -def test_x_forwarded_for_with_trust_proxy_and_leading_comma(): +def test_x_forwarded_for_with_trust_proxy_and_leading_comma(monkeypatch): # Test case 6: x-forwarded-for with trailing comma + monkeypatch.setenv("AIKIDO_TRUST_PROXY", "true") headers = Headers() headers.store_header("x-forwarded-for", ",9.9.9.9,,") assert get_ip_from_request("1.2.3.4", headers) == "9.9.9.9" -def test_x_forwarded_for_with_trust_proxy_public_ip(): +def test_x_forwarded_for_with_trust_proxy_public_ip(monkeypatch): # Test case 9: x-forwarded-for with trust proxy and public IP + monkeypatch.setenv("AIKIDO_TRUST_PROXY", "true") headers = Headers() headers.store_header("x-forwarded-for", "9.9.9.9") assert get_ip_from_request("1.2.3.4", headers) == "9.9.9.9" -def test_x_forwarded_for_with_trust_proxy_multiple_ips(): +def test_x_forwarded_for_with_trust_proxy_multiple_ips(monkeypatch): # Test case 10: x-forwarded-for with trust proxy and multiple IPs + monkeypatch.setenv("AIKIDO_TRUST_PROXY", "true") headers = Headers() headers.store_header("x-forwarded-for", "9.9.9.9, 8.8.8.8, 7.7.7.7") assert get_ip_from_request("1.2.3.4", headers) == "9.9.9.9" -def test_x_forwarded_for_with_trust_proxy_multiple_ips_ipv6(): +def test_x_forwarded_for_with_trust_proxy_multiple_ips_ipv6(monkeypatch): # Test case 10: x-forwarded-for with trust proxy and multiple IPs + monkeypatch.setenv("AIKIDO_TRUST_PROXY", "true") headers = Headers() headers.store_header( "x-forwarded-for", diff --git a/aikido_zen/vulnerabilities/ssrf/is_request_to_itself_test.py b/aikido_zen/vulnerabilities/ssrf/is_request_to_itself_test.py index 5049c2a79..85f7140be 100644 --- a/aikido_zen/vulnerabilities/ssrf/is_request_to_itself_test.py +++ b/aikido_zen/vulnerabilities/ssrf/is_request_to_itself_test.py @@ -30,14 +30,18 @@ def test_returns_false_if_hostname_is_different(): assert not is_request_to_itself("https://aikido.dev:4000", "google.com", 443) -def test_returns_true_if_server_does_request_to_itself(): +def test_returns_true_if_server_does_request_to_itself(monkeypatch): + # Need to explicitly trust proxy for this check to work + monkeypatch.setenv("AIKIDO_TRUST_PROXY", "true") assert is_request_to_itself("https://aikido.dev", "aikido.dev", 443) assert is_request_to_itself("http://aikido.dev:4000", "aikido.dev", 4000) assert is_request_to_itself("http://aikido.dev", "aikido.dev", 80) assert is_request_to_itself("https://aikido.dev:4000", "aikido.dev", 4000) -def test_returns_true_for_special_case_http_to_https(): +def test_returns_true_for_special_case_http_to_https(monkeypatch): + # Need to explicitly trust proxy for this check to work + monkeypatch.setenv("AIKIDO_TRUST_PROXY", "true") assert is_request_to_itself("http://aikido.dev", "aikido.dev", 443) assert is_request_to_itself("https://aikido.dev", "aikido.dev", 80) @@ -48,6 +52,12 @@ def test_returns_false_if_trust_proxy_is_false(monkeypatch): assert not is_request_to_itself("http://aikido.dev", "aikido.dev", 80) +def test_returns_false_if_trust_proxy_is_default(): + # With the new secure default, trust_proxy is false by default + assert not is_request_to_itself("https://aikido.dev", "aikido.dev", 443) + assert not is_request_to_itself("http://aikido.dev", "aikido.dev", 80) + + def test_returns_false_if_server_url_is_null(): assert not is_request_to_itself(None, "aikido.dev", 80) assert not is_request_to_itself(None, "aikido.dev", 443) diff --git a/sample-apps/common.mk b/sample-apps/common.mk index 06322f92b..5466f15f1 100644 --- a/sample-apps/common.mk +++ b/sample-apps/common.mk @@ -16,7 +16,8 @@ AIKIDO_ENV_COMMON = \ AIKIDO_TOKEN="AIK_secret_token" \ AIKIDO_REALTIME_ENDPOINT="http://localhost:5000/" \ AIKIDO_ENDPOINT="http://localhost:5000/" \ - AIKIDO_DISABLE=0 + AIKIDO_DISABLE=0 \ + AIKIDO_TRUST_PROXY=true AIKIDO_ENV_BENCHMARK = \ AIKIDO_DEBUG=false \