Flask app.secret_key'in gizemini çöz


127

Eğer app.secret_keyayarlanmamış, Flask sen oturumu sözlük ayarlamak veya erişim izin vermez.

Bu, tüm olmasıdır şişesi kullanım kılavuzu söyleyeceklerini konuda.

Web geliştirmede çok yeniyim ve herhangi bir güvenlik öğesinin nasıl / neden çalıştığı hakkında hiçbir fikrim yok. Flask'ın kaputun altında ne yaptığını anlamak istiyorum.

  • Flask neden bizi bu secret_keyözelliği ayarlamaya zorluyor ?
  • Flask secret_keymülkü nasıl kullanıyor ?

Yanıtlar:


102

Şifreleme gerektiren her şey (saldırganların kurcalamaya karşı güvenliğini sağlamak için) gizli anahtarın ayarlanmasını gerektirir. İçin sadece Flask kendisi, işte şey "dir Sessionnesne, ancak diğer uzantıları aynı sırrın yararlanabilir.

secret_keyyalnızca SECRET_KEYyapılandırma anahtarı için ayarlanan değerdir veya doğrudan ayarlayabilirsiniz.

Quickstart Oturumlar bölümünde tür sunucu tarafı gizli ayarladığınız gerektiğine dair iyi, aklı başında danışma sahiptir.

Şifreleme sırlara dayanır; Şifrelemenin kullanması için bir sunucu tarafı sırrı ayarlamadıysanız, herkes şifrelemenizi kırabilir; bilgisayarınızın şifresi gibidir. Gizli ve imzalanacak veri, bir kriptografik karma algoritma kullanarak yeniden oluşturulması zor bir değer olan bir imza dizisi oluşturmak için kullanılır ; yalnızca aynı sırra sahipseniz ve orijinal veriler bu değeri yeniden oluşturabilir ve Flask'ın izinsiz herhangi bir değişiklik olup olmadığını tespit etmesine izin verirsiniz. Sır, Flask'ın istemciye gönderdiği verilere asla dahil edilmediğinden, müşteri oturum verilerini kurcalayamaz ve yeni, geçerli bir imza üretmeyi umar.

Flask, tüm zor işleri yapmak için itsdangerouskütüphaneyi kullanır ; oturumlar, itsdangerous.URLSafeTimedSerializersınıfı özelleştirilmiş bir JSON serileştiriciyle kullanır.


91

Aşağıdaki cevap, temel olarak oturum kavramının bir uygulaması olan İmzalı Çerezler ile ilgilidir (web uygulamalarında kullanıldığı gibi). Flask hem normal (imzasız) çerezler (aracılığıyla ve ) hem de imzalı çerezler (request.cookiesresponse.set_cookie()flask.session ) sunar. Cevabın iki bölümü vardır, ilki İmzalı Çerezin nasıl üretildiğini açıklar ve ikincisi, planın farklı yönlerini ele alan bir QA biçiminde sunulur. Örnekler için kullanılan sözdizimi Python3'tür, ancak kavramlar önceki sürümler için de geçerlidir.

SECRET_KEYİmzalı Çerez nedir (veya nasıl oluşturulur)?

Çerezleri imzalamak, çerez kurcalamaya karşı önleyici bir önlemdir. Tanımlama bilgisini imzalama işlemi sırasında, SECRET_KEYbir parolanın hashing işleminden önce karıştırılması için bir "tuz" un nasıl kullanılacağına benzer bir şekilde kullanılır. İşte konseptin (çılgınca) basitleştirilmiş bir açıklaması. Örneklerdeki kodun açıklayıcı olması amaçlanmıştır. Adımların çoğu atlanmıştır ve tüm işlevler gerçekte mevcut değildir. Buradaki amaç, genel fikrin anlaşılmasını sağlamaktır, gerçek uygulamalar biraz daha dahil olacaktır. Ayrıca, Flask'ın bunun çoğunu sizin için arka planda yaptığını unutmayın. Bu nedenle, çerezinize (oturum API'si aracılığıyla) değer belirlemenin ve bir a sağlamanın yanı sıra SECRET_KEY, bunu kendi başınıza yeniden uygulamanız kötü bir tavsiye değildir, aynı zamanda bunu yapmaya gerek yoktur:

