Keselamatan
Model keselamatan kami dalam satu ayat: tiada apa-apa di pelayan yang boleh diserang. Semua di bawah boleh disahkan daripada DevTools anda.
Seni Bina
Penjana ini ialah aplikasi halaman tunggal statik yang dihidangkan daripada Cloudflare Pages: tiada akaun pengguna, tiada pengesahan, dan tiada laluan kod bahagian belakang di mana-mana dalam aliran penjanaan. Setiap operasi penjanaan, pengekodan, pengimbasan, dan pemaparan kod QR dijalankan sepenuhnya dalam penyemak imbas anda. Satu titik akhir tanpa pelayan yang kecil berada di sisinya dan disenaraikan di sini dan bukan disembunyikan: /api/contact (borang hubungi, yang menyimpan apa yang anda hantar dalam Cloudflare D1 dan meng-e-melkannya kepada kami). Ia tidak dipanggil semasa anda membuat kod QR; penyemak keselamatan URL adalah produk berasingan di check.qr.abundera.ai. Semak sama ada kod QR selamat
Model ancaman
Oleh sebab penjana ini tidak mengumpul, menyimpan, dan menghantar sebarang data pengguna (dua titik akhir di atas hanya mengendalikan apa yang anda hantar secara eksplisit kepadanya), ancaman aplikasi web yang paling biasa, pencurian kelayakan, pelanggaran pangkalan data, rampasan sesi, suntikan sisi pelayan, tidak terpakai kepadanya. Permukaan serangan yang tinggal ialah pakej aset statik (HTML, CSS, JavaScript) yang dihidangkan daripada origin kami. Kami mereka bentuk dengan andaian:
- Kompromi origin: penyerang menggantikan salah satu aset terbundel kami dengan yang berniat jahat. CSP di bawah mengehadkan radius letupan; token cache-buster memudahkan pemulihan semula kepada versi yang diketahui baik.
- Input yang dibekalkan pengguna: muatan QR, nama vCard, kata laluan WiFi, baris CSV kelompok, kandungan imej yang diimbas. Setiap laluan input dilayan sebagai tidak dipercayai apabila dipapar semula ke DOM.
- Imej yang dibekalkan pengguna: URL foto vCard dan muat naik logo. Imej dipapar ke dalam kanvas, tidak pernah dibenamkan ke dalam DOM sebagai penanda tangan mentah.
- Sambungan penyemak imbas pihak ketiga: di luar skop. Jika sambungan dalam penyemak imbas anda mempunyai kebenaran untuk mengubah suai setiap halaman, ia boleh mengubah suai halaman kami. Jaminan kami berlaku apabila halaman dimuatkan tanpa pengubahsuaian.
Dasar Keselamatan Kandungan, mengikut direktif
Dasar di bawah dibaca daripada fail _headers yang digunakan sebenar semasa halaman ini dibina, jadi ia tidak boleh terpesong daripada apa yang dihantar oleh edge. Sahkan dalam pengepala tindak balas untuk sebarang permintaan.
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'Apa yang setiap direktif membenarkan kami lakukan dan di mana ia berkompromi:
default-src 'self', lantai keras. Apa sahaja yang kami tidak longgarkan secara eksplisit kekal sebagai same-origin.script-src 'self' https://abundera.ai 'wasm-unsafe-eval' https://challenges.cloudflare.com, tiada<script>sebaris, tiadaeval().abundera.aiialah domain induk kami sendiri dan menghidangkan satu skrip kongsi, pemilih bahasa.challenges.cloudflare.comialah widget Turnstile yang digunakan hanya pada /contact/.'wasm-unsafe-eval'diperlukan oleh laluan kompilasi WebAssembly perpustakaan penekod QR kami; ia TIDAK membenarkaneval()tradisional. Semakan pra-deploy kami mengimbas setiap halaman HTML untuk skrip sebaris dan menggagalkan binaan.style-src 'self' 'unsafe-inline', konsesi sebenar. Pratonton QR kami mengira warna peringkat piksel secara sebaris (atribut gaya pada modul individu). Senarai benarkan berasaskan hash akan berfungsi tetapi akan gagal pada setiap kemas kini gaya tanpa deploy. Pertimbangan: kami menerima dasar gaya yang sedikit lebih lemah; penggayaan tidak boleh mengekstrak data pun (CSS tidak mempunyai jangkauanconnect-src).img-src 'self' data: blob: https:,data:untuk render QR sebaris,blob:untuk URL muat turun eksport,https:untuk URL foto dan avatar vCard yang dibekalkan pengguna. URL yang dibekalkan pengguna tidak pernah dilaksanakan, hanya dipapar. Ambil perhatian bahawa direktif ini juga merupakan saluran keluar: mana-mana skrip yang berjalan pada halaman boleh meminta imej daripada mana-mana hos HTTPS dan meletakkan data dalam URL. Kami menerima itu kerana ciri ini memerlukannya, dan kami menyatakannya di sini dan bukannya menggambarkan dasar ini sebagai kedap sepenuhnya.connect-src 'self' https: https://challenges.cloudflare.com, yang satu ini perlu dibaca dengan teliti.https:ialah sumber skema: ia membenarkanfetch(), XMLHttpRequest, WebSocket melalui TLS, EventSource dansendBeacon()mencapai mana-mana origin HTTPS, bukan hanya yang anda taip. Ia ada supaya medan foto vCard dan semakan keselamatan URL boleh mengambil alamat yang anda tampal. Ia tidak mencegah ekstrakan oleh skrip berniat jahat; tiada direktif CSP yang mampu berbuat demikian sebaik sahaja skrip itu sudah berjalan sebagai kami. Apa yang mencegah ekstrakan ialah kod yang kami hantar tidak membuat permintaan sedemikian, yang boleh anda perhatikan dalam tab Network.frame-src 'self' https://challenges.cloudflare.com, hanya widget Turnstile boleh dibenamkan dalam bingkai.frame-ancestors 'none', tiada laman lain boleh membenamkan kami. Mencegah clickjacking.base-uri 'self', tag<base>yang disuntik dengan berniat jahat tidak boleh mengalihkan URL relatif ke origin penyerang.form-action 'self', mana-mana borang yang disuntik hanya boleh menghantar semula ke origin kami. Borang hubungi adalah satu-satunya borang yang menghantar ke mana-mana.
Apa yang CSP tidak boleh lakukan
CSP mengehadkan dari mana penyemak imbas akan memuatkan kod. Ia tidak menyemak apa yang dilakukan oleh kod yang dimuatkan itu. Jika origin kami pernah terjejas, item pertama dalam model ancaman, skrip penyerang akan berjalan dengan kebenaran yang sama seperti kod kami, termasuk kebenaran connect-src dan img-src di atas. Pertahanan kami terhadap perkara itu berada di hulu CSP: deploy dihantar melalui satu akaun Cloudflare dengan token berskop, nama fail aset di-hash mengikut kandungan supaya fail yang ditukar ganti mengubah setiap URL yang merujuknya, dan pekerja perkhidmatan hanya menyimpan cache respons GET same-origin. Manifesto menerangkan laman ini sebagaimana ia dihantar. Ia bukan dakwaan bahawa tiada halaman web boleh menghantar data ke mana-mana; kami lebih suka anda pegang kami pada kenyataan yang lebih sempit dan boleh disemak itu.
Dasar CSP yang berbeza terpakai untuk /bio/* (longgarkan img-src untuk avatar yang dibekalkan pengguna) dan /embed/* (longgarkan frame-ancestors untuk pembenaman yang disengajakan). Kedua-duanya didokumenkan dalam site/_headers.
Pengepala pengangkutan dan pembingkaian
- HSTS:
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload, 1 tahun, semua subdomain, layak untuk senarai pramuatan HSTS. Penyemak imbas yang menepati menolak penurunan taraf ke HTTP. - X-Frame-Options: DENY, berlebihan dengan CSP
frame-ancestors, dikekalkan untuk liputan penyemak imbas lama. - X-Content-Type-Options: nosniff, mencegah serangan kekeliruan MIME.
- Referrer-Policy: strict-origin-when-cross-origin, klik pautan keluar mendedahkan origin tetapi bukan laluan.
- Permissions-Policy:
camera=(self), microphone=(), geolocation=(), kamera dibenarkan hanya untuk pengimbas kami sendiri; mikrofon dan lokasi dinafikan secara eksplisit walaupun dibenamkan.
Pekerja perkhidmatan
Pekerja perkhidmatan kami (site/sw.js) hanya menyimpan aset same-origin dalam cache. Pengendali fetch secara eksplisit menolak permintaan cross-origin dan kaedah bukan GET, anda boleh membaca logiknya di /sw.js (sumbernya dihantar tanpa minifikasi yang mencukupi untuk diikuti). Penulisan cache dibungkus dalam event.waitUntil() supaya tidak boleh digugurkan di tengah navigasi.
Pembersihan input
Setiap laluan pemaparan yang menerima input pengguna melayan ia sebagai teks tidak dipercayai:
- Pratonton muatan QR menggunakan
textContent, bukaninnerHTML. - Sasaran kongsi (papan klip,
navigator.share()) menghantar teks pengguna sebagai rentetan, tidak pernah sebagai penanda tangan. - Eksport SVG dijana daripada perpustakaan penekod kami; kandungan pengguna dikodkan base64 ke dalam
<image>xlink:href, tidak disuntik sebagai elemen SVG. - Pratonton cetak menggunakan URL blob, bukan
document.write(). - Penghuraian localStorage dibungkus dalam
try/catch, entri yang rosak menghasilkan lalai kosong baharu, tidak pernah pengecualian yang boleh membuka ke laluan kod langsung. - URL yang dibekalkan pengguna yang ditunjukkan sebagai butang "Buka pautan" dihadkan kepada
http(s)://, skimjavascript:dandata:ditolak.
Pengambilan imej cross-origin
Apabila pengguna menampal URL https: sebagai foto vCard atau logo, penyemak imbas mengambilnya tertakluk kepada CORS dan senarai benarkan img-src CSP kami. Imej dipapar ke dalam kanvas. Ia tidak pernah menjadi DOM langsung, tidak pernah dijalankan sebagai kod, dan tidak pernah sampai ke origin kami, pengambilan adalah penyemak imbas → imej jauh, dan hasilnya dilukis pada sisi klien. Penyerang yang mengawal URL imej jauh boleh menjejaki bahawa URL telah dimuatkan (baris log pada pelayan mereka sendiri) tetapi tidak boleh mengekstrak apa-apa daripada halaman kami.
Integriti Subresource (SRI)
Semua JavaScript dan CSS yang kami hantar adalah same-origin. Kami tidak memuatkan skrip atau helaian gaya pihak ketiga, jadi hash SRI tidak terpakai. Jika kami pernah memuatkan aset pihak ketiga, kami akan menghantar atribut integrity SRI padanya dan mendokumenkan proses kemas kini hash dalam halaman ini.
Melaporkan kerentanan
Jika anda menemui isu keselamatan yang menjejaskan Abundera QR, sama ada dalam kod kami, deployment kami, atau dalam kebergantungan yang kami hantar, sila laporkannya secara peribadi ke security@abundera.ai. Kami berhasrat untuk melakukan triaj dalam masa 72 jam. Anda juga boleh menghubungi kami melalui butiran hubungan dalam fail /.well-known/security.txt kami.
Tiada bug bounty (buat masa ini)
Kami tidak menawarkan hadiah berbayar buat masa ini, tetapi setiap laporan sah yang disahkan menerima kredit dalam changelog dan ucapan terima kasih awam kami.
Sahkan mana-mana perkara di atas
Setiap dakwaan di halaman ini boleh disahkan daripada DevTools penyemak imbas anda tanpa mempercayai kami:
- CSP: DevTools → Rangkaian →
/→ Pengepala. Baca pengepala tindak balasContent-Security-Policy. - HSTS + pengepala keselamatan: tempat yang sama, semua
Strict-Transport-Security,X-Frame-Options, dsb. kelihatan. - Tiada panggilan keluar: DevTools → Rangkaian → Fetch/XHR. Jana QR. Perhatikan kiraan kekal pada sifar.
- Skop pekerja perkhidmatan: DevTools → Aplikasi → Pekerja Perkhidmatan. Sahkan sumber skrip dan senarai aset cache.
- Tiada kuki: DevTools → Aplikasi → Kuki. Kosong.
- Panduan penuh: bahagian pengesahan manifesto.
Hubungi
Pendedahan keselamatan: security@abundera.ai