@@ -111,3 +111,45 @@ def test_initial_heartbeat():
111111 assert req_stats ["rateLimited" ] == 0
112112 assert req_stats ["attacksDetected" ] == {"blocked" : 2 , "total" : 2 }
113113 assert req_stats ["attackWaves" ] == {"total" : 0 , "blocked" : 0 }
114+
115+
116+ # --- AIKIDO-5RDTZW1V regression: invalid UTF-8 bytes must not bypass detection ---
117+
118+ def test_bypass_invalid_utf8_bytes_path_traversal ():
119+ # An attacker prepends \xff (invalid UTF-8) to a path traversal payload.
120+ # Before the fix, decode("utf-8") raised UnicodeDecodeError and the body was
121+ # never stored, so the firewall saw nothing. After the fix the body is decoded
122+ # with errors="replace" and the traversal is still detected.
123+ body = b"\xff /../../../../../etc/passwd"
124+ res = requests .post (base_url_fw + "/read" , data = body )
125+ assert res .status_code == 500
126+
127+ time .sleep (5 )
128+ events = fetch_events_from_mock ("http://localhost:5000" )
129+ attacks = filter_on_event_type (events , "detected_attack" )
130+
131+ assert len (attacks ) == 3
132+ assert attacks [2 ]["attack" ]["kind" ] == "path_traversal"
133+ assert attacks [2 ]["attack" ]["blocked" ] is True
134+ assert attacks [2 ]["attack" ]["source" ] == "body"
135+
136+
137+ # --- AIKIDO-B3YABOSP regression: surrogate bytes in JSON must not bypass detection ---
138+
139+ def test_bypass_surrogate_bytes_sql_injection ():
140+ # Surrogate bytes (\xed\xa0\x80) make decode("utf-8") raise, so the old code
141+ # never parsed the body as JSON and the SQL injection payload was invisible.
142+ # After the fix, json.loads(bytes) is tried first (it uses surrogatepass internally)
143+ # so the dict is extracted and the injection is caught when the cursor executes.
144+ body = b'{"dog_name": "Dangerous bobby\\ ", 1); -- ", "bypass": "\xed \xa0 \x80 "}'
145+ res = requests .post (base_url_fw + "/json-sql" , data = body )
146+ assert res .status_code == 500
147+
148+ time .sleep (5 )
149+ events = fetch_events_from_mock ("http://localhost:5000" )
150+ attacks = filter_on_event_type (events , "detected_attack" )
151+
152+ assert len (attacks ) == 4
153+ assert attacks [3 ]["attack" ]["kind" ] == "sql_injection"
154+ assert attacks [3 ]["attack" ]["blocked" ] is True
155+ assert attacks [3 ]["attack" ]["source" ] == "body"
0 commit comments