2013-05-06 8 views
32

Muszę przygotować plan utworzenia RESTful API (Python/Flask), który może być użyty przez naszą przyszłą aplikację internetową (Angularjs) i aplikacje mobilne (iOS/Android).Zabezpieczone RESTful API, które może być używane przez aplikację internetową (kątową), iOS i Android

Prowadzę badania przez trzy dni i natknąłem się na kilka scenariuszy: Korzystanie z HTTPS jest jednym ze sposobów na poniższą metodę, aby zachować bezpieczeństwo. Ale https jest wolniejszy, co może oznaczać, że potrzebujemy szybszych i droższych serwerów.

  1. Używanie Basic-Http-Auth i wysyłanie nazwy użytkownika/hasła w prostym (ale https) przez przewód dla każdego żądania do API.
  2. Korzystanie z funkcji Digest-Auth, która jest hash hasła i śledzenie będzie automatyczne To działałoby dla aplikacji internetowej, jednak nie byłem w stanie potwierdzić, czy iPhone i system Android będą obsługiwały to natywnie. Jeśli tak, to może być proste rozwiązanie!
  3. Używanie niestandardowego nagłówka http, w którym po pomyślnym uwierzytelnieniu został wysłany niestandardowy ciąg znaków Auth w nagłówku http. Ale potem muszę się upewnić, że wysyłam ten kod autoryzacyjny dla każdego żądania, które robi użytkownik. To sprawia, że ​​jest dokładnie taki jak 1) z tą różnicą, że zwykłe hasła nie są używane, a kod autoryzacji może wygasnąć bez żadnego ryzyka. Problematyczne jest również śledzenie kodu auth, który nie jest już zautomatyzowany, jak w 2).
  4. Korzystanie z OAuth jest opcją. Ale jest to dość trudne do ustawienia. Jeśli nie ma lepszego sposobu, może to jedyny sposób?
  5. Zabezpieczanie interfejsu API, podobnie jak w przypadku Amazon S3, zgodnie z opisem w tym great article. Mówiąc krótko, mówi on, że zarówno serwer, jak i klient znają klucz prywatny, którego użyliby do połączenia komunikacji. To będzie jak uścisk dłoni gangstera, że ​​zaufasz tylko chłopcu-doręczycielowi, jeśli pozna gangsterski uścisk dłoni. Dalej w dół komentarze ktoś pyta:

Jak zachować klucz prywatny „bezpieczne” w czystej aplikacji HTML5?

Masz dokładnie rację; w czystej aplikacji HTML5 (JS/CSS/HTML), , nie ma ochrony klucza. Będziesz wykonywać całą komunikację ponad HTTPS, w którym to przypadku nie potrzebujesz klucza, ponieważ możesz bezpiecznie zidentyfikować klienta przy użyciu standardowego klucza API_KEY lub innego przyjaznego identyfikatora bez potrzeby lub złożoności HMAC.

Innymi słowy, nie ma nawet sensu stosowanie metody dla aplikacji internetowej na pierwszym miejscu. Szczerze mówiąc nie rozumiem, jak to powinno działać na urządzeniu mobilnym. Użytkownik ściąga naszą aplikację i jak wysłać klucz prywatny z iPhone'a na serwer? W momencie, kiedy go przeniosę, zostanie on skompromitowany.

Im więcej badam, tym bardziej jestem niezdecydowany.

Miałem nadzieję spytać niektórych profesjonalistów, którzy zrobili to wcześniej i mogli podzielić się swoimi doświadczeniami. Wielkie dzięki

+2

Mam z tym samym pytaniem. Uwierzytelnienie wydaje się być słoniem w pokoju REST ... – jbandi

+0

jbandi, to pytanie dotyczy raczej zabezpieczenia ruchu, a nie uwierzytelniania (jeśli czytam to dobrze). Jeśli masz konkretne pytanie dotyczące obsługi uwierzytelniania w RESTful/Web API, nie miałbym nic przeciwko temu. Po ustaleniu, opcje uwierzytelniania/zarządzania sesją są identyczne z tradycyjnymi aplikacjami internetowymi. –

