Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions aikido_zen/helpers/get_ip_from_request.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
31 changes: 24 additions & 7 deletions aikido_zen/helpers/get_ip_from_request_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
14 changes: 12 additions & 2 deletions aikido_zen/vulnerabilities/ssrf/is_request_to_itself_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand All @@ -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)
Expand Down
3 changes: 2 additions & 1 deletion sample-apps/common.mk
Original file line number Diff line number Diff line change
Expand Up @@ -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 \
Expand Down
Loading