Linux中國

PHP 、Python 等網站應用驚爆遠程代理漏洞:httpoxy

這是一個針對 PHP、Go、Python 等語言的 CGI 應用的漏洞。

httpoxy 是一系列影響到以 CGI 或類 CGI 方式運行的應用的漏洞名稱。簡單的來說,它就是一個名字空間的衝突問題。

  • RFC 3875 (CGI)中定義了從 HTTP 請求的 Proxy 頭部直接填充到環境變數 HTTP_PROXY 的方式
  • HTTP_PROXY 是一個常用於配置外發代理的環境變數

這個缺陷會導致遠程攻擊。如果你正在運行著 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[&apos;HTTP_PROXY&apos;]) 並不會影響到 getenv() 返回的值,所以無用
  • 使用 putenv(&apos;HTTP_PROXY=&apos;) 也沒效果(putenv 只能影響到來自實際環境變數的值,而不是來自請求頭部的)

httpoxy 的歷史

該漏洞首次發現與15年前。

2001 年 3 月
Randal L. Schwartz 在 libwww-perl 發現該缺陷並修復。

2001 年 4 月
Cris Bailiff 在 curl 中發現該缺陷並修復。

2012 年 7 月
Net::HTTPHTTP_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

對這篇文章感覺如何?

太棒了
0
不錯
0
愛死了
0
不太好
0
感覺很糟
0
雨落清風。心向陽

    You may also like

    Leave a reply

    您的電子郵箱地址不會被公開。 必填項已用 * 標註

    此站點使用Akismet來減少垃圾評論。了解我們如何處理您的評論數據

    More in:Linux中國