防敏感信息泄漏是Web應用防火牆針對網安法明確提出,企業運營者應當採取技術措施和其他必要措施,確保個人信息安全,防止信息泄露、毀損、丟失。

在發生或者可能發生個人信息泄露、毀損、丟失的情況時,應當立即採取補救措施,按照規定及時告知用戶並向有關主管部門報告”所給出的安全防護方案。

防敏感信息泄漏功能針對網站中存在的敏感信息(尤其是手機號、***、***等信息)泄漏、敏感詞彙泄露提供脫敏和告警措施,並支持攔截指定的HTTP狀態碼。

事實上做好水平權限控制也是防敏感信息泄漏重要的一環,數據的訪問權限,數據脫敏等。防敏感信息泄漏屬於DLP數據防泄漏範疇,本文只討論雲waf如何防敏感信息泄漏,DLP範圍比較廣,後面單獨介紹。

網站中常見的造成信息泄漏的場景包括:

URL未授權訪問(例如,網站管理後臺未授權訪問)。

越權查看漏洞(例如,水平越權查看漏洞和垂直越權查看漏洞)。

網頁中的敏感信息被惡意爬蟲爬取。

針對網站中常見的敏感信息泄露場景,防敏感信息泄漏提供以下功能:

針對網站頁面中出現的個人隱私敏感數據進行檢測識別,並提供預警和屏蔽敏感信息等防護措施,避免網站經營數據泄露。這些敏感隱私數據包括但不限於***號、手機號、***號等。

針對有可能暴露網站所使用的Web應用軟件、操作系統類型,版本信息等服務器敏感信息,支持一鍵攔截,避免服務器敏感信息泄露。

根據內置的非法敏感關鍵詞庫,針對在網站頁面中出現的相關非法敏感詞,提供告警和非法關鍵詞屏蔽等防護措施。

工作原理

防敏感信息泄露通過檢測響應頁面中是否帶有***號、手機號、***號等敏感信息,發現敏感信息匹配命中後,根據所設置的匹配動作進行告警或者過濾敏感信息。其中,敏感信息過濾動作以*號替換敏感信息部分,從而達到保護敏感信息的效果。

