feat(prospecting): implement security audit pipeline (Workstream 2A)
Complete security audit integration into the enrichment pipeline:
Backend:
- SecurityAuditService with 7 passive checks: HTTPS, SSL cert, security
headers, exposed files, cookies, server info, technology detection
- Constants file with SECURITY_HEADERS, EXPOSED_PATHS, SEVERITY_SCORES
- SecurityAuditResponse schema with JSON field validators + aliases
- Endpoints: POST /security-audit/{id}, POST /security-audit/batch
- Added to full_enrichment pipeline (Step 5, before scoring)
- get_pending_security_audit() query in prospect_service
Frontend:
- Security tab on prospect detail page with grade badge (A+ to F),
score/100, severity counts, HTTPS/SSL status, missing headers,
exposed files, technologies, and full findings list
- "Run Security Audit" button with loading state
- "Security Audit" batch button on scan-jobs page
Tested on batirenovation-strasbourg.fr: Grade D (50/100), 11 issues
found (missing headers, exposed wp-login, server version disclosure).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
75
app/modules/prospecting/services/security_audit_constants.py
Normal file
75
app/modules/prospecting/services/security_audit_constants.py
Normal file
@@ -0,0 +1,75 @@
|
||||
# app/modules/prospecting/services/security_audit_constants.py
|
||||
"""
|
||||
Constants for security audit checks.
|
||||
|
||||
Structural data used by SecurityAuditService. Translations for report
|
||||
generation are kept in the standalone script (scripts/security-audit/audit.py)
|
||||
until Phase 2B (report service) migrates them.
|
||||
"""
|
||||
|
||||
# Severity scores — deducted from a starting score of 100
|
||||
SEVERITY_SCORES = {
|
||||
"critical": 15,
|
||||
"high": 10,
|
||||
"medium": 5,
|
||||
"low": 2,
|
||||
"info": 0,
|
||||
}
|
||||
|
||||
# Security headers to check and their severity if missing
|
||||
SECURITY_HEADERS = {
|
||||
"Strict-Transport-Security": {"severity": "high", "impact": "MITM attacks, session hijacking via HTTP downgrade"},
|
||||
"Content-Security-Policy": {"severity": "high", "impact": "XSS attacks, script injection, data theft"},
|
||||
"X-Frame-Options": {"severity": "medium", "impact": "Clickjacking attacks via invisible iframes"},
|
||||
"X-Content-Type-Options": {"severity": "medium", "impact": "MIME type confusion, content injection"},
|
||||
"Referrer-Policy": {"severity": "low", "impact": "URL parameter leakage to third parties"},
|
||||
"Permissions-Policy": {"severity": "low", "impact": "Unrestricted browser API access (camera, mic, location)"},
|
||||
"X-XSS-Protection": {"severity": "info", "impact": "Legacy XSS filter not configured"},
|
||||
}
|
||||
|
||||
# Paths to check for exposed sensitive files/directories
|
||||
EXPOSED_PATHS = [
|
||||
("/.env", "Environment file (database passwords, API keys)", "critical"),
|
||||
("/.git/config", "Git repository (full source code)", "critical"),
|
||||
("/.git/HEAD", "Git repository HEAD", "critical"),
|
||||
("/.htpasswd", "Password file", "critical"),
|
||||
("/wp-admin/", "WordPress admin panel", "high"),
|
||||
("/wp-login.php", "WordPress login page", "high"),
|
||||
("/administrator/", "Joomla admin panel", "high"),
|
||||
("/admin/", "Admin panel", "high"),
|
||||
("/admin/login", "Admin login page", "high"),
|
||||
("/phpmyadmin/", "phpMyAdmin (database manager)", "high"),
|
||||
("/backup/", "Backup directory", "high"),
|
||||
("/backup.zip", "Backup archive", "high"),
|
||||
("/backup.sql", "Database backup", "high"),
|
||||
("/db.sql", "Database dump", "high"),
|
||||
("/dump.sql", "Database dump", "high"),
|
||||
("/.htaccess", "Server configuration", "medium"),
|
||||
("/web.config", "IIS configuration", "medium"),
|
||||
("/server-status", "Apache server status", "medium"),
|
||||
("/server-info", "Apache server info", "medium"),
|
||||
("/info.php", "PHP info page", "medium"),
|
||||
("/phpinfo.php", "PHP info page", "medium"),
|
||||
("/graphql", "GraphQL endpoint", "medium"),
|
||||
("/debug/", "Debug endpoint", "medium"),
|
||||
("/elmah.axd", ".NET error log", "medium"),
|
||||
("/trace.axd", ".NET trace log", "medium"),
|
||||
("/readme.html", "CMS readme (reveals version)", "low"),
|
||||
("/license.txt", "CMS license (reveals version)", "low"),
|
||||
("/CHANGELOG.md", "Changelog (reveals version)", "low"),
|
||||
("/robots.txt", "Robots file", "info"),
|
||||
("/.well-known/security.txt", "Security contact file", "info"),
|
||||
("/sitemap.xml", "Sitemap", "info"),
|
||||
("/crossdomain.xml", "Flash cross-domain policy", "low"),
|
||||
("/api/", "API endpoint", "info"),
|
||||
]
|
||||
|
||||
# Paths that are admin panels (separate severity logic)
|
||||
ADMIN_PATHS = {"/wp-admin/", "/wp-login.php", "/administrator/", "/admin/", "/admin/login"}
|
||||
|
||||
# Robots.txt disallow patterns that may reveal sensitive areas
|
||||
ROBOTS_SENSITIVE_PATTERNS = [
|
||||
"admin", "backup", "private", "secret", "staging",
|
||||
"test", "dev", "internal", "api", "config",
|
||||
"database", "panel", "dashboard", "login", "cgi-bin",
|
||||
]
|
||||
Reference in New Issue
Block a user