Skip to content
Open
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
2 changes: 1 addition & 1 deletion .github/workflows/qa-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -52,4 +52,4 @@ jobs:
app_port: 8080
sleep_before_test: 30
config_update_delay: 100
skip_tests: test_bypassed_ip_for_geo_blocking,test_demo_apps_generic_tests,test_path_traversal,test_outbound_domain_blocking,test_bypassed_ip,test_wave_attack,test_block_traffic_by_countries,test_user_rate_limiting_1_minute
skip_tests: test_bypassed_ip_for_geo_blocking,test_demo_apps_generic_tests,test_outbound_domain_blocking,test_bypassed_ip,test_wave_attack,test_block_traffic_by_countries,test_user_rate_limiting_1_minute
5 changes: 5 additions & 0 deletions aikido_zen/context/asgi/build_url_from_asgi.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,9 @@ def build_url_from_asgi(scope):
root_path = scope.get("root_path", "")
path = scope.get("path", "")
uri = path.replace(root_path, "", 1)

query_string = scope.get("query_string") or b""
if query_string:
uri = f"{uri}?{query_string.decode('utf-8', errors='replace')}"

return f"{scheme}://{host}{uri}"
27 changes: 26 additions & 1 deletion aikido_zen/context/asgi/build_url_from_asgi_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,32 @@ def test_build_url_from_asgi_with_query_string():
"scheme": "http",
"server": ("localhost", 8000),
"root_path": "",
"path": "/api/v1/resource?query=1",
"path": "/api/v1/resource",
"query_string": b"query=1",
}
expected = "http://localhost:8000/api/v1/resource?query=1"
assert build_url_from_asgi(scope) == expected


def test_build_url_from_asgi_with_empty_query_string():
scope = {
"scheme": "http",
"server": ("localhost", 8000),
"root_path": "",
"path": "/api/v1/resource",
"query_string": b"",
}
expected = "http://localhost:8000/api/v1/resource"
assert build_url_from_asgi(scope) == expected


def test_build_url_from_asgi_path_traversal_query():
scope = {
"scheme": "http",
"server": ("localhost", 3018),
"root_path": "",
"path": "/api/read",
"query_string": b"path=../secrets/key.txt",
}
expected = "http://localhost:3018/api/read?path=../secrets/key.txt"
assert build_url_from_asgi(scope) == expected
6 changes: 3 additions & 3 deletions aikido_zen/context/asgi/init_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ def test_asgi_scope_1():
"HEADER1_TEST_2": ["testValue2198&"],
}
assert context1.cookies == {"a": "b", "c": "d"}
assert context1.url == "https://192.168.0.1:443/a/b/c/d"
assert context1.url == "https://192.168.0.1:443/a/b/c/d?a=b&b=d"


# Scope 2 :
Expand All @@ -63,7 +63,7 @@ def test_asgi_scope_2():
"HEADER2_TEST_1": ["anotherValue"],
}
assert context2.cookies == {"x": "y", "z": "w"}
assert context2.url == "http://192.168.0.2:80/path/to/resource"
assert context2.url == "http://192.168.0.2:80/path/to/resource?x=y&z=w"


# Scope 3 :
Expand All @@ -90,7 +90,7 @@ def test_asgi_scope_3():
"HEADER3_TEST_3": ["postValue"],
}
assert context3.cookies == {"session": "abc123"}
assert context3.url == "http://192.168.0.3:8080/v1/resource"
assert context3.url == "http://192.168.0.3:8080/v1/resource?key1=value1&key2=value2"


# Scope 4 :
Expand Down
6 changes: 3 additions & 3 deletions aikido_zen/context/init_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ def test_wsgi_context_1():
"CONTENT_TYPE": ["application/x-www-form-urlencoded"],
},
"cookies": {"sessionId": "abc123xyz456"},
"url": "https://example.com/hello",
"url": "https://example.com/hello?user=JohnDoe&age=30&age=35",
"query": {"user": ["JohnDoe"], "age": ["30", "35"]},
"body": 123,
"route": "/hello",
Expand Down Expand Up @@ -91,7 +91,7 @@ def test_wsgi_context_2():
"USER_AGENT": ["Mozilla/5.0"],
},
"cookies": {"sessionId": "abc123xyz456"},
"url": "http://localhost:8080/hello",
"url": "http://localhost:8080/hello?user=JohnDoe&age=30&age=35",
"query": {"user": ["JohnDoe"], "age": ["30", "35"]},
"body": {"test": True},
"route": "/hello",
Expand Down Expand Up @@ -130,7 +130,7 @@ def test_context_is_picklable(mocker):
assert unpickled_obj.source == "flask"
assert unpickled_obj.method == "GET"
assert unpickled_obj.remote_address == "198.51.100.23"
assert unpickled_obj.url == "http://localhost:8080/hello"
assert unpickled_obj.url == "http://localhost:8080/hello?user=JohnDoe&age=30&age=35"
assert unpickled_obj.body == 123
assert unpickled_obj.headers == {
"HEADER_1": ["header 1 value"],
Expand Down
4 changes: 4 additions & 0 deletions aikido_zen/context/wsgi/build_url_from_wsgi.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,8 @@ def build_url_from_wsgi(request):
else:
host = request["HTTP_HOST"]

query_string = request.get("QUERY_STRING", "")
if query_string:
uri = f"{uri}?{query_string}"

return f"{scheme}://{host}{uri}"
23 changes: 22 additions & 1 deletion aikido_zen/context/wsgi/build_url_from_wsgi_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,32 @@ def test_build_url_from_wsgi_with_query_string():
"PATH_INFO": "/search",
"QUERY_STRING": "q=test",
}
# Note: The function does not currently handle query strings, so we won't include it in the expected output
expected = "http://example.com/search?q=test"
assert build_url_from_wsgi(request) == expected


def test_build_url_from_wsgi_with_empty_query_string():
request = {
"wsgi.url_scheme": "http",
"HTTP_HOST": "example.com",
"PATH_INFO": "/search",
"QUERY_STRING": "",
}
expected = "http://example.com/search"
assert build_url_from_wsgi(request) == expected


def test_build_url_from_wsgi_path_traversal_query():
request = {
"wsgi.url_scheme": "http",
"HTTP_HOST": "localhost:3018",
"PATH_INFO": "/api/read",
"QUERY_STRING": "path=../secrets/key.txt",
}
expected = "http://localhost:3018/api/read?path=../secrets/key.txt"
assert build_url_from_wsgi(request) == expected


def test_build_url_from_wsgi_root_path():
request = {"wsgi.url_scheme": "http", "HTTP_HOST": "example.com", "PATH_INFO": "/"}
expected = "http://example.com/"
Expand Down
2 changes: 1 addition & 1 deletion aikido_zen/vulnerabilities/init_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ def test_sql_injection_with_comms(caplog, get_context, monkeypatch):
"method": "GET",
"route": "/hello",
"source": "flask",
"url": "http://localhost:8080/hello",
"url": "http://localhost:8080/hello?user=JohnDoe&age=30&age=35",
"userAgent": None,
}
del call_args[1].event["attack"]["stack"] # Hard to test
Expand Down
Loading