Fakir bir adamın çerez imzası

Tarayıcıya bir Yanıt göndermeden önce:

(1) Önce a SECRET_KEYkurulur. Yalnızca uygulama tarafından bilinmeli ve uygulamanın yeniden başlatılması dahil olmak üzere uygulamanın yaşam döngüsü boyunca nispeten sabit tutulmalıdır.

# choose a salt, a secret string of bytes
>>> SECRET_KEY = 'my super secret key'.encode('utf8')

(2) bir çerez oluşturun

>>> cookie = make_cookie(
...     name='_profile', 
...     content='uid=382|membership=regular',
...     ...
...     expires='July 1 2030...'
... )

>>> print(cookie)
name: _profile
content: uid=382|membership=regular...
    ...
    ...
expires: July 1 2030, 1:20:40 AM UTC

(3) bir imza oluşturmak, SECRET_KEYbunu çerez bayt dizesine eklemek (veya başına eklemek) , ardından bu kombinasyondan bir karma oluşturmak.

# encode and salt the cookie, then hash the result
>>> cookie_bytes = str(cookie).encode('utf8')
>>> signature = sha1(cookie_bytes+SECRET_KEY).hexdigest()
>>> print(signature)
7ae0e9e033b5fa53aa....

(4) Şimdi contentorijinal çerez alanının bir ucuna imzayı yapıştırın .

# include signature as part of the cookie
>>> cookie.content = cookie.content + '|' + signature
>>> print(cookie)
name: _profile
content: uid=382|membership=regular|7ae0e9...  <--- signature
domain: .example.com
path: /
send for: Encrypted connections only
expires: July 1 2030, 1:20:40 AM UTC

ve müşteriye gönderilen budur.

# add cookie to response
>>> response.set_cookie(cookie)
# send to browser --> 

Çerezi tarayıcıdan aldıktan sonra:

(5) Tarayıcı bu çerezi sunucuya geri gönderdiğinde content, orijinal çerezi geri almak için çerez alanındaki imzayı çıkarın .

# Upon receiving the cookie from browser
>>> cookie = request.get_cookie()
# pop the signature out of the cookie
>>> (cookie.content, popped_signature) = cookie.content.rsplit('|', 1)

(6) SECRET_KEYAdım 3'tekiyle aynı yöntemi kullanarak imzayı yeniden hesaplamak için uygulamanın orijinal tanımlama bilgisini kullanın .

# recalculate signature using SECRET_KEY and original cookie
>>> cookie_bytes = str(cookie).encode('utf8')
>>> calculated_signature = sha1(cookie_bytes+SECRET_KEY).hexdigest()

(7) Hesaplanan sonucu, yeni alınan çerezden daha önce atılan imza ile karşılaştırın. Eşleşirlerse, çerezin karıştırılmadığını biliyoruz. Ancak çereze sadece bir boşluk eklenmiş olsa bile imzalar eşleşmeyecektir.

# if both signatures match, your cookie has not been modified
>>> good_cookie = popped_signature==calculated_signature

(8) Eşleşmiyorlarsa, herhangi bir sayıda eylemle yanıt verebilir, olayı günlüğe kaydedebilir, tanımlama bilgisini atabilir, yeni bir tanımlama yapabilir, bir giriş sayfasına yönlendirebilirsiniz, vb.

>>> if not good_cookie:
...     security_log(cookie)

Karma tabanlı Mesaj Kimlik Doğrulama Kodu (HMAC)

Bazı içeriklerin bütünlüğünü sağlamak için gizli bir anahtar gerektiren yukarıda üretilen imza türüne kriptografide bir Mesaj Kimlik Doğrulama Kodu veya MAC denir .

Daha önce yukarıdaki örneğin bu konseptin aşırı basitleştirilmesi olduğunu ve kendi imzanızı uygulamanın iyi bir fikir olmadığını belirtmiştim. Bunun nedeni, Flask'ta çerezleri imzalamak için kullanılan algoritmanın HMAC olarak adlandırılması ve yukarıdaki basit adım adımdan biraz daha karmaşık olmasıdır. Genel fikir aynıdır, ancak bu tartışmanın kapsamı dışındaki nedenlerden dolayı, bir dizi hesaplama biraz daha karmaşıktır. Hala bir DIY yapmakla ilgileniyorsanız, genellikle olduğu gibi, Python'da başlamanıza yardımcı olacak bazı modüller vardır :) işte bir başlangıç ​​bloğu:

