csrf攻击(Cross-Site Request Forgery)也称为“跨站要求捏造”,是一种网络攻击方式,利用用户在已登录的情况下,通过捏造用户要求的方式向服务器发送要求,从而履行歹意操作。
为了避免CSRF攻击,经常使用的措施是在每次要求中加上一个Token,在后端进行验证。具体步骤以下:
- 将Token添加到表单中
在所有需要进行身份验证的表单中,需要添加一个隐藏的input框,其名称为”_csrf_token”,值就是生成的Token。可使用UUID等算法生成随机数作为Token。
<form method="POST"> <!-- 其他表单内容 --> <input type="hidden" name="_csrf_token" value="生成的Token"> <button type="submit">提交</button> </form>
- 后端进行验证
当服务器收到表单提交的要求时,需要在后端进行验证。首先,需要从要求中获得Token,这里使用Python的Flask框架作为示例。
from flask import Flask, request, abort from uuid import uuid4 app = Flask(__name__) app.secret_key = 'a secret key' app.config['WTF_CSRF_SECRET_KEY'] = 'a secret key' @app.before_request def csrf_protect(): if request.method == 'POST': csrf_token = request.form.get('_csrf_token') if csrf_token is None or csrf_token != session.pop('_csrf_token', None): abort(403) @app.route('/') def index(): return 'Hello, world!' if __name__ == '__main__': app.run()
在Flask框架中,可使用before_request
修饰器来注册一个预处理函数,该函数会在处理每一个要求之前被调用。在这个函数中,我们判断要求的方法会不会是POST,如果是,就获得要求表单中的Token,然后与服务器存储的Session中的Token对照。如果Token不匹配,就返回403毛病。
在Flask框架中,Session中的Token可以通过访问session['_csrf_token']
来获得,session.pop('_csrf_token', None)
则是从Session中弹出Token元素。注意,后一个参数是默许值,如果Session中不存在’_csrf_token’键,就返回None。
- 给Session添加Token
在每一个要求中,服务器都需要在Session中添加一个Token,以便在后面的要求中进行验证。Token的生成方法已在上面介绍过了,这里只需要在每一个要求处理的函数中添加一行代码就好了。
@app.route('/login', methods=['GET', 'POST']) def login(): if request.method == 'POST': session['_csrf_token'] = str(uuid4()) return redirect('/') return render_template('login.html')
在这个示例中,当用户通过POST方法提交表单时,服务器会生成一个Token,并将其存储在Session中。最后,重定向到首页。
Referer指的是要求的来源地址,在HTTP要求中由要求头信息中的’Referer’字段指明。通过验证Referer可以避免一些攻击,如禁止第三方网站通过iframe等方式嵌入我们的网站页面中,避免自己的服务器成为D盾等。
假定我们的网站只允许在pidancode.com域名下提交要求,那末可以在Flask框架中的每一个要求处理函数中添加以下代码:
from flask import request @app.before_request def check_referer(): # 如果要求的来源地址不是pidancode.com,则返回403毛病 if not request.referrer.startswith('http://pidancode.com/'): abort(403)
在这个代码中,可使用before_request
修饰器来注册一个预处理函数。该函数会在处理每一个要求之前被调用。在这个函数中,我们判断要求的来源地址会不会是以’http://pidancode.com/’开头,如果不是,就返回403毛病。
需要注意的是,Referrer信息是可以捏造的,所以这类方式其实不能完全避免攻击。
本文来源:https://www.yuntue.com/post/83490.html | 云服务器网,转载请注明出处!