SECRET_KEY作用
本质上是一个加密盐
SECTET_KEY 在 django在加密,安全方面都有很突出的用处
json object的签名
加密函数中必不可少的,密码重置,表单提交,csrf的key,session数据等等都是需要SELECT_KEY的
这里面就要重点讲到session的问题,在这里使用不当就会导致攻击代码执行
settings的session设置
django默认存储session到数据库中,但是可能会比较慢,就会使用到缓存,文件,还有cookie等方式
如果采用了cookie机制,settings配置如下:
SESSION_ENGINE = 'django.contrib.sessions.backends.signed_cookies'
版本问题:django 1.6以下
在django1.6以下,session默认是采用pickle执行序列号操作
在1.6及以上版本默认采用json序列化。代码执行只存在于使用pickle序列号的操作中。
session处理流程
可以简单的分为两部分
process_request负责选择session引擎
process_response初始化cookie数据
代码
class SessionMiddleware(object):
def process_request(self, request):
engine = import_module(settings.SESSION_ENGINE)
session_key = request.COOKIES.get(settings.SESSION_COOKIE_NAME, None)
request.session = engine.SessionStore(session_key)
process_response 是用来处理 返回给用户的信息,这包括有关cookie的一些信息,比如修改过期时间等等。
在将session存入缓存后,可能在某个操作中会用到session信息,这个时候就会通过反序列化操作从缓存中取SECRET__KEY
如果反序列化引擎是采用pickle机制的话就有可能存在攻击代码执行。
反序列化的代码位于django.core.signing.py中,这个模块主要是一些签名,加解密操作,同时也包含序列化和反序列化,默认采用JSON引擎
反序列化loads的代码:
def loads(s, key=None, salt='django.core.signing', serializer=JSONSerializer, max_age=None):
"""
Reverse of dumps(), raises BadSignature if signature fails
"""
base64d = smart_str(
TimestampSigner(key, salt=salt).unsign(s, max_age=max_age))
decompress = False
if base64d[0] == '.':
# It's compressed; uncompress it first
base64d = base64d[1:]
decompress = True
data = b64_decode(base64d)
if decompress:
data = zlib.decompress(data)
return serializer().loads(data)
-
其攻击方式为:
-
首先泄露了SECRET_KEY
其次session引擎采用了signed_cookies
之后就是根据SECRET_KEY反序列化得到所想要得到的。。。
注:
django版本小于1.6即存在攻击代码执行问题。
同样的问题也存在于python的其他web框架中,如flask,bottle。