feat: initial implementation of website integrity scanner
Python-Package zur unabhängigen Überwachung statischer Websites gegen SEO-Spam und unbefugte Manipulationen. Läuft außerhalb des Hosters. Kernfunktionen: - Reiner Python-Crawler (bs4+lxml), kein wget - Baseline-Management mit manuellem Freigabe-Workflow (niemals automatisch) - Text-/Link-/Meta-Diff mit Risiko-Scoring (grün/gelb/rot) - Hidden-Content-Erkennung (CSS inline, noscript, Kommentar-Links) - Whitelist für externe Domains und interne Pfade - E-Mail + Webhook Alarmierung - CLI: init, crawl, check, scan, approve, report, status - 79 Unit-Tests (pytest), alle grün Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
commit
98e8d11eb5
24 changed files with 4295 additions and 0 deletions
112
config.yaml
Normal file
112
config.yaml
Normal file
|
|
@ -0,0 +1,112 @@
|
|||
# Integrity Scanner — Hauptkonfiguration
|
||||
# Alle Werte sind optional; fehlende werden aus den Defaults übernommen.
|
||||
|
||||
target: "https://bredelar.info"
|
||||
user_agent: "integrity-scanner/1.0 (+security-monitoring)"
|
||||
request_timeout: 20
|
||||
|
||||
data_dir: "data"
|
||||
reports_dir: "reports"
|
||||
logs_dir: "logs"
|
||||
config_dir: "config"
|
||||
|
||||
crawl:
|
||||
max_pages: 200
|
||||
delay_seconds: 1.0
|
||||
respect_robots_txt: false
|
||||
skip_extensions:
|
||||
- ".jpg"
|
||||
- ".jpeg"
|
||||
- ".png"
|
||||
- ".gif"
|
||||
- ".webp"
|
||||
- ".svg"
|
||||
- ".ico"
|
||||
- ".pdf"
|
||||
- ".zip"
|
||||
- ".woff"
|
||||
- ".woff2"
|
||||
- ".ttf"
|
||||
- ".otf"
|
||||
- ".eot"
|
||||
- ".mp4"
|
||||
- ".mp3"
|
||||
- ".webm"
|
||||
- ".avi"
|
||||
- ".mov"
|
||||
|
||||
scoring:
|
||||
new_external_domain: 50
|
||||
new_internal_url: 30
|
||||
missing_internal_url: 20
|
||||
hidden_content: 40
|
||||
unexpected_canonical: 35
|
||||
meta_refresh: 40
|
||||
unexpected_jsonld: 35
|
||||
large_text_addition: 20
|
||||
new_inline_script_suspicious: 30
|
||||
missing_security_header: 5
|
||||
suspicious_content_pattern: 50
|
||||
comment_links: 25
|
||||
noscript_links: 25
|
||||
new_external_link_unlisted: 40
|
||||
|
||||
thresholds:
|
||||
yellow: 20 # ab diesem Score: Warnung (gelb)
|
||||
red: 60 # ab diesem Score: Alarm (rot)
|
||||
large_text_block_chars: 200 # Textblock ab dieser Länge wird als „groß" gewertet
|
||||
|
||||
alerting:
|
||||
min_level: "yellow" # "yellow" oder "red"
|
||||
email:
|
||||
enabled: false
|
||||
smtp_host: "localhost"
|
||||
smtp_port: 587
|
||||
smtp_tls: true
|
||||
smtp_user: ""
|
||||
smtp_password_env: "SCANNER_SMTP_PASSWORD" # Passwort aus Umgebungsvariable
|
||||
from: "scanner@bredelar.info"
|
||||
to:
|
||||
- "admin@bredelar.info"
|
||||
webhook:
|
||||
enabled: false
|
||||
url: "" # z.B. Telegram-Bot-Webhook, Slack-Incoming-Webhook
|
||||
|
||||
normalization:
|
||||
strip_html_comments: true
|
||||
collapse_whitespace: true
|
||||
# Selektoren, die vor dem Diff ignoriert werden (z.B. Datums-/Cache-Elemente)
|
||||
ignore_selectors:
|
||||
# - "#last-modified"
|
||||
# - ".timestamp"
|
||||
# Regex-Muster im Text, die vor dem Diff entfernt werden
|
||||
ignore_patterns:
|
||||
# - '\d{1,2}\.\d{1,2}\.\d{4}' # Datumsangaben
|
||||
# - 'Stand:\s+\S+'
|
||||
|
||||
# Erlaubte @type-Werte in JSON-LD (alles andere löst Alarm aus)
|
||||
allowed_jsonld_types:
|
||||
- "Organization"
|
||||
- "WebSite"
|
||||
- "WebPage"
|
||||
- "Article"
|
||||
- "BreadcrumbList"
|
||||
- "ItemList"
|
||||
- "LocalBusiness"
|
||||
- "Place"
|
||||
- "Person"
|
||||
- "Event"
|
||||
- "FAQPage"
|
||||
- "Question"
|
||||
- "Answer"
|
||||
- "ImageObject"
|
||||
- "SiteLinksSearchBox"
|
||||
- "ContactPage"
|
||||
- "AboutPage"
|
||||
|
||||
# Security-Header, die auf jeder Seite erwartet werden
|
||||
security_headers:
|
||||
- "Content-Security-Policy"
|
||||
- "Strict-Transport-Security"
|
||||
- "X-Content-Type-Options"
|
||||
- "Referrer-Policy"
|
||||
Loading…
Add table
Add a link
Reference in a new issue