Keamanan
Model keamanan kami dalam satu kalimat: tidak ada apa pun di server yang bisa diserang. Semua yang ada di bawah ini dapat diverifikasi dari DevTools Anda.
Arsitektur
Abundera QR adalah aplikasi satu halaman statis yang disajikan dari Cloudflare Pages. Tidak ada server aplikasi, tidak ada basis data, tidak ada akun pengguna, tidak ada autentikasi, tidak ada titik akhir API, dan tidak ada jalur kode backend yang memproses data pengguna. Setiap operasi pembuatan, pengkodean, pemindaian, dan rendering kode QR berjalan sepenuhnya di dalam browser Anda.
Model ancaman
Karena kami tidak mengumpulkan, menyimpan, dan mengirimkan data pengguna, ancaman aplikasi web yang paling umum, pencurian kredensial, pelanggaran basis data, pembajakan sesi, injeksi sisi server, tidak berlaku. Permukaan serangan yang tersisa adalah bundel aset statis (HTML, CSS, JavaScript) yang disajikan dari origin kami. Kami merancang dengan asumsi:
- Kompromi origin: penyerang mengganti salah satu aset terbundel kami dengan yang berbahaya. CSP di bawah membatasi radius ledakan; token cache-buster memudahkan pengembalian ke versi yang diketahui baik.
- Input yang disediakan pengguna: muatan QR, nama vCard, kata sandi WiFi, baris CSV batch, konten gambar yang dipindai. Setiap jalur input diperlakukan sebagai tidak tepercaya saat dirender kembali ke DOM.
- Gambar yang disediakan pengguna: URL foto vCard dan unggahan logo. Gambar dirender ke dalam kanvas, tidak pernah disematkan ke DOM sebagai markup mentah.
- Ekstensi browser pihak ketiga: di luar cakupan. Jika ekstensi di browser Anda memiliki izin untuk memodifikasi setiap halaman, ekstensi itu dapat memodifikasi halaman kami. Jaminan kami berlaku saat halaman dimuat tanpa modifikasi.
Kebijakan Keamanan Konten, per direktif
Kebijakan saat ini (verifikasi di header Respons untuk permintaan apa pun):
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'Apa yang setiap direktif memungkinkan kami lakukan dan di mana berkompromi:
default-src 'self', lantai keras. Apa pun yang tidak kami longgarkan secara eksplisit tetap same-origin.script-src 'self' 'wasm-unsafe-eval', tidak ada<script>inline, tidak adaeval().'wasm-unsafe-eval'diperlukan oleh jalur kompilasi WebAssembly pustaka enkoder QR kami; ini TIDAK mengizinkaneval()tradisional. Pemeriksaan pra-deploy kami memindai setiap halaman HTML untuk skrip inline dan menggagalkan build.style-src 'self' 'unsafe-inline', konsesi nyata. Pratinjau QR kami menghitung warna tingkat piksel secara inline (atribut style pada modul individual). Daftar izin berbasis hash akan berfungsi tetapi akan gagal pada pembaruan gaya apa pun tanpa deploy. Kompromi: kami menerima kebijakan gaya yang sedikit lebih lemah; gaya bagaimanapun tidak dapat mengekstrak data (CSS tidak memiliki jangkauanconnect-src).img-src 'self' data: blob: https:,data:untuk render QR inline,blob:untuk URL unduhan ekspor,https:untuk URL foto vCard yang disediakan pengguna. URL yang disediakan pengguna tidak pernah dieksekusi, hanya dirender.connect-src 'self' https:, fetch() dibatasi ke origin kami ditambah pengambilan HTTPS yang diprakarsai pengguna (misalnya, memindai URL foto). Mencegah eksfiltrasi melalui DNS / WebSocket / beacon ke host sembarang.frame-ancestors 'none', tidak ada situs lain yang dapat menyematkan kami. Mencegah clickjacking.base-uri 'self', tag<base>yang disuntikkan dengan berbahaya tidak dapat mengalihkan URL relatif ke origin penyerang.form-action 'self', formulir yang disuntikkan hanya dapat mengirim kembali ke origin kami. Kami tidak memiliki formulir yang mengirim data sisi server; ini adalah lapisan keamanan tambahan.
Kebijakan CSP yang berbeda berlaku untuk /bio/* (longgarkan img-src untuk avatar yang disediakan pengguna) dan /embed/* (longgarkan frame-ancestors untuk penyematan yang disengaja). Keduanya didokumentasikan di site/_headers.
Header transport dan framing
- HSTS:
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload, 1 tahun, semua subdomain, memenuhi syarat untuk daftar preload HSTS. Browser yang sesuai menolak downgrade ke HTTP. - X-Frame-Options: DENY, redundan dengan CSP
frame-ancestors, dipertahankan untuk cakupan browser lama. - X-Content-Type-Options: nosniff, mencegah serangan kebingungan MIME.
- Referrer-Policy: strict-origin-when-cross-origin, klik tautan keluar membocorkan origin tetapi bukan jalur.
- Permissions-Policy:
camera=(self), microphone=(), geolocation=(), kamera hanya diizinkan untuk pemindai kami sendiri; mikrofon dan lokasi secara eksplisit ditolak meskipun disematkan.
Service worker
Service worker kami (site/sw.js) hanya menyimpan aset same-origin dalam cache. Pengendali fetch secara eksplisit menolak permintaan cross-origin dan metode non-GET, Anda dapat membaca logikanya di GitHub. Penulisan cache dibungkus dalam event.waitUntil() sehingga tidak dapat dihapus di tengah navigasi.
Sanitasi input
Setiap jalur rendering yang menerima input pengguna memperlakukannya sebagai teks tidak tepercaya:
- Pratinjau muatan QR menggunakan
textContent, bukaninnerHTML. - Target berbagi (papan klip,
navigator.share()) meneruskan teks pengguna sebagai string, tidak pernah sebagai markup. - Ekspor SVG dibuat dari pustaka enkoder kami; konten pengguna dikodekan base64 ke dalam
<image>xlink:href, tidak disuntikkan sebagai elemen SVG. - Pratinjau cetak menggunakan URL blob, bukan
document.write(). - Penguraian localStorage dibungkus dalam
try/catch, entri yang rusak menghasilkan default kosong baru, tidak pernah pengecualian yang dapat terurai ke jalur kode langsung. - URL yang disediakan pengguna yang ditampilkan sebagai tombol "Buka tautan" dibatasi ke
http(s)://, skemajavascript:dandata:ditolak.
Pengambilan gambar cross-origin
Ketika pengguna menempelkan URL https: sebagai foto vCard atau logo, browser mengambilnya tunduk pada CORS dan daftar izin img-src CSP kami. Gambar dirender ke dalam kanvas. Gambar tidak pernah menjadi DOM langsung, tidak pernah dijalankan sebagai kode, dan tidak pernah mencapai origin kami, pengambilan adalah browser → gambar jarak jauh, dan hasilnya dilukis di sisi klien. Penyerang yang mengendalikan URL gambar jarak jauh dapat melacak bahwa URL tersebut dimuat (baris log di server mereka sendiri) tetapi tidak dapat mengekstrak apa pun dari halaman kami.
Integritas Subresource (SRI)
Semua JavaScript dan CSS yang kami kirimkan adalah same-origin. Kami tidak memuat skrip atau lembar gaya pihak ketiga, sehingga hash SRI tidak berlaku. Jika kami pernah memuat aset pihak ketiga, kami akan mengirimkan atribut integrity SRI padanya dan mendokumentasikan proses pembaruan hash di halaman ini.
Melaporkan kerentanan
Jika Anda menemukan masalah keamanan yang mempengaruhi Abundera QR, baik dalam kode kami, deployment kami, atau dalam dependensi yang kami kirimkan, harap laporkan secara pribadi ke security@abundera.ai. Kami bertujuan untuk melakukan triage dalam 72 jam. Anda juga dapat menghubungi kami melalui detail kontak di file /.well-known/security.txt kami.
Belum ada bug bounty
Kami saat ini tidak menawarkan hadiah berbayar, tetapi setiap laporan valid yang dikonfirmasi menerima kredit di changelog dan ucapan terima kasih publik kami.
Verifikasi hal di atas
Setiap klaim di halaman ini dapat diverifikasi dari DevTools browser Anda tanpa harus mempercayai kami:
- CSP: DevTools → Jaringan →
/→ Header. Baca header responsContent-Security-Policy. - HSTS + header keamanan: tempat yang sama, semua
Strict-Transport-Security,X-Frame-Options, dll. terlihat. - Tidak ada panggilan keluar: DevTools → Jaringan → Fetch/XHR. Buat QR. Perhatikan hitungan tetap di nol.
- Cakupan service worker: DevTools → Aplikasi → Service Workers. Verifikasi sumber skrip dan daftar aset yang di-cache.
- Tidak ada cookie: DevTools → Aplikasi → Cookie. Kosong.
- Panduan lengkap: bagian verifikasi manifesto.
Kontak
Pengungkapan keamanan: security@abundera.ai