REST API çağrılarını nasıl güvenli hale getirebilirim?


92

Arka uçta bazı popüler web çerçevelerini (raylar, sinatra, flask, express.js) kullanan dinlendirici web uygulamasını geliştiriyorum. İdeal olarak, Backbone.js ile istemci tarafı geliştirmek istiyorum. Yalnızca javascript istemci tarafımın bu API çağrılarıyla etkileşim kurmasına nasıl izin veririm? Bu API çağrılarının herkese açık olmasını ve tarafından curlveya sadece tarayıcıya bağlantı girilerek çağrılmasını istemiyorum .


Tüm API çağrılarınız, sayfanız sunulduğunda istemciye iletilen bir jeton gerektiriyor mu?
hajpoj


Amazon AWS javascript SDK, önceden imzalanmış nesne URL'sini kullanır: - docs.aws.amazon.com/AmazonS3/latest/dev/…
rjha94

Yanıtlar:


91

İlk prensip olarak, API'niz JS istemciniz tarafından kullanılıyorsa, bunun herkese açık olduğunu varsaymanız gerekir: Basit bir JS hata ayıklayıcı, bir saldırganı bir bayt için bayt aynı istek gönderebileceği bir konuma yerleştirir seçtiği araç.

Bununla birlikte, sorunuzu doğru okursam, kaçınmak isteyeceğiniz şey bu değildir: Gerçekten olmasını istemediğiniz şey, API'nizin JS istemciniz dahil olmadan (düzenli olarak) tüketilmesidir. İşte nasıl uygulanmayacağına dair bazı fikirler, en azından müşterinizi kullanmayı teşvik edin:

  • Eminim, API'nizin bir tür kimlik doğrulama alanı vardır (örneğin, istemcide hesaplanan Hash). Değilse, Bu SO sorusuna bir göz atın . JS istemcinize bir oturum bazında (kodlanmış değil) verilen bir tuz (hatta API anahtarı) kullandığınızdan emin olun . Bu şekilde, API'nizin yetkisiz bir tüketicisi çok daha fazla çalışmaya zorlanır.

  • JS istemcisini yüklerken, bazı HTTP başlıklarını (kullanıcı aracısı akla gelir) ve IP adresini hatırlayın ve normal şüpheliler için kara listeler kullanarak, değişirse yeniden kimlik doğrulamasını isteyin. Bu, bir saldırganı ödevini daha kapsamlı bir şekilde yapmaya zorlar.

  • Sunucu tarafında, son birkaç API çağrısını hatırlayın ve bir başkasına izin vermeden önce, iş mantığının şu anda yenisine izin verip vermediğini kontrol edin: Bu, bir saldırganın birçok oturumunu sunucunuzla tek bir oturuma yoğunlaştırma yeteneğini reddeder: diğer önlemlerle birlikte kullanıldığında, bu, istismarcının kolayca tespit edilmesini sağlayacaktır.

Bunu göz önünde bulundurun: Ben gerekli açıklıkla ifade etti olmayabilir imkansız tamamen imkansız bir istismar hizmetinizi tüketmek için yapmak, ancak bu kadar zor, buna değer güçlük olmayabilir yapabilirsiniz.


bu yararlı bir bilgidir, ancak ya arka uç api'mden ayrı bir sunucu gibi başka bir api uygulamasına biraz kimlik doğrulaması yapmak istersem, sorumu basitleştirmek için arka uç node.js'nin getirme isteğini başka bir arkaya göndermesini istiyorum. benim olan son sunucu, bazı nedenlerden dolayı buna ihtiyaç duyuluyor, ancak hassas verilere erişebildiği için api çağrılarını güvenli hale getirmek istiyorum ve seansları veya jwt'yi kullanamıyorum çünkü onları gerçekten tarayıcıda saklayamıyorum.
Piramit

@Thepyramid API çağrısının sunucu tarafında ne yaptığı önemli değil, özellikle de sunucu tarafı başka bir 2. seviye API çağrısı yapıyorsa. Önemli olan, sunucunuzu bir proxy olarak değil, bir uygulama olarak ele almaktır.
Eugen Rieck

vekil olarak değil uygulama olarak nasıl yapılacağını daha fazla açıklayabilir misiniz
The pyramid

1
Demek istediğim: Yeterli miktarda güvenlik elde etmek için bir web uygulamasının sahip olduğu tüm araçları kullanmanız gerekir: Oturumlar, bir kimlik doğrulama veritabanı, bir iş mantığı. Bunu yapmazsanız ve sunucunuza yalnızca istekleri başka bir sunucuya iletmenin bir yolu olarak davranırsanız, onu yalnızca diğer sunucu için bir proxy olarak kullanıyorsunuz ve diğer sunucunun sunduğu güvenlik ile sınırlısınız.
Eugen Rieck

