Bezpieczeństwo
Jak zbudowane jest schronienie i jakie odkrycia można znaleźć w razie włamania.
Ostatnia aktualizacja: 21 września 2026 r. · AssuredAuth, autorstwa CircleRoll LLC
To jest publiczny opis sposobu, w jaki AssuredAuth chroni przechowywane w nim dwuskładnikowe hasła, sekrety i karty. Został on napisany tak, aby czytelnik dbający o bezpieczeństwo mógł sprawdzić każde oświadczenie w odniesieniu do aplikacji i opublikowanych wektorów testowych (dostępnych dla recenzentów na życzenie pod adresem hello@assuredauth.com). Opis ten jest prawdziwy i nic więcej: nic nie obiecuje, że jest odporne na ataki, ani nic nie jest obiecywaniem procentowym.
W skrócie: sejf znajduje się w jednym miejscu – Twoim telefonie. Każda wartość w nim zaszyfrowana jest kluczem, który jest przechowywany przez zabezpieczenia telefonu i nie może zostać wyeksportowany. Nie prowadzimy serwera sejfu, nie przechowujemy kopii ani klucza. Plik kopii zapasowej opuszcza telefon dopiero po zaszyfrowaniu go hasłem, które nigdy nie jest nigdzie przechowywane.
Zgłoś problem: hello@assuredauth.com. Zobacz „Zgłaszanie słabości” na końcu.
1. Co jest szyfrowane, czym
| Dane | Na telefonie | Klucz |
|---|---|---|
| Sekrety dwuskładnikowe (TOTP/HOTP/Steam Seeds) | Na telefonieSklep obsługiwany przez Keychain (iOS) / Android Keystore | KluczKlucz sprzętowy platformy; wiersz bazy danych zawiera tylko odniesienie (secretRef), nigdy ziarno |
| Hasła (wartość hasła, notatki) | Na telefonieZapieczętowany wiersz: AES-256-GCM, losowy 96-bitowy nonce na wartość | KluczLosowy 256-bitowy klucz danych, który sam jest owinięty kluczem sprzętowym w §2 |
| Karty (numer, data ważności, imię i nazwisko na karcie, kod CVC) | Na telefonieTa sama pieczęć co w przypadku haseł; kod CVC jest opcjonalny i jest przechowywany tylko wtedy, gdy go wpiszesz | KluczTen sam klucz danych |
| Metadane (nazwy usług, nazwy użytkowników, ikony, kolejność sortowania) | Na telefonieBaza danych aplikacji (SwiftData / Room) | KluczChronione przez szyfrowanie plików systemu operacyjnego; traktowane jako nietajne |
| Plik kopii zapasowej (.authbackup) | Na telefonieGdziekolwiek je umieścisz: Pliki, iCloud Drive, aplikacja Google Drive, Folder danych, arkusz udostępniania | KluczKlucz wyprowadzony z Twojego hasła (§3). Apple i Google otrzymują zapieczętowany plik i nic więcej. |
| Aplikacja na Watch / Wear | Na telefonieWłasny brelok zegarka / szyfrowane współdzielone preferencje | KluczKlucze platformy zegarka przesyłane przez kanał sparowanego urządzenia platformy |
| Ruch rozszerzeń pulpitu (jednorazowe kody na żądanie) | Na telefonieNieprzechowywane; przekazywane w postaci kopert szyfrowanych od końca do końca | KluczPara kluczy X25519 na parę, klucz prywatny w pęku kluczy/magazynie kluczy; przekaźnik widzi tylko tekst zaszyfrowany |
Diagnostyka nie posiada metody akceptującej tajny klucz. Żadne zdarzenie analityczne nie zawiera pola skarbca. Żadna wartość z skarbca nie jest zapisywana w dzienniku, w żadnej kompilacji.
2. Gdzie znajdują się klucze, na każdej platformie
iOS. Klucz danych jest opakowany w klucz generowany w bezpiecznej enklawie (kSecAttrTokenIDSecureEnclave) z kontrolą dostępu .privateKeyUsage + .userPresence, funkcją dostępności… ThisDeviceOnly, w udostępnionej grupie dostępu aplikacji do pęku kluczy, dzięki czemu rozszerzenie AutoFill może używać tego samego klucza. Klucza prywatnego nie można odczytać z enklawy przez aplikację, kopię zapasową ani debugger; enklawa zgadza się na jego użycie dopiero po obecności użytkownika (Face ID, Touch ID lub hasło urządzenia). ThisDeviceOnly oznacza, że kopia zapasowa telefonu w iCloud lub iTunes nie zawiera klucza; przywrócony telefon uruchamia się z pustym sejfem i prosi o plik kopii zapasowej oraz hasło. Telefon bez kodu dostępu nie może zablokować klucza .userPresence (Enclave odmawia jego utworzenia), a symulator działa w ten sam sposób (monit o obecność to alert, na który żaden test nie potrafi odpowiedzieć): w tym przypadku klucz danych to zwykły element pęku kluczy dostępny tylko dla urządzenia — nadal nieuwzględniony w żadnej kopii zapasowej, nadal niemożliwy do odczytania, gdy telefon jest zablokowany, ale bez drugiego monitu — a ekran zabezpieczeń wyświetla dokładnie tę informację i sugeruje ustawienie kodu dostępu.
Android. Klucz danych jest opakowany w klucz AndroidKeyStore AES-256, generowany w StrongBox, gdy urządzenie go posiada (w przeciwnym razie TEE), z setUserAuthenticationRequired(true) i 30-sekundową ważnością uwierzytelnienia po poświadczeniu biometrycznym lub urządzenia, setUnlockedDeviceRequired(true) i setInvalidatedByBiometricEnrollment(true) pozostawionymi włączonymi. Ta ostatnia flaga jest uczciwa, a nie obciążająca: Android stosuje ją tylko do kluczy, które wymagają danych biometrycznych przy każdym użyciu, więc w tym 30-sekundowym kluczu z dozwolonym poświadczeniem urządzenia nic nie zmienia — to, co trzyma palec obcej osoby na zewnątrz, to fakt, że rejestracja wymaga podania kodu PIN, a zdjęcie blokady ekranu na dobre unieważnia klucz. Klucze keystore nie są eksportowalne i są wyłączone z kopii zapasowej w chmurze Androida. Domena, którą aplikacja nazywa we własnych widokach (webDomain), jest uznawana tylko ze znanej przeglądarki; z każdego innego pakietu musi to być również pakiet, który system zweryfikował dla tego pakietu (Digital Asset Links), ponieważ każda aplikacja może rościć sobie prawo do dowolnej domeny.
Co to oznacza w przypadku kradzieży pliku bazy danych. Plik SQLite i zapieczętowane wiersze są szyfrowane. Klucz, który je otwiera, znajduje się w sprzęcie zabezpieczającym w telefonie, z którego pochodzi plik, i nie można go skopiować razem z plikiem. W trybie offline nie ma nic do odgadnięcia: klucz danych jest losowy, nie pochodzi z żadnego wybranego przez użytkownika tekstu.
3. Plik kopii zapasowej
Kopie zapasowe to jedyna rzecz, która pozostaje w telefonie, więc w zasadzie to właśnie one są jedynym miejscem, w którym atak offline jest możliwy. Konstrukcja sprawia, że atak jest kosztowny i ogranicza go do minimum:
- Fraza hasłowa ma co najmniej 12 znaków (arkusz odrzuca krótsze i pokazuje pasek siły).
- Nigdzie, ani w pliku, ani w aplikacji, nie jest przechowywana żadna wskazówka dotycząca hasła.
- Świeża, losowa sól o długości 16 bajtów i 12 bajtów dla każdego zapisanego pliku.
- Cały kod jest szyfrowany algorytmem AES-256-GCM, więc błędne hasło lub uszkodzony plik zostanie odrzucony i nigdy nie zostanie odszyfrowany do postaci śmieci.
- Nagłówek (format, wersja, parametry KDF, sól) jest powiązany ze znacznikiem GCM jako dodatkowe uwierzytelnione dane, więc plik, którego współczynnik pracy został zmniejszony, nie zostanie otwarty.
Plik jest w formacie JSON i można go odczytać w dowolnym edytorze tekstu; jedynie szyfrogram jest nieprzezroczysty. Ktoś, kto znajdzie plik za pięć lat, gdy aplikacja zniknie, będzie mógł dokładnie zobaczyć, jak został zapieczętowany i otworzyć go za pomocą OpenSSL lub dowolnej biblioteki Argon2.
Format v1 (dostarczany w wersji 1.0, pozostaje czytelny)
{
"format": "authbackup",
"version": 1,
"kdf": "PBKDF2-HMAC-SHA256",
"rounds": 600000,
"salt": "<base64, 16 bytes>",
"cipher": "AES-256-GCM",
"nonce": "<base64, 12 bytes>",
"ciphertext": "<base64>",
"tag": "<base64, 16 bytes>"
}
| Krok | Bajty |
|---|---|
key | PBKDF2-HMAC-SHA256(passphrase as UTF-8, salt, 600000 rounds, 32 bytes) |
aad | UTF-8("authbackup:1:600000:") ‖ salt (surowe bajty soli, nie base64) |
ciphertext, tag | AES-256-GCM(key, nonce, plaintext, aad); znacznik 16 bajtów, przechowywany osobno |
plaintext | UTF-8 JSON, klucze posortowane: {"accounts":[…],"exportedAt":"…Z","passwords":[…],"version":1} |
Uwaga dotycząca zgodności: Android 1.0 zapisał wariant v1 — kdf małymi literami, bez klucza tagu (16-bajtowego tagu dodanego do tekstu zaszyfrowanego), bez dodatkowych danych. Obie platformy odczytują te pliki (gdy tag jest nieobecny: rozdziel ostatnie 16 bajtów, otwórz z pustym AAD; porównaj kdf bez uwzględniania wielkości liter) i obie teraz zapisują tylko powyższy układ.
Format v2 (bieżący, domyślny dla nowych kopii zapasowych)
{
"format": "authbackup",
"version": 2,
"kdf": "Argon2id",
"memoryKiB": 65536,
"passes": 3,
"lanes": 1,
"salt": "<base64, 16 bytes>",
"cipher": "AES-256-GCM",
"nonce": "<base64, 12 bytes>",
"ciphertext": "<base64>",
"tag": "<base64, 16 bytes>"
}
| Krok | Bajty |
|---|---|
key | Argon2id(version 0x13, passphrase as UTF-8, salt, m = 65536 KiB, t = 3, p = 1, tagLength 32, no secret, no associated data) |
aad | UTF-8("authbackup:2:argon2id:65536:3:1:") ‖ salt |
ciphertext, tag | AES-256-GCM(key, nonce, plaintext, aad); znacznik 16 bajtów, przechowywany osobno |
plaintext | UTF-8 JSON, klucze posortowane: {"accounts":[…],"cards":[…],"exportedAt":"…Z","passwords":[…],"version":2} |
Argon2id to referencyjna implementacja języka C (phc-winner-argon2, CC0), dostępna na obu platformach. 64 MiB i 3 przebiegi zajmują około sekundy na obecnym telefonie i sprawiają, że każde odgadnięcie zajmuje tyle samo pamięci i czasu na dowolnym sprzęcie — tej właściwości brakuje PBKDF2 w porównaniu z platformami GPU i to właśnie dlatego istnieje wersja v2. Czytnik ignoruje klucze, których nie zna, więc czytnik v1 z danymi v2 po prostu nigdy nie widzi kart.
Dowód
Trzy pliki wektorów testowych (backup v1, backup v2 i Argon2id) są generowane przez trzecią implementację, niezależną od obu aplikacji (Node's OpenSSL dla PBKDF2 i AES-GCM, WebAssembly Argon2id sprawdzany w trakcie generacji z opublikowanymi odpowiedziami implementacji referencyjnej). Każdy z nich zawiera hasło, sól, wartość nonce, tekst jawny, klucz pochodny, AAD, oczekiwany tekst zaszyfrowany i tag oraz cały plik. Testy jednostkowe na iOS i Androidzie odczytują te same pliki i potwierdzają te same bajty — więc kopia zapasowa zapieczętowana na jednej platformie jest udowodniona, a nie zakładana, że jest otwarta na drugiej, a zgodność wszystkich trzech nie oznacza dwóch kopii tego samego błędu. Narzędzie towarzyszące otwiera plik, który w rzeczywistości został zapisany na telefonie z tą samą trzecią implementacją, i sprawdza, czy nagłówek jest zgodny z powyższymi regułami (dokładnie klucze formatu, więc nie może być żadnej wskazówki ani nazwy; 16-bajtowa sól, 12-bajtowy nonce, 16-bajtowy tag przechowywane oddzielnie; wersja 2 dokładnie 64 MiB / 3 / 1; nieprawidłowe hasło odrzucone). Zautomatyzowane uruchomienie systemu iOS zapisuje nagłówek na symulatorze i otwiera go w ten sposób, a następnie przeszukuje kontener aplikacji symulatora, kontener grupy aplikacji i bazę danych pęku kluczy w celu znalezienia każdego wprowadzonego hasła i numeru karty w formacie UTF-8 i UTF-16 (0 trafień).
4. Model zagrożeń
| Sytuacja | Co oni mają | Co dostają |
|---|---|---|
| Zgubiony lub skradziony telefon, zablokowany | Co oni mająUrządzenie, plik bazy danych, zapieczętowane wiersze | Co dostająSzyfrogram. Klucz do zawijania znajduje się w Secure Enclave/SilverBox i zostaje zwolniony dopiero po zablokowaniu urządzenia i wprowadzeniu nowego kodu biometrycznego lub hasła. Zdalne wyczyszczenie telefonu (funkcja Znajdź mój telefon/Znajdź moje urządzenie) powoduje zniszczenie klucza. |
| Skradziony plik kopii zapasowej | Co oni mająPlik .authbackup z konta w chmurze, poczty e-mail, laptopa | Co dostająTreść AES-256-GCM oparta na kluczu utworzonym na podstawie hasła o długości co najmniej 12 znaków, z solą dla każdego pliku i Argon2id o rozmiarze 64 MiB × 3 przebiegi (v2) lub PBKDF2 o 600 000 rund (v1). Brak podpowiedzi, nazwy użytkownika i listy kont w postaci jawnej. Każde odgadnięcie kosztuje pełne wyprowadzenie hasła; nie ma skrótu. Silne hasło to cała obrona, o czym aplikacja informuje na arkuszu. |
| Skradzione urządzenie z odblokowanym ekranem | Co oni mająTelefon w Twojej dłoni, odblokowany | Co dostająLista kodów. Sejf (hasła, karty) znajduje się za blokadą aplikacji i blokuje się automatycznie po upływie ustawionego czasu (natychmiast / 1 min / 5 min); odszyfrowana wartość znajduje się w pamięci tylko wtedy, gdy jest wyświetlana na ekranie. Funkcje autouzupełniania i eksportu zwykłego tekstu wymagają zaktualizowanych danych biometrycznych nawet po otwarciu aplikacji. Włącz blokadę aplikacji z opcją „Natychmiast”, jeśli Cię to martwi. |
| Złośliwa aplikacja na tym samym telefonie | Co oni mająPiaskownica innej aplikacji, schowek, ułatwienia dostępu lub sztuczki nakładki | Co dostająNie może odczytać naszych plików (piaskownica platformy) ani użyć naszego klucza (klucz jest powiązany z naszą tożsamością podpisującą i obecnością użytkownika). Kopie są usuwane ze schowka po 30 sekundach; na Androidzie kopia jest oznaczana jako poufna i pomijana w historii schowka. Ekrany Vault na Androidzie mają ustawioną flagę FLAG_SECURE (brak zrzutów ekranu, brak nagrywania ekranu, pusta miniatura w przełączniku); iOS czyści miniaturę w przełączniku. Autouzupełnianie na Androidzie jest obsługiwane tylko przez aplikacje, które system zweryfikował w oparciu o zapisaną domenę (Digital Asset Links), więc aplikacja imitująca tę samą aplikację nie otrzymuje hasła. |
| Strona phishingowa | Co oni mająStrona wyglądająca jak ta, którą zapisałeś | Co dostająNic nie jest wypełniane. Dopasowanie odbywa się według domeny rejestrowalnej (publiczna lista sufiksów, dołączona i aktualizowana w aplikacji): login.example.com i example.com pasują, example.com.evil.net i examp1e.com nie. Przeglądarka w aplikacji dopasowuje w ten sam sposób i wypełnia tylko ramkę, która została zapytana, ponownie sprawdzając jej pochodzenie w momencie wypełniania; host bez własnej domeny rejestrowalnej — adresu IP, samej nazwy w sieci lokalnej — pasuje dokładnie i nic luźniej. Funkcja automatycznego wypełniania w systemie iOS dodaje sprawdzanie powiązanych domen Apple. Hasło, które trzeba wkleić ręcznie do podobnego adresu, nadal stanowi ryzyko; aplikacja nie może tego usunąć, a jedynie unikać pomocy. |
| Nasze własne serwery | Co oni mają— | Co dostająNie ma serwera sejfu. AssuredAuth nie ma kont, logowania ani kopii Twojego sejfu, więc po naszej stronie nie ma żadnych Twoich danych, które mogłyby zostać skradzione i złamane. Dwie rzeczy działają po stronie serwera, z których żadna nie ma kontaktu ze sejfem: skrzynka pocztowa przekaźnikowa dla rozszerzenia na komputer, która przechowuje zaszyfrowane od początku do końca koperty (jednorazowe kody, usuwane po odczytaniu; przekaźnik nigdy nie ma klucza) oraz serwery wyjściowe opcjonalnego połączenia prywatnego, które przenoszą ruch i nie przechowują logów dostępu. |
| Wezwanie sądowe lub żądanie rządowe | Co oni mająPostępowanie prawne skierowane do nas | Co dostająNie mamy nic do przekazania: nie posiadamy sejfu, klucza, hasła ani kopii zapasowej. Można nas zmusić do powiedzenia tego; nie można nas zmusić do przedstawienia czegoś, co nie istnieje. |
5. Schowek, zrzuty ekranu i pamięć
- Kopiowanie umieszcza wartość w schowku na 30 sekund, a następnie ją usuwa, jeśli nadal należy do nas. Na Androidzie klip jest oznaczony jako EXTRA_IS_SENSITIVE, więc system ukrywa go w podglądzie i historii schowka; na iOS element schowka jest dostępny tylko lokalnie (nie jest przekazywany do innych urządzeń).
- Ekrany Vault (Hasła, Hasło, Karty, Karta, arkusze haseł, eksport zwykłego tekstu) ustawiają FLAG_SECURE na Androidzie. iOS nie ma równoważnej flagi; aplikacja domyślnie wyłącza miniaturę w przełączniku aplikacji, a wartości są wyświetlane za pomocą przycisku oka.
- Odszyfrowane wartości są przechowywane w pamięci tylko wtedy, gdy ekran jest wyświetlany, i są usuwane po jego zamknięciu lub zablokowaniu aplikacji. Klucz danych jest rozpakowywany na żądanie i nie jest buforowany po zablokowaniu.
- Istnieje eksport zwykłego tekstu (więc zawsze możesz zrezygnować) i jest on obsługiwany przez arkusz potwierdzenia oraz nowy biometr, a jego ekran ma również oznaczenie FLAG_SECURE.
6. Automatyczne wypełnianie: co wypełnia, a co nie
| Gdzie | Hasła | Karty |
|---|---|---|
| iOS: Safari i aplikacje (rozszerzenie AutoFill) | HasłaTak, po nowym Face ID/Touch ID/kodzie dostępu w rozszerzeniu (LAContext) i tylko dla domeny rejestrowalnej, dla której zapisano wpis, z kontrolą powiązanych domen Apple dla aplikacji | KartyNie. Funkcja automatycznego wypełniania kart w Safari jest dostępna wyłącznie w Apple. Na ekranie karty widnieje komunikat „Wypełnianie w przeglądarce AssuredAuth i za pomocą funkcji Kopiuj” i nie ma żadnych innych obietnic. |
| Android: aplikacje i Chrome (AutofillService) | HasłaTak, uwierzytelnianie na podstawie zestawu danych: system wyświetla komunikat BiometricPrompt przed wypełnieniem; pakiet aplikacji jest dopasowywany tylko wtedy, gdy Digital Asset Links powiąże go z zapisaną domeną | KartyTak, wskazówki dotyczące creditCardNumber, creditCardExpiration* i creditCardSecurityCode to ta sama bramka biometryczna |
| Przeglądarka AssuredAuth (obie platformy) | HasłaTak, według domeny rejestrowalnej — hosta, do którego nie pasuje żaden z jego własnych — do ramki, o którą pytano, biometrycznie przed wypełnieniem | KartyTak, poprzez wykrywanie pola, biometryczne przed wypełnieniem |
| Przyciski kopiowania | HasłaZa blokadą aplikacji, schowek na 30 sekund | KartyNumer, data ważności, CVC (te same zasady) |
Nic nie pasuje do hosta, który wygląda podobnie. Nic nie pasuje bez danych biometrycznych.
7. Co nigdy się nie zdarza
Brak serwera skarbca. Brak analiz zawierających pole skarbca. Brak eksportu zwykłego tekstu bez arkusza potwierdzenia i nowych danych biometrycznych. Brak załadowania zewnętrznego zestawu SDK na ekranie skarbca. Brak zrzutu ekranu skarbca. Brak wskazówki dotyczącej hasła. Brak rejestrowania wartości w żadnej kompilacji.
8. Przed czym nie możemy się uchronić
Hasło na tyle słabe, że można je odgadnąć. Telefon, którego system operacyjny jest zainfekowany u źródła (urządzenie z jailbreakiem lub rootem może okłamać aplikację w powyższych kwestiach). Osoba obserwowana podczas pisania. Złośliwe oprogramowanie na pulpicie, do którego wklejasz. Mówimy o tym, aby powyższa lista była zrozumiała: elementy, które projekt może usunąć, usunięte.
9. Sprawdź status
Ten projekt został przetestowany jednostkowo pod kątem opublikowanych, znanych odpowiedzi na obu platformach oraz pod kątem własnych wektorów międzyplatformowych. Zewnętrzna recenzja znajduje się na liście właściciela, zanim sejf zostanie ogłoszony w ofercie sklepu; do momentu jej opublikowania, niniejszy dokument będzie o tym informował.
10. Gdzie wszystko się toczy
Nic z sejfu nie opuszcza telefonu, ale kilka rzeczy w jego pobliżu działa na komputerach innych osób. Oto lista i informacje o tym, co każdy z nich przechowuje; same przepływy danych są opisane w polityce prywatności pod adresem https://assuredauth.com/privacy.
- Google Cloud/Firebase — skrzynka pocztowa przekaźnikowa dla rozszerzenia na komputer (koperty szyfrowane od końca do końca, usuwane po odczytaniu), tokeny push, stan zakupów i wiadomości wysyłane za pośrednictwem formularza kontaktowego.
- Vercel — worriedauth.com, jego strony i drobne funkcje, które za nimi stoją.
- Vultr — serwery wyjściowe połączenia prywatnego. Ruch przechodzi przez nie; nic nie jest przechowywane.
- Apple i Google Play — zakupy i subskrypcje w ich własnych sklepach.
- PostHog — analityka produktów: liczba wykorzystanych produktów, niepowiązana z tożsamością.
- RevenueCat — stan subskrypcji: aktywna lub wygasła oraz na jakim planie jest objęta.
Każdy z nich zawiera to, co wskazuje jego linia, i nic z sejfu. Lista zmienia się wraz z produktem, a ta sekcja zmienia się wraz z nim.
Zgłaszanie słabości
Jeśli uważasz, że znalazłeś lukę w którymkolwiek z opisanych tutaj elementów, napisz na adres hello@assuredauth.com, w temacie wiadomości wpisując „Bezpieczeństwo”. Prosimy o podanie platformy, wersji aplikacji i kroków; dowód oparty na Twoich własnych danych jest wystarczający i prosimy o nieprzeprowadzanie testów na danych innych osób. Nie oferujemy klucza PGP; jeśli raport nie powinien zostać wysłany w zwykłej wiadomości e-mail, poinformuj o tym w pierwszej wiadomości, a ustalimy inny sposób.
W zamian obiecujemy: potwierdzimy zgłoszenie w ciągu trzech dni roboczych, będziemy Cię informować na bieżąco o postępach prac, poprawimy to, co jest prawdziwe, zanim cokolwiek zostanie opublikowane, oraz podajemy Twoje nazwisko, jeśli sobie tego życzysz. Nie będziemy podejmować kroków prawnych w związku z badaniami przeprowadzonymi w dobrej wierze w zakresie opisanym poniżej.
Zakres: aplikacje na iOS i Androida, aplikacje na zegarki, rozszerzenie na pulpit, Ensureauth.com i jego API. Poza zakresem: App Store i Google Play, dostawcy wymienieni powyżej, socjotechnika stosowana wobec kogokolwiek oraz odmowa usługi.
W tej chwili nie ma nagrody. Na zgłoszenie odpowiadamy poprawką i podziękowaniem, a nie pieniędzmi.