Publiczne strony SaaS mogą pozostać otwarte dla wszystkich, podczas gdy operacje administracyjne za nimi odrzucają każdego spoza VPN. Mechanizm, który to umożliwia, to nie ukryte menu ani osobna strona logowania; to sprawdzenie ścieżki sieciowej, która dostarczyła żądanie. Jeśli dowód adresu jest błędny, sprawdzenie albo blokuje prawdziwych administratorów, albo wpuszcza każdego, kto potrafi wpisać nagłówek. Zacznij od tego, co źródło faktycznie otrzymuje.

Co źródło faktycznie otrzymuje po tunelu

Gdy przeglądarka dociera do publicznej witryny przez VPN, który przenosi też ruch internetowy, brama tłumaczy połączenie, zanim ono wyjdzie. SaaS widzi publiczny adres wyjściowy bramy, zwykle jeden adres lub niewielki zakres, i nigdy nie widzi adresu tunelu laptopa. Dlatego dodanie 10.90.0.42 do listy dozwolonych zawodzi, a dlatego dodanie całego RFC 1918 zawodzi jeszcze głośniej: to drugie wpuszcza każdą sieć prywatną, która może do Ciebie dotrzeć. Jedyny adres wart warunku to ten, który Twoja organizacja faktycznie posiada na wyjściu.

curl -s https://ifconfig.me
dig +short admin.example.com

Dzielony tunel cicho łamie to założenie. Jeśli VPN przenosi tylko prywatne trasy biurowe, żądanie do publicznej nazwy hosta administracyjnego wychodzi przez lokalnego dostawcę, a źródło widzi adres domowy. Podłączona ikona VPN niczego nie dowodzi w kwestii tej konkretnej destynacji, więc testuj destynację, a nie tunel.

Zatrzymaj się i napraw trasowanie, zanim napiszesz jakąkolwiek politykę, jeśli adres wyjściowy różni się dla poszczególnych użytkowników. Warunek pasujący tylko do części administratorów jest gorszy niż brak warunku, bo ukrywa problem aż do incydentu.

Ufaj tylko proxy, które przepisuje adres

Większość publicznych witryn stoi za CDN lub odwrotnym proxy, więc adres gniazda źródła należy do tego frontendu, a nie do odwiedzającego. Frontend zwykle przekazuje oryginalny adres w nagłówku, i ten nagłówek jest kontrolowany przez atakującego, chyba że źródło przyjmuje go tylko od znanych proxy. Skonfiguruj jawnie listę zaufanych źródeł i uczyń źródło nieosiągalnym z każdego innego miejsca. Bez tej drugiej połowy atakujący omija proxy i wysyła nagłówek bezpośrednio.

set_real_ip_from 192.0.2.0/24;
real_ip_header X-Forwarded-For;
real_ip_recursive on;
curl -H 'X-Forwarded-For: 198.51.100.27' https://origin.example.com/admin

To samo rozumowanie dotyczy protokołu PROXY: jest godny zaufania tylko wtedy, gdy nasłuch jest przypisany do interfejsu, do którego proxy może dotrzeć, a nic innego nie może. Brak kontekstu adresu musi spowodować niepowodzenie chronionego sprawdzenia, a nie przejście do domyślnego zezwolenia. Brakujący nagłówek nie jest dowodem zaufanej ścieżki.

Przypnij warunek do każdej chronionej operacji

Umieść sprawdzenie na granicy autoryzacji, przez którą przechodzi każda chroniona operacja, a nie na stronie renderującej menu. Grupy tras, middleware lub warstwa polityk działają wszystkie; kopia dla każdego handlera nie, bo handler dodany w następnym kwartale jej nie będzie miał.

user = requireAuthenticatedSession()
requirePermission(user, "admin")
requireVpnEgress(verifiedClientAddress(request))
performProtectedOperation(user, request)

Ta sama granica musi obejmować JSON API, eksporty, podpisane adresy URL pobierania i uścisk dłoni WebSocket, ponieważ żadne z nich nie wymaga wcześniejszego żądania strony HTML. Link do pobrania utworzony, gdy VPN był aktywny, pozostaje ważny później, chyba że punkt pobierania sprawdzi ponownie. Długotrwałe sesje również wymagają reguły ponownej oceny, inaczej jedno uwierzytelnione żądanie staje się trwałym wyjątkiem. Domyślna odmowa to jedyne ustawienie, które przetrwa rotację personelu.

Współdzielone pamięci podręczne to druga droga wokół sprawdzenia. Pamięć podręczna, która już przechowuje chronioną odpowiedź, może ją wydać bez kontaktowania się ze źródłem, więc oznacz odpowiedzi administracyjne jako prywatne i trzymaj je poza współdzielonym magazynem. Jeśli pamięć podręczna musi je wydawać, sprawdzenie dostępu musi zostać uruchomione przed wydaniem, co zwykle oznacza, że w ogóle nie może być współdzieloną pamięcią podręczną.

Przetestuj obejścia, które właśnie zamknąłeś

Przećwicz macierz, a nie szczęśliwą ścieżkę: administrator przez VPN, ten sam administrator bez niego, nie-administrator przez niego i sfałszowany nagłówek adresu. Dodaj żądanie bezpośrednio do źródła i żądanie z odpowiedzią z pamięci podręcznej, bo właśnie te dwa całkowicie omijają frontend.

curl -sI https://admin.example.com/export.csv
curl -s -H 'X-Forwarded-For: 198.51.100.27' https://origin.example.com/admin
curl -s https://admin.example.com/api/me -o /dev/null -w '%{http_code}\n'

Każde żądanie powinno zwracać status, który obiecuje polityka, a log powinien rejestrować, którego dowodu adresu użyto. Obejmij IPv6 osobno, bo źródło dwustosowe może widzieć inną rodzinę źródeł niż testowana. Utrzymuj zwykłe operacje klientów działające poza VPN, inaczej zmiana zostanie wycofana przy pierwszej skardze klienta. Zapisz oczekiwany wynik dla każdego wiersza przed uruchomieniem, aby niespodziewane przejście było widoczne.

Adres wyjściowy dowodzi dozwolonej ścieżki sieciowej, a nie osoby i nie zarządzanego urządzenia. Trzymaj go jako jeden warunek obok uwierzytelnienia i uprawnienia, a strefa administracyjna pozostaje wąska bez zamieniania całego produktu w usługę tylko dla VPN. To rozdzielenie jest projektem, a nie jego ograniczeniem.

Powiązane artykuły