2011-09-08
IP アドレスが偽装可能か確認してみよう
PHP フレームワークでのクライアント IP アドレス取得メソッドの実装について で、CakePHP, CodeIgniter, Symfony, Zend Framework でのクライアント IP アドレス取得メソッドについてみてみました。
今回は、実際に自分のサーバで IP アドレスが偽装可能か確認してみましょう。
まず、サーバに検証用のソースを置きます。
CodeIgniter だと、こんなコードになります。
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed'); class Ip_address extends CI_Controller { function __construct() { parent::__construct(); } function index() { echo $this->input->ip_address(); } } /* End of file ip_address.php */ /* Location: ./application/controllers/ip_address.php */
タイムリー?にも、プロキシ経由でもリアルIPを取得するPHPコードスニペット:phpspot開発日誌 という記事がありました。そこで紹介されているコードは以下のようなものでした。
<?php if (!empty($_SERVER["HTTP_CLIENT_IP"])) { //check for ip from share internet $ip = $_SERVER["HTTP_CLIENT_IP"]; } elseif (!empty($_SERVER["HTTP_X_FORWARDED_FOR"])) { // Check for the Proxy User $ip = $_SERVER["HTTP_X_FORWARDED_FOR"]; } else { $ip = $_SERVER["REMOTE_ADDR"]; } // This will print user's real IP Address // does't matter if user using proxy or not. echo $ip;
ここでは、上記のファイルを show_ip.php という名前にして、サーバに転送することにします。
次に、テスト用のコードを書きましょう。
サーバに
- 追加ヘッダなし
- X-FORWARDED-FOR ヘッダ付き
- CLIENT-IP ヘッダ付き
- X-FORWARDED-FOR および CLIENT-IP ヘッダ付き
のリクエストを送るコードです。
test.php:
<?php $uri = 'http://www.example.jp/show_ip.php'; // no additional headers $page = file_get_contents($uri); echo 'No headers: '; echo $page, "\n"; // send X-FORWARDED-FOR $opt = array( 'http'=> array( 'header' => 'X-FORWARDED-FOR: 88.88.88.88', ) ); $context = stream_context_create($opt); $page = file_get_contents($uri, 0, $context); echo 'X-FORWARDED-FOR: '; echo $page, "\n"; // send CLIENT-IP $opt = array( 'http'=> array( 'header' => 'CLIENT-IP: 99.99.99.99', ) ); $context = stream_context_create($opt); $page = file_get_contents($uri, 0, $context); echo 'CLIENT-IP: '; echo $page, "\n"; // send X-FORWARDED-FOR and CLIENT-IP $opt = array( 'http'=> array( 'header' => array('X-FORWARDED-FOR: 88.88.88.88', 'CLIENT-IP: 99.99.99.99', ) ) ); $context = stream_context_create($opt); $page = file_get_contents($uri, 0, $context); echo 'Both: '; echo $page, "\n";
さあ、このコードを手許の PC から実行してみましょう。
例えば、こんな結果になりました。
この環境では、リバースプロキシがあり CLIENT-IP ヘッダは通りませんが、X-FORWARDED-FOR は通るようです。
そもそも、カンマ区切りで IP アドレスが複数ありますね。これをそのまま IP アドレスだとして処理したらまずいことになりますね。
関連
トラックバック - http://d.hatena.ne.jp/Kenji_s/20110908/1315440340
リンク元
- 126 http://phpspot.org/blog/archives/2011/09/ipphp.html
- 34 http://twitter.com/
- 32 http://pipes.yahoo.com/pipes/pipe.info?_id=f8e50936209277c7946c9bc16b988bf7
- 24 http://ow.ly/6oifE
- 10 http://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q1380425743
- 10 http://www.google.co.jp/url?sa=t&rct=j&q=&esrc=s&source=web&cd=2&ved=0CDMQFjAB&url=http://d.hatena.ne.jp/Kenji_s/20110908/1315440340&ei=s6lzT-DCEofHmQWRz935Bw&usg=AFQjCNF9x2bEc9BLwBhL-o5bzkty4XPemw&sig2=jOIKzgwC5LqljCXLWXO3ZQ
- 9 http://www.google.co.jp/url?sa=t&rct=j&q=ipアドレスを偽装&source=web&cd=11&ved=0CC4QFjAAOAo&url=http://d.hatena.ne.jp/Kenji_s/20110908/1315440340&ei=5UCET4-NO_HKmQWJpcSoBw&usg=AFQjCNF9x2bEc9BLwB
- 8 http://longurl.org
- 8 http://www.google.co.jp/url?sa=t&rct=j&q=&esrc=s&source=web&cd=3&ved=0CEQQFjAC&url=http://d.hatena.ne.jp/Kenji_s/20110908/1315440340&ei=qTV8T6-KH6yKmQX1oMX_Cw&usg=AFQjCNF9x2bEc9BLwBhL-o5bzkty4XPemw&sig2=nLBcd_ypO-Km69d01DiuaQ
- 7 http://hootsuite.com/dashboard


