b4fbd6fe9f
Deploy Site / deploy-vercel (push) Has been skipped
Deploy Site / deploy-docs (push) Has been skipped
Build Skills Index / build-index (push) Has been skipped
Build Skills Index / trigger-deploy (push) Waiting to run
CI / Deny unrelated histories (push) Has been skipped
CI / CI timing report (push) Blocked by required conditions
CI / Detect affected areas (push) Successful in 27m35s
CI / OSV scan (push) Failing after 4s
CI / Build&Test Docker image (push) Successful in 9s
CI / Supply-chain scan (push) Has been skipped
CI / Lint Docker scripts (push) Failing after 5m13s
CI / Check contributors (push) Failing after 12m8s
CI / Docs Site (push) Failing after 12m8s
CI / TypeScript (push) Failing after 12m8s
CI / Python lints (push) Failing after 12m9s
CI / Python tests (push) Failing after 12m9s
CI / Check uv.lock (push) Failing after 23m22s
CI / All required checks pass (push) Waiting to run
44 lines
1.5 KiB
Python
44 lines
1.5 KiB
Python
"""Tests that verify SQL injection mitigations in insights and state modules."""
|
|
|
|
import re
|
|
|
|
from agent.insights import InsightsEngine
|
|
|
|
|
|
def test_session_cols_no_injection_chars():
|
|
"""_SESSION_COLS must not contain SQL injection vectors."""
|
|
cols = InsightsEngine._SESSION_COLS
|
|
assert ";" not in cols
|
|
assert "--" not in cols
|
|
assert "'" not in cols
|
|
assert "DROP" not in cols.upper()
|
|
|
|
|
|
def test_get_sessions_all_query_is_parameterized():
|
|
"""_GET_SESSIONS_ALL must use a ? placeholder for the cutoff value."""
|
|
query = InsightsEngine._GET_SESSIONS_ALL
|
|
assert "?" in query
|
|
assert "started_at >= ?" in query
|
|
# Must not embed any runtime-variable content via brace interpolation
|
|
assert "{" not in query
|
|
|
|
|
|
def test_get_sessions_with_source_query_is_parameterized():
|
|
"""_GET_SESSIONS_WITH_SOURCE must use ? placeholders for both parameters."""
|
|
query = InsightsEngine._GET_SESSIONS_WITH_SOURCE
|
|
assert query.count("?") == 2
|
|
assert "started_at >= ?" in query
|
|
assert "source = ?" in query
|
|
assert "{" not in query
|
|
|
|
|
|
def test_session_col_names_are_safe_identifiers():
|
|
"""Every column name listed in _SESSION_COLS must be a simple identifier."""
|
|
cols = InsightsEngine._SESSION_COLS
|
|
identifiers = [c.strip() for c in cols.split(",")]
|
|
safe_identifier = re.compile(r"^[a-zA-Z_][a-zA-Z0-9_]*$")
|
|
for col in identifiers:
|
|
assert safe_identifier.match(col), (
|
|
f"Column name {col!r} is not a safe SQL identifier"
|
|
)
|