APIキーのリファラ制限だけじゃマズくない?だけど制限できない難しさ。
API利用登録などで発行されるAPIキーは秘匿情報として、
決して公開すべきキーではありません。
APIキー秘匿としただけでAPIの不正利用からAPIの使用量を守る事ができるのでしょうか。
現時点では、外部プログラムから守るベストな方法は浮かんできません。
追記
その後、APIキーの指定が不要でCSEの呼び出しができる
制限なしの利用法と思われる記述を見つけ、試しています。(人柱中)
目次
ん?やっぱりAPIキーのリファラ制限だけじゃマズくない?
カスタム検索エンジンAPIでは「100クエリ/day」までが無料枠になっています。
この無料枠を超えれば、課金が有効ではない場合は、API利用が停止し、
課金が有効ならば、1000クエリあたり5ドルが請求されます。(1日あたり最大10kクエリ)
このAPIキーの不正使用を制限できるのか?という問題です。
APIキーの「認証情報」設定では、以下の選択肢があります。
- なし
- HTTPリファラ―
- IPアドレス(ウェブサーバー、cronジョブなど)
- Androidアプリ
- iOSアプリ
今まで、なんとなく「HTTPリファラ」を選択して利用してきましたが、
ふと、思ったのが当然ながらリファラ偽装は可能ですよね。
PHPによるAPIキーの不正使用とリファラ偽装例
今回、テスト用にPHPのプログラムをサイトに設置して以下のように構成しています。
認証からAPIキーには「http://ipvx.info/*」でHTTPリファラ制限を設定しています。
プログラムは簡単なもので、cURLでPHPからCSEの結果を取得して表示しています。
4行目が、APIキー
6行目が、 リファラの申告値
です。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
<?php $keystr = "株式会社ケイ・オプティコム"; $cx = "014810786654675656813:8jolq19mpc8"; $key = "{APIキー}"; $url = "https://www.googleapis.com/customsearch/v1?key={$key}&cx={$cx}&q={$keystr}"; $ref = 'http://ipvx.info/'; $ua = "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.139 Safari/537.36"; //JSONを要求する $ch = curl_init(); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt ($ch, CURLOPT_URL, $url ); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); //for SSL curl_setopt($ch, CURLOPT_REFERER, $ref); //REFERER curl_setopt($ch, CURLOPT_USERAGENT, $ua); //USERAGENT $json = curl_exec ( $ch ); //$search_result = file_get_contents($url, true); $search_result = json_decode($json); echo "<!DOCTYPE html><html lang='ja'><head><meta charset='utf-8'/></head><body>"; echo "HTTP_REFERER-> ". $_SERVER['HTTP_REFERER'] ."<br/>"; echo "SERVER_NAME-> ". $_SERVER['SERVER_NAME'] ."<br/>"; echo "REMOTE_ADDR-> ". $_SERVER['REMOTE_ADDR'] ."<br/>"; echo "このPHPはcURLでREFERERを「http://ipvx.info/」として実行しています。(正規)";//ここはそれぞれ変わる echo '<pre>'. print_r($search_result, true) . '<pre>'; echo "</body></html>"; |
このプログラムを当サイトのディレクトリ配下に設置してリファラ偽装したものと、
別サイトに設置して、 リファラ偽装したもので動作確認をします。
ドメイン | プログラム | リファラ値 | パターン | 結果 |
---|---|---|---|---|
ipvx.info | cse_demo.php | http://ipvx.info/ | 正規 | 〇 |
cse_demo_disguise.php | https://rensrv.com/ | 偽装 | - | |
rensrv.com | cse_demo.php | https://rensrv.com/ | 正規 | - |
cse_demo_disguise.php | http://ipvx.info/ | 偽装 | 〇 |
見ての通りですがPHPからリファラとして設定した「http://ipvx.info/」と、
HTTPリファラの制限として設定している「http://ipvx.info/」が一致していれば、
別にどこのドメインのサイトから呼び出しができています。
容易に想像できる話です。
要は「HTTPリファラ制限」ではこの程度の制約と言う事になります。
自サイトでプログラムを設置していれば、
当然サイトドメインはHTTPリファラ制限に設定しているだろうと推測できますし、
誰でもAPIキーが分かれば、このAPIを利用することができます。
APIキーは他人には口外しないし、大丈夫じゃない?
普通はAPIキーは秘匿として、他人に公開するものではありません。
一応、隠すべきものとされています。
上記のようなPHPプログラムではPHPが実行して結果を返しますので、
APIキーは基本的に知られることはありません。
PHPが利用する「検索キーが固定」なら何も気にする必要はありません。
しかし、URLクエリパラメータや、GET,POSTなどで「パラメータ」を受け取り、
パラメータによって検索をした結果を返すようなプログラムの場合は、
自サイト上のページからの呼び出しか、
外部の悪意あるプログラムからの呼び出しかを判断する必要があると言う事です。
APIキーが漏れなくても、悪意あるプログラムに正規のレスポンスを返していては、
実質APIが制限なく利用されてしまう事は同じなのです。
その判定が掘れば掘るほどカオスというか、イタチごっこになってしまいます。
以下ではそうしたスクレイピング(プログラムによるコンテンツ巡回・搾取)を、
どのように回避させるかなどを考えておられます。
webスクレイピング対策への対処について – bz0のにっき
普及して欲しくないアンチスクレイピングサービス – happyou.infoのブログ
クローラー/スクレイピング Advent Calendar 2014 – Qiita
https://www.nic.ad.jp/ja/materials/iw/2005/proceedings/T18.pdf
最近はヘッドレスブラウザなども利用されるようになって、
プログラムアクセスか否かの判定は一層難しくなっている様相です。
Gather-Tech.info #59: ヘッドレスChromeの判定方法
こうして見ていると、APIキーが秘匿にできた所で、
実行プログラム(のURL)が分かる以上は、直接アクセスを阻止することは困難です。
よく見る「$_SERVER[‘HTTP_REFERER’]」で判断すればいいというアプローチは、
当然ながら、偽装されていれば意味がありません。
上記の判定でもわかるように、
Google Search Engine API もcURLの偽装であっても許容しているのが分かります。
$_SERVER[‘HTTP_REFERER’]を利用してPHPで判断する方法は、気休めなのです。
IPアドレス制限を使えばいいじゃないか。
GoogleAPIの認証キー(APIキー)の制限には「IPアドレス指定」の項目があります。
これは特定のIPアドレスのみの要求を受け付けるという設定ですので、
サーバーに割当てられているグローバルIPを指定して利用することと思います。
JavaScript経由でAJAXなどでリクエストする場合には、
サーバーに届くIPアドレスは、閲覧者のグローバルIPアドレスです。
IP制限をかけた場合、全グローバルIPアドレスを設定する必要がある事になります。
ですので、PHPプログラムをサイトに設置して、
WebサーバーからのみAPIを利用する仕組みにするわけですが、
前述の通り、PHPプログラムが自サイト上のページからの呼び出しか、
外部の悪意あるプログラムからの呼び出しかを判断出来ない限り、結局は同じなのです。
そう考えていくと、
こうしたAPIサービスでAPIキーの不正使用(タダ乗り)を阻止するいい方法は、
今のところ浮かんではきません。
APIキーを秘匿にしてPHPが不正使用か判定すると言う事も困難で、
JavaScriptでクライアント側の環境から、不正使用を判定したとしても、
そのままでは、APIキーはダダ漏れという事になります。
不正使用を排除しつつ、Googlebotなどの必要なプログラムアクセスは許可する。
実に悩ましい限りなのです。
この結論が出るまでは、
APIの課金設定は怖くて有効化できないというのが現時点の判断です。
本サイトで公開しているツールについては、
十分にテストは行っておりますが個人で作成している為、
潜在的なバグがないとは言い切れません。
その為、ツールを用いた結果については十分検証の上ご利用ください。
当サイトおよび、管理人は如何なる損害もその責を負いません。
当サイト内のコンテンツおよび画像において、
出典・引用の外部著作権者の明記がないものは、
すべて管理人による著作物です。
当サイトでご紹介しておりますコンテンツの著作権の放棄は致しません。
サイト内コンテンツを引用される際にはご連絡は不要です。
ただし、出典元として当サイト(個別記事)へのリンクをお願いいたします。
申し訳ございませんが、無断転載、複製をお断りさせて頂いております。
コンテンツを有益であると感じていただけましたら非常に光栄です。
ありがとうございます。
公開日:
最終更新日:2019/06/20