动态

详情 返回 返回

[nginx] 一個CORS的漏洞修復 - 动态 详情

前端項目被掃描出了一個CORS漏洞,記錄一下漏洞的復現和修復。

首先要明確,這個問題出在哪裏。

我負責的系統是一個前後端分離的應用,前端部署使用Nginx做反向代理。對於前端應用來説client是瀏覽器,瀏覽器發起的請求都是通過nginx配置轉發到不同後端的服務器。

舉個例子,某個用户用瀏覽器瀏覽頁面,發起了4個請求:
front.domain/api/auth/login -> auth服務
front.domain/api/auth/user -> auth服務
front.domain/api/fund/detail -> fund服務
front.domain/api/gold/overview -> gold服務

上面4個請求,對應了3個後端服務。

這次被掃描出來的漏洞報告中,僅有front.domain/api/fund/detail 這個URL。
但是我們心裏要明白,問題出在fund這個服務。
(即所有的front.domain/api/fund/xxx 都存在CORS的風險)

1.漏洞復現
用postman或者其他類似的開發工具向被檢查出的接口所在服務發送請求。
我們還用front.domain/api/fund/detail 這個接口説明
(當然也可以用front.domain/api/fund/overview, front.domain/api/fund/xxx, ...
只要這些接口地址存在)

1.1使用postman不修改參數,向front.domain/api/fund/detail接口發送請求
查看返回值,在postman中把response header, response body分別截圖(截圖1)。

1.2 繼續使用postman,在request header中增加一個參數 "Origin", Origin的值隨意寫,我們就用 www.test.com來舉例。 再次front.domain/api/fund/detail接口向發送請求,查看response header,response body再截個圖(截圖2)。

1.3 對比兩次的截圖,發現在漏洞存在的情況下截圖2中的response body與截圖1中的response body 返回值相同(即請求正常返回了)。

而對比兩張截圖,截圖2中的header中會多了2個字段:
"Access-Control-Allow-Origin" 和 "Access-Control-Expose-Headers"

key value
Access-Control-Allow-Origin *
Access-Control-Expose-Headers Authorization

在加上了Origin的情況下,請求能夠正常響應並返回結果,就已經證明存在了CORS漏洞。

2.漏洞修復
現在要明確,去哪裏修復這個漏洞。
答案是要修改Nginx配置,因為用户不直接於後端服務器通信,用户的請求是通過nginx轉發到後端的。

2.1修改nginx配置
找到nginx.conf 或者 yaml文件

定位到location /api/auth

location /api/auth {
proxy_pass http://backend.domain.com
}

修改為

location /api/auth {
set $allow_cors 0;
if ($http_origin) {
set $allow_cors 1;
}
if ($http_origin !~* "(www.white-list1.com|www.white-list2.com)" ) {
set $allow_cors "${allow_cors}1";
}
if ($allow_cors = "11") {
return 403;
}

add_header 'Access-Control-Allow-Origin' 'http://www.white-list.com' always;
add_header 'Access-Control-Allow-Credentials' 'false'  always;

proxy_pass http://backend.domain.com
}

其中 www.white-list.com, www.white-list1.com, www.white-list2.com 是可選的。(自定義CORS白名單網站)

對變更的配置寫一點解釋:

set $allow_cors 0; - 這裏定義了一個變量$allow_cors,初始值為0。

if ($http_origin) - 這個條件語句檢查請求頭中是否包含Origin字段,如果存在,則將$allow_cors設置為1。

if ($http_origin !~* "(www.white-list1.com|www.white-list2.com)" ) - 這個條件語句檢查Origin字段的值是否在白名單內,如果不在白名單內,則將$allow_cors的值加1。

if ($allow_cors = "11") - 這個條件語句檢查是否同時滿足了前兩個條件,如果不為空且不在白名單內,則返回403錯誤。

add_header 'Access-Control-Allow-Origin' 'http://10.14.32.138:80' always; - 如果請求通過了所有的條件檢查,這裏設置了Access-Control-Allow-Origin響應頭,允許特定來源http://www.white-list.com訪問資源。

add_header 'Access-Control-Allow-Credentials' 'false' always; - 設置了Access-Control-Allow-Credentials響應頭,表示不允許發送認證信息。

結束。

同步更新到自己的語雀
https://www.yuque.com/dirackeeko/blog/wx529mmxq8xyi8ur

user avatar dingtongya 头像 littlelyon 头像 zzd41 头像 congjunhua 头像 user_ze46ouik 头像 abcdxj555 头像 cynthia_59675eba1a2ee 头像 dengzhanyong 头像 alienzhou 头像 awbeci 头像 onlythinking 头像 gaoxingdeqincai 头像
点赞 33 用户, 点赞了这篇动态!
点赞

Add a new 评论

Some HTML is okay.