Sicherheit
Unser Sicherheitsmodell in einem Satz: Es gibt nichts auf einem Server, das angegriffen werden könnte. Alles Folgende ist über Ihre DevTools nachprüfbar.
Architektur
Abundera QR ist eine statische Single-Page-Anwendung, die von Cloudflare Pages bereitgestellt wird. Es gibt keinen Anwendungsserver, keine Datenbank, keine Benutzerkonten, keine Authentifizierung, keine API-Endpunkte und keinen Backend-Code-Pfad, der Benutzerdaten verarbeitet. Jede QR-Generierungs-, Kodierungs-, Scan- und Rendering-Operation läuft vollständig in Ihrem Browser.
Bedrohungsmodell
Da wir keine Benutzerdaten erfassen, speichern oder übertragen, gelten die häufigsten Web-App-Bedrohungen — Credential-Diebstahl, Datenbankeinbruch, Session-Hijacking, serverseitige Injection — nicht. Die verbleibende Angriffsfläche ist das statische Asset-Bundle (HTML, CSS, JavaScript), das von unserem Ursprung bereitgestellt wird. Wir entwickeln unter der Annahme:
- Kompromittierung des Ursprungs: Ein Angreifer ersetzt eines unserer gebündelten Assets durch ein bösartiges. Die unten beschriebene CSP begrenzt den Explosionsradius; Cache-Buster-Token erleichtern den Rollback auf eine bekannte gute Version.
- Benutzereingaben: QR-Payloads, vCard-Namen, WLAN-Passwörter, CSV-Zeilen im Batch-Betrieb, gescannte Bildinhalte. Jeder Eingabepfad wird als nicht vertrauenswürdig behandelt, wenn er wieder im DOM gerendert wird.
- Vom Benutzer bereitgestellte Bilder: vCard-Foto-URLs und Logo-Uploads. Bilder werden in ein Canvas gerendert, nie als rohes Markup in das DOM eingebettet.
- Browser-Erweiterungen von Drittanbietern: außerhalb des Geltungsbereichs. Wenn eine Erweiterung in Ihrem Browser die Berechtigung hat, jede Seite zu modifizieren, kann sie auch unsere modifizieren. Unsere Garantien gelten, wenn die Seite unverändert geladen wird.
Content Security Policy — nach Direktive
Die aktuelle Richtlinie (prüfen Sie die Antwort-Header bei jeder Anfrage):
Content-Security-Policy:
default-src 'self';
script-src 'self' 'wasm-unsafe-eval';
worker-src 'self' blob:;
style-src 'self' 'unsafe-inline';
font-src 'self';
img-src 'self' data: blob: https:;
connect-src 'self' https:;
frame-ancestors 'none';
base-uri 'self';
form-action 'self'Was jede Direktive uns erlaubt zu tun und wo sie Kompromisse eingeht:
default-src 'self'— der harte Boden. Alles, was wir nicht explizit lockern, bleibt same-origin.script-src 'self' 'wasm-unsafe-eval'— kein inline<script>, keineval().'wasm-unsafe-eval'wird durch den WebAssembly-Kompilierungspfad unserer QR-Encoder-Bibliothek benötigt; es erlaubt NICHT traditionelleseval(). Unsere eigene Pre-Deploy-Prüfung scannt jede HTML-Seite nach Inline-Skripten und bricht den Build ab.style-src 'self' 'unsafe-inline'— ein echtes Zugeständnis. Unsere QR-Vorschau berechnet Farben auf Pixelebene inline (Style-Attribute auf einzelnen Modulen). Eine Hash-basierte Allowlist würde funktionieren, würde aber bei jeder Style-Aktualisierung ohne Deploy fehlschlagen. Kompromiss: Wir akzeptieren die leicht schwächere Style-Richtlinie; Styling kann ohnehin keine Daten exfiltrieren (CSS hat keineconnect-src-Reichweite).img-src 'self' data: blob: https:—data:für inline QR-Renderings,blob:für Export-Download-URLs,https:für vom Benutzer bereitgestellte vCard-Foto-URLs. Vom Benutzer bereitgestellte URLs werden nie ausgeführt, nur gerendert.connect-src 'self' https:— fetch() ist auf unseren Ursprung plus vom Benutzer initiierte HTTPS-Anfragen beschränkt (z. B. Scannen einer Foto-URL). Verhindert Exfiltration über DNS / WebSocket / Beacon an beliebige Hosts.frame-ancestors 'none'— keine andere Website kann uns einbetten. Verhindert Clickjacking.base-uri 'self'— ein bösartig injiziertes<base>-Tag kann relative URLs nicht zum Ursprung eines Angreifers umleiten.form-action 'self'— jedes injizierte Formular kann nur an unseren Ursprung posten. Wir haben keine Formulare, die Daten serverseitig senden; dies ist eine zusätzliche Sicherheitsmaßnahme.
Für /bio/* (gelockertes img-src für vom Benutzer bereitgestellte Avatare) und /embed/* (gelockertes frame-ancestors für absichtliches Einbetten) gelten andere CSP-Richtlinien. Beide sind in site/_headers dokumentiert.
Transport- und Framing-Header
- HSTS:
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload— 1 Jahr, alle Subdomains, berechtigt für die HSTS-Preload-Liste. Downgrades auf HTTP werden von konformen Browsern abgelehnt. - X-Frame-Options: DENY — redundant mit CSP
frame-ancestors, wird für ältere Browser-Abdeckung beibehalten. - X-Content-Type-Options: nosniff — verhindert MIME-Verwechslungsangriffe.
- Referrer-Policy: strict-origin-when-cross-origin — ausgehende Link-Klicks geben den Ursprung, aber nicht den Pfad preis.
- Permissions-Policy:
camera=(self), microphone=(), geolocation=()— Kamera nur für unseren eigenen Scanner erlaubt; Mikrofon und Standort explizit verweigert, auch wenn eingebettet.
Service Worker
Unser Service Worker (site/sw.js) cached nur same-origin Assets. Der fetch-Handler lehnt Cross-Origin-Anfragen und Nicht-GET-Methoden explizit ab — Sie können die Logik auf GitHub lesen. Cache-Schreibvorgänge sind in event.waitUntil() eingebettet, damit sie nicht mitten in einer Navigation verworfen werden können.
Eingabe-Sanitisierung
Jeder Rendering-Pfad, der Benutzereingaben akzeptiert, behandelt sie als nicht vertrauenswürdigen Text:
- QR-Payload-Vorschauen verwenden
textContent, nichtinnerHTML. - Share-Ziele (Zwischenablage,
navigator.share()) übergeben Benutzertext als String, nie als Markup. - SVG-Exporte werden von unserer Encoder-Bibliothek generiert; Benutzerinhalte werden base64-kodiert in
<image>xlink:href, nicht als SVG-Elemente injiziert. - Druckvorschauen verwenden eine Blob-URL, nicht
document.write(). - localStorage-Parsing ist in
try/catcheingebettet — ein korrupter Eintrag ergibt einen frischen leeren Standard, nie eine Ausnahme, die sich in einen aktiven Code-Pfad entfalten könnte. - Vom Benutzer bereitgestellte URLs, die als "Link öffnen"-Schaltflächen angezeigt werden, sind auf
http(s)://beschränkt —javascript:- unddata:-Schemata werden abgelehnt.
Cross-Origin-Bildabruf
Wenn ein Benutzer eine https:-URL als vCard-Foto oder Logo einfügt, ruft der Browser sie gemäß CORS und der img-src-Allowlist unserer CSP ab. Das Bild wird in ein Canvas gerendert. Es wird nie zu aktivem DOM, wird nie als Code ausgeführt und erreicht nie unseren Ursprung — der Abruf erfolgt Browser → Remote-Bild, und das Ergebnis wird clientseitig gerendert. Ein Angreifer, der eine Remote-Bild-URL kontrolliert, kann nachverfolgen, dass die URL geladen wurde (eine Log-Zeile auf seinem eigenen Server), kann aber nichts von unserer Seite exfiltrieren.
Subresource Integrity (SRI)
Alles JavaScript und CSS, das wir ausliefern, ist same-origin. Wir laden keine Skripte oder Stylesheets von Drittanbietern, daher sind SRI-Hashes nicht anwendbar. Wenn wir jemals ein Drittanbieter-Asset laden, werden wir ein SRI-integrity-Attribut daran anbringen und den Hash-Aktualisierungsprozess auf dieser Seite dokumentieren.
Eine Schwachstelle melden
Wenn Sie ein Sicherheitsproblem entdecken, das Abundera QR betrifft — sei es in unserem Code, unserer Bereitstellung oder einer Abhängigkeit, die wir ausliefern — melden Sie es bitte vertraulich an security@abundera.ai. Wir streben eine Triage innerhalb von 72 Stunden an. Sie können uns auch über die Kontaktdaten in unserer /.well-known/security.txt-Datei erreichen.
Kein Bug-Bounty-Programm (noch nicht)
Wir bieten derzeit keine bezahlten Prämien an, aber jeder bestätigte gültige Bericht erhält eine Erwähnung im Changelog und unseren öffentlichen Dank.
Überprüfen Sie das oben Genannte
Jede Behauptung auf dieser Seite ist über die DevTools Ihres Browsers falsifizierbar, ohne uns vertrauen zu müssen:
- CSP: DevTools → Netzwerk →
/→ Header. Lesen Sie denContent-Security-Policy-Antwort-Header. - HSTS + Sicherheits-Header: gleicher Ort — alle
Strict-Transport-Security,X-Frame-Optionsusw. sind sichtbar. - Keine ausgehenden Aufrufe: DevTools → Netzwerk → Fetch/XHR. Generieren Sie einen QR-Code. Beobachten Sie, wie die Anzahl bei null bleibt.
- Service-Worker-Scope: DevTools → Anwendung → Service Workers. Überprüfen Sie die Skriptquelle und die Liste der gecachten Assets.
- Keine Cookies: DevTools → Anwendung → Cookies. Leer.
- Vollständige Anleitung: der Verifizierungsabschnitt des Manifests.
Kontakt
Sicherheitsmeldungen: security@abundera.ai