1
@PirateApp Bir saldırgan kolayca CSRF başlıklarını yok sayabilir. Yalnızca son cihaz yamalanmamış bir tarayıcıysa çalışırlar
Eugen Rieck

12

Bir çeşit kimlik doğrulama sistemi uygulamalısınız. Bunu halletmenin iyi bir yolu, bazı beklenen başlık değişkenlerini tanımlamaktır. Örneğin, bir oturum belirteci döndüren bir kimlik doğrulama / oturum açma API çağrınız olabilir. API'nize yapılan sonraki çağrılar, bir oturum simgesinin 'your-api-token' gibi belirli bir adla bir HTTP başlık değişkeninde ayarlanmasını bekler.

Alternatif olarak birçok sistem, bir tür api hesap sistemi kullanarak beklenen erişim belirteçlerini veya anahtarlarını (youtube, facebook veya twitter gibi) oluşturur. Bu durumlarda, müşterinizin bunları bir şekilde istemcide saklaması gerekir.

Daha sonra, REST çerçevenize oturuma bir kontrol eklemek ve bir istisna atmak yeterlidir. Mümkünse, durum kodu (dinlendirici olmak için) bir 401 hatası olacaktır.


8
Her ne kadar onları başlıklara bakıp yeniden üretmekten alıkoyan hiçbir şey yok.
cdmckay

1
@cdmckay - Bir jeton, bir oturumda depolanan bir jetonla eşleşmelidir. Başlığın yeniden üretilmesi, farklı bir oturumdan geliyorsa "Yetkisiz" yanıtla sonuçlanacaktır.
Andrei Volgin

3
Yine de aynı oturumu kullanabilir ve istekleri API'ye gönderilmeden önce değiştirebilirler ... hatta çalışma zamanında konsolu kullanarak, yalnızca ihtiyacınız olan parçaları değiştiren eşleşen başlıklar / alanlar içeren bir çağrı oluştururlar ...
Potter Rafed

2
@PotterRafed: Bir kullanıcı kendi geçerli oturumuna erişirse, buna bir uygulama kullanılarak çağrılır, ona saldırmak değil. Kimlik doğrulamanın amacı, diğer kullanıcıların oturumlarına / verilerine erişimi engellemektir .
Andrei Volgin

@AndreiVolgin evet yeterince adil, ama yine de bir güvenlik açığı
Potter Rafed

9

Artık "JSON Web Token" adında açık bir standart var,

bkz. https://jwt.io/ & https://en.wikipedia.org/wiki/JSON_Web_Token

JSON Web Token (JWT), bazı iddiaları öne süren belirteçler oluşturmak için JSON tabanlı bir açık standarttır (RFC 7519). Örneğin, bir sunucu "yönetici olarak oturum açıldı" iddiasına sahip bir belirteç oluşturabilir ve bunu bir istemciye sağlayabilir. İstemci daha sonra bu belirteci yönetici olarak oturum açtığını kanıtlamak için kullanabilir. Belirteçler, sunucunun anahtarı tarafından imzalanır, böylece sunucu, belirtecin meşru olduğunu doğrulayabilir. Belirteçler, kompakt, URL güvenli ve özellikle web tarayıcısı tek oturum açma (SSO) bağlamında kullanılabilir olacak şekilde tasarlanmıştır. JWT talepleri tipik olarak kimliği doğrulanmış kullanıcıların kimliğini bir kimlik sağlayıcı ile bir hizmet sağlayıcı arasında veya iş süreçlerinin gerektirdiği diğer herhangi bir talep türü arasında geçirmek için kullanılabilir. Jetonlar ayrıca doğrulanabilir ve şifrelenebilir. [3] [4]


Bir kullanıcının jetonunu kopyalayıp başka bir yanıtta kullanmasını ne engelleyebilir?
Ulad Kasach

1
@UladKasach Dürüst olmak gerekirse, onların derinliklerine hiç girmedim, ama ne yazık ki süresi dolabilir, kullanıcınız için benzersiz ve SSL ile şifrelenmiş (tabii ki pratik yapıyorsunuz), oauth afaik'in arkasındaki fikir tam olarak aynı
bbozo

3

Affedersiniz @MarkAmery ve Eugene, ama bu yanlış.

