diff --git a/backend/app/middleware/security.py b/backend/app/middleware/security.py
index b58d2f6..aba4c3a 100644
--- a/backend/app/middleware/security.py
+++ b/backend/app/middleware/security.py
@@ -52,29 +52,29 @@ class SecurityHeadersMiddleware(BaseHTTPMiddleware):
# Content Security Policy (CSP)
# Restricts sources of content that can be loaded
- #
+ #
# SECURITY TODO: Current CSP includes 'unsafe-inline' and 'unsafe-eval' which
# weaken XSS protection. To remove these:
- #
+ #
# For script-src 'unsafe-inline':
# 1. Move all inline "}
- result = validate_domain_config(malicious_config)
+ def test_domain_config_xss_description(self):
+ result = validate_domain_config(
+ {"name": "example.com", "description": ""}
+ )
assert not result["valid"]
assert "description" in result["errors"]
class TestFileUploadSecurity:
- """Test file upload security features."""
+ """Test file upload size limits."""
def test_file_size_limit(self):
- """Test file size limit enforcement."""
- parser = DMARCParser()
-
- # Create a file that's too large (> 10 MB)
large_content = b"x" * (11 * 1024 * 1024)
-
- with pytest.raises(ValueError) as exc_info:
- parser.parse_file(large_content, "test.xml")
-
- assert "too large" in str(exc_info.value).lower()
+ with pytest.raises(ValueError, match="too large"):
+ DMARCParser.parse_file(large_content, "test.xml")
class TestXMLParsingSecurity:
- """Test XML parsing security features."""
+ """Test XML parsing security (defusedxml, XXE protection)."""
- def test_defusedxml_import(self):
- """Test that defusedxml is being used."""
+ def test_defusedxml_is_used(self):
import app.services.dmarc_parser as parser_module
- # Check that the module uses defusedxml
assert hasattr(parser_module, "ET")
- # The module name should contain 'defusedxml'
- assert (
- "defusedxml" in str(parser_module.ET.__name__).lower()
- or "defusedxml" in str(parser_module.ET.__module__).lower()
+ module_info = str(getattr(parser_module.ET, "__name__", "")) + str(
+ getattr(parser_module.ET, "__module__", "")
)
+ assert "defusedxml" in module_info.lower()
- def test_xml_entity_expansion_protection(self):
- """Test protection against XML entity expansion attacks."""
- parser = DMARCParser()
-
- # XXE attack payload
- xxe_payload = b"""
+ def test_xxe_protection(self):
+ """defusedxml should prevent XXE entity expansion."""
+ xxe_payload = b"""\
+
]>
@@ -195,23 +144,10 @@ class TestXMLParsingSecurity:
"""
-
- # Should either fail parsing or not expand the entity
- # defusedxml should prevent this
+ # defusedxml should raise an error or not expand the entity
try:
- result = parser.parse_file(xxe_payload, "test.xml")
- # If it doesn't raise an error, the entity should not be expanded
+ result = DMARCParser.parse_file(xxe_payload, "test.xml")
org_name = result.get("org_name", "")
- assert not org_name.startswith("root:") and "/bin" not in org_name
- except Exception:
- # Expected - defusedxml should prevent parsing
- pass
-
-
-# Note: TestSecurityHeaders and TestErrorHandling tests are not implemented
-# because they require proper async client setup. These will be added in a future PR
-# with proper integration test infrastructure.
-
-
-if __name__ == "__main__":
- pytest.main([__file__, "-v"])
+ assert "root:" not in org_name and "/bin" not in org_name
+ except (ValueError, Exception):
+ pass # Expected – defusedxml blocks DTD processing