Bảo mật
Mô hình bảo mật của chúng tôi trong một câu: không có gì trên máy chủ để tấn công. Mọi thứ dưới đây đều có thể kiểm chứng từ DevTools của bạn.
Kiến trúc
Abundera QR là ứng dụng trang đơn tĩnh được phục vụ từ Cloudflare Pages. Không có máy chủ ứng dụng, cơ sở dữ liệu, tài khoản người dùng, xác thực, điểm cuối API hay đường dẫn mã backend xử lý dữ liệu người dùng. Mọi thao tác tạo QR, mã hóa, quét và kết xuất đều chạy hoàn toàn trong trình duyệt của bạn.
Mô hình mối đe dọa
Vì chúng tôi không thu thập, lưu trữ hay truyền dữ liệu người dùng, các mối đe dọa web phổ biến nhất, đánh cắp thông tin xác thực, vi phạm cơ sở dữ liệu, chiếm quyền phiên, tiêm lệnh phía máy chủ, không áp dụng. Bề mặt tấn công còn lại là gói tài sản tĩnh (HTML, CSS, JavaScript) được phục vụ từ nguồn gốc của chúng tôi. Chúng tôi thiết kế với các giả định:
- Xâm phạm nguồn gốc: kẻ tấn công thay thế một trong các tài sản được đóng gói của chúng tôi bằng tài sản độc hại. CSP dưới đây giới hạn bán kính thiệt hại; các token cache-buster giúp dễ dàng quay lại phiên bản đã biết là tốt.
- Đầu vào do người dùng cung cấp: payload QR, tên vCard, mật khẩu WiFi, hàng CSV theo lô, nội dung hình ảnh được quét. Mọi đường dẫn đầu vào đều được coi là không tin cậy khi hiển thị lại vào DOM.
- Hình ảnh do người dùng cung cấp: URL ảnh vCard và tải lên logo. Hình ảnh được kết xuất vào canvas, không bao giờ được nhúng vào DOM dưới dạng markup thô.
- Tiện ích mở rộng trình duyệt của bên thứ ba: ngoài phạm vi. Nếu một tiện ích mở rộng trong trình duyệt của bạn có quyền chỉnh sửa mọi trang, nó có thể chỉnh sửa trang của chúng tôi. Các đảm bảo của chúng tôi có hiệu lực khi trang được tải mà không bị chỉnh sửa.
Chính sách bảo mật nội dung, theo chỉ thị
Chính sách hiện tại (xác minh trong tiêu đề Phản hồi cho bất kỳ yêu cầu nào):
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'Mỗi chỉ thị cho phép chúng tôi làm gì và đánh đổi ở đâu:
default-src 'self', nền tảng cứng. Bất cứ điều gì chúng tôi không nới lỏng rõ ràng vẫn là same-origin.script-src 'self' 'wasm-unsafe-eval', không có<script>inline, không cóeval().'wasm-unsafe-eval'được yêu cầu bởi đường dẫn biên dịch WebAssembly của thư viện encoder QR; nó KHÔNG cho phépeval()truyền thống. Kiểm tra trước khi triển khai của chúng tôi quét mọi trang HTML để tìm script inline và làm hỏng bản dựng.style-src 'self' 'unsafe-inline', một nhượng bộ thực sự. Bản xem trước QR của chúng tôi tính toán màu ở cấp độ pixel theo kiểu inline (thuộc tính style trên các mô-đun riêng lẻ). Danh sách cho phép dựa trên hash sẽ hoạt động nhưng sẽ thất bại ở bất kỳ cập nhật style nào mà không có triển khai. Đánh đổi: chúng tôi chấp nhận chính sách style yếu hơn một chút; style dù sao cũng không thể rò rỉ dữ liệu (CSS không có phạm viconnect-src).img-src 'self' data: blob: https:,data:cho các render QR inline,blob:cho URL tải xuống xuất khẩu,https:cho URL ảnh vCard do người dùng cung cấp. URL do người dùng cung cấp không bao giờ thực thi, chỉ kết xuất.connect-src 'self' https:, fetch() bị giới hạn ở nguồn gốc của chúng tôi cộng với các fetch HTTPS do người dùng khởi tạo (ví dụ: quét URL ảnh). Ngăn chặn rò rỉ qua DNS / WebSocket / beacon đến các máy chủ tùy ý.frame-ancestors 'none', không có trang web nào khác có thể nhúng chúng tôi. Ngăn chặn clickjacking.base-uri 'self', thẻ<base>được tiêm độc hại không thể chuyển hướng URL tương đối đến nguồn gốc của kẻ tấn công.form-action 'self', bất kỳ form được tiêm nào chỉ có thể gửi lại nguồn gốc của chúng tôi. Chúng tôi không có form nào gửi dữ liệu phía máy chủ; đây là biện pháp bảo vệ kép.
Các chính sách CSP khác nhau áp dụng cho /bio/* (nới lỏng img-src cho avatar do người dùng cung cấp) và /embed/* (nới lỏng frame-ancestors cho nhúng có chủ ý). Cả hai đều được ghi lại trong site/_headers.
Tiêu đề truyền tải và đóng khung
- HSTS:
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload, 1 năm, tất cả tên miền con, đủ điều kiện cho danh sách preload HSTS. Việc hạ xuống HTTP bị từ chối bởi các trình duyệt tuân thủ. - X-Frame-Options: DENY, thừa so với CSP
frame-ancestors, được giữ để hỗ trợ các trình duyệt cũ hơn. - X-Content-Type-Options: nosniff, ngăn chặn các cuộc tấn công nhầm lẫn MIME.
- Referrer-Policy: strict-origin-when-cross-origin, các nhấp vào liên kết đi ra ngoài rò rỉ nguồn gốc nhưng không rò rỉ đường dẫn.
- Permissions-Policy:
camera=(self), microphone=(), geolocation=(), camera chỉ được phép cho máy quét của chúng tôi; mic và vị trí bị từ chối rõ ràng ngay cả khi được nhúng.
Service worker
Service worker của chúng tôi (site/sw.js) chỉ lưu vào cache các tài sản same-origin. Trình xử lý fetch từ chối rõ ràng các yêu cầu cross-origin và các phương thức không phải GET, bạn có thể đọc logic trên GitHub. Các lần ghi vào cache được bọc trong event.waitUntil() để chúng không thể bị bỏ qua giữa điều hướng.
Làm sạch đầu vào
Mọi đường dẫn kết xuất chấp nhận đầu vào của người dùng đều coi nó là văn bản không tin cậy:
- Bản xem trước payload QR sử dụng
textContent, không phảiinnerHTML. - Các đích chia sẻ (clipboard,
navigator.share()) truyền văn bản người dùng dưới dạng chuỗi, không bao giờ dưới dạng markup. - Các xuất SVG được tạo từ thư viện encoder của chúng tôi; nội dung người dùng được mã hóa base64 vào
<image>xlink:href, không được tiêm dưới dạng các phần tử SVG. - Bản xem trước in sử dụng blob URL, không phải
document.write(). - Phân tích localStorage được bọc trong
try/catch, một mục nhập bị hỏng tạo ra một giá trị mặc định rỗng mới, không bao giờ là ngoại lệ có thể mở ra vào đường dẫn mã trực tiếp. - URL do người dùng cung cấp được hiển thị dưới dạng nút "Mở liên kết" bị giới hạn ở
http(s)://, các lược đồjavascript:vàdata:bị từ chối.
Tải hình ảnh cross-origin
Khi người dùng dán URL https: làm ảnh vCard hoặc logo, trình duyệt tải về theo CORS và danh sách cho phép img-src của CSP. Hình ảnh được kết xuất vào canvas. Nó không bao giờ trở thành DOM trực tiếp, không bao giờ chạy như mã, và không bao giờ đến nguồn gốc của chúng tôi, tải về là trình duyệt → hình ảnh từ xa, và kết quả được vẽ phía client. Kẻ tấn công kiểm soát URL hình ảnh từ xa có thể theo dõi rằng URL đã được tải (một dòng log trên máy chủ của họ) nhưng không thể rò rỉ bất cứ điều gì từ trang của chúng tôi.
Tính toàn vẹn tài nguyên con (SRI)
Tất cả JavaScript và CSS chúng tôi cung cấp đều là same-origin. Chúng tôi không tải script hoặc stylesheet của bên thứ ba, vì vậy hash SRI không áp dụng. Nếu chúng tôi từng tải tài sản của bên thứ ba, chúng tôi sẽ thêm thuộc tính SRI integrity vào đó và ghi lại quy trình cập nhật hash trong trang này.
Báo cáo lỗ hổng
Nếu bạn phát hiện vấn đề bảo mật ảnh hưởng đến Abundera QR, trong mã của chúng tôi, triển khai của chúng tôi, hoặc trong một phụ thuộc mà chúng tôi cung cấp, vui lòng báo cáo riêng tư đến security@abundera.ai. Chúng tôi hướng đến việc phân loại trong vòng 72 giờ. Bạn cũng có thể liên hệ qua thông tin liên lạc trong file /.well-known/security.txt của chúng tôi.
Chưa có chương trình thưởng lỗi
Hiện tại chúng tôi không cung cấp tiền thưởng, nhưng mọi báo cáo hợp lệ được xác nhận đều nhận được ghi nhận trong changelog và lời cảm ơn công khai của chúng tôi.
Xác minh những điều trên
Mọi tuyên bố trên trang này đều có thể kiểm chứng từ DevTools của trình duyệt mà không cần tin tưởng chúng tôi:
- CSP: DevTools → Network →
/→ Headers. Đọc tiêu đề phản hồiContent-Security-Policy. - HSTS + tiêu đề bảo mật: cùng chỗ, tất cả
Strict-Transport-Security,X-Frame-Options, v.v. đều hiển thị. - Không có cuộc gọi đi ra ngoài: DevTools → Network → Fetch/XHR. Tạo một QR. Xem số đếm dừng ở không.
- Phạm vi service worker: DevTools → Application → Service Workers. Xác minh nguồn script và danh sách tài sản được lưu vào cache.
- Không có cookie: DevTools → Application → Cookies. Trống.
- Hướng dẫn đầy đủ: phần xác minh của bản tuyên ngôn.
Liên hệ
Báo cáo bảo mật: security@abundera.ai