Analyze HTTP headers for security issues.
(self, target: Target)
| 27 | ] |
| 28 | |
| 29 | async def run(self, target: Target) -> ScanResult: |
| 30 | """Analyze HTTP headers for security issues.""" |
| 31 | result = self.create_result(target) |
| 32 | url = self._build_url(target) |
| 33 | self.logger.info(f"Analyzing headers for {url}") |
| 34 | |
| 35 | try: |
| 36 | async with HTTPClient() as client: |
| 37 | response = await client.get(url) |
| 38 | headers = dict(response.headers) |
| 39 | headers_lower = {k.lower(): v for k, v in headers.items()} |
| 40 | |
| 41 | result.raw_data["url"] = str(response.url) |
| 42 | result.raw_data["status_code"] = response.status_code |
| 43 | result.raw_data["headers"] = headers |
| 44 | |
| 45 | missing_headers = [] |
| 46 | present_headers = [] |
| 47 | |
| 48 | for header, info in self.SECURITY_HEADERS.items(): |
| 49 | if header in headers_lower: |
| 50 | present_headers.append({"header": info["name"], "value": headers_lower[header]}) |
| 51 | else: |
| 52 | missing_headers.append({"header": info["name"], "severity": info["severity"]}) |
| 53 | |
| 54 | if missing_headers: |
| 55 | medium_missing = [h for h in missing_headers if h["severity"] == Severity.MEDIUM] |
| 56 | if medium_missing: |
| 57 | result.add_finding( |
| 58 | title="Missing Important Security Headers", |
| 59 | description=f"Missing {len(medium_missing)} important security header(s)", |
| 60 | severity=Severity.MEDIUM, |
| 61 | data={"missing": [h["header"] for h in medium_missing]}, |
| 62 | ) |
| 63 | |
| 64 | if present_headers: |
| 65 | result.add_finding( |
| 66 | title="Security Headers Present", |
| 67 | description=f"Found {len(present_headers)} security header(s)", |
| 68 | severity=Severity.INFO, |
| 69 | data={"headers": present_headers}, |
| 70 | ) |
| 71 | |
| 72 | disclosed = [] |
| 73 | for header in self.INFO_DISCLOSURE_HEADERS: |
| 74 | if header in headers_lower: |
| 75 | disclosed.append({"header": header, "value": headers_lower[header]}) |
| 76 | |
| 77 | if disclosed: |
| 78 | result.add_finding( |
| 79 | title="Information Disclosure in Headers", |
| 80 | description=f"Found {len(disclosed)} header(s) revealing server info", |
| 81 | severity=Severity.LOW, |
| 82 | data={"headers": disclosed}, |
| 83 | ) |
| 84 | |
| 85 | except Exception as e: |
| 86 | result.errors.append(f"Failed to fetch headers: {str(e)}") |
no test coverage detected