|
跨站請求偽造 (CSRF)是一種安全漏洞,攻擊者會誘騙使用者在不知情的情況下向已驗證身分的 Web 應用程式提交請求。這可能導致攻擊者以使用者的名義執行未經授權的操作,例如更改帳戶設定或進行交易。
如何防止 CSRF 攻擊?
預防 CSRF 攻擊最有效的方法之一是使用 CSRF 令牌。這些令牌是唯一的、動態產生的值,包含在表單中,並在發出請求時由伺服器驗證。由於攻擊者無法預測這些令牌,因此他們無法偽造有效的請求。
Flask CSRF 保護
在 Flask 中實現 CSRF 保護
步驟1:安裝依賴項
若要在 Flask 中實現 CSRF 保護,請使用以下命令安裝所需的軟體包:
- pip install flask flask-wtf
複製代碼
步驟2:設定Flask應用程式
在 Flask 中,可以使用 Flask-WTF 啟用 CSRF 保護,它為表單提供自動 CSRF 保護。下面是一個基本範例:
- from flask import Flask, render_template, request, flash
- from flask_wtf import FlaskForm, CSRFProtect
- from wtforms import StringField, SubmitField
- from wtforms.validators import DataRequired
- app = Flask(__name__)
- app.secret_key = 'your_secret_key' # Required for CSRF protection
- csrf = CSRFProtect(app) # Enable CSRF Protection
- # Creating a FlaskForm to manage CSRF properly
- class NameForm(FlaskForm):
- name = StringField('Name', validators=[DataRequired()])
- submit = SubmitField('Submit')
- @app.route("/", methods=['GET', 'POST'])
- def index():
- form = NameForm()
- if request.method == 'POST':
- if form.validate_on_submit():
- name = form.name.data
- flash(f'Hello {name} from Protected Form!', 'success')
- return render_template('index.html', form=form)
- else:
- flash('CSRF Token Missing or Invalid!', 'danger')
- return render_template('index.html', form=form)
- @app.route("/unprotected_form", methods=['POST'])
- def unprotected_form():
- name = request.form.get('Name', '').strip()
- if not name:
- return "Error: Name is required!", 400
- return f'Hello {name} from Unprotected Form!'
- if __name__ == '__main__':
- app.run(debug=True)
複製代碼
步驟3:建立安全的HTML表單
一個包含受 CSRF 保護和不受保護的表單的簡單 HTML 頁面:
- <!DOCTYPE html>
- <html>
- <head>
- <title>CSRF Protection Demo</title>
- </head>
- <body>
- <h2>Protected Form (CSRF Token Required)</h2>
- <form action="{{ url_for('index') }}" method="POST">
- {{ form.hidden_tag() }} <!-- This automatically includes CSRF token -->
- <label for="Name">Your Name Please?</label>
- {{ form.name() }} <!-- Flask-WTF handles input -->
- {{ form.submit() }} <!-- Submit button -->
- </form>
- <h2>Unprotected Form (No CSRF Token)</h2>
- <form action="{{ url_for('unprotected_form') }}" method="POST">
- <label for="Name">Your Name Please?</label>
- <input type="text" name="Name" required>
- <button type="submit">Submit</button>
- </form>
- <!-- Flash Messages -->
- {% with messages = get_flashed_messages(with_categories=True) %}
- {% if messages %}
- {% for category, message in messages %}
- <p style="color: {{ 'red' if category == 'danger' else 'green' }}">{{ message }}</p>
- {% endfor %}
- {% endif %}
- {% endwith %}
- </body>
- </html>
複製代碼
步驟5:測試CSRF保護
在瀏覽器中開啟http://127.0.0.1:5000/protected_form 。
嘗試提交兩種表格:
不受保護的表單:提交時沒有任何令牌,因此容易受到 CSRF 攻擊。
受保護的表單:需要有效的 CSRF 令牌才能成功提交。
如果您嘗試在沒有 CSRF 令牌的情況下提交受保護的表單,則會發生錯誤,從而阻止未經授權的請求。
Flask CSRF 保護
Flask CSRF 保護
Flask CSRF 保護
Flask CSRF 保護
注意:要提交需要 CSRF 令牌的表單,請使用 Flask-WTF 的 hidden_tag() 方法,它會自動在表單內產生包含 CSRD 令牌的隱藏欄位。
https://www.geeksforgeeks.org/python/csrf-protection-in-flask/
|
|