服务器
例如,我们开发一个显示所有用户的留言的网站:
建立如下的flask
项目:
app.py
为python程序,代码:
import json
import flask
app = flask.Flask(__name__)
@app.route('/', methods=['GET', 'POST'])
def index():
request = flask.request
with open('messages.json', 'r', encoding='utf-8') as fp:
data = json.load(fp) # 读入用户留言
data = list(data) # 建议有这一句,防止JSON被篡改
if request.method == 'GET': # GET请求
return flask.render_template('index.html', messages=data)
else: # POST请求
message = request.form.get('message').strip()
if not message:
flask.flash('请填入信息')
return flask.redirect(flask.url_for('index'))
data.append(message)
with open('messages.json', 'w', encoding='utf-8') as fp:
json.dump(data, fp) # 写入用户留言
return flask.redirect(flask.url_for('index'))
app.run(debug=True)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
index.html
为网站页面,代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>测试XSS注入</title>
<!-- 导入bootstrap -->
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://cdn.staticfile.org/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
</head>
<body>
<div class="container">
<ul>
<!-- Flask Jinja2模板-->
{% for i in messages %}
<li> {{ i }} </li>
{% endfor %}
</ul>
<br>
<hr>
<form method="post" action="/" class="bs-example bs-example-form" role="form">
<!-- 用户输入框 -->
<div class="input-group" align="center">
<span class="input-group-addon">留言:</span>
<input type="text" class="form-control" name="message">
</div>
<hr>
<input type="submit" value="发送" class="btn btn-primary" align="center">
</form>
</div>
{% for message in get_flashed_messages() %}
<div class="alert alert-warning">
<a href="#" class="close" data-dismiss="alert">
×
</a>
<strong>{{ message }}</strong>
</div>
{% endfor %}
</body>
</html>
- 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
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
messages.json
为用户信息储存器:
["test", "hello world"]
- 1
效果如下:
攻击者
现在,我们在网站的输入框中输入一句JavaScript
代码:
alert("你已被XSS攻击!")
- 1
刷新网站后:
防御
(这里只提供最简单的思路)
我们加入如下代码:
nopass = ['<script>', 'SB'] # 违法字典,你也可以用它屏蔽脏话
- 1
for i in nopass:
if i in message:
flask.flash('信息不合法')
return flask.redirect(flask.url_for('index'))
- 1
- 2
- 3
- 4
改动后的代码:
import json
import flask
app = flask.Flask(__name__)
@app.route('/', methods=['GET', 'POST'])
def index():
request = flask.request
with open('messages.json', 'r', encoding='utf-8') as fp:
data = json.load(fp) # 读入用户留言
data = list(data) # 建议有这一句,防止JSON被篡改
if request.method == 'GET': # GET请求
return flask.render_template('index.html', messages=data)
else: # POST请求
nopass = ['<script>', 'SB'] # 违法字典,你也可以用它屏蔽脏话
message = request.form.get('message').strip()
if not message:
flask.flash('请填入信息')
return flask.redirect(flask.url_for('index'))
for i in nopass:
if i in message:
flask.flash('信息不合法')
return flask.redirect(flask.url_for('index'))
data.append(message)
with open('messages.json', 'w', encoding='utf-8') as fp:
json.dump(data, fp) # 写入用户留言
return flask.redirect(flask.url_for('index'))
app.run(debug=True)
- 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