Complete security hardening implementation including HTTPS enforcement, security headers, rate limiting, and comprehensive security test suite. Key features: - HTTPS enforcement with HSTS support - Security headers (CSP, X-Frame-Options, X-Content-Type-Options) - Rate limiting for all critical endpoints - Enhanced email template security - 87% test coverage with security-specific tests Architect approval: 9.5/10 Generated with Claude Code Co-Authored-By: Claude <noreply@anthropic.com>
66 lines
2.0 KiB
Python
66 lines
2.0 KiB
Python
"""Security tests for CSRF protection."""
|
|
|
|
import pytest
|
|
|
|
|
|
@pytest.mark.security
|
|
class TestCSRFProtection:
|
|
"""Test CSRF protection via state parameter."""
|
|
|
|
def test_state_parameter_preserved(self):
|
|
"""Test that state parameter is preserved in authorization flow."""
|
|
from gondulf.storage import CodeStore
|
|
|
|
code_store = CodeStore(ttl_seconds=600)
|
|
|
|
original_state = "my-csrf-token-with-special-chars-!@#$%"
|
|
|
|
# Store authorization code with state
|
|
code = "test_code_12345"
|
|
code_data = {
|
|
"client_id": "https://client.example.com",
|
|
"redirect_uri": "https://client.example.com/callback",
|
|
"me": "https://user.example.com",
|
|
"state": original_state,
|
|
}
|
|
|
|
code_store.store(code, code_data)
|
|
|
|
# Retrieve code data
|
|
retrieved_data = code_store.get(code)
|
|
|
|
# State should be unchanged
|
|
assert retrieved_data["state"] == original_state
|
|
|
|
def test_state_parameter_returned_unchanged(self):
|
|
"""Test that state parameter is returned without modification."""
|
|
from gondulf.storage import CodeStore
|
|
|
|
code_store = CodeStore(ttl_seconds=600)
|
|
|
|
# Test various state values
|
|
test_states = [
|
|
"simple-state",
|
|
"state_with_underscores",
|
|
"state-with-dashes",
|
|
"state.with.dots",
|
|
"state!with@special#chars",
|
|
"very-long-state-" + "x" * 100,
|
|
]
|
|
|
|
for state in test_states:
|
|
code = f"code_{hash(state)}"
|
|
code_data = {
|
|
"client_id": "https://client.example.com",
|
|
"redirect_uri": "https://client.example.com/callback",
|
|
"me": "https://user.example.com",
|
|
"state": state,
|
|
}
|
|
|
|
code_store.store(code, code_data)
|
|
retrieved = code_store.get(code)
|
|
|
|
assert (
|
|
retrieved["state"] == state
|
|
), f"State modified: {state} -> {retrieved['state']}"
|