"""Artikel-HTML bereinigen: nur einfache Formatierung, Links und Bilder aus den eigenen Uploads.
Bilder von fremden Servern sind nicht erlaubt: Beim Lesen würde der Browser sie dort abrufen und so
IP-Adresse und Lesezeitpunkt verraten (Tracking-Pixel). Externe Links bleiben erlaubt (erst ein Klick ruft sie auf).
"""
import re
import nh3
ALLOWED_TAGS = {"p", "br", "h2", "h3", "strong", "b", "em", "i", "u", "s", "ul", "ol", "li", "blockquote", "hr", "a", "img"}
ALLOWED_ATTRS = {"a": {"href"}, "img": {"src", "alt"}}
UPLOAD_SRC = re.compile(r"/uploads/[a-f0-9]{24}\.(?:jpg|png|gif|webp)")
def _attribute_filter(tag: str, attr: str, value: str) -> str | None:
if tag == "img" and attr == "src" and not UPLOAD_SRC.fullmatch(value):
return None
return value
def sanitize(content: str) -> str:
cleaned = nh3.clean(
content,
tags=ALLOWED_TAGS,
clean_content_tags={"script", "style"},
attributes=ALLOWED_ATTRS,
attribute_filter=_attribute_filter,
url_schemes={"http", "https", "mailto"},
link_rel="noopener noreferrer",
)
# Bilder, deren Quelle entfernt wurde, ganz weglassen
return re.sub(r"
]*\ssrc=)[^>]*>", "", cleaned).strip()