PHP 、Python 等網站應用驚爆遠程代理漏洞:httpoxy
這是一個針對 PHP、Go、Python 等語言的 CGI 應用的漏洞。
httpoxy 是一系列影響到以 CGI 或類 CGI 方式運行的應用的漏洞名稱。簡單的來說,它就是一個名字空間的衝突問題。
這個缺陷會導致遠程攻擊。如果你正在運行著 PHP 或 CGI 程序,你應該馬上封擋 Proxy 頭部!馬上! 具體做法參見下面。httpoxy 是一個伺服器端 web 應用漏洞,如果你沒有在伺服器端部署這些代碼,則不用擔心。
如果我的 Web 應用存在這種漏洞會怎麼樣?
當一個利用了此漏洞的 HTTP 客戶端發起請求時,它可以做到:
- 通過你的 Web 應用去代理請求別的 URL
- 直接讓你的伺服器打開指定的遠程地址及埠
- 浪費伺服器的資源,替攻擊者訪問指定的資源
httpoxy 漏洞非常容易利用。希望安全人員儘快掃描該漏洞並快速修復。
哪些受到影響?
以下情況會存在安全漏洞:
- 代碼運行在 CGI 上下文中,這樣
HTTP_PROXY
就會變成一個真實的或模擬的環境變數 - 一個信任
HTTP_PROXY
的 HTTP 客戶端,並且支持代理功能 - 該客戶端會在請求內部發起一個 HTTP(或 HTTPS)請求
下列情形是已經發現存在該缺陷的環境:
語言 | 環境 | HTTP 客戶端 |
---|---|---|
PHP | php-fpm mod_php | Guzzle 4+ Artax |
Python | wsgiref.handlers.CGIHandler twisted.web.twcgi.CGIScript | requests |
Go | net/http/cgi | net/http |
肯定還有很多我們沒有確定是否存在缺陷的語言和環境。
PHP
- 是否存在缺陷依賴於你的應用代碼和 PHP 庫,但是影響面看起來似乎非常廣泛
- 只要在處理用戶請求的過程中使用了一個帶有該缺陷的庫,就可能被利用
- 如果你使用了有該缺陷的庫,該缺陷會影響任意 PHP 版本
- 甚至會影響到替代的 PHP 運行環境,比如部署在 FastCGI 模式下的 HHVM
- 確認影響 Guzzle、Artax 等庫,可能還有很多很多的庫也受影響
- Guzzle 4.0.0rc2 及其以後版本受影響,Guzzle 3 及更低版本不受影響
- 其它的例子還有 Composer 的 StreamContextBuilder 工具類
舉個例子說,如果你在 Drupal 中使用 Guzzle 6 模塊發起外發請求(比如請求一個天氣 API),該模塊發起的請求就存在這個 httpoxy 缺陷。
Python
- Python 代碼只有部署在 CGI 模式下才存在缺陷,一般來說,存在缺陷的代碼會使用類似
wsgiref.handlers.CGIHandler
的 CGI 控制器- 正常方式部署的 Python web 應用不受影響(大多數人使用 WSGI 或 FastCGI,這兩個不受影響),所以受到影響的 Python 應用要比 PHP 少得多
- wsgi 不受影響,因為 os.environ 不會受到 CGI 數據污染
- 存在缺陷的 requests 庫必須信任和使用
os.environ['HTTP_PROXY']
,並且不做內容檢查
Go
- Go 代碼必須部署在 CGI 下才受影響。一般來說受到影響的代碼會使用
net/http/cgi
包- 像 Python 一樣,這並不是部署 Go 為一個 Web 應用的通常方式。所以受到影響的情形很少
- 相較而言,Go 的
net/http/fcgi
包並不設置實際的環境變數,所以不受影響
- 存在缺陷的
net/http
版本需要在外發請求中信任並使用HTTP_PROXY
,並不做內容檢查
馬上修復
最好的修復方式是在他們攻擊你的應用之前儘早封擋 Proxy
請求頭部。這很簡單,也很安全。
- 說它安全是因為 IETF 沒有定義
Proxy
請求頭部,也沒有列在 IANA 的消息頭部註冊中。這表明對該頭部的使用是非標準的,甚至也不會臨時用到 - 符合標準的 HTTP 客戶端和伺服器絕不應該讀取和發送這個頭部
- 你可以從請求中去掉這個頭部或者乾脆整個封擋使用它的請求
- 你可以在上游沒有發布補丁時自己來解決這個問題
- 當 HTTP 請求進來時就檢查它,這樣可以一次性修復好許多存在缺陷的應用
- 在反向代理和應用防火牆之後的應用剔除
Proxy
請求頭部是安全的
如何封擋 Proxy
請求頭部依賴於你的配置。最容易的辦法是在你的 Web 應用防火牆上封擋該頭部,或者直接在 Apache 和 Nginx 上做也行。以下是一些如何做的指導:
Nginx/FastCGI
使用如下語句封擋傳遞給 PHP-FPM、PHP-PM 的請求頭,這個語句可以放在 fastcgi.conf 或 fastcgi_param 中(視你使用了哪個配置文件):
fastcgi_param HTTP_PROXY "";
在 FastCGI 模式下,PHP 存在缺陷(但是大多數使用 Nginx FastCGI 的其它語言則不受影響)。
Apache
對於 Apache 受影響的具體程度,以及其它的 Apache 軟體項目,比如 Tomcat ,推薦參考 Apache 軟體基金會的官方公告。 以下是一些主要信息:
如果你在 Apache HTTP 伺服器中使用 mod_cgi
來運行 Go 或 Python 寫的腳本,那麼它們會受到影響(這裡 HTTP_PROXY
環境變數是「真實的」)。而 mod_php
由於用於 PHP 腳本,也存在該缺陷。
如果你使用 mod_headers 模塊,你可以通過下述配置在進一步處理請求前就 unset 掉 Proxy
請求頭部:
RequestHeader unset Proxy early
如果你使用 mod_security 模塊,你可以使用一個 SecRule
規則來拒絕帶有 Proxy
請求頭部的請求。下面是一個例子,要確保 SecRuleEngine
打開了。你可以根據自己的情況調整。
SecRule &REQUEST_HEADERS:Proxy "@gt 0" "id:1000005,log,deny,msg:'httpoxy denied'"
最後,如果你使用 Apache Traffic Server 的話,它本身不受影響。不過你可以用它來剔除掉 Proxy 請求頭部,以保護其後面的其它服務。具體可以參考 ASF 指導。
HAProxy
通過下述配置剔除該請求頭部:
http-request del-header Proxy
Varnish
通過下述語句取消該頭部,請將它放到已有的 vcl_recv 小節裡面:
sub vcl_recv {
[...]
unset req.http.proxy;
[...]
}
OpenBSD relayd
使用如下語句移除該頭部。把它放到已有的過濾器裡面:
http protocol httpfilter {
match request header remove "Proxy"
}
lighttpd (<= 1.4.40)
彈回包含 Proxy
頭部的請求。
- 創建一個
/path/to/deny-proxy.lua
文件,讓它對於 lighttpd 只讀,內容如下:
if (lighty.request["Proxy"] == nil) then return 0 else return 403 end
- 修改
lighttpd.conf
以載入mod_magnet
模塊,並運行如上 lua 代碼:
server.modules += ( "mod_magnet" )
magnet.attract-raw-url-to = ( "/path/to/deny-proxy.lua" )
lighttpd2 (開發中)
從請求中剔除 Proxy
頭部。加入如下語句到 lighttpd.conf
中:
req_header.remove "Proxy";
用戶端的 PHP 修復沒有作用
用戶端的修復不能解決該缺陷,所以不必費勁:
- 使用
unset($_SERVER['HTTP_PROXY'])
並不會影響到getenv()
返回的值,所以無用 - 使用
putenv('HTTP_PROXY=')
也沒效果(putenv 只能影響到來自實際環境變數的值,而不是來自請求頭部的)
httpoxy 的歷史
該漏洞首次發現與15年前。
2001 年 3 月
Randal L. Schwartz 在 libwww-perl 發現該缺陷並修復。
2001 年 4 月
Cris Bailiff 在 curl 中發現該缺陷並修復。
2012 年 7 月
在Net::HTTP
的 HTTP_PROXY
實現中, Ruby 團隊的 Akira Tanaka 發現了該缺陷
2013 年 11 月
在 nginx 郵件列表中提到了該缺陷。發現者 Jonathan Matthews 對此不太有把握,不過事實證明他是對的。
2015 年 2 月
Stefan Fritsch 在 Apache httpd-dev 郵件列表中提到了它。
2016 年 7 月
Vend 安全團隊的 Scott Geary 發現了對該缺陷,並且它影響到了 PHP 等許多現代的編程語言和庫。
所以,這個缺陷已經潛伏了許多年,許多人都在不同方面發現了它的存在,但是沒有考慮到它對其它語言和庫的影響。安全研究人員為此專門建立了一個網站: https://httpoxy.org/ ,可以在此發現更多內容。
本文轉載來自 Linux 中國: https://github.com/Linux-CN/archive