import hmac
import hashlib

def create_signature(secret_key, msg, digestmod=None):
    if digestmod is None:
        digestmod = hashlib.sha1
    mac = hmac.new(secret_key, msg=msg, digestmod=digestmod)
    return mac.digest()

Hmac ve hashlib için belge .


SECRET_KEY:) "Demystification"

Bu bağlamda "imza" nedir?

Bu, bazı içeriğin bir kişi veya bunu yapmaya yetkili bir varlık dışında herhangi biri tarafından değiştirilmediğinden emin olmak için bir yöntemdir.

İmzanın en basit biçimlerinden biri , iki veri parçasının aynı olduğunu basitçe doğrulayan " sağlama toplamı " dır . Örneğin, kaynaktan yazılım yüklerken, öncelikle kaynak kodu kopyanızın yazarın kopyasıyla aynı olduğunu doğrulamak önemlidir. Bunu yapmak için yaygın bir yaklaşım, kaynağı bir kriptografik karma işlevi aracılığıyla çalıştırmak ve çıktıyı projenin ana sayfasında yayınlanan sağlama toplamı ile karşılaştırmaktır.

Örneğin, bir projenin kaynağını bir web aynasından gzip ile sıkıştırılmış bir dosyada indirmek üzere olduğunuzu varsayalım. Projenin web sayfasında yayınlanan SHA1 sağlama toplamı 'eb84e8da7ca23e9f83 ....'

# so you get the code from the mirror
download https://mirror.example-codedump.com/source_code.tar.gz
# you calculate the hash as instructed
sha1(source_code.tar.gz)
> eb84e8da7c....

Her iki karma da aynıdır, aynı kopyaya sahip olduğunuzu bilirsiniz.

Çerez nedir?

Çerezler hakkında kapsamlı bir tartışma, bu sorunun kapsamının ötesine geçecektir. Burada bir genel bakış sunuyorum, çünkü asgari düzeyde bir anlayış, nasıl ve neden yararlı olduğunu daha iyi anlamak SECRET_KEYiçin yararlı olabilir. HTTP Çerezleri ile ilgili bazı kişisel okumaları takip etmenizi şiddetle tavsiye ederim.

Web uygulamalarında yaygın bir uygulama, istemciyi (web tarayıcısı) hafif bir önbellek olarak kullanmaktır. Çerezler, bu uygulamanın bir uygulamasıdır. Tanımlama bilgisi tipik olarak sunucu tarafından bir HTTP yanıtına başlıkları yoluyla eklenen bazı verilerdir. Tarayıcı tarafından tutulur ve daha sonra istekleri gönderirken, yine HTTP başlıkları yoluyla sunucuya geri gönderir. Bir çerezde yer alan veriler, adı verilen şeyi taklit etmek için kullanılabilir. durum bilgisi, sunucunun istemciyle sürekli bir bağlantı sürdürdüğü yanılsaması. Yalnızca bu durumda, bağlantıyı "canlı" tutmak için bir kablo yerine, uygulamanın bir müşterinin talebini yerine getirdikten sonra durumunun anlık görüntülerine sahip olursunuz. Bu anlık görüntüler, istemci ve sunucu arasında ileri geri taşınır. Bir istek aldıktan sonra, sunucu ilk olarak müşteri ile görüşmesinin içeriğini yeniden oluşturmak için tanımlama bilgisinin içeriğini okur. Daha sonra bu bağlamda isteği işler ve yanıtı istemciye geri göndermeden önce çerezi günceller. Devam eden bir oturumun illüzyonu böylece korunur.

Bir çerez neye benzer?

Tipik bir çerez şu şekilde görünür:

name: _profile
content: uid=382|status=genie
domain: .example.com
path: /
send for: Encrypted connections only
expires: July 1 2030, 1:20:40 AM UTC