Odpowiedz

65

Wydajesz się być zagmatwany/połączenie dwóch różnych koncepcji razem. Zaczynamy mówić o szyfrowaniu ruchu (HTTPS), a następnie zaczynamy mówić o różnych sposobach zarządzania uwierzytelnionymi sesjami. W bezpiecznej aplikacji nie są to wzajemnie wykluczające się zadania. Wydaje się również, że istnieje nieporozumienie, w jaki sposób zarządzanie sesją może wpływać na uwierzytelnianie. Na tej podstawie udostępnię element startowy w zarządzaniu sesjami aplikacji internetowych/web api, uwierzytelnianiu i szyfrowaniu.

Wprowadzenie

Session Management

transakcji HTTP jest bezpaństwowcem domyślnie. HTTP nie określa żadnej metody informowania aplikacji, że żądanie HTTP zostało wysłane od określonego użytkownika (uwierzytelnionego lub nie).

Dla niezawodnych aplikacji internetowych jest to niedopuszczalne. Potrzebujemy sposobu na powiązanie żądań i danych z wielu żądań. Aby to zrobić, na pierwsze żądanie do serwera użytkownik musi mieć przypisaną "sesję". Ogólnie sesje mają pewien unikalny identyfikator wysyłany do klienta. Klient wysyła ten identyfikator sesji z każdym żądaniem, a serwer używa identyfikatora sesji wysłanego w każdym żądaniu, aby odpowiednio przygotować odpowiedź dla użytkownika.

Należy pamiętać, że "identyfikator sesji" można nazwać wieloma innymi rzeczami. Oto kilka przykładów: token sesji, token itd. W celu zachowania spójności będę używał "identyfikatora sesji" do końca tej odpowiedzi.

Każde żądanie HTTP od klienta musi zawierać identyfikator sesji; można tego dokonać na wiele sposobów. Popularne przykłady to:

  1. Może być przechowywany w pliku cookie - pliki cookie dla bieżącej domeny są automatycznie wysyłane na każde żądanie.
  2. Może zostać wysłany na adres URL - każde żądanie może wysłać identyfikator sesji na adres URL, a nie sugerowane, ponieważ identyfikatory sesji pozostaną w historii klientów
  3. Może zostać wysłane jako nagłówek HTTP - każde żądanie będzie potrzebne w celu określenia nagłówka

Większość frameworków aplikacji internetowych używa plików cookie. Jednak aplikacje oparte na JavaScript i projektach na jednej stronie mogą zdecydować się na użycie nagłówka HTTP/zapisać go w innej lokalizacji obserwowalnej przez serwer.

Bardzo ważne jest, aby pamiętać, że odpowiedź HTTP, która powiadamia klienta o identyfikatorze sesji i żądaniach klienta, które zawierają identyfikator sesji, jest całkowicie czysta i w 100% niebezpieczna. Aby to zwalczyć, cały ruch HTTP musi zostać zaszyfrowany; właśnie tam pojawia się HTTPS.

Należy również podkreślić, że nie rozmawialiśmy o łączeniu sesji z konkretnym użytkownikiem w naszym systemie. Zarządzanie sesją to po prostu powiązanie danych z konkretnym klientem uzyskującym dostęp do naszego systemu. Klient może znajdować się zarówno w stanie uwierzytelnionym, jak i nieuwierzytelnionym, ale w obu stanach zazwyczaj ma sesję.

Authentication

Uwierzytelnianie jest gdzie odwołuje sesję do określonego użytkownika w naszym systemie. Zwykle jest to obsługiwane przez proces logowania, w którym użytkownik dostarcza poświadczenia, te poświadczenia są weryfikowane, a następnie łączymy sesje z konkretnym rekordem użytkownika w naszym systemie.

