80320ae698
Close audit findings: anti-spoof client IP for login rate limit, JWT/CORS enforce on startup, SSH host-key verification and sudo via stdin, optional WinRM HTTPS, SSE httpOnly cookie auth, ingest body limit, ILIKE escaping, and HMAC API key hashing with legacy SHA-256 fallback.
53 lines
1.7 KiB
Python
53 lines
1.7 KiB
Python
"""Security bootstrap and API key hashing."""
|
|
|
|
import hashlib
|
|
import pytest
|
|
|
|
from app.auth.api_key import _legacy_hash_api_key, hash_api_key, verify_api_key_hash
|
|
from app.security_bootstrap import validate_security_settings
|
|
from app.config import Settings
|
|
|
|
|
|
def test_hash_api_key_uses_hmac(monkeypatch):
|
|
monkeypatch.setenv("JWT_SECRET", "unit-test-secret")
|
|
from app.config import get_settings
|
|
|
|
get_settings.cache_clear()
|
|
raw = "sac_example_key"
|
|
assert hash_api_key(raw) != _legacy_hash_api_key(raw)
|
|
assert verify_api_key_hash(raw, hash_api_key(raw))
|
|
get_settings.cache_clear()
|
|
|
|
|
|
def test_verify_api_key_hash_accepts_legacy_sha256(monkeypatch):
|
|
monkeypatch.setenv("JWT_SECRET", "unit-test-secret")
|
|
from app.config import get_settings
|
|
|
|
get_settings.cache_clear()
|
|
raw = "sac_legacy_key"
|
|
legacy = hashlib.sha256(raw.encode("utf-8")).hexdigest()
|
|
assert verify_api_key_hash(raw, legacy)
|
|
get_settings.cache_clear()
|
|
|
|
|
|
def test_validate_security_settings_rejects_weak_jwt():
|
|
settings = Settings(
|
|
jwt_secret="change-me-in-production",
|
|
sac_public_url="https://sac.example.com",
|
|
cors_origins="https://sac.example.com",
|
|
sac_security_enforce=True,
|
|
)
|
|
with pytest.raises(RuntimeError, match="JWT_SECRET"):
|
|
validate_security_settings(settings)
|
|
|
|
|
|
def test_validate_security_settings_rejects_wildcard_cors(monkeypatch):
|
|
settings = Settings(
|
|
jwt_secret="strong-secret-value",
|
|
sac_public_url="https://sac.example.com",
|
|
cors_origins="*",
|
|
sac_security_enforce=True,
|
|
)
|
|
with pytest.raises(RuntimeError, match="CORS_ORIGINS"):
|
|
validate_security_settings(settings)
|