Autoryzacja i kontrola dostępu
Uwierzytelnianie udowadnia, kim jesteś. Autoryzacja decyduje, czego możesz dotknąć. Najczęstszą i najbardziej szkodliwą wadą nowoczesnych aplikacji jest błąd w tej drugiej kwestii: zalogowany użytkownik odczytuje lub zmienia dane, które nie są jego.
Lista kontrolna
- Sprawdzaj własność przy każdym dostępie do obiektu. Dla każdej trasy, która przyjmuje identyfikator (fakturę, notatkę, projekt, wiadomość), potwierdź, że bieżący użytkownik jest właścicielem lub może uzyskać dostęp do tego konkretnego rekordu, zanim go zwrócisz lub zmienisz. To Broken Object Level Authorization (BOLA), zwane także IDOR, i jest to ryzyko numer jeden według OWASP.
- Filtruj po właścicielu, a nie tylko po identyfikatorze. Zapytanie w rodzaju
SELECT * FROM invoices WHERE id = ?jest IDOR. Zamień je naWHERE id = ? AND owner_id = ?i zwracaj 404 przy braku trafienia. - Nie polegaj na kliencie w ukrywaniu rzeczy. Ukryty przycisk ani brakujący link nie są kontrolą dostępu. Sprawdzenie musi odbywać się po stronie serwera.
- Zachowaj autoryzację przy refaktoryzacji. Sprawdzenia dostępu dodane w jednej zmianie są często usuwane w następnej. Po każdej zmianie w trasach danych ponownie testuj własność.
- Wymuszaj bezpieczeństwo na poziomie wierszy w bazie danych (row-level security), jeśli Twoja platforma to obsługuje, aby zapomniane sprawdzenie w kodzie zostało wychwycone przez warstwę danych.
- Chroń każdą trasę administracyjną i wewnętrzną. Potwierdź, że wywołujący jest rzeczywiście administratorem ze zaufanego źródła (rola po stronie serwera, a nie pole, które użytkownik może ustawić), i utrzymuj trasy tylko wewnętrzne niedostępne z publicznego internetu.
- Izoluj najemców. W aplikacji wielodzierżawnej każde zapytanie i każda ścieżka pliku muszą być ograniczone do najemcy wywołującego przez jeden punkt kontrolny, aby jeden klient nigdy nie mógł dotrzeć do danych ani plików innego.
- Ogranicz ścieżki plików. Gdy żądanie wskazuje plik, rozwiąż jego ścieżkę i potwierdź, że pozostaje w dozwolonym katalogu. Sprawdzenie musi uwzględniać separator ścieżki, aby katalog-sąsiad o dłuższej nazwie, zaczynającej się tak samo, nie był osiągalny.
Jak testować
- Utwórz dwa konta. Jako konto A zażądaj bezpośrednio identyfikatorów obiektów konta B. Nic z należącego do B nie powinno wrócić.
- Wywołaj trasę administracyjną tokenem zwykłego użytkownika. Oczekuj 403.
- Wyślij ścieżki z sekwencją
../oraz ścieżki z sąsiednim katalogiem o dłuższej nazwie do dowolnego punktu końcowego plików.