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