Tietoturva
Tietoturvamallimme yhdessä lauseessa: palvelimella ei ole mitään hyökkättävää. Kaiken alla olevan voi falsifioida DevTools-työkalullasi.
Arkkitehtuuri
Generaattori on staattinen yhden sivun sovellus, jota tarjoillaan Cloudflare Pages -palvelusta: ei käyttäjätilejä, ei todennusta eikä taustajärjestelmän koodipolkua missään kohtaa generointiketjua. Kaikki QR-koodin luomis-, koodaus-, skannaus- ja renderöintitoiminnot suoritetaan kokonaan selaimessasi. Yksi pieni serveritön päätepiste on sen vieressä ja se luetellaan tässä piilottamisen sijaan: /api/contact (yhteydenottolomake, joka tallentaa lähettämäsi sisällön Cloudflare D1:een ja lähettää sen meille sähköpostitse). Sitä ei kutsuta, kun luot QR-koodia; URL-turvallisuustarkistin on erillinen tuote osoitteessa check.qr.abundera.ai. Tarkista, onko QR-koodi turvallinen
Uhkamalli
Koska generaattori ei kerää, tallenna tai siirrä käyttäjätietoja (yllä olevat kaksi päätepistettä käsittelevät vain sen, minkä nimenomaisesti lähetät niille), yleisimmät web-sovellusten uhat — tunnistetietojen varastaminen, tietokantamurto, istunnon kaappaaminen, palvelinpuolen injektio — eivät koske sitä. 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
Alla oleva käytäntö luetaan julkaistusta _headers-tiedostosta tämän sivun rakennushetkellä, joten se ei voi ajautua eroon siitä, mitä reuna lähettää. Vahvista se minkä tahansa pyynnön vastausotsakkeista.
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'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' https://abundera.ai 'wasm-unsafe-eval' https://challenges.cloudflare.com— ei inline-<script>:iä, eieval():ia.abundera.aion oma emoverkkotunnuksemme ja tarjoilee yhden jaetun skriptin, kielivalitsimen.challenges.cloudflare.comon Turnstile-widget, jota käytetään vain sivulla /contact/.'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- ja avatar-URL:ille. Käyttäjän toimittamia URL:ja ei koskaan suoriteta, ne vain renderöidään. Huomaa, että tämä direktiivi on myös lähtevä kanava: mikä tahansa sivulla suoritettava skripti voisi pyytää kuvan mistä tahansa HTTPS-isännästä ja upottaa tietoa URL:iin. Hyväksymme tämän, koska ominaisuus tarvitsee sitä, ja kerromme sen tässä sen sijaan, että kuvailisimme käytännön vedenpitäväksi.connect-src 'self' https: https://challenges.cloudflare.com— tämä kannattaa lukea tarkkaan.https:on skeemalähde: se salliifetch():n, XMLHttpRequestin, WebSocketin TLS:n yli, EventSourcen jasendBeacon():n tavoittaa minkä tahansa HTTPS-lähteen, ei vain sellaisia, jotka itse kirjoitit. Se on olemassa, jotta vCard-kuvakenttä ja URL-turvallisuustarkistus voivat hakea liittämäsi osoitteen. Se ei estä haitallisen skriptin suorittamaa tietojen suodattamista; mikään CSP-direktiivi ei estä sitä, kun skripti jo suoritetaan meidän oikeuksillamme. Tietojen suodattamisen estää se, että toimittamamme koodi ei tee tällaisia pyyntöjä, minkä voit todeta Verkko-välilehdeltä.frame-src 'self' https://challenges.cloudflare.com— vain Turnstile-widget voidaan kehystää.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. Yhteydenottolomake on ainoa lomake, joka lähettää tietoa mihinkään.
Mitä CSP ei pysty tekemään
CSP rajoittaa, mistä selain lataa koodia. Se ei tarkista, mitä ladattu koodi tekee. Jos alkuperämme vaarantuisi, uhkamallin ensimmäinen kohta, hyökkääjän skripti suoritettaisiin samoilla oikeuksilla kuin omamme, mukaan lukien yllä olevat connect-src- ja img-src-myönnytykset. Puolustuksemme sitä vastaan sijaitsevat CSP:n yläpuolella: julkaisut kulkevat yhden Cloudflare-tilin kautta rajatuilla tokeneilla, resurssien tiedostonimet ovat sisältöhajautettuja, joten vaihdettu tiedosto muuttaa jokaisen siihen viittaavan URL:n, ja service worker tallentaa välimuistiin vain same-origin-GET-vastaukset. Manifesti kuvaa sivuston sellaisena kuin se toimitetaan. Se ei ole väite, ettei mikään verkkosivu voisi koskaan lähettää tietoa minnekään, ja pidämme parempana, että pidät meidät vastuussa suppeammasta, tarkistettavissa olevasta väitteestä.
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 tiedostosta /sw.js (lähdekoodi toimitetaan riittävän lukukelpoisena, jotta sitä voi seurata). 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