Użytkownik jest z kolei powiązany z uprawnieniami do drobnoziarnistej kontroli dostępu za pomocą list kontroli dostępu i wpisów kontroli dostępu (ACL i ACE). Jest to ogólnie określane jako "autoryzacja". Większość systemów zawsze ma uwierzytelnienie i autoryzację. W niektórych prostych systemach wszyscy uwierzytelnieni użytkownicy są równi, w takim przypadku nie będziesz mieć autoryzacji poza prostym uwierzytelnianiem. Dalsze informacje na ten temat są poza zakresem tego pytania, ale rozważ przeczytanie o ACE/ACL.

Określona sesja może być oflagowana jako reprezentująca uwierzytelnionego użytkownika na różne sposoby.

  1. Ich dane sesji po stronie serwera przechowywane mógłby przechowywać swoje ID użytkownika/jakąś inną flagę, która oznacza, że ​​używanie jest uwierzytelniona jako konkretnego użytkownika
  2. Inny użytkownik Token może być wysyłany do klienta jak identyfikator sesji (która przez nieszyfrowany HTTP jest tak samo niebezpieczna jak wysyłanie identyfikatora sesji bez szyfrowania)

Każda opcja jest w porządku. Zasadniczo sprowadza się do technologii, w której pracujesz i co oferuje domyślnie.

Klient zwykle inicjuje proces uwierzytelniania. Można to zrobić, wysyłając poświadczenia do określonego adresu URL (np. Twoja_witryna.com/api/login). Jeśli jednak chcemy być "ZWALNIENI", generalnie odnosilibyśmy się do zasobu przez jakiś rzeczownik i wykonywaliśmy akcję "tworzenia". Można to zrobić, wymagając POST poświadczeń do yoursite.com/api/authenticatedSession/. Gdzie pomysł polega na stworzeniu uwierzytelnionej sesji. Większość witryn po prostu POST poświadczeń do/api/login lub tym podobne. Jest to odejście od "prawdziwych" lub "czystych" ideałów REST, ale większość ludzi uważa to za prostszą koncepcję, zamiast myśleć o niej jako o "tworzeniu uwierzytelnionej sesji".

Encryption

HTTPS jest używany do szyfrowania ruchu HTTP między klientem a serwerem. W systemie, który opiera się na uwierzytelnionych i nieuwierzytelnionych użytkownikach, cały ruch związany z uwierzytelnionym użytkownikiem musi być szyfrowany za pomocą protokołu HTTPS; nie da się tego obejść.

Powodem tego jest to, że jeśli uwierzytelnisz użytkownika, podzielisz się z nim sekretem (ich identyfikatorem sesji, itp.), A następnie zaczniesz paradować w tajemnicy w prostym protokole HTTP, a ich sesja może zostać przejęta przez man-in-the- ataki średnie. Haker będzie czekał, aż ruch przejdzie przez obserwowaną sieć i ukradnie sekret (od zwykłego tekstu przez HTTP), a następnie zainicjuje połączenie z serwerem, udając pierwotnego klienta.

Jednym ze sposobów walki z tym jest powiązanie zdalnego adresu IP żądań z sesją uwierzytelnioną. Jest to nieefektywne, ponieważ każdy haker będzie w stanie sfałszować swoje żądania dotyczące zdalnego adresu IP w swoich fałszywych żądaniach, a następnie obserwować odpowiedzi wysyłane przez serwer.Większość twierdzi, że nie jest to nawet warte wdrożenia, chyba że śledzisz dane historyczne i używasz ich do identyfikacji wzorców logowania określonego użytkownika (takich jak Google).

Jeśli zachodzi potrzeba podziału witryny między sekcje HTTP i HTTPS, ruch HTTP nie powinien wysyłać ani odbierać identyfikatora sesji ani żadnego tokena używanego do zarządzania statusem uwierzytelniania użytkownika. Ważne jest również, aby nie wysyłać poufnych danych aplikacji w żądaniach/odpowiedziach innych niż HTTPs.

Jedynym sposobem zabezpieczenia danych w aplikacjach internetowych/interfejsach API jest szyfrowanie ruchu.

Twoje tematy jeden po drugim

