Bezpieczeństwo

Nasz model bezpieczeństwa w jednym zdaniu: na serwerze nie ma nic do zaatakowania. Wszystko poniżej można zweryfikować z poziomu DevTools.

Architektura

Generator to statyczna aplikacja jednostronicowa serwowana z Cloudflare Pages: bez kont użytkowników, bez uwierzytelniania i bez żadnej ścieżki kodu backendowego w przepływie generowania. Każda operacja generowania, kodowania, skanowania i renderowania kodu QR odbywa się w całości w przeglądarce. Obok działa jeden mały endpoint serverless, wymieniony tutaj, a nie ukryty: /api/contact (formularz kontaktowy, który zapisuje to, co przesyłasz, w Cloudflare D1 i wysyła nam e-mailem). Nie jest wywoływany podczas tworzenia kodu QR; sprawdzanie bezpieczeństwa URL to osobny produkt pod adresem check.qr.abundera.ai. Sprawdź, czy kod QR jest bezpieczny

Model zagrożeń

Ponieważ generator nie zbiera, nie przechowuje ani nie przesyła żadnych danych użytkownika (dwa powyższe endpointy obsługują wyłącznie to, co jawnie do nich wyślesz), najczęstsze zagrożenia aplikacji webowych, kradzież danych logowania, naruszenie bazy danych, przejęcie sesji, wstrzyknięcie po stronie serwera, nie mają do niego zastosowania. Pozostała powierzchnia ataku to statyczny pakiet zasobów (HTML, CSS, JavaScript) serwowany z naszego origin. Projektujemy zakładając:

Content Security Policy, dyrektywa po dyrektywie

Poniższa polityka jest odczytywana z wdrożonego pliku _headers w momencie budowania tej strony, więc nie może rozjechać się z tym, co wysyła edge. Zweryfikuj ją w nagłówkach odpowiedzi dowolnego żądania.

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'

Co każda dyrektywa nam umożliwia i gdzie stanowi kompromis:

Czego CSP nie potrafi

CSP ogranicza, skąd przeglądarka może wczytać kod. Nie sprawdza, co ten wczytany kod robi. Gdyby nasz origin został skompromitowany, pierwszy punkt modelu zagrożeń, skrypt atakującego działałby z tymi samymi uprawnieniami co nasz, w tym z uprawnieniami connect-src i img-src wymienionymi powyżej. Nasze zabezpieczenia przed tym stoją o krok przed CSP: wdrożenia idą przez jedno konto Cloudflare z tokenami o ograniczonym zakresie, nazwy plików zasobów są hashowane na podstawie treści, więc podmieniony plik zmienia każdy URL, który się do niego odwołuje, a service worker cache'uje wyłącznie odpowiedzi GET z tego samego origin. Manifest opisuje stronę taką, jaka jest wdrożona. To nie jest twierdzenie, że żadna strona internetowa nigdy nie mogłaby nigdzie wysłać danych, i wolimy, żebyś rozliczał nas z węższego, sprawdzalnego stwierdzenia.

Różne polityki CSP mają zastosowanie do /bio/* (rozluźnione img-src dla awatarów podanych przez użytkownika) i /embed/* (rozluźnione frame-ancestors dla zamierzonego osadzania). Obie są udokumentowane w site/_headers.

Nagłówki transportu i ramkowania

Service worker

Nasz service worker (site/sw.js) buforuje tylko zasoby same-origin. Procedura obsługi fetch jawnie odrzuca żądania cross-origin i metody inne niż GET, logikę możesz przeczytać w pliku /sw.js (źródło jest na tyle nieminifikowane, by dało się je śledzić). Zapisy do pamięci podręcznej są opakowane w event.waitUntil(), aby nie mogły zostać porzucone w trakcie nawigacji.

Sanityzacja danych wejściowych

Każda ścieżka renderowania akceptująca dane od użytkownika traktuje je jako niezaufany tekst:

Pobieranie obrazów cross-origin

Gdy użytkownik wkleja URL https: jako zdjęcie vCard lub logo, przeglądarka pobiera go z zastrzeżeniem CORS i allowlisty img-src naszego CSP. Obraz jest renderowany na kanwasie. Nigdy nie staje się żywym DOM, nie jest wykonywany jako kod i nie dociera do naszego origin, fetch to przeglądarka → zdalny obraz, a wynik jest malowany po stronie klienta. Atakujący kontrolujący zdalny URL obrazu może śledzić załadowanie tego URL (wpis w logach własnego serwera), ale nie może eksfiltrować niczego z naszej strony.

Subresource Integrity (SRI)

Cały JavaScript i CSS, który dostarczamy, jest same-origin. Nie ładujemy zewnętrznych skryptów ani arkuszy stylów, więc hashe SRI nie mają zastosowania. Jeśli kiedykolwiek załadujemy zewnętrzny zasób, dodamy do niego atrybut integrity SRI i udokumentujemy proces aktualizacji hasha na tej stronie.

Zgłaszanie luki bezpieczeństwa

Jeśli odkryjesz problem z bezpieczeństwem dotyczący Abundera QR, czy to w naszym kodzie, wdrożeniu, czy w zależności, którą dostarczamy, zgłoś go prywatnie na adres security@abundera.ai. Dążymy do triage'u w ciągu 72 godzin. Możesz się z nami skontaktować również przez dane kontaktowe w naszym pliku /.well-known/security.txt.

Brak programu bug bounty (na razie)

Nie oferujemy obecnie płatnych nagród, ale każdy potwierdzony ważny raport otrzymuje uznanie w changelogu i nasze publiczne podziękowania.

Zweryfikuj powyższe

Każde twierdzenie na tej stronie można zweryfikować z poziomu DevTools przeglądarki bez konieczności ufania nam:

Kontakt

Zgłoszenia bezpieczeństwa: security@abundera.ai

Ostatnia aktualizacja: 2026-09-03. Następny przegląd: 2026-12-03.