Bezpośrednie przesyłanie plików Amazon S3 z przeglądarki klienta - ujawnienie klucza prywatnego
Implementuję bezpośrednie przesyłanie plików z KOMPUTERA Klienta do Amazon S3 przez REST API przy użyciu tylko JavaScript, bez kodu po stronie serwera. Wszystko działa dobrze, ale jedno mnie martwi...
Kiedy wysyłam zapytanie do Amazon S3 REST API, muszę je podpisać i umieścić podpis w nagłówku Authentication
. Aby stworzyć 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 / szyfruję mój źródła).
Rozwiązanie" Bezserwerowe " jest idealne, ale mogę rozważyć włączenie przetwarzania po stronie serwera, z wyłączeniem przesłania pliku na mój serwer, a następnie wysłania na S3.
8 answers
Myślę, że to, czego chcesz, to przesyłanie przez przeglądarkę za pomocą posta.
Zasadniczo potrzebujesz kodu po stronie serwera, ale wszystko, co robi, to generuje podpisane Zasady. Gdy kod po stronie klienta ma podpisaną politykę, może przesłać za pomocą POST bezpośrednio do S3 bez danych przechodzących przez serwer.
Oto oficjalne linki do doc:
Diagram: 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 będzie w Twoim html w postaci takiej jak Ta:
<html>
<head>
...
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
...
</head>
<body>
...
<form action="http://johnsmith.s3.amazonaws.com/" method="post" enctype="multipart/form-data">
Key to upload: <input type="input" name="key" value="user/eric/" /><br />
<input type="hidden" name="acl" value="public-read" />
<input type="hidden" name="success_action_redirect" value="http://johnsmith.s3.amazonaws.com/successful_upload.html" />
Content-Type: <input type="input" name="Content-Type" value="image/jpeg" /><br />
<input type="hidden" name="x-amz-meta-uuid" value="14365123651274" />
Tags for File: <input type="input" name="x-amz-meta-tag" value="" /><br />
<input type="hidden" name="AWSAccessKeyId" value="AKIAIOSFODNN7EXAMPLE" />
<input type="hidden" name="Policy" value="POLICY" />
<input type="hidden" name="Signature" value="SIGNATURE" />
File: <input type="file" name="file" /> <br />
<!-- The elements after this will be ignored -->
<input type="submit" name="submit" value="Upload to Amazon S3" />
</form>
...
</html>
Zauważ, że akcja formularza wysyła plik bezpośrednio do S3 - nie za pośrednictwem serwera.
Za każdym razem, gdy jeden z Twoich użytkowników chce przesłać plik, tworzysz POLICY
i SIGNATURE
na swoim 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.
Podpisując polisę, zwykle powoduje, że polisa wygasa po kilku minutach. Zmusza to Użytkowników do rozmowy z serwerem przed przesłaniem. Pozwala to monitorować i ograniczać przesyłanie, jeśli chcesz.
Jedynymi danymi wchodzącymi do lub z serwera są podpisane adresy URL. Twoje tajne klucze pozostają tajne na serwerze.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-07-17 02:15:19
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ę wiadra
<!DOCTYPE html>
<html>
<head>
<title>AWS S3 File Upload</title>
<script src="https://sdk.amazonaws.com/js/aws-sdk-2.1.12.min.js"></script>
</head>
<body>
<input type="file" id="file-chooser" />
<button id="upload-button">Upload to S3</button>
<div id="results"></div>
<script type="text/javascript">
AWS.config.region = 'your-region'; // 1. Enter your region
AWS.config.credentials = new AWS.CognitoIdentityCredentials({
IdentityPoolId: 'your-IdentityPoolId' // 2. Enter your identity pool
});
AWS.config.credentials.get(function(err) {
if (err) alert(err);
console.log(AWS.config.credentials);
});
var bucketName = 'your-bucket'; // Enter your bucket name
var bucket = new AWS.S3({
params: {
Bucket: bucketName
}
});
var fileChooser = document.getElementById('file-chooser');
var button = document.getElementById('upload-button');
var results = document.getElementById('results');
button.addEventListener('click', function() {
var file = fileChooser.files[0];
if (file) {
results.innerHTML = '';
var objKey = 'testing/' + file.name;
var params = {
Key: objKey,
ContentType: file.type,
Body: file,
ACL: 'public-read'
};
bucket.putObject(params, function(err, data) {
if (err) {
results.innerHTML = 'ERROR: ' + err;
} else {
listObjs();
}
});
} else {
results.innerHTML = 'Nothing to upload.';
}
}, false);
function listObjs() {
var prefix = 'testing';
bucket.listObjects({
Prefix: prefix
}, function(err, data) {
if (err) {
results.innerHTML = 'ERROR: ' + err;
} else {
var objKeys = "";
data.Contents.forEach(function(obj) {
objKeys += obj.Key + "<br>";
});
results.innerHTML = objKeys;
}
});
}
</script>
</body>
</html>
Aby uzyskać więcej informacji, sprawdź - Github Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-20 08:23:00
Mówisz, że chcesz rozwiązania "bezserwerowego". Ale to oznacza, że nie masz możliwości wprowadzenia żadnego" swojego " kodu w pętli. (Uwaga: po przekazaniu kodu Klientowi, jest to teraz " ich " kod.) Blokowanie CORS nie pomoże: ludzie mogą łatwo napisać narzędzie nie-internetowe (lub internetowe proxy), które dodaje poprawny nagłówek CORS, aby nadużywać systemu.
Duży problem polega na tym, że nie można odróżnić różnych użytkowników. Nie możesz pozwolić jednemu użytkownikowi na listę / dostęp do jego plików, ale uniemożliwiają to innym. Jeśli wykryjesz nadużycie, nie możesz nic z tym zrobić, poza zmianą klucza. (Które napastnik może prawdopodobnie po prostu dostać ponownie.)
Najlepiej jest utworzyć "iam user" z kluczem do klienta javascript. Daj mu tylko dostęp do zapisu tylko do jednego wiadra. (ale najlepiej, nie włączaj operacji ListBucket, która uczyni ją bardziej atrakcyjną dla atakujących.)
Jeśli masz serwer (nawet prostą instancję micro za $ 20 / miesiąc), możesz może podpisać klucze na serwerze podczas monitorowania / zapobiegania nadużyciom w czasie rzeczywistym. Bez serwera najlepsze, co możesz zrobić, to okresowo monitorować nadużycia po fakcie. Oto co bym zrobił:
1) okresowo obracaj klucze dla 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 logowanie S3 i pobieraj logi co godzinę. Ustaw alerty na "zbyt wiele przesłanych" i "za dużo 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 kontrole można wykonać "bezserwerowo", ponieważ można je uruchomić na pulpicie. (tzn. S3 wykonuje całą pracę, te procesy tylko po to, aby ostrzec Cię o nadużyciu wiadra S3, abyś nie dostał gigantycznego rachunku AWS pod koniec miesiąca.)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-07-14 14:19:47
Dodając więcej informacji do zaakceptowanej odpowiedzi, możesz odwołać się do mojego bloga, aby zobaczyć uruchomioną wersję kodu, używając AWS Signature version 4.
Podsumujemy tutaj:
Jak tylko użytkownik wybierze plik do przesłania, wykonaj następujące czynności: 1. Wykonaj połączenie z serwerem WWW, aby zainicjować usługę generowania wymaganych params
-
W tym serwisie wykonaj połączenie z serwisem AWS IAM, aby uzyskać tymczasową wiarygodność
-
Po uzyskaniu cred Utwórz politykę bucket (base 64 encoded string). Następnie podpisz Zasady wiadra tymczasowym tajnym kluczem dostępu, aby wygenerować ostateczny podpis
-
Wyślij niezbędne parametry z powrotem do interfejsu
Po odebraniu, Utwórz obiekt formularza html, ustaw wymagane params i opublikuj go.
Aby uzyskać szczegółowe informacje, zapoznaj się https://wordpress1763.wordpress.com/2016/10/03/browser-based-upload-aws-signature-version-4/
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-03 09:50:29
Tutaj źle zrozumiałeś. Podpisy cyfrowe są używane po to, aby można było zweryfikować coś jako poprawne bez ujawniania tajnego klucza. W takim przypadku podpis cyfrowy jest używany, aby uniemożliwić użytkownikowi modyfikację zasad ustawionych dla formularz post.Aby stworzyć 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 / szyfruję moje źródła).
Podpisy cyfrowe, takie jak ten tutaj, są używane dla bezpieczeństwa w całej sieci. Jeśli ktoś (NSA?) naprawdę byli w stanie je złamać, mieliby znacznie większe cele niż Twoje wiadro S3:)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-07-25 11:38:42
Jeśli nie masz żadnego kodu po stronie serwera, Twoje bezpieczeństwo zależy od bezpieczeństwa dostępu do kodu JavaScript po stronie klienta(czyli każdy, kto ma kod może coś wgrać).
Więc polecam, aby po prostu utworzyć specjalne wiadro S3, które jest publiczne do zapisu (ale nie do odczytu), więc nie potrzebujesz żadnych podpisanych komponentów po stronie klienta.
Nazwa wiadra (np. GUID) będzie twoją jedyną obroną przed złośliwym uploadem (ale potencjalny napastnik może nie używaj wiadra do przesyłania danych, ponieważ jest to zapis tylko do niego)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-05-08 16:46:48
Podałem prosty kod, aby przesłać pliki z przeglądarki Javascript do AWS S3 i wyświetlić listę wszystkich plików w wiadrze S3.
Kroki:
-
Aby wiedzieć, jak stworzyć 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 bucket i zapisz do niej następujący kod XML.
<?xml version="1.0" encoding="UTF-8"?> <CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/"> <CORSRule> <AllowedMethod>GET</AllowedMethod> <AllowedMethod>PUT</AllowedMethod> <AllowedMethod>DELETE</AllowedMethod> <AllowedMethod>HEAD</AllowedMethod> <AllowedHeader>*</AllowedHeader> </CORSRule> </CORSConfiguration>
-
Tworzenie pliku HTML zawierający następujący kod Zmień poświadczenia, otwórz plik w przeglądarce i ciesz się.
<script type="text/javascript"> AWS.config.region = 'ap-north-1'; // Region AWS.config.credentials = new AWS.CognitoIdentityCredentials({ IdentityPoolId: 'ap-north-1:*****-*****', }); var bucket = new AWS.S3({ params: { Bucket: 'MyBucket' } }); var fileChooser = document.getElementById('file-chooser'); var button = document.getElementById('upload-button'); var results = document.getElementById('results'); function upload() { var file = fileChooser.files[0]; console.log(file.name); if (file) { results.innerHTML = ''; var params = { Key: n + '.pdf', ContentType: file.type, Body: file }; bucket.upload(params, function(err, data) { results.innerHTML = err ? 'ERROR!' : 'UPLOADED.'; }); } else { results.innerHTML = 'Nothing to upload.'; } } </script> <body> <input type="file" id="file-chooser" /> <input type="button" onclick="upload()" value="Upload to S3"> <div id="results"></div> </body>
-
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-27 10:18:37
Jeśli chcesz skorzystać z usługi 3rd party, auth0.com wspiera tę integrację. Usługa auth0 wymienia uwierzytelnianie usługi SSO innej firmy na token sesji tymczasowej AWS będzie miał ograniczone uprawnienia.
Zobacz:
https://github.com/auth0-samples/auth0-s3-sample/
i dokumentacji auth0.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-04-03 07:42:36