初窺CSRF攻擊方式以及Flask-WTF

含義

CSRF(Cross-site request forgery),中文名稱:跨站請求僞造,也被稱爲:one click attack/session riding,縮寫爲:CSRF/XSRF。

解釋

在這裏插入圖片描述這幅圖非常形象的解釋了CSRF原理的具體過程。

從上圖可以看出,要完成一次CSRF攻擊,受害者必須依次完成兩個步驟:

  1. 登錄受信任網站A,並在本地生成Cookie。
  2. 在不登出A的情況下,訪問危險網站B。

看到這裏,你也許會說:“如果我不滿足以上兩個條件中的一個,我就不會受到CSRF的攻擊”。是的,確實如此,但你不能保證以下情況不會發生:

  1. 你不能保證你登錄了一個網站後,不再打開一個tab頁面並訪問另外的網站。

  2. 你不能保證你關閉瀏覽器了後,你本地的Cookie立刻過期,你上次的會話已經結束。(事實上,關閉瀏覽器不能結束一個會話,但大多數人都會錯誤的認爲關閉瀏覽器就等於退出登錄/結束會話了…)

  3. 上圖中所謂的攻擊網站,可能是一個存在其他漏洞的可信任的經常被人訪問的網站。

flask 中的CSRF保護

Flask-WTF 表單保護你免受 CSRF 威脅,你不需要有任何擔心。儘管如此,如果你有不包含表單的視圖,那麼它們仍需要額外的保護。
例如,由 AJAX 發送的 POST 請求,並沒有通過表單。在 0.9.0 之前版本,你無法獲得 CSRF 令牌。這就是爲什麼我們編寫了 CSRF 模塊。

實現

要對所有視圖函數啓用 CSRF 保護,你需要啓用 CsrfProtect 模塊:

from flask_wtf.csrf import CsrfProtect

CsrfProtect(app)

與任何其它的 Flask 擴展一樣,你可以惰性加載它:

from flask_wtf.csrf import CsrfProtect

csrf = CsrfProtect()

def create_app():
    app = Flask(__name__)
    csrf.init_app(app)

如果模板中有表單,你不需要做任何事。與之前一樣:

<form method="post" action="/">
    {{ form.csrf_token }}
</form>

但如果模板中沒有表單,你仍需要 CSRF 令牌:

<form method="post" action="/">
    <input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
</form>

無論何時未通過 CSRF 驗證,都會返回 400 響應。你可以自定義這個錯誤響應:

@csrf.error_handler
def csrf_error(reason):
    return render_template('csrf_error.html', reason=reason), 400

我們強烈建議你對所有視圖啓用 CSRF 保護。但也提供了將某些視圖函數除外的途徑:

@csrf.exempt
@app.route('/foo', methods=('GET', 'POST'))
def my_handler():
    # ...
    return 'ok'

參考

https://www.cnblogs.com/hyddd/archive/2009/04/09/1432744.html
http://docs.jinkan.org/docs/flask-wtf/csrf.html

發佈了205 篇原創文章 · 獲贊 139 · 訪問量 102萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章