Czy jestem nadmiernie inżynierski, jeśli rozważę celowe niewłaściwe postępowanie użytkownika?

12

Czy to nadmierna inżynieria, jeśli dodam ochronę przed umyślnym wykroczeniem użytkownika (delikatnie mówiąc), jeśli szkoda, którą może ponieść użytkownik, nie jest związana z moim kodem?

Aby to wyjaśnić, udostępniam prostą usługę JSON RESTful, taką jak ta:

GET /items - to retrieve list of user's items
PUT /items/id - to modify an item
POST /items - to add a new item

Sama usługa nie jest przeznaczona do korzystania z przeglądarki, ale tylko z aplikacji innych firm, kontrolowanych przez użytkownika (takich jak aplikacje na telefon, aplikacje komputerowe itp.). Ponadto sama usługa powinna być bezstanowa (tzn. Bez sesji).

Uwierzytelnianie odbywa się za pomocą uwierzytelniania podstawowego za pośrednictwem protokołu SSL.

Mówię o jednym możliwym „szkodliwym” zachowaniu, takim jak to:

Użytkownik wprowadza adres GET w przeglądarce (bez powodu, ale ...). Przeglądarka prosi o uwierzytelnienie podstawowe, przetworzenie go i zapisuje uwierzytelnienie dla bieżącej sesji przeglądania. Bez zamykania przeglądarki użytkownik odwiedza złośliwą stronę internetową, która zawiera złośliwy kod JavaScript CSRF / XSRF, który wysyła POST do naszej usługi.

Powyższy scenariusz jest wysoce nieprawdopodobny i wiem, że z perspektywy biznesowej nie powinienem się zbytnio przejmować. Ale czy dla poprawy sytuacji uważasz, że jeśli nazwa użytkownika / hasło są wymagane również w danych JSON POST, to pomoże?

A może powinienem całkowicie zrezygnować z Podstawowego uwierzytelniania, pozbyć się GET i używać tylko POST / PUT z zawartymi w nim informacjami autoryzacyjnymi? Ponieważ informacje pobierane przez GET mogą być również wrażliwe.

Z drugiej strony, czy używanie niestandardowych nagłówków uważa się za czystą implementację REST? Mogę upuścić uwierzytelnianie podstawowe i używać niestandardowych nagłówków. W ten sposób można uniknąć przynajmniej ataku CSRF z przeglądarki, a aplikacje korzystające z usługi ustawią nazwę użytkownika / hasło w niestandardowym wrzosie. Złe dla tego podejścia jest to, że teraz usługa nie może być pobierana z przeglądarki.

Słoneczny
źródło
3
Oprócz mojej odpowiedzi, chciałbym również zostawić to oświadczenie, myślę, że lepiej byłoby odpowiedzieć na SO lub Security
Jeff Langemeier
1
Myślę, że zmieniłeś PUT i POST zgodnie z definicją w RFC 2616 ( tools.ietf.org/html/rfc2616#section-9.5 ).
Svante

Odpowiedzi:

6

Nadmiar inżynierii? Ani trochę. Środki anty-XSRF są niezbędną częścią każdej bezpiecznej aplikacji lub usługi internetowej. Może być „bardzo mało prawdopodobne”, że ktoś zdecyduje się cię zaatakować, ale to nie zmniejsza bezpieczeństwa twojego oprogramowania.

Systemy były często atakowane przy użyciu XSRF i chociaż wyniki są mniej natychmiast - oczywiście złe - niż wstrzykiwanie SQL lub XSS, są wystarczająco złe, aby zagrozić wszystkim funkcjom interakcji użytkownika.

Oznacza to, że nie możesz mieć „czystego” interfejsu RESTful, w którym jedynymi parametrami są właściwości samego wywołania. Musisz uwzględnić w żądaniu coś, czego napastnik nie mógł odgadnąć. Które mogłyby być parę nazwa-hasło, ale to daleko od możliwego tylko wyboru. Możesz mieć nazwę użytkownika razem z tokenem wygenerowanym z solonego skrótu hasła. Możesz mieć tokeny wydane przez samą usługę w czasie uwierzytelniania (które można zapamiętać w sesji lub zweryfikować kryptograficznie).

powinienem pozbyć się GET

Nie, żądania GET są używane dla żądań odczytu, które nie mają żadnej aktywnej operacji zapisu (są „idempotentne”). Tylko operacje zapisu wymagają ochrony XSRF.

Bobin
źródło
Co się stanie, jeśli żądanie GET może ujawnić poufne informacje?
Sunny,
@Sunny: Co uważasz za wrażliwe dane?
Chris,
2
Chris, jeśli popadnę w paranoję, wszystkie dane są wrażliwe, jeśli są odbierane przez „niewłaściwego” użytkownika :). To jest teoretyczne.
Sunny,
proszę przejrzeć zmiany w dodanym przeze mnie pytaniu.
Sunny,
1
Odpowiedzi (GET lub innej metody) może zawierać dane, które powinien widzieć tylko użytkownik. Atak XSRF pozwala osobie atakującej tylko na wysłanie określonego żądania, ale nie pozwala mu odczytać odpowiedzi, która pochodzi z tego żądania. Chyba że skrypt docelowy jest skonstruowany w specjalny sposób, aby umożliwić stronom trzecim czytanie go ze <script>znacznika, celowo („JSONP”) lub przypadkowo ( niezabezpieczony JSON ).
bobince
32

