Tietoturva
Tietoturvamallimme yhdessä lauseessa: palvelimella ei ole mitään hyökkättävää. Kaiken alla olevan voi falsifioida DevTools-työkalullasi.
Arkkitehtuuri
Abundera QR on staattinen yhden sivun sovellus, jota tarjoillaan Cloudflare Pages -palvelusta. Ei ole sovelluspalvelinta, tietokantaa, käyttäjätilejä, todennusta, API-päätepisteitä eikä taustajärjestelmän koodipolkua, joka käsittelisi käyttäjätietoja. Kaikki QR-koodin luomis-, koodaus-, skannaus- ja renderöintitoiminnot suoritetaan kokonaan selaimessasi.
Uhkamalli
Koska emme kerää, tallenna tai siirrä käyttäjätietoja, yleisimmät web-sovellusten uhat — tunnistetietojen varastaminen, tietokantamurto, istunnon kaappaaminen, palvelinpuolen injektio — eivät koske meitä. Jäljelle jäävä hyökkäyspinta on staattinen resurssipaketti (HTML, CSS, JavaScript), jota tarjoillaan lähteestämme. Suunnittelemme olettaen:
- Lähteen vaarantuminen: hyökkääjä korvaa jonkin pakatuista resursseistamme haitallisella. Alla oleva CSP rajoittaa vahingon laajuutta; cache-buster-tunnisteet tekevät paluun tunnetusti hyvään versioon helpoksi.
- Käyttäjän syöttämä tieto: QR-hyötykuormat, vCard-nimet, WiFi-salasanat, erä-CSV-rivit, skannattujen kuvien sisällöt. Kaikkia syöttöpolkuja käsitellään epäluotettavina, kun ne renderöidään takaisin DOM:iin.
- Käyttäjän toimittamat kuvat: vCard-kuva-URL:t ja logon lataukset. Kuvat renderöidään canvakseen, eivät koskaan sisällytetä DOM:iin raakana merkintäkielenä.
- Kolmannen osapuolen selainlaajennukset: soveltamisalan ulkopuolella. Jos selaimesi laajennuksella on lupa muokata kaikkia sivuja, se voi muokata oursämme. Takuumme ovat voimassa, kun sivu ladataan muuttumattomana.
Content Security Policy — direktiiveittäin
Nykyinen käytäntö (tarkista vastausotsakkeista minkä tahansa pyynnön osalta):
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'Mitä kukin direktiivi sallii meidän tehdä ja missä se tekee myönnytyksiä:
default-src 'self'— kova lattia. Kaikki, mitä emme eksplisiittisesti lievennä, pysyy same-origin-rajoituksen piirissä.script-src 'self' 'wasm-unsafe-eval'— ei inline-<script>:iä, eieval():ia.'wasm-unsafe-eval'tarvitaan QR-koodauskirjastomme WebAssembly-käännöspolkua varten; se EI salli perinteistäeval():ia. Oma pre-deploy-tarkistuksemme skannaa kaikki HTML-sivut inline-skriptien varalta ja hylkää buildin.style-src 'self' 'unsafe-inline'— todellinen myönnytys. QR-esikatselu laskee pikseli tason värit inline-tyyleinä (style-attribuutit yksittäisissä moduuleissa). Hash-pohjainen sallittujen lista toimisi, mutta epäonnistuisi jokaisen tyylimuutoksen yhteydessä ilman deployta. Kompromissi: hyväksymme hieman heikomman tyylipolitiikan; tyylittely ei kuitenkaan voi suodattaa tietoja ulos (CSS:llä ei oleconnect-src-ulottuvuutta).img-src 'self' data: blob: https:—data:inline-QR-renderöinneille,blob:vientilatauksien URL:ille,https:käyttäjän toimittamille vCard-kuva-URL:ille. Käyttäjän toimittamia URL:ja ei koskaan suoriteta, ne vain renderöidään.connect-src 'self' https:— fetch() on rajoitettu lähteemme sekä käyttäjän aloittamiin HTTPS-hakuihin (esim. kuva-URL:n skannaus). Estää tietojen suodattamisen DNS:n / WebSocketin / beaconin kautta mielivaltaisiin isäntiin.frame-ancestors 'none'— mikään muu sivu ei voi upottaa meitä. Estää clickjackingin.base-uri 'self'— haitallisesti injektoitu<base>-tunniste ei voi ohjata suhteellisia URL:ja hyökkääjän lähteeseen.form-action 'self'— mikä tahansa injektoitu lomake voi lähettää vain lähteemme takaisin. Meillä ei ole lomakkeita, jotka lähettävät tietoja palvelinpuolelle; tämä on lisäsuoja.
Eri CSP-käytännöt koskevat /bio/*-polkua (lievennetty img-src käyttäjän toimittamille avatarille) ja /embed/*-polkua (lievennetty frame-ancestors tarkoituksellista upotusta varten). Molemmat on dokumentoitu tiedostossa site/_headers.
Liikenne + kehystys-otsakkeet
- HSTS:
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload— 1 vuosi, kaikki aliverkkotunnukset, oikeutettu HSTS-esilatauslistalle. Yhdenmukaiset selaimet kieltäytyvät alentamasta HTTP:hen. - X-Frame-Options: DENY — redundantti CSP
frame-ancestors:n kanssa, säilytetty vanhempien selainten tukea varten. - X-Content-Type-Options: nosniff — estää MIME-sekaannushyökkäykset.
- Referrer-Policy: strict-origin-when-cross-origin — lähtevät linkkiklikkaukset paljastavat lähteen mutta eivät polun.
- Permissions-Policy:
camera=(self), microphone=(), geolocation=()— kamera sallittu vain omalle skannerille; mikrofoni ja sijainti eksplisiittisesti kielletty, vaikka upotettu.
Service worker
Service workerimme (site/sw.js) tallentaa välimuistiin vain same-origin-resursseja. Fetch-käsittelijä hylkää eksplisiittisesti cross-origin-pyynnöt ja muut kuin GET-metodit — voit lukea logiikan GitHubissa. Välimuistikirjoitukset on kääritty event.waitUntil():iin, jotta niitä ei voi keskeyttää kesken navigoinnin.
Syötteen sanitointi
Kaikki käyttäjän syötteen hyväksyvät renderöintipolut käsittelevät sen epäluotettavana tekstinä:
- QR-hyötykuorman esikatselut käyttävät
textContent:ia, eivätinnerHTML:ää. - Jakamiskohteet (leikepöytä,
navigator.share()) välittävät käyttäjätekstin merkkijonona, ei koskaan merkintäkielenä. - SVG-viennit generoidaan koodauskirjastostamme; käyttäjäsisältö on base64-koodattu
<image>xlink:href:iin, ei injektoitu SVG-elementteinä. - Tulostusesikatselut käyttävät blob-URL:a, eivät
document.write():ia. - localStorage-jäsennys on kääritty
try/catch:iin — vioittunut merkintä tuottaa tuoreen tyhjän oletuksen, ei koskaan poikkeusta, joka voisi kulkeutua aktiiviseen koodipolkuun. - Käyttäjän toimittamat URL:t, jotka näytetään "Avaa linkki"-painikkeina, on rajoitettu
http(s)://-muotoon —javascript:- jadata:-skeemat hylätään.
Cross-origin-kuvien hakeminen
Kun käyttäjä liittää https:-URL:n vCard-kuvana tai logona, selain hakee sen CORSin ja CSP:n img-src-sallittujen listan alaisena. Kuva renderöidään canvakseen. Se ei koskaan muutu eläväksi DOM:iksi, ei koskaan suorita koodina eikä koskaan saavuta lähdettämme — haku on selain → etäkuva, ja tulos maalataan asiakaspuolella. Hyökkääjä, joka hallitsee etäkuva-URL:a, voi seurata, että URL ladattiin (lokimerkintä heidän omalla palvelimellaan), mutta ei voi suodattaa mitään sivultamme.
Subresource Integrity (SRI)
Kaikki toimittamamme JavaScript ja CSS on same-origin. Emme lataa kolmannen osapuolen skriptejä tai tyylitaulukoita, joten SRI-hashit eivät ole sovellettavissa. Jos koskaan lataamme kolmannen osapuolen resurssin, lisäämme siihen SRI integrity-attribuutin ja dokumentoimme hash-päivitysprosessin tällä sivulla.
Haavoittuvuuden ilmoittaminen
Jos löydät Abundera QR:ään vaikuttavan tietoturvaongelman — olipa se koodissamme, käyttöönotossamme tai toimittamassamme riippuvuudessa — ilmoita siitä yksityisesti osoitteeseen security@abundera.ai. Tavoitteemme on luokitella ongelma 72 tunnin sisällä. Voit myös ottaa meihin yhteyttä tiedostossa /.well-known/security.txt olevien yhteystietojen kautta.
Ei bug bounty -ohjelmaa (vielä)
Emme tällä hetkellä tarjoa maksullisia palkkioita, mutta jokainen vahvistettu pätevä raportti saa maininnan muutoslokissa ja julkisen kiitoksemme.
Tarkista kaikki yllä oleva
Jokaisen tällä sivulla esitetyn väitteen voi falsifioida selaimesi DevTools-työkalulla ilman, että sinun tarvitsee luottaa meihin:
- CSP: DevTools → Verkko →
/→ Otsakkeet. LueContent-Security-Policy-vastausotsake. - HSTS + tietoturva-otsakkeet: sama paikka — kaikki
Strict-Transport-Security,X-Frame-Optionsjne. ovat näkyvissä. - Ei lähtevä kutsuja: DevTools → Verkko → Fetch/XHR. Luo QR-koodi. Katso määrän pysyvän nollana.
- Service workerin laajuus: DevTools → Sovellus → Service Workers. Tarkista skriptin lähde ja välimuistissa oleva resurssien luettelo.
- Ei evästeitä: DevTools → Sovellus → Cookies. Tyhjä.
- Täydellinen läpikäynti: manifestin vahvistusosio.
Yhteystiedot
Tietoturvan paljastukset: security@abundera.ai