Echte Bugs: - extractor: JSON-LD-Crash bei Nicht-Dict-Items (isinstance-Guard) - baseline/__main__: Crawl-Fehler ins Snapshot-Manifest -> erscheinen im Report - __main__: Whitelist-/Header-/Webshell-Checks nur noch auf status==200 - crawler: Noise-Param-Regex auf Voll-Key (view=/value= nicht mehr verworfen) - differ/__main__: unerwartetes JSON-LD via eigenem Kanal, auch auf unveraenderten Seiten erkannt, kein Re-Alert auf bereits genehmigte Typen Aufgeraeumt: - checker: check_internal_paths, find_broken_pages, canonical_is_hijacked, check_jsonld_types entfernt (nicht verdrahtet) - allowed_paths.yaml-Logik und tote Scoring-Keys entfernt - tote Imports entfernt Neuer aktiver Schutz: - Webshell-/Backdoor-Dateinamen-Check verdrahtet (suspicious_filename: 60). Regex wortgrenzen-verankert gegen Fehlalarm auf PSEMailerAntispam.js Effizienz/Struktur: - crawler nutzt requests.Session (keep-alive) - Cache-Buster-Normalisierung an einer Stelle (Extraktion) -> stabile Snapshots, differ wieder reiner Set-Diff Tests: 111 gruen (neu: test_checker.py + Regressionstests) CLAUDE.md aktualisiert Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
63 lines
2.2 KiB
Python
63 lines
2.2 KiB
Python
"""Tests for stateless checker helpers."""
|
|
import pytest
|
|
from scanner.checker import (
|
|
check_links_against_whitelist,
|
|
check_security_headers,
|
|
is_suspicious_url,
|
|
)
|
|
|
|
|
|
class TestIsSuspiciousUrl:
|
|
@pytest.mark.parametrize("url", [
|
|
"https://b.info/uploads/shell.php",
|
|
"https://b.info/c99.php",
|
|
"https://b.info/wso.aspx",
|
|
"https://b.info/admin/backdoor.php",
|
|
"https://b.info/webshell.php",
|
|
])
|
|
def test_flags_webshell_names(self, url):
|
|
assert is_suspicious_url(url) is True
|
|
|
|
@pytest.mark.parametrize("url", [
|
|
"https://b.info/index.html",
|
|
"https://b.info/css/app.css",
|
|
"https://b.info/impressum",
|
|
"https://b.info/team/photo.jpg",
|
|
# Regression: legitimate site assets must NOT be flagged
|
|
"https://b.info/assets/js/PSEMailerAntispam.js",
|
|
"https://b.info/navigate.php",
|
|
"https://b.info/uploads/document.pdf",
|
|
])
|
|
def test_ignores_normal_names(self, url):
|
|
assert is_suspicious_url(url) is False
|
|
|
|
|
|
class TestSecurityHeaders:
|
|
def test_reports_missing(self):
|
|
present = {"Content-Type": "text/html"}
|
|
missing = check_security_headers(present, ["Content-Security-Policy", "X-Content-Type-Options"])
|
|
assert "Content-Security-Policy" in missing
|
|
|
|
def test_case_insensitive(self):
|
|
present = {"content-security-policy": "default-src 'self'"}
|
|
missing = check_security_headers(present, ["Content-Security-Policy"])
|
|
assert missing == []
|
|
|
|
|
|
class TestWhitelist:
|
|
def _page(self, ext_url):
|
|
return {
|
|
"links": {"a": [{"url": ext_url, "class": "external"}]},
|
|
"comment_links": [],
|
|
"hidden_content": [],
|
|
}
|
|
|
|
def test_flags_unlisted_domain(self):
|
|
page = self._page("https://spam.example.com/x")
|
|
violations = check_links_against_whitelist(page, set(), "b.info")
|
|
assert any(v["domain"] == "spam.example.com" for v in violations)
|
|
|
|
def test_allows_listed_domain(self):
|
|
page = self._page("https://good.example.com/x")
|
|
violations = check_links_against_whitelist(page, {"good.example.com"}, "b.info")
|
|
assert violations == []
|