翻译自: How Secure Is The Flask User Session?

我已经很多次听过人们说在Flask中的用户session是加密过的,因此在里面写入隐私信息也是安全的。这是一个误解,而且可能会在应用中导致灾难性的后果,最重要的是,对你的用户。不相信我吗?下面你可以看到我数秒之内解析一个Flask用户session,根本不需要应用的secret key.

Video

因此绝对不要在Flask session cookie中存储密码。当然,你可以存储不是密码的东西,但是仍然需要安全的存储。我希望这个视频可以澄清在用户session中的数据是非常容易获取的,有非常好的保护来对抗这个篡改,只要服务器的secret key不会妥协。

The Example Application

下面就是视频中的服务器的代码。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import os
import random
from flask import Flask, session, redirect, url_for, request, render_template
app = Flask(__name__)
app.config['SECRET_KEY'] = os.getenv('SECRET_KEY') or \
'e5ac358c-f0bf-11e5-9e39-d3b532c10a28'
@app.route('/')
def index():
# answer值不能在用户session中存储
# 因为session会被在cookie中发送到客户端,而cookie是没有被加密的
session['answer'] = random.randint(1, 10)
session['try_number'] = 1
return redirect(url_for('guess'))
@app.route('/guess')
def guess():
guess = int(request.args['guess']) if 'guess' in request.args else None
if request.args.get('guess'):
if guess == session['answer']:
return render_template('win.html')
else:
session['try_number'] += 1
if session['try_number'] > 3:
return render_template('lose.html', guess=guess)
return render_template('guess.html', try_number=session['try_number'],
guess=guess)
if __name__ == '__main__':
app.run()

下面是在templates子文件夹中存储的3个模版文件,第一个是guess.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<html>
<head>
<title>Guess the number!</title>
</head>
<body>
<h1>Guess the number!</h1>
{% if try_number == 1 %}
<p>I thought of a number from 1 to 10. Can you guess it?</p>
{% else %}
<p>Sorry, {{ guess }} is incorrect. Try again!</p>
{% endif %}
<form action="">
Try #{{ try_number }}: <input type="text" name="guess">
<input type="submit">
</form>
</body>
</html>

第二个是win.html

1
2
3
4
5
6
7
8
9
10
<html>
<head>
<title>Guess the number: You win!</title>
</head>
<body>
<h1>Guess the number!</h1>
<p>Congratulations, {{ session['answer'] }} is the correct number.</p>
<p><a href="{{ url_for('index') }}">Play again</a></p>
</body>
</html>

最后一个是lose.html

1
2
3
4
5
6
7
8
9
10
<html>
<head>
<title>Guess the number: You lose!</title>
</head>
<body>
<h1>Guess the number!</h1>
<p>Sorry, {{ guess }} is incorrect. My guess was {{ session['answer'] }}.</p>
<p><a href="{{ url_for('index') }}">Play again</a></p>
</body>
</html>

If Sessions Aren’t Secure Enough, Then What Is?

现在你知道了Flask用户session不是一个存储敏感信息的地方,那么如果你需要存储私密信息,但是使用数据库看起来有点过分。

一个好的方式是使用不同的用户session实现。Flask默认使用的是基于cookie的session,但是仍然有在其他地方存储数据的自定义session。特别的,Flask-Session扩展非常有意思,它将用户session数据存储在服务器,给你了不同的存储选项:文件,Redis,关系型数据库等等。当session数据在服务器中存储的时候,你可以确保你存储的数据和你的服务器一样安全。