Basic-http-Auth

  • Authentication: TAK
  • Session Management: BRAK
  • szyfrowania: BRAK

Jest metoda uwierzytelniania wyłącznie za pomocą zasobów sieciowych. Podstawowe uwierzytelnianie uwierzytelnia zastosowania według zasobów zidentyfikowanych przez URL. Zostało to najczęściej zaimplementowane przez Apache HTTP Web Server przy użyciu uwierzytelniania katalogu/lokalizacji opartego na .htaccess. Poświadczenia należy wysyłać przy każdym żądaniu; klienci zwykle traktowali to w sposób przejrzysty dla użytkowników.

Uwierzytelnianie podstawowe może być używane przez inne systemy jako tryb uwierzytelniania. Jednak systemy korzystające z Basic-Http-Auth zapewniają uwierzytelnianie i zarządzanie sesją, a nie samo Basic-Http-Auth.

  • To nie jest zarządzanie sesją.
  • To nie jest szyfrowanie; treść i poświadczenia to prawie 100% zwykłego tekstu.
  • Nie zapewnia to zawartości żądań/odpowiedzi HTTP aplikacji.

Digest-Auth

  • Uwierzytelnianie: TAK
  • Session Management: NIE
  • Szyfrowanie: BRAK

To jest dokładnie taka sama jak Basic-http-Auth z dodatkiem prostego trawienia MD5. To trawienie nie powinno polegać na szyfrowaniu.

  • To nie jest zarządzanie sesją.
  • To nie jest szyfrowanie; Podsumowanie jest łatwo zerwane.
  • Nie zapewnia to zawartości żądań/odpowiedzi HTTP aplikacji.

OAuth

  • Uwierzytelnianie: TAK
  • Session Management: NIE
  • Szyfrowanie: BRAK

OAuth tylko pozwala mieć usług zewnętrznych sprawdzania referencji. Następnie musisz zarządzać/pracować z wynikiem żądania uwierzytelnienia do swojego dostawcy OAuth.

  • To nie jest zarządzanie sesją.
  • To nie jest szyfrowanie; Twój ruch w witrynie wciąż jest zwykłym tekstem. Proces uwierzytelniania będzie bezpieczny z powodu ograniczeń HTTPS, ale twoja aplikacja jest nadal podatna na ataki.
  • Nie zapewnia to zawartości żądań/odpowiedzi HTTP aplikacji.

Gangster Handshake/niestandardowy nagłówek HTTP

  • Uwierzytelnianie: TAK, potencjalnie
  • Session Management: TAK, potencjalnie
  • Szyfrowanie: BRAK

„Niestandardowy Nagłówek HTTP "jest typem" Gangster Handshak es "; jako taki będę używał tej samej sekcji do omawiania ich. Jedyną różnicą jest to, że "niestandardowy nagłówek HTTP" określa, gdzie będzie przechowywany hanshake (identyfikator sesji, token, token uwierzytelniania użytkownika itp.) (Tj. W nagłówku HTTP).

Należy pamiętać, że nie określają one sposobu obsługi uwierzytelnienia ani nie określają sposobu zarządzania sesją. Zasadniczo opisują, jak i gdzie będą przechowywane identyfikatory sesji/uwierzytelnienia.

Uwierzytelnienie musi być obsługiwane przez aplikację lub przez stronę trzecią (np. OAuth). Zarządzanie sesją nadal będzie musiało zostać wdrożone. Ciekawe jest to, że możesz wybrać scalenie dwóch, jeśli chcesz.

  • To nie jest szyfrowanie; Twój ruch w witrynie wciąż jest zwykłym tekstem. Proces uwierzytelniania będzie bezpieczny z powodu ograniczeń HTTPS, jeśli korzystasz z protokołu OAuth, ale Twoja aplikacja jest nadal podatna na ataki.
  • Nie zapewnia to zawartości żądań/odpowiedzi HTTP aplikacji.

Co trzeba uczynić

