CSRF(Cross-Site Request Forgery,跨站要求捏造)是一种常见的网络攻击方式,主要针对已登录的用户。本实验课程将使用python演示CSRF攻击和防御的方法。
- CSRF攻击
首先,我们需要编写一个简单的Flask利用程序来演示CSRF攻击。该利用程序包括一个简单的表单和一个提交按钮,用户可以在表单中输入一个文本字符串,并将其发送到服务器上。
from flask import Flask, render_template, request app = Flask(__name__) @app.route('/') def index(): return render_template('index.html') @app.route('/submit', methods=['POST']) def submit(): text = request.form['text'] return f'Text submitted: {text}' if __name__ == '__main__': app.run()
上述代码中,index
函数用于渲染一个包括表单的HTML页面,submit
函数用于接收用户提交的表单数据并将其显示在结果页面上。
接下来,我们编写一个简单的HTML页面作为CSRF攻击的载体。该页面包括一个隐藏的表单,在用户不知情的情况下,提交用户的登录状态(例如cookie)和一个文本字符串到服务器。
<!DOCTYPE html> <html> <body> <script> function submit_form() { // 创建一个隐藏的表单 const form = document.createElement('form'); form.method = 'POST'; form.action = 'http://localhost:5000/submit'; // 创建表单元素并将其添加到表单中 const text = document.createElement('input'); text.type = 'hidden'; text.name = 'text'; text.value = 'pidancode.com'; // 添加表单元素到表单中 form.appendChild(text); // 将表单添加到页面中 document.body.appendChild(form); // 提交表单 form.submit(); } </script> <button onclick="submit_form()">Click me</button> </body> </html>
上述代码中的Javascript函数,会在用户点击“Click me”按钮时,自动创建一个隐藏的表单并将其提交到服务器。用户其实不知道正在提交表单,因此这类方式被称为“捏造要求”。
在使用CSRF攻击之前,我们需要登录到Flask利用程序中。我们可以手动在浏览器中登录到利用程序中,或使用以下代码进行登录:
import requests # 登录到Flask利用程序中 session = requests.Session() data = { 'username': 'username', 'password': 'password' } login_url = 'http://localhost:5000/login' response = session.post(login_url, data=data)
现在,我们可使用上述准备过的HTML页面进行CSRF攻击。将HTML页面保存为csrf.html
文件,并使用以下代码在本地服务器上运行:
from flask import Flask, render_template, request app = Flask(__name__) # 登录状态 logged_in = False @app.route('/') def index(): return render_template('index.html') @app.route('/submit', methods=['POST']) def submit(): global logged_in text = request.form['text'] if logged_in: return f'Text submitted: {text}' else: return 'Not logged in.' @app.route('/login', methods=['POST']) def login(): global logged_in logged_in = True return 'Logged in.' if __name__ == '__main__': app.run()
最后,在浏览器中打开Flask利用程序并登录,然后访问csrf.html
文件。在页面中,单击“Click me”按钮,看到文本字符串通过CSRF攻击已成功提交到服务器。
- CSRF防御
为了避免CSRF攻击,我们可使用CSRF令牌来验证每次提交会不会是合法的。在Flask框架中,可使用flask-wtf
扩大来轻松地生成和验证CSRF令牌。
首先,我们需要安装Flask-WTF扩大。可使用以下命令进行安装:
pip install flask-wtf
接下来,在Flask利用程序中添加CSRF保护,只需使用CSRFProtect
类便可。您还需要通过在Flask配置中设置SECRET_KEY来配置利用程序的加密密钥。
from flask import Flask, render_template, request from flask_wtf.csrf import CSRFProtect app = Flask(__name__) csrf = CSRFProtect(app) app.config['SECRET_KEY'] = 'your-secret-key'
现在,每次Flask利用程序显现包括表单的页面时,csrf_token()
函数将自动为表单生成CSRF令牌。我们需要将CSRF令牌包括在每一个表单提交中,这可以通过在模板中添加一个隐藏的输入字段来完成。
<!DOCTYPE html> <html> <body> {{ form.csrf_token }} <form method="POST" action="{{ url_for('submit') }}"> <input type="text" name="text"> <button type="submit">Submit</button> </form> </body> </html>
现在,当用户提交表单时,Flask-WTF扩大将自动验证CSRF令牌会不会匹配,以确保要求是合法的。如果CSRF令牌不匹配,利用程序将谢绝要求并显示毛病。
from flask import Flask, render_template, request from flask_wtf.csrf import CSRFProtect app = Flask(__name__) csrf = CSRFProtect(app) app.config['SECRET_KEY'] = 'your-secret-key' @app.route('/') def index(): form = TextForm() return render_template('index.html', form=form) @app.route('/submit', methods=['POST']) @csrf.exempt # 在测试代码中,我们需要在这里禁用CSRF保护 def submit(): text = request.form['text'] return f'Text submitted: {text}'
注:为了方便,这里使用了一个名为TextForm
的WTForms表单,用于在index
函数中显现表单。实际上,这其实不是一定要的,您可使用原始HTML表单来替换它。
现在,我们可以再次启动Flask利用程序,并访问具有安全保护的页面,进行手动测试。在进行CSRF攻击时,Flask-WTF扩大将验证CSRF令牌会不会匹配,从而禁止攻击。
以上就是Python编写CSRF攻击和防御的实验课程,希望对您有所帮助。
本文来源:https://www.yuntue.com/post/83474.html | 云服务器网,转载请注明出处!