PHPの脆弱性まとめ

PHP/Laravel

Is your PHP/Laravel website hackable? という面白い記事を見かけたので、日本語訳しながら解説していきたいと思います。

正直、自分も知らない脆弱性があって勉強になりました。

てか、別にLaravelに対する脆弱性は載ってないです。

SQL injection

はい、でましたSQLインジェクションです。SQL界隈では最も有名で、致命的な脆弱性の一つですね。

例えば、PHPから以下のようなSQLを実行できたとします。

$post_id = $_POST['post_id'];
$sql = "DELETE FROM posts WHERE user_id = 1 AND id = $post_id";
\DB::statement($sql);

記事とかスレッドを削除するような場合でしょうか。

user_id=1(管理人)の場合、指定されたIDのpostを削除するというコードが実行されるわけですね。

ただ、このコードはPOSTで送られてきた文字列をなんのチェックもせずにSQLに代入してしまっています。

この、チェックをしないっていうのが最もキケンな実装なんよね。

このとき、攻撃者は例えば “1 OR 1” のようなリクエストをサーバに対して送ります。

すると、このときPHPは以下のようなSQLクエリを実行します。

$sql = "DELETE FROM posts WHERE user_id = 1 AND id = 1 OR 1";

これはすべてのユーザの全てのpostsを削除するというクエリになってしまっています。

XSS(cross site scripting

XSSでクロスサイトスクリプティングと読みます、かっこいい!!

XSSはSQLインジェクションに似ている脆弱性で、HTMLやJavascriptのコードをあなたのHTMLに挿入することを許してしまいます。

例えば、Googleのサイトのような検索システムを想像してください。検索用語を入力して、エンターキーを押せばその結果が表示されるようなウェブサイトです。

それを実装する際に、以下のようなコードを書いていると脆弱性となります。

<?php echo 'You searched for: ' . $_GET['search_query']; ?>

一見すると何のワードで検索したかを表示するだけのように見えますが、このとき検索ワードとして、

<script>alert('surprise!');</script>

のようなものを与えると、このJavascriptが実行されてしまいます。

アラートを表示するくらいでは何の影響もありませんが、XSSを利用してクッキーの情報を盗んだり、他のウェブサイトへユーザをリダイレクトさせたり、パスワードを盗んだりできるのです。

CSRF (cross site request forgery)

知っていたようで知らなかった脆弱性でした。

例えば、あるサイトでアカウント削除が以下のURLを踏むことで実行されるものだとします。

<a href="http://your-website.com/delete-account">delete account</a>

これはサイト側の実装不備の問題であって、ユーザ側に落ち度はないことに注意。

で、それを知っている攻撃者は以下のような書き込みをあなたのウェブサイトに載せます。

<img src=”http://your-website.com/delete-account”> lol :D

「これめちゃおもろいでハハッ」みたいな書き込みです。

これは画像タグで、本来は画像のURLをはらなければいけないのですがその代わりに先程のURLが設定されています。

もしもあなたがそのウェブサイトの登録者で、ログイン状態になっているとしたらこの画像のリンクをクリックした瞬間にアカウントが削除されてしまいます。

ブラウザによっては画像読み込み時にURLにアクセスしてしまうので、書き込みがあるページをひらいた瞬間にアカウントが消されてしまうということですね。

file_get_contents()

file_get_contents()は簡単にファイルダウンロードや読み込みが行える関数で、以下のように使っている方も多いかと思います。

echo file_get_contents('https://some-website.com/friend-list.txt');

定数を使っているなら良いのですが、file_get_contents() の引数を入力できる状態になっていると攻撃者がサーバからファイル名を直接入力して中身を盗み見ることができます。

echo file_get_contents('.env');
OR
echo file_get_contents('secret-code.php');

これ、echoだからPHPの中身が見えちゃう!

いやー、file_get_contents()は結構使ってるから気をつけないといけないなと思いました…

しかし、参考文献曰くこの脆弱性をみつけるのはピカチュウを見つけるくらい難しいとのこと。

ピカチュウなんてトキワの森適当に歩いてたら一時間くらいでゲットできるやん…っていう気もする。

まとめ

今回の記事の執筆にあたって以下の記事を参考にさせていただきました。