Çerezleri herhangi bir modern tarayıcıdan incelemek önemsizdir. Örneğin Firefox'ta Tercihler> Gizlilik> Geçmiş'e gidin> çerezleri tek tek kaldırın .

contentSaha uygulamasında en alakalı. Diğer alanlar, çeşitli etki alanlarını belirlemek için çoğunlukla meta talimatlar taşır.

Neden çerez kullanıyorsunuz?

Kısa cevap performanstır. Tanımlama bilgilerini kullanmak, çeşitli veri depolarında (bellek önbellekleri, dosyalar, veritabanları, vb.) Arama yapma ihtiyacını en aza indirir, böylece sunucu uygulamasının işlerini hızlandırır. Çerez ne kadar büyükse, ağ üzerindeki yükün o kadar ağır olacağını, bu nedenle sunucuda veritabanı aramasında kaydettiklerinizi ağ üzerinden kaybedebileceğinizi unutmayın. Çerezlerinize neleri dahil edeceğinizi dikkatlice düşünün.

Çerezlerin neden imzalanması gerekir?

Çerezler, bazıları çok hassas olabilen her türlü bilgiyi saklamak için kullanılır. Ayrıca doğaları gereği güvenli değildirler ve her iki taraf, istemci ve sunucu için herhangi bir şekilde güvenli kabul edilmesi için bir dizi yardımcı önlemin alınmasını gerektirir. Tanımlama bilgilerinin imzalanması, özellikle sunucu uygulamalarını kandırma girişimlerinde düzeltilebilecekleri sorunu ele alır. Diğer güvenlik açıklarını azaltmak için başka önlemler de var, çerezler hakkında daha fazla bilgi edinmenizi tavsiye ederim.

Bir çerez nasıl tahrif edilebilir?

Çerezler, müşteride metin biçiminde bulunur ve herhangi bir çaba gösterilmeden düzenlenebilir. Sunucu uygulamanız tarafından alınan bir tanımlama bilgisi, bazıları masum olmayabilecek birkaç nedenden dolayı değiştirilmiş olabilir. Çerezlerde kullanıcılarıyla ilgili izin bilgilerini tutan ve bu bilgilere dayanarak ayrıcalıklar veren bir web uygulaması hayal edin. Tanımlama bilgisi düzeltmeye karşı korumalı değilse, herhangi biri kendi statüsünü "rol = ziyaretçi" den "rol = yönetici" ye yükseltmek için kendi durumunu değiştirebilir ve uygulama daha akıllıca olmaz.

SECRET_KEYÇerezleri imzalamak neden gereklidir?

Çerezleri doğrulamak, kaynak kodunu daha önce anlatıldığı gibi doğrulamaktan biraz farklıdır. Kaynak kod söz konusu olduğunda, orijinal yazar, halka açık tutulacak olan referans parmak izinin (sağlama toplamı) mütevelli ve sahibidir. Güvenmediğiniz şey kaynak koddur, ancak genel imzaya güvenirsiniz. Bu nedenle, kaynak kopyanızı doğrulamak için, hesaplanan hashinizin genel hash ile eşleşmesini istersiniz.

Çerez olması durumunda, uygulama imzayı takip etmez, onun kaydını tutar SECRET_KEY. SECRET_KEYReferans parmak izidir. Çerezler, yasal olduğunu iddia ettikleri bir imza ile seyahat ederler. Buradaki meşruiyet, imzanın çerez sahibi, yani uygulama tarafından verildiği anlamına gelir ve bu durumda, güvenmediğiniz ve imzanın geçerliliğini kontrol etmeniz gerektiği iddiasıdır. Bunu yapmak için imzaya yalnızca sizin bildiğiniz bir öğeyi eklemeniz gerekir, bu SECRET_KEY. Birisi bir çerezi değiştirebilir, ancak geçerli bir imzayı düzgün bir şekilde hesaplayacak gizli içeriğe sahip olmadıkları için onu yanıltamazlar. Biraz daha önce belirtildiği gibi, bu tür parmak izi alma, sağlama toplamının en üstünde bir gizli anahtar da sağlar,

Oturumlar ne olacak?

