Wdrażam bezpośrednie przesyłanie plików z komputera klienckiego do Amazon S3 przez REST API przy użyciu tylko JavaScript, bez żadnego kodu po stronie serwera. Wszystko działa dobrze, ale martwi mnie jedna rzecz ...
Kiedy wysyłam żądanie do Amazon S3 REST API, muszę je podpisać i umieścić podpis w Authentication
nagłówku. Aby utworzyć podpis, muszę użyć mojego tajnego klucza. Ale wszystko dzieje się po stronie klienta, więc tajny klucz można łatwo ujawnić ze źródła strony (nawet jeśli zaciemniam / zaszyfruję moje źródła).
Jak sobie z tym poradzić? I czy to w ogóle problem? Może mogę ograniczyć użycie określonego klucza prywatnego tylko do wywołań REST API z określonego źródła CORS i tylko do metod PUT i POST lub może połączyć klucz tylko z S3 i określonym zasobnikiem? Czy mogą istnieć inne metody uwierzytelniania?
Rozwiązanie „bezserwerowe” jest idealne, ale mogę rozważyć włączenie przetwarzania po stronie serwera, z wyłączeniem przesyłania pliku na mój serwer, a następnie wysyłania go do S3.
Odpowiedzi:
Myślę, że to, czego chcesz, to przesyłanie oparte na przeglądarce przy użyciu POST.
Zasadniczo potrzebujesz kodu po stronie serwera, ale wszystko, co robi, to generowanie podpisanych zasad. Gdy kod po stronie klienta ma podpisaną politykę, można go przesłać za pomocą POST bezpośrednio do S3 bez przesyłania danych przez serwer.
Oto oficjalne linki do dokumentów:
Schemat: http://docs.aws.amazon.com/AmazonS3/latest/dev/UsingHTTPPOST.html
Przykładowy kod: http://docs.aws.amazon.com/AmazonS3/latest/dev/HTTPPOSTExamples.html
Podpisana polityka zostanie umieszczona w Twoim html w następującej formie:
Zauważ, że akcja FORM wysyła plik bezpośrednio do S3 - nie przez twój serwer.
Każdy czas użytkowników chce przesłać plik, należy utworzyć
POLICY
iSIGNATURE
na serwerze. Zwracasz stronę do przeglądarki użytkownika. Użytkownik może następnie przesłać plik bezpośrednio do S3 bez przechodzenia przez serwer.Po podpisaniu polisy zazwyczaj wygasa się po kilku minutach. Zmusza to użytkowników do komunikowania się z serwerem przed przesłaniem. Pozwala to monitorować i ograniczać wysyłanie, jeśli chcesz.
Jedyne dane przychodzące do lub z serwera to podpisane adresy URL. Twoje tajne klucze pozostają tajne na serwerze.
źródło
${filename}
do nazwy klucza, więc w powyższym przykładzieuser/eric/${filename}
zamiast tylkouser/eric
. Jeśliuser/eric
jest to już istniejący folder, przesyłanie po cichu zakończy się niepowodzeniem (zostaniesz nawet przekierowany do Success_action_redirect), a przesłanych treści tam nie będzie. Po prostu spędziłem godziny na debugowaniu tego, myśląc, że to kwestia uprawnień.Możesz to zrobić przez AWS S3 Cognito, wypróbuj ten link tutaj:
http://docs.aws.amazon.com/AWSJavaScriptSDK/guide/browser-examples.html#Amazon_S3
Wypróbuj również ten kod
Po prostu zmień Region, IdentityPoolId i nazwę swojego zasobnika
źródło
Mówisz, że potrzebujesz rozwiązania „bezserwerowego”. Ale to oznacza, że nie masz możliwości umieszczenia żadnego „swojego” kodu w pętli. (UWAGA: gdy już przekażesz swój kod klientowi, jest to teraz „jego” kod). Blokowanie CORS nie pomoże: ludzie mogą łatwo napisać narzędzie inne niż internetowe (lub serwer proxy sieci Web), które dodaje poprawny nagłówek CORS, aby nadużywać systemu.
Duży problem polega na tym, że nie możesz rozróżnić różnych użytkowników. Nie możesz pozwolić jednemu użytkownikowi na wyświetlanie listy / uzyskiwanie dostępu do jego plików, ale uniemożliwić innym to. Jeśli wykryjesz nadużycie, nie możesz nic zrobić poza zmianą klucza. (Które prawdopodobnie napastnik może po prostu odzyskać).
Najlepszym rozwiązaniem jest utworzenie „użytkownika IAM” z kluczem do klienta javascript. Daj mu uprawnienia do zapisu tylko do jednego zasobnika. (ale najlepiej nie włączaj operacji ListBucket, co uczyni ją bardziej atrakcyjną dla atakujących).
Gdybyś miał serwer (nawet prostą mikro-instancję za 20 $ / miesiąc), mógłbyś podpisać klucze na swoim serwerze, monitorując / zapobiegając nadużyciom w czasie rzeczywistym. Bez serwera najlepsze, co możesz zrobić, to okresowe monitorowanie pod kątem nadużyć po fakcie. Oto, co bym zrobił:
1) okresowo zmieniaj klucze tego użytkownika IAM: co noc generuj nowy klucz dla tego użytkownika IAM i zastępuj najstarszy klucz. Ponieważ są 2 klucze, każdy klucz będzie ważny przez 2 dni.
2) włącz rejestrowanie S3 i pobieraj dzienniki co godzinę. Ustaw alerty dotyczące „zbyt wielu przesłanych plików” i „zbyt wielu pobrań”. Będziesz chciał sprawdzić zarówno całkowity rozmiar pliku, jak i liczbę przesłanych plików. Będziesz chciał monitorować zarówno sumy globalne, jak i sumy na adres IP (z niższym progiem).
Te testy można przeprowadzić „bez serwera”, ponieważ można je uruchomić na komputerze stacjonarnym. (tj. S3 wykonuje całą pracę, te procesy tylko po to, aby ostrzec Cię o nadużyciu wiadra S3, abyś nie otrzymał gigantycznego rachunku AWS pod koniec miesiąca).
źródło
Dodając więcej informacji do zaakceptowanej odpowiedzi, możesz odwołać się do mojego bloga, aby zobaczyć działającą wersję kodu, używając AWS Signature w wersji 4.
Podsumuję tutaj:
Gdy tylko użytkownik wybierze plik do przesłania, wykonaj następujące czynności: 1. Zadzwoń do serwera WWW, aby zainicjować usługę w celu wygenerowania wymaganych parametrów
W tej usłudze zadzwoń do usługi AWS IAM, aby uzyskać tymczasowe środki
Po uzyskaniu kredytu utwórz zasadę zasobnika (ciąg zakodowany w oparciu o 64). Następnie podpisz zasady zasobnika tymczasowym tajnym kluczem dostępu, aby wygenerować ostateczny podpis
wyślij niezbędne parametry z powrotem do interfejsu użytkownika
Po otrzymaniu tego, utwórz obiekt formularza html, ustaw wymagane parametry i POST.
Szczegółowe informacje można znaleźć pod adresem https://wordpress1763.wordpress.com/2016/10/03/browser-based-upload-aws-signature-version-4/
źródło
To jest, gdy źle zrozumiałeś. Jedynym powodem używania podpisów cyfrowych jest to, że możesz zweryfikować coś jako poprawnego bez ujawniania swojego tajnego klucza. W tym przypadku podpis cyfrowy jest używany, aby uniemożliwić użytkownikowi modyfikowanie zasad ustawionych dla postu formularza.
Podpisy cyfrowe, takie jak ten tutaj, są używane do zapewnienia bezpieczeństwa w całej sieci. Gdyby ktoś (NSA?) Naprawdę był w stanie je złamać, miałby znacznie większe cele niż twoje wiadro S3 :)
źródło
Podałem prosty kod, aby przesłać pliki z przeglądarki Javascript do AWS S3 i wyświetlić listę wszystkich plików w zasobniku S3.
Kroki:
Aby dowiedzieć się, jak utworzyć Create IdentityPoolId http://docs.aws.amazon.com/cognito/latest/developerguide/identity-pools.html
Wejdź na stronę konsoli S3 i otwórz konfigurację cors z właściwości zasobnika i napisz w niej następujący kod XML.
Utwórz plik HTML zawierający poniższy kod, zmień dane logowania, otwórz plik w przeglądarce i ciesz się.
źródło
Jeśli nie masz żadnego kodu po stronie serwera, twoje bezpieczeństwo zależy od bezpieczeństwa dostępu do twojego kodu JavaScript po stronie klienta (tj. Każdy, kto ma kod, może coś przesłać).
Dlatego zalecałbym po prostu utworzenie specjalnego wiadra S3, który jest publicznie zapisywalny (ale nieczytelny), więc nie potrzebujesz żadnych podpisanych komponentów po stronie klienta.
Nazwa zasobnika (np. GUID) będzie jedyną obroną przed złośliwym przesyłaniem (ale potencjalny napastnik nie może użyć twojego zasobnika do przesyłania danych, ponieważ zapisuje tylko do niego)
źródło
Oto sposób generowania dokumentu zasad przy użyciu węzłów i serwera bez serwera
Używany obiekt konfiguracyjny jest przechowywany w magazynie parametrów SSM i wygląda następująco
źródło
Jeśli chcesz skorzystać z usługi innej firmy, auth0.com obsługuje tę integrację. Usługa auth0 wymienia uwierzytelnianie usługi logowania jednokrotnego innej firmy na token tymczasowej sesji AWS z ograniczonymi uprawnieniami.
Zobacz: https://github.com/auth0-samples/auth0-s3-sample/
i dokumentację auth0.
źródło