Tarayıcıda çalışan js + html (istemci) uygulamanız , API'ye yetkisiz doğrudan çağrıları aşağıdaki şekilde hariç tutmak için AYARLANABİLİR :

  1. İlk adım: API'yi kimlik doğrulaması gerektirecek şekilde ayarlayın. İstemci ilk sunucusu (veya başka bir güvenlik sunucusu) üzerinden kendi kimliğini doğrulamak gerekir doğru şifreyi sağlamak için insan kullanıcı soran örneğin.

Kimlik doğrulamadan önce API'ye yapılan çağrılar kabul edilmez.

Kimlik doğrulama sırasında bir "belirteç" döndürülür.

Kimlik doğrulamasından sonra yalnızca kimlik doğrulama "belirteci" ile API çağrıları kabul edilir.

Elbette bu aşamada yalnızca şifreye sahip olan yetkili kullanıcılar API'ye erişebilir, ancak uygulamada hata ayıklayan programcılarsa, test amacıyla doğrudan erişebilirler.

  1. İkinci adım: Şimdi, istemcinin js + html uygulaması ilk olarak sunucudan talep edildikten sonra kısa bir süre içinde çağrılacak ekstra bir güvenlik API'si ayarlayın. Bu "geri arama", sunucuya istemcinin başarıyla indirildiğini söyleyecektir. REST API çağrılarınızı yalnızca istemcinin yakın zamanda ve başarılı bir şekilde istenmesi durumunda çalışacak şekilde kısıtlayın.

Şimdi API'nizi kullanmak için önce istemciyi indirmeleri ve aslında bir tarayıcıda çalıştırmaları gerekir. Yalnızca geri aramayı başarıyla aldıktan sonra ve kısa bir süre içinde kullanıcı girişi yaptıktan sonra, API çağrıları kabul eder.

Bu nedenle, bunun kimlik bilgileri olmayan yetkisiz bir kullanıcı olabileceğinden endişelenmenize gerek yok.

('REST API çağrılarını nasıl güvenceye alabilirim' sorusunun başlığı ve söylediklerinizin çoğundan, asıl endişeniz budur ve tam anlamıyla API'nizin NASIL çağrıldığı değil, KİMİN TARAFINDAN çağrıldığı doğru mu? )


5
İkinci nokta mantıklı değil. Bir saldırganın uygulamanızı yüklemesi gerekiyorsa, bunu yapacaktır (geri aramanız görünür). Ve sonra saldırın.
Andrei Volgin

Nokta 2, nokta 1'e ilavedir. Saldırganın hala kimlik doğrulamasına ihtiyacı vardır. Nokta 2, sadece yetkilendirilmek için html uygulamasını gerçekten indirme ihtiyacını ekler. Dolayısıyla, uygulama olmadan doğrudan API'lere çağrı (muhtemelen erişilir ve yalnızca kimlik doğrulamadan sonra indirilir) imkansızdır. Bu soruda istenen bir şeydi.
pashute

Yalnızca alanınızdan gelen isteklere izin verebilirsiniz.
Andrei Volgin

Bu, çağrıları yalnızca etki alanının içine sınırlar, bu nedenle artık javascript tarayıcı uygulaması kullanıcıları etki alanının içinde olmalıdır (muhtemelen istenen bir şey değildir) ve bu kullanıcılar API'yi yine de curl aracılığıyla doğrudan arayabilirler.
2016

2
Gözden kaçırdığınız şey şu ki, kullanıcınızın tarayıcısından ne yapmasını isterseniz, bir saldırgan tarafından kopyalanabilir - tarayıcının bunu yapması için okunabilir olması gerekir.
Eugen Rieck

1
  1. İstemci sunucunuzu index.html(veya backbone.jsvb.) İlk kez yüklediğinde sunucuda bir SESSION var

  2. Her API çağrısında sunucu tarafında bu değişkeni kontrol edin.

Not: Bu bir "güvenlik" çözümü değildir !!! Bu, yalnızca sunucunuzdaki yükü hafifletmek içindir, böylece insanlar onu kötüye kullanmaz veya API'nizi diğer web sitelerinden ve uygulamalardan "bağlantı kurmaz".


0

İşte yaptığım şey:

  1. API'yi, X-APITOKEN gibi çağrılarla bir HTTP Başlığı ile güvenceye alın:

  2. PHP'de oturum değişkenlerini kullanın. Yerinde bir oturum açma sistemine sahip olun ve kullanıcı jetonunu oturum değişkenlerine kaydedin.

  3. JS kodunu Ajax ile PHP'ye çağırın ve API'yi çağırmak için curl ile oturum değişkenini kullanın. Bu şekilde, oturum değişkeni ayarlanmazsa, çağrı yapmaz ve PHP kodu API'ye Erişim Simgesini içerir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.