fix: Bugfixes, toten Code entfernt, Cache-Normalisierung & Session

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>
This commit is contained in:
Your Name 2026-06-12 03:20:32 +02:00
commit 68243a97b9
13 changed files with 323 additions and 153 deletions

View file

@ -79,6 +79,15 @@ class TestDiffLinkSet:
result = diff_link_set(links, links)
assert result == {"added": [], "removed": []}
def test_truly_new_url_detected(self):
# Cache-buster stripping happens at extraction time; diff_link_set is a
# plain set comparison on already-normalised URLs.
old = [{"url": "https://example.com/style.css"}]
new = [{"url": "https://example.com/style.css"},
{"url": "https://example.com/extra.js"}]
result = diff_link_set(old, new)
assert "https://example.com/extra.js" in result["added"]
class TestDiffMetadata:
def test_detects_title_change(self):
@ -153,6 +162,59 @@ class TestCompareSnapshots:
assert "spam.example.com" in result["new_external_domains"]
class TestUnexpectedJsonLd:
CFG = {**BASE_CFG, "allowed_jsonld_types": ["Organization", "WebPage"]}
def _page(self, url, jsonld):
return {
"url": url, "status": 200, "text": "Inhalt",
"links": {"a": [], "script": [], "iframe": [], "link_rel": [], "form": [], "meta_refresh": [], "canonical": None},
"metadata": {"title": "T", "h1": [], "h2": []},
"hidden_content": [], "inline_scripts": [], "jsonld": jsonld, "comment_links": [],
}
def test_unexpected_type_flagged_without_page_diff(self):
# Page is otherwise unchanged (same text/links) but carries a bad @type.
base = {"https://b.info/": self._page("https://b.info/", [{"type": "Organization"}])}
cur = {"https://b.info/": self._page("https://b.info/", [{"type": "Pharmacy"}])}
result = compare_snapshots(base, cur, self.CFG)
types = [e["type"] for e in result["unexpected_jsonld"]]
assert "Pharmacy" in types
def test_allowed_type_not_flagged(self):
base = {"https://b.info/": self._page("https://b.info/", [])}
cur = {"https://b.info/": self._page("https://b.info/", [{"type": "WebPage"}])}
result = compare_snapshots(base, cur, self.CFG)
assert result["unexpected_jsonld"] == []
def test_preexisting_unexpected_type_not_realerted(self):
# Bad type already in baseline → approved → should not re-alert.
base = {"https://b.info/": self._page("https://b.info/", [{"type": "Pharmacy"}])}
cur = {"https://b.info/": self._page("https://b.info/", [{"type": "Pharmacy"}])}
result = compare_snapshots(base, cur, self.CFG)
assert result["unexpected_jsonld"] == []
def test_unexpected_type_scores(self):
result = score_diff({
"new_internal_urls": [], "missing_internal_urls": [],
"new_external_domains": [], "page_diffs": [], "new_pages_analysis": [],
"unexpected_jsonld": [{"url": "https://b.info/", "type": "Pharmacy"}],
}, BASE_CFG)
assert result["score"] == 35
assert result["level"] == "yellow"
class TestSuspiciousFilenames:
def test_suspicious_filename_scores_red(self):
result = score_diff({
"new_internal_urls": [], "missing_internal_urls": [],
"new_external_domains": [], "page_diffs": [], "new_pages_analysis": [],
"suspicious_filenames": [{"page": "https://b.info/", "url": "https://b.info/shell.php"}],
}, BASE_CFG)
assert result["score"] == 60
assert result["level"] == "red"
class TestBrokenLinks:
def _make_page(self, url, text="Inhalt", status=200):
return {