ワードプレスのプラグイン開発者が知っておきたい5つのセキュリティ対策2

はじめに

前回、ワードプレスのプラグインを開発するに当たって知っておきたい5つのセキュリティ対策の内、XSSとCSRFの2つを解説しました。今回は、残りのSQLインジェクション、ディレクトリトラバーサル、HTTPヘッダーインジェクションの3つを解説します。

3.SQLインジェクション

SQLインジェクションとは、正規の手続きを踏まずにデータベースにアクセスすることができる脆弱性のことです。


はじめてSQLインジェクションが世の中に出始めたのは2002年の2月、米国アパレル大手Guess社で顧客のクレジットカード番号が閲覧可能になっていた事が発覚したことから話題なりました。日本でも2005年5月、カカクコムでもSQLインジェクションによる不正アクセスにより一時的にWebサイトの閉鎖を余儀なくされた事件を記憶している人もいるのではないでしょうか?

このSQLインジェクションが具体的にどのような攻撃手法なのかを解説したいと思います。次のコードはユーザーからの入力を受けてログインするSQLを発行するクエリです。

$username = $_POST[‘usernmae’];
$password = $_POST[‘password’];
SELECT * FROM user WHERE uid=’$username’ AND pwd=’$password’

この時とき、次のようなパラメータをフォームから入力するとパスワードが違っていてもログインできてしまいます。

$username:sato
$password:’ OR ‘1’ = ‘1

SELECT * FROM user WHERE uid=’sato’ AND pwd=” OR ‘1’ = ‘1’

これを実行すると、ORの後のpwdは常に真なので、パスワードが一致しないにもかかわらず正規ユーザーと判断されてしまうという現象が起きてしまうのです。

これを回避するにはフォームから送られてきたパラメータはエスケープ処理してから使用するようにすればいい。

SQLインジェクションへのワードプレスでの対策

ワードプレスの場合はprepareメソッドを使用することでエスケープできます。

$results = $wpdb->get_results($wpdb->prepare(“SELECT * FROM user WHERE uid=%s AND pwd=%s”, $username, $password ));

変数を入れる個所には「%s」や「%d」などのパラメータで置き換えます。
変数が文字列の場合は「%s」を、整数の場合は「%d」を、浮動小数点数の場合は「%f」
を代入します。変数はprepare()メソッドに第2引数以降に順番にセットします。

4.ディレクトリトラバーサル

ディレクトリとラバーサルとは、Webサーバーの管理者が公開を許可していないファイルにアクセスする攻撃手法です。公開を許可していないアプリケーションの設定ファイルやユーザーのパスワードを管理しているファイルなどです。

通常、Webアプリケーションの開発者は決められたディレクトリだけを閲覧・更新することを想定しています。しかし、ファイル名前にディレクトリを追加することでアプリケーションの想定外のディレクトリのファイルにアクセスすることができてしまいます。その結果、大事な情報の漏えいやファイルの破壊などが起こりうる危険性があります。

ディレクトリトラバーサル脆弱性は次のコードのようにフォームからファイル名を指定できるようなWebアプリケーションの場合に発生するリスクがあります。

<?php
// データのあるディレクトリのパスを持つ
$dir = ‘/www/wordpress/data’;

// フォームから入力されたファイル名と結合して絶対パスに変換する。
$file_name = $dir . ‘/’ . $_POST[‘file_name’];

$data = ile_get_contents($file_name);
echo $data;
?>

この時、$_POST[‘file_name’]に相対パス「../」を含めることで、「/www/wordpress/data」以外の
ディレクトリの中のファイルも閲覧できてしまいます。

例えば、$_POST[‘file_name’]に「../wp-config.php」と記述すればwp-config.phpの中身を画面に表示してしまい、データベースへ接続するための情報を抜き取られ、攻撃者に改ざんされてしまうことになります。

ディレクトリトラバーサル脆弱性へのワードプレスでの対策

ワードプレスでこれを防ぐには、validate_file()関数を使いましょう。下記のコードは前述のコードをvalidate_file()関数を使ってチェックをするように変更した物です。validate_file()関数は引数に「./」や「../」が含まれている場合は”1″を返すので、非公開ファイルにアクセスする事を防ぐことが可能になるのです。

<?php
// データのあるディレクトリのパスを持つ
$dir = ‘/www/wordpress/data’;

// フォームから入力されたファイル名と結合して絶対パスに変換する。
$file_name = $dir . ‘/’ . $_POST[‘file_name’];

if(validate_file($file_name)){
die(“公開ディレクトリ以外は閲覧できません。”);
}

$data = ile_get_contents($file_name);
echo $data;
?>

5.HTTPヘッダーインジェクション

HTTPヘッダーインジェクションとは、クッキーやリダイレクト処理など、
HTTPレスポンスヘッダーを動的に組み立てて出力している箇所に対する攻撃です。

外部からのパラメータをそのまま使って、組み立てている場合にこの脆弱性が発生します。
例えば、次のコードは脆弱な実装です。

<?php
// ログインしたユーザー名をクッキーにセット
$name = $_POST[‘name’];
header(“Location: maypage.php?name=” . $name);
?>
これはLocationヘッダによって、アクセスしたユーザーを指定のURLへとリダイレクトさせるプログラムの一部です。このプログラムではまず $name 変数にnameパラメータを代入します。そして、2行目では$name変数を元にLocation ヘッダを作成し、HTTPレスポンスとして出力します。このコードはnameパラメータに改行コードを含む値を指定されることを考慮していないため、想定外のレスポンスを作成されてしまいます。

このコードでは、nameパラメータに %0D%0ASet-Cookie:sid=daemonを指定された場合、リダイレクト時に下記のように攻撃者の意図したCookieが発行されます。この方法でなりすましに成功するとマイページを見る際に購入履歴や個人情報などの個人情報を抜き取られてしまいます。

※「%0D%0A」は改行コードCRLFをurlencodeしたものです。

HTTP/1.x 302 Found
Date: Sat, 07 Mar 2013 17:32:48 GMT
Server: Apache/2.2.3 (Unix)
Set-Cookie: sid=daemon
Location: maypage.php?name=suzuki
Content-Length: 308
Connection: close
Content-Type: text/html; charset=utf-8

HTTPヘッダーインジェクションのワードプレスでの対応策

ワードプレスでHTTPヘッダーインジェクションを防ぐためには、wp_safe_redirect()関数を使うようにする。例のコードをwp_safe_redirect()関数を使うことで、パラメータに含まれている「%0D%0A」などの文字列を除去した上でリダイレクトするようになります。

<?php
// ログインしたユーザー名をクッキーにセット
$name = $_POST[‘name’];

$redirect_url = “login.php?name=” . $name”;
wp_safe_redirect($redirect_url);

?>

執筆者:カニ
創刊号が特別価格(890円ぐらい)で販売されているディアゴスティーニを全巻揃えると15万~20万円近くかかるそう。ということは、最終号が100巻の場合は、15万円の商品をクレジットカードのリボ払い100回で買うことに相当するのか。趣味で何かを集めるのは絶対にやめておこうと決意しました。

関連記事一覧

  1. この記事へのコメントはありません。