Sikkerhet
Sikkerhetsmodellen vår i én setning: det er ingenting på en server å angripe. Alt nedenfor kan falsifiseres fra dine DevTools.
Arkitektur
Generatoren er en statisk enkeltsideapplikasjon som betjenes fra Cloudflare Pages: ingen brukerkontoer, ingen autentisering, og ingen backend-kodesti noe sted i genereringsflyten. Alle QR-genererings-, kodnings-, skannings- og renderingsoperasjoner kjører utelukkende i nettleseren din. Ett lite serverløst endepunkt finnes ved siden av og listes her i stedet for å skjules: /api/contact (kontaktskjemaet, som lagrer det du sender inn i Cloudflare D1 og sender det til oss på e-post). Det kalles ikke mens du lager en QR-kode; URL-sikkerhetssjekkeren er et separat produkt på check.qr.abundera.ai. Sjekk om en QR-kode er trygg
Trusselmodell
Fordi generatoren ikke samler inn, lagrer eller overfører brukerdata (de to endepunktene ovenfor håndterer bare det du eksplisitt sender dem), gjelder ikke de vanligste web-app-truslene — tyveri av legitimasjon, databasebrudd, sesjonskapring, server-side-injeksjon — for den. Den gjenværende angrepsflaten er den statiske ressurspakken (HTML, CSS, JavaScript) som betjenes fra vår opprinnelse. Vi designer med forutsetning om:
- Kompromittering av opprinnelsen: en angriper erstatter en av våre medfølgende ressurser med en ondsinnet. CSP nedenfor begrenser skadeomfanget; cache-buster-tokens gjør det enkelt å rulle tilbake til en kjent god versjon.
- Brukerlevert input: QR-nyttelaster, vCard-navn, WiFi-passord, batch-CSV-rader, skannede bildeinnhold. Alle inputstier behandles som upålitelige når de gjengis tilbake til DOM-en.
- Brukerleverte bilder: vCard-foto-URL-er og logo-opplastinger. Bilder gjengis til et canvas, aldri innebygd i DOM-en som rå markup.
- Tredjeparts nettleserutvidelser: utenfor scope. Hvis en utvidelse i nettleseren din har tillatelse til å endre alle sider, kan den endre vår. Garantiene våre gjelder når siden lastes inn uendret.
Content Security Policy — per direktiv
Policyen nedenfor leses fra den utrullede _headers-filen når denne siden bygges, så den kan ikke skli fra det som faktisk sendes fra edgen. Verifiser den i svarheaderne for enhver forespørsel.
Content-Security-Policy:
default-src 'self';
script-src 'self' https://abundera.ai 'wasm-unsafe-eval' https://challenges.cloudflare.com;
worker-src 'self' blob:;
style-src 'self' 'unsafe-inline' https://abundera.ai;
font-src 'self';
img-src 'self' data: blob: https:;
connect-src 'self' https: https://challenges.cloudflare.com;
frame-src 'self' https://challenges.cloudflare.com;
frame-ancestors 'none';
base-uri 'self';
form-action 'self'Hva hvert direktiv lar oss gjøre og hvor det kompromitterer:
default-src 'self'— det harde gulvet. Alt vi ikke eksplisitt lemper på, forblir same-origin.script-src 'self' https://abundera.ai 'wasm-unsafe-eval' https://challenges.cloudflare.com— ingen inline<script>, ingeneval().abundera.aier vårt eget overordnede domene og leverer ett delt skript, språkvelgeren.challenges.cloudflare.comer Turnstile-widgeten som bare brukes på /contact/.'wasm-unsafe-eval'er nødvendig for QR-enkodningsbiblioteketts WebAssembly-kompileringssti; det tillater IKKE tradisjonelleval(). Vår egen pre-deploy-sjekk skanner alle HTML-sider for inline-skript og feiler bygget.style-src 'self' 'unsafe-inline'— en reell innrømmelse. QR-forhåndsvisningen vår beregner farger på pikselnivå inline (style-attributter på individuelle moduler). En hash-basert tillatelseliste ville fungert, men ville feile ved enhver stiloppdatering uten en deploy. Avveiing: vi aksepterer den litt svakere stilpolicyen; styling kan uansett ikke eksfiltrere data (CSS har ingenconnect-src-rekkevidde).img-src 'self' data: blob: https:—data:for inline QR-gjengivelser,blob:for eksport-nedlastings-URL-er,https:for brukerleverte vCard-foto- og avatar-URL-er. Brukerleverte URL-er kjøres aldri, de gjengis bare. Vær oppmerksom på at dette direktivet også er en utgående kanal: et hvilket som helst skript som kjører på siden, kunne be om et bilde fra en hvilken som helst HTTPS-vert og legge data i URL-en. Vi aksepterer det fordi funksjonen trenger det, og vi sier det her i stedet for å beskrive policyen som vanntett.connect-src 'self' https: https://challenges.cloudflare.com— den du bør lese nøye.https:er en skjemakilde: den larfetch(), XMLHttpRequest, WebSocket over TLS, EventSource ogsendBeacon()nå hvilken som helst HTTPS-opprinnelse, ikke bare de du skrev inn selv. Den er der slik at vCard-fotofeltet og URL-sikkerhetssjekken kan hente en adresse du limte inn. Den forhindrer ikke eksfiltrering fra et ondsinnet skript — det gjør ingen CSP-direktiv når skriptet allerede kjører som oss. Det som forhindrer eksfiltrering, er at koden vi leverer ikke gjør slike forespørsler, noe du kan følge med på i Network-fanen.frame-src 'self' https://challenges.cloudflare.com— bare Turnstile-widgeten kan rammes inn.frame-ancestors 'none'— ingen annen side kan bygge oss inn. Forhindrer clickjacking.base-uri 'self'— et ondsinnet injisert<base>-tag kan ikke omdirigere relative URL-er til en angripers opprinnelse.form-action 'self'— ethvert injisert skjema kan bare sende tilbake til vår opprinnelse. Kontaktskjemaet er det eneste skjemaet som i det hele tatt sender noe.
Hva CSP ikke kan gjøre
CSP begrenser hvor nettleseren vil laste kode fra. Den kontrollerer ikke hva den lastede koden gjør. Hvis vår opprinnelse ble kompromittert, det første punktet i trusselmodellen, ville angriperens skript kjøre med samme tillatelser som vårt eget, inkludert connect-src- og img-src-tillatelsene ovenfor. Våre forsvar mot det ligger oppstrøms for CSP: distribusjoner går ut gjennom én Cloudflare-konto med avgrensede tokens, ressursfilnavn er innholdshashet slik at en byttet fil endrer hver URL som viser til den, og service workeren cacher bare same-origin GET-svar. Manifestet beskriver nettstedet slik det er levert. Det er ikke en påstand om at ingen nettside noensinne kunne sende data et sted, og vi vil heller at du holder oss til den snevrere, kontrollerbare påstanden.
Ulike CSP-policyer gjelder for /bio/* (lempet img-src for brukerleverte avatarer) og /embed/* (lempet frame-ancestors for intensjonell innebygging). Begge er dokumentert i site/_headers.
Transport + framing-headere
- HSTS:
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload— 1 år, alle underdomener, kvalifisert for HSTS-forhåndsinnlastingslisten. Nedgraderinger til HTTP avvises av konformante nettlesere. - X-Frame-Options: DENY — redundant med CSP
frame-ancestors, beholdt for eldre nettleserstøtte. - X-Content-Type-Options: nosniff — forhindrer MIME-forvirringsa ngrep.
- Referrer-Policy: strict-origin-when-cross-origin — utgående lenkeklikk lekker opprinnelsen men ikke stien.
- Permissions-Policy:
camera=(self), microphone=(), geolocation=()— kamera tillatt kun for vår egen skanner; mikrofon og posisjon eksplisitt avvist selv om innebygd.
Service worker
Service workeren vår (site/sw.js) cacher bare same-origin-ressurser. Fetch-handleren avviser eksplisitt cross-origin-forespørsler og ikke-GET-metoder — du kan lese logikken i /sw.js (kilden leveres uminifisert nok til å følge med). Cache-skrivinger er pakket inn i event.waitUntil() slik at de ikke kan droppes midt i en navigasjon.
Input-sanitering
Alle renderingsstier som aksepterer brukerinput, behandler det som upålitelig tekst:
- QR-nyttelastforhåndsvisninger bruker
textContent, ikkeinnerHTML. - Delingsmål (utklippstavle,
navigator.share()) sender brukertekst som en streng, aldri som markup. - SVG-eksporter genereres fra enkodningsbiblioteket vårt; brukerinnhold er base64-kodet inn i
<image>xlink:href, ikke injisert som SVG-elementer. - Utskriftsforhåndsvisninger bruker en blob-URL, ikke
document.write(). - localStorage-parsing er pakket inn i
try/catch— en korrupt oppføring gir en frisk tom standard, aldri et unntak som kunne rulle inn i en aktiv kodesti. - Brukerleverte URL-er vist som "Åpne lenke"-knapper er begrenset til
http(s)://—javascript:- ogdata:-skjemaer avvises.
Cross-origin bildehenging
Når en bruker limer inn en https:-URL som et vCard-foto eller logo, henter nettleseren det underlagt CORS og vår CSPs img-src-tillatelsesliste. Bildet gjengis til et canvas. Det blir aldri levende DOM, kjører aldri som kode, og når aldri vår opprinnelse — hentingen er nettleser → eksternt bilde, og resultatet males klientsiden. En angriper som kontrollerer en ekstern bilde-URL kan spore at URL-en ble lastet (en loggpost på deres egen server), men kan ikke eksfiltrere noe fra siden vår.
Subresource Integrity (SRI)
All JavaScript og CSS vi leverer er same-origin. Vi laster ikke inn tredjeparts skript eller stilark, så SRI-hasher er ikke relevante. Hvis vi noen gang laster inn en tredjeparts ressurs, legger vi ved en SRI integrity-attributt og dokumenterer hash-oppdateringsprosessen på denne siden.
Rapportere en sårbarhet
Hvis du oppdager et sikkerhetsproblem som påvirker Abundera QR — enten i koden vår, vår distribusjon eller i en avhengighet vi leverer — vennligst rapporter det privat til security@abundera.ai. Vi sikter mot å triagere innen 72 timer. Du kan også nå oss via kontaktdetaljene i vår /.well-known/security.txt-fil.
Ingen bug-bounty (ennå)
Vi tilbyr for øyeblikket ikke betalte bounties, men hver bekreftet gyldig rapport får kredit i endringsloggen og vår offentlige takk.
Verifiser alt ovenfor
Hvert krav på denne siden kan falsifiseres fra nettleserens DevTools uten å stole på oss:
- CSP: DevTools → Nettverk →
/→ Headere. LesContent-Security-Policy-svarheaderen. - HSTS + sikkerhedsheadere: samme sted — alle
Strict-Transport-Security,X-Frame-Optionsosv. er synlige. - Ingen utgående kall: DevTools → Nettverk → Fetch/XHR. Generer en QR. Se antallet forbli null.
- Service worker-scope: DevTools → Applikasjon → Service Workers. Verifiser skriptkilden og den cachede ressurslisten.
- Ingen informasjonskapsler: DevTools → Applikasjon → Cookies. Tom.
- Fullstendig gjennomgang: manifestets verifikasjonsseksjon.
Kontakt
Sikkerhetsrapporter: security@abundera.ai