Klasik uygulamalarındaki oturumlar, contentalanında yalnızca bir kimlik taşıyan çerezlerdir session_id. Oturumların amacı, imzalı tanımlama bilgileriyle tamamen aynıdır, yani tanımlama bilgilerinin değiştirilmesini önlemek için. Klasik seansların farklı bir yaklaşımı var. Bir oturum tanımlama bilgisini aldıktan sonra, sunucu kimliği kendi yerel deposunda oturum verilerini aramak için kullanır, bu bir veritabanı, dosya veya bazen bellekte bir önbellek olabilir. Oturum tanımlama bilgisi genellikle tarayıcı kapatıldığında sona erecek şekilde ayarlanır. Yerel depolama araması adımı nedeniyle, oturumların bu şekilde uygulanması genellikle bir performans vuruşuna neden olur. İmzalı çerezler tercih edilen bir alternatif haline geliyor ve Flask'ın oturumları bu şekilde uygulanıyor. Başka bir deyişle, Flask oturumları vardırimzalı çerezler ve Flask'ta imzalı çerezleri kullanmak için sadece SessionAPI'sini kullanın .

Neden çerezleri de şifrelemiyorsunuz?

Bazen çerezlerin içeriği de imzalanmadan önce şifrelenebilir . Bu, tarayıcıdan görünemeyecek kadar hassas oldukları kabul edilirse yapılır (şifreleme, içeriği gizler). Bununla birlikte, yalnızca çerezleri imzalamak, farklı bir ihtiyaca hitap eder; tarayıcıda çerezlerin bir dereceye kadar görünebilirliğini ve kullanılabilirliğini sürdürürken, aynı zamanda müdahale edilmelerini önler.

Değiştirirsem ne olur SECRET_KEY?

Değiştirerek SECRET_KEYEğer geçersiz konum tüm önceki anahtarla imzalanmış çerezleri. Uygulama, önceki bir çerezle imzalanmış bir çerez içeren bir talep aldığında SECRET_KEY, yeni ile imzayı hesaplamaya çalışacak SECRET_KEYve her iki imza da eşleşmeyecek, bu çerez ve tüm verileri reddedilecek, sanki tarayıcı sunucuya ilk kez bağlanıyor. Kullanıcıların oturumu kapatılacak ve eski çerezleri, içinde saklanan her şeyle birlikte unutulacaktır. Bunun, süresi dolmuş bir tanımlama bilgisinin işlenme biçiminden farklı olduğunu unutmayın. Süresi dolan bir tanımlama bilgisinin, imzası kontrol edilirse kira süresi uzatılabilir. Geçersiz bir imza, yalnızca geçersiz bir tanımlama bilgisi anlamına gelir.

Bu nedenle, tüm imzalı çerezleri geçersiz kılmak istemiyorsanız, SECRET_KEYuzun süre aynı şekilde kalmaya çalışın .

İyi olan nedir SECRET_KEY?

Gizli bir anahtarın tahmin edilmesi zor olmalı. Sessions'daki dokümantasyon, rastgele anahtar üretimi için iyi bir reçeteye sahiptir:

>>> import os
>>> os.urandom(24)
'\xfd{H\xe5<\x95\xf9\xe3\x96.5\xd1\x01O<!\xd5\xa2\xa0\x9fR"\xa1\xa8'

Anahtarı kopyalayıp yapılandırma dosyanıza değeri olarak yapıştırırsınız SECRET_KEY.

Rastgele oluşturulmuş bir anahtarı kullanmak yerine, muhtemelen yalnızca sizin tarafınızdan bilinen, bayt biçiminde kodlanmış bir cümle halinde düzenlenmiş karmaşık bir kelime, sayı ve simge çeşitliliği kullanabilirsiniz.

Do not set SECRET_KEYfarklı bir anahtar denir her zaman üreten bir işlevle doğrudan. Örneğin, şunu yapmayın:

# this is not good
SECRET_KEY = random_key_generator()

Uygulamanız her yeniden başlatıldığında, ona yeni bir anahtar verilecek ve böylece öncekini geçersiz kılacaktır.

Bunun yerine, etkileşimli bir python kabuğu açın ve anahtarı oluşturmak için işlevi çağırın, ardından bunu kopyalayıp yapılandırmaya yapıştırın.

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.