Fix SQLite LIKE wildcard escaping in IP filter queries
- Add escape_like() helper to escape % and _ wildcards in LIKE queries - Update fail2ban_db_repo.get_history_page() to use escaping - Update history_archive_repo.get_archived_history() to use escaping - Add ESCAPE clause to all LIKE queries - Add comprehensive unit tests for escape_like function - Add integration tests for LIKE wildcard handling - Document LIKE escaping best practices in Backend-Development.md Fixes TASK-017: Prevent unintended LIKE matches when IP filter contains special characters like underscore or percent sign. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
60
backend/tests/test_utils/test_fail2ban_db_utils.py
Normal file
60
backend/tests/test_utils/test_fail2ban_db_utils.py
Normal file
@@ -0,0 +1,60 @@
|
||||
"""Tests for fail2ban_db_utils module."""
|
||||
|
||||
from app.utils.fail2ban_db_utils import escape_like
|
||||
|
||||
|
||||
def test_escape_like_percent_sign() -> None:
|
||||
"""Test escaping of percent signs (% wildcard)."""
|
||||
assert escape_like("10.0.0%") == "10.0.0\\%"
|
||||
|
||||
|
||||
def test_escape_like_underscore() -> None:
|
||||
"""Test escaping of underscores (_ wildcard)."""
|
||||
assert escape_like("10.0.0_1") == "10.0.0\\_1"
|
||||
|
||||
|
||||
def test_escape_like_backslash() -> None:
|
||||
"""Test escaping of backslashes."""
|
||||
assert escape_like("10.0.0\\") == "10.0.0\\\\"
|
||||
|
||||
|
||||
def test_escape_like_combined_wildcards() -> None:
|
||||
"""Test escaping when both % and _ are present."""
|
||||
assert escape_like("10.0_%") == "10.0\\_\\%"
|
||||
|
||||
|
||||
def test_escape_like_combined_with_backslash() -> None:
|
||||
"""Test escaping backslash first, then wildcards."""
|
||||
assert escape_like("10\\0_%") == "10\\\\0\\_\\%"
|
||||
|
||||
|
||||
def test_escape_like_normal_ip() -> None:
|
||||
"""Test that normal IPs pass through unchanged (dots are not wildcards)."""
|
||||
assert escape_like("10.0.0.1") == "10.0.0.1"
|
||||
|
||||
|
||||
def test_escape_like_empty_string() -> None:
|
||||
"""Test escaping empty string."""
|
||||
assert escape_like("") == ""
|
||||
|
||||
|
||||
def test_escape_like_only_backslash() -> None:
|
||||
"""Test string with only backslashes."""
|
||||
assert escape_like("\\\\") == "\\\\\\\\"
|
||||
|
||||
|
||||
def test_escape_like_only_percent() -> None:
|
||||
"""Test string with only percent signs."""
|
||||
assert escape_like("%%%") == "\\%\\%\\%"
|
||||
|
||||
|
||||
def test_escape_like_only_underscore() -> None:
|
||||
"""Test string with only underscores."""
|
||||
assert escape_like("___") == "\\_\\_\\_"
|
||||
|
||||
|
||||
def test_escape_like_backslash_before_wildcard() -> None:
|
||||
"""Test that backslash before wildcard is properly escaped."""
|
||||
result = escape_like("10\\_%")
|
||||
# Expected: backslash → \\ , underscore → \_ , percent → \%
|
||||
assert result == "10\\\\\\_\\%"
|
||||
Reference in New Issue
Block a user