跨站請求偽造(CSRF)在 Nginx 層的防護方案

csrf攻擊防范的核心在于驗證請求來源合法性。解決方案包括:1.referer頭檢查,通過nginx配置限制請求來源,但存在被偽造風險;2.origin頭檢查,相比referer更可靠,但瀏覽器兼容性需注意;3.雙重提交Cookie,前端生成Token并同時置于cookie和請求參數中,nginx初步驗證,安全性更高但實現復雜;4.自定義請求頭驗證,適用于api接口,避免跨域問題。選擇方案時應權衡安全性和實現成本,結合多種方法提升防護效果。此外,nginx層防護不能替代后端驗證,仍需后端進一步確認token有效性。其他手段如同步令牌模式、samesite cookie及用戶行為驗證也應納入整體防御策略。

跨站請求偽造(CSRF)在 Nginx 層的防護方案

CSRF攻擊防范的核心在于驗證請求的來源是否合法。在Nginx層進行防護,可以有效攔截惡意請求,減輕后端服務器的壓力。

解決方案:

  1. Referer Header 檢查: Nginx可以配置檢查Referer請求頭。如果Referer頭不存在或不在白名單內,則拒絕請求。 這種方法簡單直接,但Referer頭可以被篡改,因此并非萬無一失。

    server {     listen 80;     server_name example.com;      location / {         if ($http_referer !~ "^https?://(www.)?example.com") {             return 403;         }         proxy_pass http://backend;     } }
  2. Origin Header 檢查: Origin頭比Referer頭更可靠,因為它不能被瀏覽器在跨域請求中修改。 Nginx可以配置檢查Origin頭,并只允許來自特定域的請求。 但要注意,Origin頭并非所有瀏覽器都支持。

    server {     listen 80;     server_name example.com;      location / {         if ($http_origin !~ "^https?://(www.)?example.com") {             return 403;         }         proxy_pass http://backend;     } }
  3. 雙重提交 Cookie (double Submit Cookie): 這種方法需要在前端生成一個隨機的token,將其同時存儲在cookie中和一個請求參數中。 Nginx可以配置驗證這兩個token是否一致。 雖然增加了復雜度,但安全性更高。

    • 前端生成token并設置cookie: (假設使用JavaScript)

      function setCookie(name,value,days) {     var expires = "";     if (days) {         var date = new Date();         date.setTime(date.getTime() + (days*24*60*60*1000));         expires = "; expires=" + date.toUTCString();     }     document.cookie = name + "=" + (value || "")  + expires + "; path=/"; }  function generateToken() {     // 簡單示例,實際應用中應使用更安全的隨機數生成方法     return Math.random().toString(36).substring(2); }  const csrfToken = generateToken(); setCookie('csrf_token', csrfToken, 7); // 設置cookie有效期為7天  // 將csrfToken添加到表單或AJAX請求參數中 // 例如: <input type="hidden" name="csrf_token" value="${csrfToken}">
    • Nginx配置: (這里假設后端服務會驗證這個token,Nginx只做初步的檢查)

      server {     listen 80;     server_name example.com;      location / {         # 檢查是否存在cookie和請求參數中的csrf_token         if ($http_cookie !~* "csrf_token=([^;]+)") {             return 403;         }         if ($request_method = POST) {           if ($arg_csrf_token = "") {             return 403;           }           # 這里無法直接比較cookie和參數的值,只能簡單判斷存在性           # 實際的token驗證需要在后端進行         }          proxy_pass http://backend;     } }
  4. 自定義請求頭驗證: 類似于雙重提交Cookie,但將Token放在自定義的請求頭中。 這種方式避免了Cookie的跨域問題,更適用于API接口。

    • 前端設置自定義請求頭:

        //  假設已經通過某種方式獲取了CSRF token (例如從cookie中讀取)   const csrfToken = getCookie('csrf_token'); // 需要自己實現getCookie函數    fetch('/api/resource', {       method: 'POST',       headers: {           'Content-Type': 'application/json',           'X-CSRF-Token': csrfToken // 自定義請求頭       },       body: JSON.stringify({ data: 'your data' })   })   .then(response => response.json())   .then(data => console.log(data));
    • Nginx配置:

        server {       listen 80;       server_name example.com;        location /api/ {           if ($http_x_csrf_token = "") {               return 403;           }           proxy_pass http://backend;       }   }

如何選擇合適的CSRF防護方案?

選擇哪種方案取決于你的應用場景和安全需求。 Referer和Origin檢查簡單易用,但安全性較低。 雙重提交Cookie和自定義請求頭驗證安全性更高,但實現起來更復雜。 可以根據實際情況選擇組合使用多種方案。 關鍵在于理解每種方案的優缺點,并根據自身情況進行權衡。

Nginx層防護CSRF的局限性是什么?

Nginx層主要負責請求的初步過濾,它無法完全替代后端服務器的CSRF防護。 例如,Nginx無法驗證雙重提交Cookie中的token是否與用戶的Session關聯。 因此,即使在Nginx層進行了防護,后端服務器仍然需要進行更嚴格的驗證。 Nginx主要起一個前置過濾的作用,減輕后端壓力,提高整體安全性。

除了Nginx,還有哪些CSRF防護手段?

除了Nginx層防護,還有以下CSRF防護手段:

  • 同步令牌模式 (Synchronizer Token Pattern, STP): 這是最常見的CSRF防護方法。 服務器為每個用戶的會話生成一個唯一的CSRF令牌,并將該令牌嵌入到html表單中。 當用戶提交表單時,服務器會驗證表單中的CSRF令牌是否與會話中存儲的令牌匹配。
  • SameSite Cookie: SameSite屬性可以控制Cookie是否隨跨站請求發送。 設置SameSite=Strict可以完全阻止Cookie在跨站請求中發送,從而有效防止CSRF攻擊。 但要注意,SameSite=Strict可能會影響某些正常的跨站請求,需要謹慎使用。 SameSite=Lax 則允許部分跨站請求(例如GET請求)攜帶Cookie。
  • 用戶行為驗證: 例如,要求用戶在執行敏感操作前輸入密碼或進行驗證碼驗證。

這些方法通常需要在后端代碼中實現。 結合Nginx層的防護,可以構建更強大的CSRF防御體系。

? 版權聲明
THE END
喜歡就支持一下吧
點贊9 分享