「HTTP_PROXY」環境変数に不適切な値が与えられる脆弱性、多くの環境で影響 18
なるほど 部門より
JPCERT/CCが、CGI等を利用するWebサーバの脆弱性(CVE-2016-5385等)に関する注意喚起を行っている。
UNIX/Linux系環境で動作するHTTPクライアントの多くは、通信を行う際に「HTTP_PROXY」環境変数を参照し、もしこの環境変数が設定されていればここで指定されているホストをプロクシとして使用するという動作を行う。このHTTP_PROXY環境は本来はサーバーやアプリケーションを実行する側が設定するものであるが、HTTPリクエストヘッダを利用してこれを外部から任意の値に書き換えることができるという(INTERNET Watch、ITmedia、JPCERT/CC)。
kb.cert.orgの説明が分かりやすいが、CGIの動作について記述したRFC3875の4.1.18.では、HTTPヘッダの形でサーバーに渡されたメタ変数について、その変数名を大文字にし、「-」を「_」に置換し、先頭に「HTTP_」を付ける、というルールが明記されている。もしサーバーに対して送信されるリクエストヘッダ内に「proxy:」というヘッダが存在した場合、このルールに従うと「HTTP_PROXY」という変数名に送信されたヘッダの内容が格納されることになる。CGIの多くではこのような変数を環境変数に格納するため、結果としてHTTP_PROXY環境変数が外部から送信された値に書き換えられてしまうことになる。
また、同様にして「HTTP_」で始まるHTTP_PROXY以外の環境変数についても外部から書き換えることが可能になり、これを悪用することで攻撃者は中間者攻撃やサーバーに対し意図しない挙動を実行させることが可能になる可能性がある。
現時点ではApache HTTP ServerやPHP、GO、Pythonなど多くのソフトウェアが影響を受けるとのこと。対策としてはリクエストヘッダ内の「proxy:」ヘッダを無視するよう設定する、HTTP_PROXYや「HTTP_」で始まる環境変数を使用しない、などが挙げられている。
httpoxy 脆弱性への対策 (スコア:5, 参考になる)
HTTPリクエストヘッダーとして送られてきた Proxy が環境変数 HTTP_PROXY にセットされるのが問題なだけなので、リクエストヘッダーの Proxy を落とすだけで対策可能です。
PHPに関するHTTPOXY脆弱性の問題と対応方法 [ichikaway.com] によると、Apache (mod_header が使用可能な場合) なら、
とするだけで対策可能です。RequestHeader ディレクティブ [apache.org] は大文字と小文字は区別しないので、proxy とか proXY が送られてきても大丈夫です。
そのほか、HTTP ではなく HTTPS を使うのも対策になります(不正なプロキシを経由して通信内容が書き換わると証明書のエラーとなるため)。cgi がインターネットを経由して HTTP 通信(平文)で情報を取得するのは改ざんの危険があるので、cgi から接続する先のサーバを自分で管理している場合には Let's Encrypt [letsencrypt.jp] や その他の無料SSL/TLS証明書 [jstream.jp] でも構わないので HTTPS にすると良いでしょう(ユーザーから見える証明書ではないので、高価な OV や EV を使うメリットはありません)。
なお、CentOS や RHEL では既にパッチが出ているので、yum で更新して httpd (Apache) を再起動することでも対策可能です。
CentOS 6.8 なら httpd x86_64 2.2.15-54.el6.centos です。
Re:httpoxy 脆弱性への対策 (スコア:1)
> そのほか、HTTP ではなく HTTPS を使うのも対策になります(不正なプロキシを経由して通信内容が書き換わると証明書のエラーとなるため)
これ、CGI実行プロセスからさらに外部アクセスするときのproxy設定が乗っ取られるわけだから、サーバ自身のHTTPS設定とは関係ないですよね。
確かに、さらに外部アクセスする先のサーバ(攻撃を受けたのとは別のサーバ)がHTTPS化され、証明書の検証を省いていなければエラーになりますが、そちらは外部サーバなわけだから自分ではコントロールできないし、オレオレ証明書で証明書検証を外していたり(内部ネットワーク内でアクセスしている場合)することもままあるわけで、
「HTTP ではなく HTTPS を使うのも対策になります」
と言い方は混乱を招くのでは?
「(攻撃を受ける)サーバでHTTPSを使うのは対策にはならない」のでは?
Re:httpoxy 脆弱性への対策 (スコア:3)
その通りです。
外部サーバを自分で管理していない場合であっても、外部サーバに HTTPS で接続すれば(証明書の検証を行う設定ならば)、不正なプロキシによるデータ改ざんは防げます(正確には改ざんを検知してエラーを発生させることができます。エラーが発生することにより正常なサービスが提供できなくなる問題は残ります)。そのため、今まで cgi から外部APIに HTTP で接続するようにしていた場合、HTTPS 接続に変更するといった対策は有効です。
勿論、接続先のAPI等が HTTP (平文) 接続にしか対応しておらず、HTTPSでの接続を受け付けない場合にはどうしようもないですが、一般公開されているAPIの場合、TLS非対応のAPIは少なくなってきています。
API 等を HTTPS に対応させることは、自分が管理しているサーバじゃないとできないので、「cgi から接続する先のサーバを自分で管理している場合には Let's Encrypt [letsencrypt.jp] や その他の無料SSL/TLS証明書 [jstream.jp] でも構わないので HTTPS にすると良いでしょう」と「自分で管理している場合」に限定する文言を入れました。
「HTTPリクエストヘッダーとして送られてきた Proxy が環境変数 HTTP_PROXY にセットされることを防ぐ」、あるいは「環境変数 HTTP_PROXY を無視する」ことが httpoxy 問題への根本的な対策ではあるのですが、インターネット経由で外部APIと通信する CGI (php を含むWebアプリケーション) が多くなっており、CGIがインターネット経由で外部APIから HTTP (平文) で情報を取得すること自体に別の危険性(通信の傍受・改ざんなど)があるので、あえて HTTPS で通信を行うという対策に触れました。
ただ、おっしゃる通り、混乱を招く書き方でした。ユーザがアクセスするフロントエンドWebサーバ自体に HTTPS を導入しても対策にはならないので、「CGI等が外部サーバのAPIから情報を取得する際に HTTPS (TLS) を使用するのも、APIから取得するデータの傍受・改ざんの対策にはなります。ただし、ウェブサーバが悪意のある第三者が Proxy ヘッダで指定したプロキシに接続させられること自体を防ぐことはできません(接続後に証明書のエラーが発生)」と書くべきでした。ご指摘ありがとうございました。
相関図が無いと判りにくい (スコア:0)
Nginxの説明が判りやすかったかな
https://www.nginx.com/blog/mitigating-the-httpoxy-vulnerability-with-nginx/ [nginx.com]
うん、普通に酷い仕様バグだね
今さら感がすごい (スコア:0)
これが対策されてなかったのか。
Re: (スコア:0)
内容見る限り、これ下手すると20年以上前からの潜在バグ/仕様バグだよねぇ…。
今時のシステムは影響受けないだろうけど、これ被害甚大なんじゃあ(汗
Re:今さら感がすごい (スコア:3, 参考になる)
これだけだとアレですが
これよりかなり昔にPerlで問題になってPerlでは修正されましたが
その他の言語では修正されてませんでした・・・
Re:今さら感がすごい (スコア:1)
ニュースで見た時にperlでどうだったかなーと思ってhttpoxy.orgを読みました。
そしたらPHPが「There is a common vulnerability in many PHP libraries and applications」という感じで槍玉に挙げられていてかわいそうだと思いました。
httpoxy.orgの中の人にとってPHPは親の敵かなにかなのでしょうか。
Re:いやむしろ (スコア:0)
そう言う仕様だとおもってました。
ちなみにこれを利用してEICARを仕込むと、
システムではなくて中の人が原因調査時に
パニクルヨ
Re: (スコア:0)
なんか、ふたばちゃんねるの連投規制・書込み規制回避を目論むこのツール [github.com]が利用してるのがその脆弱性なのかしら?
Flashだかの廃止された引数にでたらめな値をぶち込むとかなんとか
Goは早速セキュリティーパッチ当てて1.6.3で対応したっぽい (スコア:0)
ねこ大好き
Re: (スコア:0)
goの修正は「CGIでは単純にHTTP_PROXYを無視する」というもので、
外部からの不正なProxy:ヘッダに由来するものだけではなく、
正当な目的で設定された環境変数まで無視されて、
外部へのアクセスにプロクシ経由がMUSTな環境で動くCGIで不具合が発生する。
# ちなみに、python、phpの修正も同様の模様。
この問題が最初に発見されて対策されたperlのLWPの修正は
これについての代替策まで含んだ完璧なものだったのに、
なぜ後発は学ぼうとしないのか。
それでもhttpsなら・・・ (スコア:0)
大丈夫?
証明書の検証まではしてないだろうから無理かな。
Re: (スコア:0)
proxyでssl通信の中身を見るにはssl通信の復号化が必要で、その際には証明書のドメイン不一致による警告が
表示されるから、httpsなら中間者攻撃対策に気付くことができるはず。
Re: (スコア:0)
×復号化
Re:それでもhttpsなら・・・ (スコア:2)
鍵を使って復号器を作るのだから、復号器化が正しい...のかもしらない。
Re: (スコア:0)
今回の件はユーザーとサーバーの間に割り込むわけではなく、クライアントからリクエストを受けたサーバー側が更にどこかにHTTPリクエストを投げるケースで、「更にどこかにHTTPリクエストを投げる」の部分に中間者攻撃が成立しうるというものであって、
これが「更にどこかにHTTPSリクエストを投げる」であればターゲットになる環境変数は「HTTPS_PROXY」とかになるんだろうけど、今回のキモはリクエストヘッダの頭に「HTTP_」を付け加えるってところなので成立しない
#よね?
Re: (スコア:0)
https_proxyが無いときはhttp_proxyを読むようになってたりするかも