# 12. Bezpieczeństwo i RODO

System przechowuje imiona, nazwiska, numery telefonów, daty urodzenia i notatki o zdrowiu i preferencjach klientek salonów. To dane osobowe, a część notatek może być danymi wrażliwymi. Wyciek oznacza koniec produktu.

## Uwierzytelnianie

| Element | Rozwiązanie |
|---|---|
| Hasła | `password_hash()` z `PASSWORD_DEFAULT`, obecnie bcrypt. Nigdy własne mieszanie ani szyfrowanie odwracalne |
| Minimalna długość | 10 znaków, bez wymuszania znaków specjalnych. Długość działa lepiej niż wykrzyknik na końcu |
| Sprawdzanie słabych haseł | Lista 1000 najczęstszych haseł, odrzucane przy rejestracji |
| Sesje | W bazie, identyfikator 64 znaki z `random_bytes`, ciasteczko `HttpOnly`, `Secure`, `SameSite=Lax` |
| Czas życia sesji | 12 godzin od ostatniej aktywności, po tym ponowne logowanie |
| Zmiana hasła | Wymaga starego hasła, unieważnia wszystkie pozostałe sesje |
| Reset hasła | Token 64 znaki, w bazie tylko jego skrót, ważny 60 minut, jednorazowy |
| Ograniczanie prób | 5 nieudanych prób na konto blokuje je na 15 minut, 20 prób z jednego adresu IP blokuje adres na godzinę |
| Wyliczanie kont | Komunikat przy logowaniu i przy resecie jest zawsze taki sam, niezależnie od tego, czy konto istnieje |
| Dwuskładnikowe | Dla operatora w etapie 9, dla salonów opcjonalnie później |

## Ochrona przed typowymi atakami

| Atak | Zabezpieczenie |
|---|---|
| SQL injection | Wyłącznie zapytania parametryzowane przez PDO. Sklejanie SQL z danymi wejściowymi jest zakazane, także dla nazw kolumn przy sortowaniu, gdzie używa się białej listy |
| XSS | Każde wyjście przez `e()`, czyli `htmlspecialchars` z `ENT_QUOTES` i UTF-8. Surowy HTML tylko tam, gdzie treść przeszła przez oczyszczanie, a takich miejsc na razie nie ma |
| CSRF | Token w sesji, sprawdzany przy każdym żądaniu POST, PUT i DELETE. Wyjątki: webhooki, które mają własną weryfikację podpisu |
| Przejęcie sesji | Odtworzenie identyfikatora sesji po zalogowaniu, powiązanie z adresem IP i przeglądarką z tolerancją na zmianę sieci |
| Wgrywanie plików | Biała lista rozszerzeń i typów MIME, sprawdzenie zawartości, nowa losowa nazwa, katalog bez prawa wykonywania, limit rozmiaru |
| Przechodzenie po katalogach | Ścieżki plików nigdy nie pochodzą z żądania, tylko z bazy |
| Wyliczanie identyfikatorów | Brak dostępu do cudzego rekordu daje 404, nie 403 |
| Clickjacking | Nagłówek `X-Frame-Options: SAMEORIGIN` |
| Podsłuch | Wymuszone HTTPS, nagłówek HSTS na rok, przekierowanie z HTTP |

### Nagłówki bezpieczeństwa

```apache
Header always set X-Content-Type-Options "nosniff"
Header always set X-Frame-Options "SAMEORIGIN"
Header always set Referrer-Policy "strict-origin-when-cross-origin"
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
Header always set Content-Security-Policy "default-src 'self'; img-src 'self' data:; style-src 'self' 'unsafe-inline'; script-src 'self'; frame-ancestors 'self'"
```

Polityka CSP bez `unsafe-inline` dla skryptów oznacza, że skrypty siedzą w plikach, nie w atrybutach `onclick`. Jest to celowe ograniczenie od pierwszego etapu, bo dołożenie go później wymaga przepisania widoków.

## Role w rozumieniu RODO

| Rola | Kto | Zakres |
|---|---|---|
| Administrator danych | Salon | Dane jego klientek. To salon decyduje, po co je zbiera |
| Podmiot przetwarzający | Operator systemu | Przetwarza dane klientek w imieniu salonu |
| Administrator danych | Operator systemu | Dane właścicielek i pracowników salonów, czyli użytkowników systemu |

Z tego wynika obowiązek zawarcia **umowy powierzenia przetwarzania danych** z każdym salonem. Umowa jest częścią regulaminu akceptowanego przy rejestracji, a jej treść musi przygotować prawnik. Wzór w internecie nie wystarczy, bo odpowiedzialność jest realna.

## Podstawy prawne przetwarzania