防敏感信息泄露功能支持的Content-Type包括text/*、image/*、application/*等,涵蓋Web端、app端和API接口。

針對特定URL頁面中的敏感信息過濾:針對特定URL頁面中存在的電話號碼和***等敏感信息,配置相應的規則對其進行過濾或告警。例如,您可以通過設置以下防護規則,過濾admin.php頁面中的***號敏感信息。 

我們當前nginx是作爲反向代理來使用,在配置proxy_hide_header前,通過瀏覽器我們可以看到主機響應頭中包含php版本信息(X-Powered-By: PHP/5.4.43),我們的目的就是將這個顯示內容從響應頭中去掉。

請求頭:

Host: mytest.com
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:43.0) Gecko/20100
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Cookie: ccmm_cookie=V1,110015&xxxx&bbb&ccc; appuser=513aaa; MM_DD=1; psessionid=99999; psessiontime=1454552430
Connection: keep-alive
Cache-Control: max-age=0

響應頭:

Connection: keep-alive
Content-Encoding: gzip
Content-Type: text/html; charset=UTF-8
Date: Thu, 04 Feb 2016 02:20:36 GMT
Transfer-Encoding: chunked
Vary: Accept-Encoding
X-Powered-By: PHP/5.4.43

根據官網說明,proxy_hide_header 可在http, server, location區段使用。

語法: proxy_hide_header field;

默認值: —

上下文: http, server, location

nginx默認不會將“Date”、“Server”、“X-Pad”,和“X-Accel-…”響應頭髮送給客戶端。proxy_hide_header指令則可以設置額外的響應頭,這些響應頭也不會發送給客戶端。相反的,如果希望允許傳遞某些響應頭給客戶端,可以使用proxy_pass_header指令。

一般nginx反向代理會配置很多站點,每個站點配置費時費力而且少有遺漏,主機信息還是會被泄露的。根據上面的說明,我們將proxy_hide_header 配置在http區段,如下所示:

http {
        server_tokens off;
        server_tag off;
        autoindex off;
        access_log off;
        include mime.types;
        default_type application/octet-stream;
        proxy_hide_header X-Powered-By;
        server_names_hash_bucket_size 128;
        client_header_buffer_size 32k;
        large_client_header_buffers 4 32k;
        client_max_body_size 1000m;
        client_body_buffer_size 256k;

檢查nginx配置文件語法:

/usr/local/nginx/sbin/nginx -t 或/etc/init.d/nginx check

重啓nginx服務:

/etc/init.d/nginx restart

配置後的主機響應頭信息:

Connection: keep-alive
Content-Encoding: gzip
Content-Type: text/html; charset=UTF-8
Date: Thu, 04 Feb 2016 02:50:16 GMT
Transfer-Encoding: chunked
Vary: Accept-Encoding
 Vary: Accept-Encoding
Content-Encoding: gzip
Content-Type: text/html
Client-Date: Thu, 27 Jun 2019 13:37:33 GMT
Client-Peer: 10.96.3.72:8080
Client-Response-Num: 1
Client-Transfer-Encoding: chunked

使源站返回不壓縮response:

在請求時加一個過濾,去掉Accept-Encoding: gzip, deflate請求頭,這樣源站返回的始終是不壓縮的response內容。

waf過濾敏感信息

Nginx實現資源壓縮的原理是通過ngx_http_gzip_module模塊攔截請求,並對需要做gzip的類型做gzip,ngx_http_gzip_module是Nginx默認集成的, 不需要重新編譯,直接開啓即可 。

nginx gzip 默認http1.1生效,因爲nginx到upsteam回源的請求是http1.0協議,所以gzip version要配置成http1.0

這樣在nginx回源的時候,如果rs返回的響應body是壓縮的,那麼在nginx需要對這個壓縮過的body解壓,然後過濾body內容,過濾後的內容重新賦給ngx.arg[1]

實現過濾效果。

踩過的坑:

1. 配置gzip version 爲http1.1,rs返回的body始終爲原body(未壓縮),body_filter階段得到的始終是原文。
2. rs返回的原body過濾後,在壓縮返回client壓縮格式的內容,client瀏覽器顯示的始終未壓縮body。
3. collections 判斷content-lengt type處直接返回。需要修改。

正常思路:

nginx 從upstrean獲取到壓縮過or未壓縮的body(未壓縮暫時沒完整測試),判斷rs返回的body如果是壓縮過的,那麼進行解壓。

解壓後得到原文過濾,然後把過濾後的原文壓縮返回給client。即:得到壓縮->解壓->過濾->壓縮->返回。

如果從upstream得到的rsp body爲原文,然後過濾→壓縮→返回,瀏覽器顯示的始終是壓縮格式。爲什麼這樣?總之不可以這樣操作。

優化:

在body filter階段,從rs得到壓縮的body,解壓賦給ngx.arg[1],然後解壓後的原文過濾crs規則,命中規則後,在body_filter文件又得到rs body,然後解壓或不解壓

然後把命中規則的字段替換掉,敏感信息、手機號等。

rs返回的rsp body爲未壓縮格式,過濾body然後返回壓縮格式的body,待測試。

mime類型判斷,動靜態文件 壓縮解壓效果。

未超過gzip min length條件下效果。

語法: gzip_min_length length

默認值: gzip_min_length 0

作用域: http, server, location

設置允許壓縮的頁面最小字節數,頁面字節數從header頭中的Content-Length中進行獲取。

默認值是0,不管頁面多大都壓縮。

建議設置成大於1k的字節數,小於1k可能會越壓越大。 即: gzip_min_length 1024

gzip_min_length

當返回內容大於此值時纔會使用gzip進行壓縮,以K爲單位,當值爲0時,所有頁面都進行壓縮。

響應時間,主要看壓縮解壓縮是否佔用過多請求時間

壓縮效果,原來的5k壓縮到1.2k

從這我們可以得出結論:

隨着壓縮級別的升高,壓縮比有所提高,但到了級別6後,很難再提高;

隨着壓縮級別的升高,處理時間明顯變慢;

gzip很消耗cpu的性能,高併發情況下cpu達到100%;

因此,建議:

不是壓縮級別越高越好,其實gzip_comp_level 1的壓縮能力已經夠用了,後面級別越高,壓縮的比例其實增長不大,反而很喫處理性能。

壓縮一定要和靜態資源緩存相結合,緩存壓縮後的版本,否則每次都壓縮高負載下服務器肯定喫不住。

gzip_disable

通過表達式,表明哪些UA頭不使用gzip壓縮

gzip_proxied

Nginx做爲反向代理的時候啓用:

off – 關閉所有的代理結果數據壓縮
expired – 如果header中包含”Expires”頭信息,啓用壓縮
no-cache – 如果header中包含”Cache-Control:no-cache”頭信息,啓用壓縮
no-store – 如果header中包含”Cache-Control:no-store”頭信息,啓用壓縮
private – 如果header中包含”Cache-Control:private”頭信息,啓用壓縮
no_last_modified – 啓用壓縮,如果header中包含”Last_Modified”頭信息,啓用壓縮
no_etag – 啓用壓縮,如果header中包含“ETag”頭信息,啓用壓縮
auth – 啓用壓縮,如果header中包含“Authorization”頭信息,啓用壓縮
any – 無條件壓縮所有結果數據

如果源站配置成http1.1 才返回壓縮的body,那麼waf受到的響應爲未壓縮的格式。

如果此時的http請求爲Accept-Encoding:gzip, deflate,那麼waf在向client回應body時,會有Content-Encoding: gzip響應head。

waf處理邏輯得到響應head Content-Encoding: gzip,然後把rs返回的body壓縮返回給client。

增加處理邏輯,在判斷rs返回body爲未壓縮格式,http請求有請求爲Accept-Encoding:gzip, deflate,即使有Content-Encoding: gzip響應head,也不壓縮body。

進一步:如果rs返回未壓縮,waf也壓縮body,client瀏覽器顯示壓縮過的亂碼。

*本文作者:stan1y,轉載請註明來自FreeBuf.COM

相關文章