openenv-secaudit / tests /test_hidden_leaks.py
dexter-2k's picture
Upload folder using huggingface_hub
ee929ba verified
Raw
History Blame Contribute Delete
6.41 kB
"""Tests for hidden leak (tiered disclosure) logic."""
from __future__ import annotations
import pytest
import sys, os
sys.path.insert(0, os.path.join(os.path.dirname(__file__), ".."))
from server.environment import SecretVisibility, SecretsAuditEnvironment
# ---------------------------------------------------------------------------
# Helpers
# ---------------------------------------------------------------------------
SAMPLE_SECRETS = [
{"id": "s1", "type": "aws_key", "path": "config.py", "line": 3, "visibility": "surface"},
{"id": "s2", "type": "db_passwd", "path": ".env", "line": 1, "visibility": "surface"},
{"id": "s3", "type": "gh_token", "path": "setup.cfg", "line": 7, "visibility": "shallow"},
{"id": "s4", "type": "jwt_secret","path": "auth.py", "line": 5, "visibility": "deep",
"requires_action": "inspect_git_history"},
{"id": "s5", "type": "ssh_privkey","path": "deploy.sh", "line": 1, "visibility": "deep",
"requires_action": "inspect_encoded"},
{"id": "s6", "type": "db_passwd", "path": "fallback.py", "line": 9, "visibility": "cascading",
"trigger_secret_id": "s1"},
]
def _make_env() -> SecretsAuditEnvironment:
"""Minimal env instance — we only need its visibility helper."""
return SecretsAuditEnvironment.__new__(SecretsAuditEnvironment)
# ---------------------------------------------------------------------------
# Tests: SURFACE secrets always visible
# ---------------------------------------------------------------------------
class TestSurfaceSecrets:
def test_surface_visible_immediately(self):
env = _make_env()
visible = env._compute_visible_secrets(
SAMPLE_SECRETS, inspected_files=set(), deep_inspected=set(), fixed_secrets=set()
)
visible_ids = {s["id"] for s in visible}
assert "s1" in visible_ids
assert "s2" in visible_ids
# ---------------------------------------------------------------------------
# Tests: SHALLOW secrets only after inspect_file
# ---------------------------------------------------------------------------
class TestShallowSecrets:
def test_shallow_not_visible_before_inspect(self):
env = _make_env()
visible = env._compute_visible_secrets(
SAMPLE_SECRETS, inspected_files=set(), deep_inspected=set(), fixed_secrets=set()
)
visible_ids = {s["id"] for s in visible}
assert "s3" not in visible_ids
def test_shallow_visible_after_inspect(self):
env = _make_env()
visible = env._compute_visible_secrets(
SAMPLE_SECRETS, inspected_files={"setup.cfg"}, deep_inspected=set(), fixed_secrets=set()
)
visible_ids = {s["id"] for s in visible}
assert "s3" in visible_ids
# ---------------------------------------------------------------------------
# Tests: DEEP secrets only after inspect_git_history / inspect_encoded
# ---------------------------------------------------------------------------
class TestDeepSecrets:
def test_deep_not_visible_before_inspect(self):
env = _make_env()
visible = env._compute_visible_secrets(
SAMPLE_SECRETS, inspected_files=set(), deep_inspected=set(), fixed_secrets=set()
)
visible_ids = {s["id"] for s in visible}
assert "s4" not in visible_ids
assert "s5" not in visible_ids
def test_deep_git_history_visible_after_scan(self):
env = _make_env()
visible = env._compute_visible_secrets(
SAMPLE_SECRETS, inspected_files=set(), deep_inspected={"."}, fixed_secrets=set()
)
visible_ids = {s["id"] for s in visible}
assert "s4" in visible_ids
def test_deep_encoded_visible_after_decode(self):
env = _make_env()
visible = env._compute_visible_secrets(
SAMPLE_SECRETS, inspected_files=set(), deep_inspected={"deploy.sh:1"}, fixed_secrets=set()
)
visible_ids = {s["id"] for s in visible}
assert "s5" in visible_ids
def test_deep_encoded_not_visible_for_wrong_path(self):
env = _make_env()
visible = env._compute_visible_secrets(
SAMPLE_SECRETS, inspected_files=set(), deep_inspected={"other.py:5"}, fixed_secrets=set()
)
visible_ids = {s["id"] for s in visible}
assert "s5" not in visible_ids
# ---------------------------------------------------------------------------
# Tests: CASCADING secrets only after trigger is fixed
# ---------------------------------------------------------------------------
class TestCascadingSecrets:
def test_cascading_not_visible_before_trigger_fixed(self):
env = _make_env()
visible = env._compute_visible_secrets(
SAMPLE_SECRETS, inspected_files=set(), deep_inspected=set(), fixed_secrets=set()
)
visible_ids = {s["id"] for s in visible}
assert "s6" not in visible_ids
def test_cascading_visible_after_trigger_fixed(self):
env = _make_env()
visible = env._compute_visible_secrets(
SAMPLE_SECRETS, inspected_files=set(), deep_inspected=set(), fixed_secrets={"s1"}
)
visible_ids = {s["id"] for s in visible}
assert "s6" in visible_ids
# ---------------------------------------------------------------------------
# Tests: hidden_count_hint
# ---------------------------------------------------------------------------
class TestHiddenCountHint:
def test_hidden_count_correct_initial(self):
env = _make_env()
visible = env._compute_visible_secrets(
SAMPLE_SECRETS, inspected_files=set(), deep_inspected=set(), fixed_secrets=set()
)
hidden = len(SAMPLE_SECRETS) - len(visible)
# 2 surface visible, 4 hidden (1 shallow + 2 deep + 1 cascading)
assert hidden == 4
def test_hidden_count_decreases_on_inspect(self):
env = _make_env()
visible = env._compute_visible_secrets(
SAMPLE_SECRETS, inspected_files={"setup.cfg"}, deep_inspected={"."}, fixed_secrets={"s1"}
)
hidden = len(SAMPLE_SECRETS) - len(visible)
# All except s5 (needs deploy.sh decode) should be visible now:
# s1=surface, s2=surface, s3=shallow(inspected), s4=deep(git scanned),
# s5=deep(encoded, NOT decoded yet), s6=cascading(s1 fixed)
assert hidden == 1