| Dane | Podstawa | Uwagi |
|---|---|---|
| Dane klientki do realizacji wizyty | Wykonanie umowy albo prawnie uzasadniony interes salonu | Imię, nazwisko, telefon |
| SMS przypominający o wizycie | Wykonanie umowy, wiadomość transakcyjna | Nadal wymaga zgody na kontakt SMS z ustawy o świadczeniu usług drogą elektroniczną |
| SMS marketingowy, urodzinowy, odzyskujący | Zgoda | Osobna, odwoływalna, z datą |
| Data urodzenia | Zgoda | Zbierana tylko przy włączonych życzeniach urodzinowych |
| Notatki o klientce | Prawnie uzasadniony interes | Uwaga: notatka o alergii albo stanie zdrowia to dane szczególnej kategorii |
| Zdjęcia przed i po | Zgoda, osobna | Funkcja z poczekalni, przy jej wdrożeniu potrzebna osobna zgoda i osobne zasady |

W interfejsie przy polu notatki pojawia się krótka informacja, żeby nie wpisywać tam informacji o zdrowiu bez zgody klientki. Nie zwalnia to salonu z odpowiedzialności, ale zmniejsza liczbę problemów.

## Prawa osób, których dane dotyczą

| Prawo | Realizacja w systemie | Etap |
|---|---|---|
| Dostęp do danych | Eksport karty klientki do PDF, przycisk w karcie | 10 |
| Sprostowanie | Edycja karty | 2 |
| Usunięcie | Usunięcie klientki, z zachowaniem danych rozliczeniowych wizyt w formie zanonimizowanej | 10 |
| Ograniczenie przetwarzania | Oznaczenie klientki jako wyłączonej z wysyłek | 5 |
| Przenoszenie danych | Eksport do CSV | 10 |
| Sprzeciw wobec marketingu | Wyłączenie zgody marketingowej, natychmiastowy skutek | 5 |

**Usunięcie klientki** nie kasuje wizyt, bo salon musi mieć historię do rozliczeń. Zamiast tego imię i nazwisko zamieniane są na "Klientka usunięta", numer telefonu i e-mail są kasowane, notatki kasowane, a wizyty zostają z kwotami i usługami.

## Retencja danych

| Dane | Okres | Potem |
|---|---|---|
| Klientka bez wizyty od 5 lat | 5 lat | Powiadomienie salonu o możliwości usunięcia, bez automatycznego kasowania |
| Wizyty | 6 lat | Wymóg przechowywania dokumentacji rozliczeniowej |
| Treści SMS | 12 miesięcy | Kasowane, w historii zostaje typ, status i koszt |
| Logi błędów | 90 dni | Kasowane |
| Próby logowania | 30 dni | Kasowane |
| Dziennik operacji | 24 miesiące | Kasowane |
| Dane salonu po rezygnacji | 90 dni | Kasowane po wcześniejszym powiadomieniu |
| Kopie zapasowe | według harmonogramu z dokumentu 11 | Nadpisywane |

Automatyczne kasowanie wykonuje zadanie `Cleanup`, a każde uruchomienie zapisuje, ile rekordów usunęło.

## Dziennik operacji

Do dziennika trafiają operacje, o które ktoś kiedyś zapyta:

- logowanie udane i nieudane, z adresem IP
- zmiana hasła i zmiana adresu e-mail
- utworzenie, zmiana i usunięcie pracownika
- każda zmiana uprawnień
- usunięcie klientki
- eksport danych
- wysyłka grupowa SMS
- zmiana ceny na wizycie już utworzonej
- każda akcja operatora w panelu, w tym wejście w tryb wsparcia

Dziennik jest tylko do odczytu, także dla właścicielki salonu. Nie ma w interfejsie sposobu na usunięcie z niego wpisu.

## Zgłaszanie naruszeń

Procedura na wypadek podejrzenia wycieku, spisana zanim będzie potrzebna:

1. Odciąć dostęp: wyłączyć konto, zmienić klucze, unieważnić wszystkie sesje.
2. Ustalić zakres z dziennika operacji i logów serwera.
3. Zabezpieczyć dowody: kopia logów w osobnym miejscu, bez nadpisywania.
4. Jeśli doszło do naruszenia ochrony danych, zgłoszenie do Prezesa UODO w ciągu 72 godzin.
5. Powiadomienie salonów, których dane dotyczą, a przy wysokim ryzyku także ich klientek. Obowiązek powiadomienia klientek leży po stronie salonu jako administratora, ale operator musi dać mu wszystko, czego do tego potrzebuje.
6. Opis zdarzenia i wniosków, w rejestrze naruszeń.

Kontakt do zgłoszeń podatności jest widoczny w stopce strony i w regulaminie. Ktoś, kto znajdzie dziurę, powinien mieć gdzie ją zgłosić, zamiast szukać innego zastosowania.

## Dokumenty do przygotowania przed sprzedażą

- [ ] Regulamin świadczenia usług
- [ ] Polityka prywatności
- [ ] Umowa powierzenia przetwarzania danych, jako załącznik do regulaminu
- [ ] Informacja o plikach cookies
- [ ] Rejestr czynności przetwarzania
- [ ] Wzór zgody dla klientek salonu, do wykorzystania przez salony

Wszystkie powinien sprawdzić prawnik przed pierwszą płatnością od klienta. To jedyny punkt w całym projekcie, którego nie da się zrobić samodzielnie.
