找回密碼
 註冊
搜索
查看: 232|回復: 0

[教學] Flask 中的 CSRF 保護

[複製鏈接]
發表於 4 天前 | 顯示全部樓層 |閱讀模式
Push to Facebook
跨站請求偽造 (CSRF)是一種安全漏洞,攻擊者會誘騙使用者在不知情的情況下向已驗證身分的 Web 應用程式提交請求。這可能導致攻擊者以使用者的名義執行未經授權的操作,例如更改帳戶設定或進行交易。

如何防止 CSRF 攻擊?
預防 CSRF 攻擊最有效的方法之一是使用 CSRF 令牌。這些令牌是唯一的、動態產生的值,包含在表單中,並在發出請求時由伺服器驗證。由於攻擊者無法預測這些令牌,因此他們無法偽造有效的請求。

Flask CSRF 保護

Flask   CSRF 保護


在 Flask 中實現 CSRF 保護
步驟1:安裝依賴項
若要在 Flask 中實現 CSRF 保護,請使用以下命令安裝所需的軟體包:

  1. pip install flask flask-wtf
複製代碼


步驟2:設定Flask應用程式
在 Flask 中,可以使用 Flask-WTF 啟用 CSRF 保護,它為表單提供自動 CSRF 保護。下面是一個基本範例:


  1. from flask import Flask, render_template, request, flash
  2. from flask_wtf import FlaskForm, CSRFProtect
  3. from wtforms import StringField, SubmitField
  4. from wtforms.validators import DataRequired

  5. app = Flask(__name__)
  6. app.secret_key = 'your_secret_key'  # Required for CSRF protection
  7. csrf = CSRFProtect(app)  # Enable CSRF Protection

  8. # Creating a FlaskForm to manage CSRF properly
  9. class NameForm(FlaskForm):
  10.     name = StringField('Name', validators=[DataRequired()])
  11.     submit = SubmitField('Submit')

  12. @app.route("/", methods=['GET', 'POST'])
  13. def index():
  14.     form = NameForm()

  15.     if request.method == 'POST':
  16.         if form.validate_on_submit():
  17.             name = form.name.data
  18.             flash(f'Hello {name} from Protected Form!', 'success')
  19.             return render_template('index.html', form=form)
  20.         else:
  21.             flash('CSRF Token Missing or Invalid!', 'danger')

  22.     return render_template('index.html', form=form)

  23. @app.route("/unprotected_form", methods=['POST'])
  24. def unprotected_form():
  25.     name = request.form.get('Name', '').strip()
  26.     if not name:
  27.         return "Error: Name is required!", 400
  28.     return f'Hello {name} from Unprotected Form!'

  29. if __name__ == '__main__':
  30.     app.run(debug=True)
複製代碼


步驟3:建立安全的HTML表單
一個包含受 CSRF 保護和不受保護的表單的簡單 HTML 頁面:

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4.     <title>CSRF Protection Demo</title>
  5. </head>
  6. <body>

  7.     <h2>Protected Form (CSRF Token Required)</h2>
  8.     <form action="{{ url_for('index') }}" method="POST">
  9.         {{ form.hidden_tag() }}  <!-- This automatically includes CSRF token -->
  10.         <label for="Name">Your Name Please?</label>
  11.         {{ form.name() }}  <!-- Flask-WTF handles input -->
  12.         {{ form.submit() }}  <!-- Submit button -->
  13.     </form>

  14.     <h2>Unprotected Form (No CSRF Token)</h2>
  15.     <form action="{{ url_for('unprotected_form') }}" method="POST">
  16.         <label for="Name">Your Name Please?</label>
  17.         <input type="text" name="Name" required>
  18.         <button type="submit">Submit</button>
  19.     </form>

  20.     <!-- Flash Messages -->
  21.     {% with messages = get_flashed_messages(with_categories=True) %}
  22.         {% if messages %}
  23.             {% for category, message in messages %}
  24.                 <p style="color: {{ 'red' if category == 'danger' else 'green' }}">{{ message }}</p>
  25.             {% endfor %}
  26.         {% endif %}
  27.     {% endwith %}

  28. </body>
  29. </html>
複製代碼


步驟5:測試CSRF保護
在瀏覽器中開啟http://127.0.0.1:5000/protected_form
嘗試提交兩種表格:
不受保護的表單:提交時沒有任何令牌,因此容易受到 CSRF 攻擊。
受保護的表單:需要有效的 CSRF 令牌才能成功提交。
如果您嘗試在沒有 CSRF 令牌的情況下提交受保護的表單,則會發生錯誤,從而阻止未經授權的請求。


Flask CSRF 保護

Flask   CSRF 保護

Flask CSRF 保護

Flask   CSRF 保護

Flask CSRF 保護

Flask   CSRF 保護

Flask CSRF 保護

Flask   CSRF 保護




注意:要提交需要 CSRF 令牌的表單,請使用 Flask-WTF 的 hidden_​​tag() 方法,它會自動在表單內產生包含 CSRD 令牌的隱藏欄位。


https://www.geeksforgeeks.org/python/csrf-protection-in-flask/
您需要登錄後才可以回帖 登錄 | 註冊

本版積分規則

Archiver|手機版|小黑屋|TShopping

GMT+8, 2025-9-14 04:09 , Processed in 0.024094 second(s), 22 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回復 返回頂部 返回列表