Bezpečnost
Náš bezpečnostní model v jedné větě: na serveru není nic, co by bylo možné napadnout. Vše níže lze ověřit přímo z vašich DevTools.
Architektura
Abundera QR je statická jednostránková aplikace hostovaná na Cloudflare Pages. Neexistuje žádný aplikační server, databáze, uživatelské účty, autentizace, API endpointy ani backendová kódová cesta zpracovávající uživatelská data. Každá operace generování, kódování, skenování a renderování QR probíhá výhradně ve vašem prohlížeči.
Model hrozeb
Protože neshromažďujeme, neukládáme ani nepřenášíme žádná uživatelská data, nejběžnější hrozby webových aplikací — krádež přihlašovacích údajů, únik databáze, únos relace, server-side injekce — se na nás nevztahují. Zbývající útočná plocha je statický balík prostředků (HTML, CSS, JavaScript) podávaný z našeho originu. Navrhujeme s předpokladem:
- Kompromitace originu: útočník nahradí jeden z našich zabalených prostředků škodlivým. Níže uvedená CSP omezuje dosah škod; cache-buster tokeny usnadňují návrat ke známé správné verzi.
- Uživatelský vstup: QR payloady, jména vCard, hesla WiFi, řádky dávkového CSV, obsah naskenovaných obrázků. Každá vstupní cesta je považována za nedůvěryhodnou při renderování zpět do DOM.
- Uživatelské obrázky: URL adresy fotek vCard a nahrávání log. Obrázky jsou renderovány do canvasu, nikdy vloženy do DOM jako surové markup.
- Rozšíření prohlížeče třetích stran: mimo rozsah. Pokud má rozšíření ve vašem prohlížeči oprávnění upravovat každou stránku, může upravit i tu naši. Naše záruky platí při načtení stránky v neupravené podobě.
Content Security Policy — podle direktiv
Aktuální politika (ověřte v hlavičkách odpovědi pro jakýkoli požadavek):
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'Co nám každá direktiva umožňuje a kde dělá kompromisy:
default-src 'self'— pevné dno. Vše, co explicitně neuvolníme, zůstane same-origin.script-src 'self' 'wasm-unsafe-eval'— žádný inline<script>, žádnýeval().'wasm-unsafe-eval'je potřebný pro cestu kompilace WebAssembly naší knihovny QR enkodéru; NEPOVOLUJE tradičníeval(). Naše pre-deploy kontrola prohledá každou HTML stránku na inline skripty a selže sestavení.style-src 'self' 'unsafe-inline'— skutečná ústupek. Náš náhled QR vypočítává barvy na úrovni pixelů inline (atributy style na jednotlivých modulech). Seznam povolených na základě hashů by fungoval, ale selhal by při jakékoli aktualizaci stylu bez nasazení. Kompromis: přijímáme o něco slabší politiku stylování; styly nemohou stejně exfiltrovat data (CSS nemá dosahconnect-src).img-src 'self' data: blob: https:—data:pro inline renderování QR,blob:pro URL pro stahování exportů,https:pro URL fotek vCard zadané uživatelem. URL zadané uživatelem se nikdy nespouštějí, pouze renderují.connect-src 'self' https:— fetch() je omezeno na náš origin a uživatelem iniciované HTTPS načítání (např. skenování URL fotky). Zabraňuje exfiltraci přes DNS/WebSocket/beacon na libovolné hostitele.frame-ancestors 'none'— žádná jiná stránka nás nemůže vložit. Zabraňuje clickjackingu.base-uri 'self'— injektovaný škodlivý tag<base>nemůže přesměrovat relativní URL na origin útočníka.form-action 'self'— injektovaný formulář může odesílat pouze zpět na náš origin. Nemáme žádné formuláře, které posílají data na server; toto je pojistka navíc.
Různé CSP politiky se vztahují na /bio/* (uvolněný img-src pro avatary zadané uživatelem) a /embed/* (uvolněný frame-ancestors pro záměrné vkládání). Obě jsou zdokumentovány v site/_headers.
Transportní a rámovací hlavičky
- HSTS:
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload— 1 rok, všechny subdomény, způsobilé pro seznam předběžného načítání HSTS. Downgrade na HTTP odmítají kompatibilní prohlížeče. - X-Frame-Options: DENY — redundantní s CSP
frame-ancestors, zachováno pro podporu starších prohlížečů. - X-Content-Type-Options: nosniff — zabraňuje útokům zmatení MIME.
- Referrer-Policy: strict-origin-when-cross-origin — kliknutí na odchozí odkaz prozradí origin, nikoli cestu.
- Permissions-Policy:
camera=(self), microphone=(), geolocation=()— kamera povolena pouze pro náš vlastní skener; mikrofon a poloha explicitně odepřeny i při vložení.
Service worker
Náš service worker (site/sw.js) ukládá do cache pouze same-origin prostředky. Obslužná rutina fetch explicitně odmítá cross-origin požadavky a metody jiné než GET — logiku si můžete přečíst na GitHubu. Zápisy do cache jsou zabaleny v event.waitUntil(), takže nemohou být zahozeny uprostřed navigace.
Sanitace vstupů
Každá renderovací cesta přijímající uživatelský vstup s ním zachází jako s nedůvěryhodným textem:
- Náhledy QR payloadů používají
textContent, nikoliinnerHTML. - Cíle sdílení (schránka,
navigator.share()) předávají uživatelský text jako řetězec, nikdy jako markup. - SVG exporty jsou generovány z naší knihovny enkodéru; uživatelský obsah je base64 zakódován do
<image>xlink:href, nevkládán jako SVG elementy. - Náhledy tisku používají blob URL, nikoli
document.write(). - Parsování localStorage je zabaleno v
try/catch— poškozená položka vrátí novou prázdnou výchozí hodnotu, nikdy výjimku, která by se mohla prosadit do živé kódové cesty. - URL zadané uživatelem zobrazené jako tlačítka "Otevřít odkaz" jsou omezeny na
http(s)://— schématajavascript:adata:jsou odmítnuta.
Načítání obrázků z jiného originu
Když uživatel vloží URL https: jako foto vCard nebo logo, prohlížeč ji načte s ohledem na CORS a seznam povolených img-src v naší CSP. Obrázek se renderuje do canvasu. Nikdy se nestane živým DOM, nikdy nespustí jako kód a nikdy nedosáhne našeho originu — načtení probíhá prohlížeč → vzdálený obrázek a výsledek je vykreslen na straně klienta. Útočník kontrolující vzdálenou URL obrázku může sledovat, že URL byla načtena (řádek záznamu na jeho vlastním serveru), ale nemůže z naší stránky nic exfiltrovat.
Subresource Integrity (SRI)
Veškerý JavaScript a CSS, který dodáváme, je same-origin. Nenačítáme skripty ani styly třetích stran, takže SRI hashe nejsou relevantní. Pokud kdy načteme prostředek třetí strany, přibalíme k němu atribut SRI integrity a zdokumentujeme proces aktualizace hashe na této stránce.
Nahlášení zranitelnosti
Pokud odhalíte bezpečnostní problém ovlivňující Abundera QR — v našem kódu, nasazení nebo závislosti, kterou dodáváme — prosím nahlaste jej soukromě na security@abundera.ai. Snažíme se provést třídění do 72 hodin. Můžete nás také kontaktovat prostřednictvím kontaktních údajů v souboru /.well-known/security.txt.
Zatím žádný bug bounty
V současnosti nenabízíme placené odměny, ale každá potvrzená platná zpráva dostane uznání v changelogu a naše veřejné poděkování.
Ověřte cokoli z výše uvedeného
Každé tvrzení na této stránce lze vyvrátit z DevTools vašeho prohlížeče bez toho, abyste nám museli důvěřovat:
- CSP: DevTools → Síť →
/→ Hlavičky. Přečtěte hlavičku odpovědiContent-Security-Policy. - HSTS + bezpečnostní hlavičky: na stejném místě — všechny
Strict-Transport-Security,X-Frame-Optionsatd. jsou viditelné. - Žádná odchozí volání: DevTools → Síť → Fetch/XHR. Vygenerujte QR. Sledujte, jak počet zůstává na nule.
- Rozsah service workeru: DevTools → Aplikace → Service Workers. Ověřte zdroj skriptu a seznam uložených prostředků.
- Žádné cookies: DevTools → Aplikace → Cookies. Prázdné.
- Úplný průvodce: sekce ověření v manifestu.
Kontakt
Bezpečnostní oznámení: security@abundera.ai