使用Python编写的基于Token的跨站请求伪造(CSRF)防护
跨站请求伪造(CSRF)攻击是一种常见的网络安全威胁,攻击者通过伪造用户身份,向受害者的服务器发送恶意请求。为了防止CSRF攻击,常见的解决方案是使用基于Token的防护机制。
下面是一个使用Python编写的基于Token的CSRF防护的例子。
首先,导入所需的库和模块:
import hashlib import os from flask import Flask, render_template, request, redirect, session, make_response
然后,创建一个Flask应用:
app = Flask(__name__) app.secret_key = os.urandom(24)
在这个例子中,使用了Flask框架,并设置了一个密钥用于生成Token。
接下来,定义一个装饰器函数,用于装饰需要进行CSRF防护的路由:
def csrf_protect(func):
def inner(*args, **kwargs):
token = session.pop('_csrf_token', None)
if not token or token != request.form.get('_csrf_token'):
return "CSRF Attack Detected!"
return func(*args, **kwargs)
return inner
在该装饰器函数中,首先从session中获取保存的Token,并与请求中的Token进行比较。如果两者不一致,说明可能存在CSRF攻击,返回相应的错误信息。否则,执行原始函数。
然后,定义一个生成Token的函数:
def generate_csrf_token():
if '_csrf_token' not in session:
session['_csrf_token'] = hashlib.sha256(os.urandom(24)).hexdigest()
return session['_csrf_token']
在这个函数中,使用了hashlib库和os库生成随机的Token。如果Token不存在于session中,将生成一个新的Token并保存到session中。
接下来,定义一个用于展示表单的路由,并使用csrf_protect装饰器对其进行保护:
@app.route('/', methods=['GET'])
@csrf_protect
def show_form():
return render_template('form.html', token=generate_csrf_token())
在该路由中,首先调用generate_csrf_token函数生成Token,并将其传递给模板文件form.html。然后,渲染表单模板并返回给用户。
最后,定义一个处理表单提交的路由,并使用csrf_protect装饰器对其进行保护:
@app.route('/', methods=['POST'])
@csrf_protect
def submit_form():
response = make_response("Form Submitted Successfully!")
return response
在该路由中,首先创建一个响应对象。然后,返回相应的成功消息。
最后,运行应用:
if __name__ == '__main__':
app.run()
完整的代码如下:
import hashlib
import os
from flask import Flask, render_template, request, session, make_response
app = Flask(__name__)
app.secret_key = os.urandom(24)
def csrf_protect(func):
def inner(*args, **kwargs):
token = session.pop('_csrf_token', None)
if not token or token != request.form.get('_csrf_token'):
return "CSRF Attack Detected!"
return func(*args, **kwargs)
return inner
def generate_csrf_token():
if '_csrf_token' not in session:
session['_csrf_token'] = hashlib.sha256(os.urandom(24)).hexdigest()
return session['_csrf_token']
@app.route('/', methods=['GET'])
@csrf_protect
def show_form():
return render_template('form.html', token=generate_csrf_token())
@app.route('/', methods=['POST'])
@csrf_protect
def submit_form():
response = make_response("Form Submitted Successfully!")
return response
if __name__ == '__main__':
app.run()
在模板文件form.html中,可以使用生成的Token来保护表单:
<form method="POST" action="/">
<input type="hidden" name="_csrf_token" value="{{ token }}">
<!-- 其他表单字段 -->
<input type="submit" value="Submit">
</form>
这样,使用Token来保护表单,可以有效防止CSRF攻击。当用户提交表单时,服务器将验证Token是否与请求中的Token一致,如果不一致,则拒绝提交,并返回相应的错误信息。
以上就是一个简单的使用Python编写的基于Token的CSRF防护的例子。通过使用Token来保护表单,可以增加Web应用的安全性,防范CSRF攻击。