...Gorąco sugerują, upewnij się, że rozumiesz, że solidna aplikacja internetowa, która jest bezpieczna wymaga następujących czynności:

  1. Encryption (HTTPS jest prawie jedynym wyborem)
  2. Session Management
  3. uwierzytelniania/autoryzacji

Autoryzacja zależy od uwierzytelnienia. Uwierzytelnianie opiera się na zarządzaniu sesją i szyfrowaniu, dzięki czemu sesja nie zostaje przejęta, a poświadczenia nie są przechwytywane.

Kolba Login

myślę, że należy patrzeć na flask-login jako sposób uniknąć ponownego wdrażającego koło. Osobiście nigdy go nie używałem (używam piramidy do aplikacji internetowych w pythonie). Jednak widziałem to wcześniej w tablicach aplikacji/python. Obsługuje zarówno uwierzytelnianie, jak i zarządzanie sesją. Rzuć api/aplikację internetową przez HTTPS i masz wszystkie trzy (Szyfrowanie, Zarządzanie sesją i Uwierzytelnienie użytkownika).

Jeśli nie możesz/nie możesz używać logowania z kolbą, przygotuj się do napisania własnego, ale najpierw wykonaj badania dotyczące tworzenia bezpiecznych mechanizmów uwierzytelniania.

Jeśli to możliwe, jeśli nie rozumieją, jak napisać procedurę uwierzytelniania proszę nie próbować go bez uprzedniego uczenia się, jak hakerzy wykorzystują ataki oparte wzór, czas ataków, itp

Proszę szyfrować danych

... pomiń ideę, że możesz uniknąć używania HTTPS z pewnym "sprytnym" użyciem tokena. Pomiń ideę, że powinieneś unikać używania HTTPS/szyfrowania, ponieważ "jest spowolniony", intensywnie przetwarza itp. Jest to proces intensywny, ponieważ jest to algorytm szyfrowania. Konieczność zapewnienia bezpieczeństwa danych użytkownika i danych aplikacji powinna zawsze stanowić najwyższy priorytet. Nie chcesz przechodzić przez przerażenie powiadamiania użytkowników, że ich dane zostały naruszone.

+4

Świetna odpowiedź na typową aplikację internetową. Uważam jednak, że OP pyta o opcje uwierzytelniania dla serwera REST API. Zarządzanie sesjami nie jest wymagane, na przykład, jeśli Twój interfejs REST API używa protokołu HTTP Basic Auth/Digest Auth. – jemeshsu

+0

@jemeshsu są jednym i tym samym. Nie ma dużej różnicy między tworzeniem REST API i tradycyjnej aplikacji internetowej pod względem zarządzania sesjami, uwierzytelniania/autoryzacji i szyfrowania transmisji. –

1

https jest wolniejszy, ale nie nie. Tylko handshaking jest wolniejszy. Dla nas największym problemem jest utrzymanie kluczowej pary po stronie serwerów i praw. Zaimplementowaliśmy również skrót wiadomości. Problem polega na tym, że trudno jest poprawnie skonfigurować wersję php-android-ios.Po wykonaniu tej czynności (parametr należy zmienić, co sugeruje Google najpierw wyniki tylko po stronie Androida) problem będzie z urządzeniami low-end: zbyt dużo procesora, spowolnienie procesu deszyfrowania, dużo wolniej niż https, zwłaszcza, gdy musisz przekształcić ciąg 10kb (może to potrwać kilka minut).

Jeśli nie przesyłać dane NASA z Hamasem, niż pójdę z bardzo prostego szyfrowania nad prostym http: jak odwrócić bity lub tak ...

1

Go z HTTPS. Jest to (marginalnie) wolniejsze, ale warto mieć pewność, że otrzymasz od niego relatywnie krótki czas inwestycji (zakup certyfikatu SSL i zmiana adresów URL z http na https). Bez HTTPS ryzykujesz, że sesje Twoich użytkowników zostaną przejęte przez niezabezpieczone sieci publiczne, co jest ekstremalnie trudne: easy for someone to do.

Powiązane problemy