使用Python编写CSRF攻击和防御的实验课程
CSRF(Cross-Site Request Forgery,跨站请求伪造)是一种常见的网络攻击方式,主要针对已经登录的用户。本实验课程将使用Python演示CSRF攻击和防御的方法。
准备工作:安装Python和Flask框架
- 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攻击和防御的实验课程,希望对您有所帮助。
相关文章