欢迎访问宙启技术站
智能推送

使用Python编写的基于Token的跨站请求伪造(CSRF)防护

发布时间:2024-01-02 16:29:38

跨站请求伪造(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攻击。