Nigdy niczego nie ufaj. Każda prośba jest atakiem. Każdy użytkownik jest hakerem. Jeśli będziesz rozwijać się w ten sposób, twoja aplikacja będzie znacznie bezpieczniejsza, stabilniejsza i rzadziej zostanie przejęta przez złośliwego użytkownika. Wystarczy jedna sprytna osoba, aby znaleźć sposób na obejście twojego bezpieczeństwa, abyś miał poważne kłopoty ze swoimi danymi (jednym z najcenniejszych zasobów ).

Jeśli zauważyłeś lukę w zabezpieczeniach w swojej aplikacji, zrób wszystko, co uważasz, że musisz zrobić, aby wypełnić lukę. Szczególnie twój interfejs API powinien być najbardziej niezaufanym oprogramowaniem na rynku. Potrzebowałbym poświadczeń i przesyłałbym prośby o pocztę.

Jarrod Pokrzywy
źródło
4
YAY na paranoję! Masz wrogów! (I +1 za każdą prośbę jest atakiem )
Treb
0

Jeśli kod zostanie ustalony i utrzymany, przypadki graniczne powinny być rozpatrywane i rozpatrywane indywidualnie dla każdego przypadku.

NAPRAWA Z POWODU NIEKTÓRYCH BŁĘDÓW Z MOJEJ strony:

GET powinien być nadal używany jako część właściwej usługi RESTful, w każdym przypadku uwierzytelnianie musi nadal tam być. Próbowałem przypuszczać, że ze względów bezpieczeństwa GET jest prawie taki sam jak POST, ale poczta działa bez umieszczania informacji w pasku adresu, co zwykle stanowi dużą różnicę w zabezpieczeniach (i dlaczego nie lubię GET), ale jako opublikowane przez @Lee,

GET requests are used to retrieve resources, and PUT/POST are used to add/update 
resources so it would be completely against expectations for a RESTful API to use
PUT/POST to get data. 

Ponieważ będą to wykorzystywane przez aplikacje innych firm, należy postępować zgodnie z dobrymi praktykami dla usługi RESTful, aby implementator końcowy nie był z tego powodu pomylony.

Jeff Langemeier
źródło
3
Czym różni się GET od POST pod względem bezpieczeństwa? Oba są wysyłane zwykłym transportem (HTTP lub HTTPS), jedyną różnicą jest to, że ciągi zapytań GET są widoczne na pasku adresu.
tdammers
1
@Sunny: POST jest pod tym względem równie narażony jak GET. Uruchom telnet i porozmawiaj z serwerem internetowym, jeśli mi nie wierzysz.
tdammers
1
@Jeff: Powodem, dla którego uruchamiam telnet (lub curl, wget lub dobry staromodny sniffer) jest to, że pozwala ci zobaczyć pełny strumień danych. Tak, HTTPS ukrywa te informacje przed osobami podsłuchującymi, ale każdy po obu stronach połączenia SSL może zobaczyć dokładnie to, co widzi telnet.
tdammers
1
@Jeremy: POST nie pokazuje parametrów w pasku adresu, ale ponieważ dane są tak samo widoczne w rzeczywistym strumieniu HTTP, masz całkowitą rację.
tdammers
7
Żądania GET służą do pobierania zasobów, a PUT / POST są używane do dodawania / aktualizacji zasobów, więc byłoby całkowicie niezgodne z oczekiwaniami, że RESTful API użyje PUT / POST do uzyskania danych.
Lee,
0

Należy wziąć pod uwagę wszystkie prawdopodobne zdarzenia, w tym użytkownika, który jest aktywnie złośliwy i (z powodzeniem) odtwarzać wszelkie bariery „bezpieczeństwa przez zaciemnienie”.

Ale jednocześnie powinieneś oceniać wpływ hakerskiego sukcesu i prawdopodobieństwo podjęcia próby. Na przykład:

  • Usługa wewnętrzna chroniona przez solidną zaporę ogniową jest mniej podatna na atak niż usługa w publicznym Internecie.

  • Wpływ, że ktoś zdejmie forum dyskusyjne z klientem, jest mniejszy niż wpływ, jaki ma kradzież kart kredytowych klienta.


Chodzi mi o to, że „całkowite bezpieczeństwo” jest „nieskończenie drogie” ... i praktycznie niemożliwe do osiągnięcia. Idealnie powinieneś podejmować decyzje o tym, gdzie wytyczyć linię na podstawie dokładnej analizy kosztów i korzyści.

Stephen C.
źródło
Dzięki. Pytanie nie dotyczyło ochrony „przed” użytkownikiem, ale ochrony samego użytkownika, jeśli będą działać nieodpowiedzialnie. Ale twoja odpowiedź zawiera kilka dobrych argumentów.
Sunny