エグゼクティブサマリ
PHP 5.5.21、PHP 5.6.5 以降、PHPにPDO::MYSQL_ATTR_MULTI_STATEMENTSというオプションが追加され、PDO+MySQLの組み合わせで、SQLの複文を禁止できるようになった。この設定はSQLインジェクションの緩和策として有効である。はじめに
2013年12月に公開した PHP+PDO+MySQLの組み合わせではSQLインジェクション攻撃で複文呼び出しが可能 にて、PDOとMySQLの組み合わせで、SQLインジェクションの文脈で複文呼び出しが可能であることを報告していましたが、その後のPHPのバージョンアップで、複文実行を禁止するオプションが追加されていましたので報告します。対象のバージョンは以下の通りです。
- PHP 5.5.21 以降
- PHP 5.6.5 以降
- 全ての PHP 7.0、7.1
この記事の中で、私は以下のように書きました。
実験に使用した環境はMySQLを使っていますが、SQLの複文が実行できていることになります。これは、DrupalがPDOを使っているためで、詳しくは以下のエントリを参照ください。すなわち、タラレバの話にはなりますが、PDOがMySQLでの複文実行を許していなければ、Drupageddonは高危険度の脆弱性には至らなかった可能性があります。少なくとも、攻撃経路はかなり限定されたはずです。
- PHP+PDO+MySQLの組み合わせではSQLインジェクション攻撃で複文呼び出しが可能
Drupalの開発陣にとっては、この事実はよほど悔しかったのかもしれません。以下のような時系列で、PDO+MySQLで複文を許さなくするオプションが提案されます。
- 2014年10月15日 Drupageddonを修正した Druapl 7.32 がリリースされる
- 2014年11月14日 PDOに複文を許さなくするオプションが提案される
- 2015年 1月22日 上記を実装したPHP 5.5.21およぴ PHP 5.6.5 がリリースされる
どうしてこのオプションに気づいたか
私はこのオプションの存在に気がついていなかったのですが、昨日modphpallでDrupal8を動かしていたところ、下記の警告が表示されていることに気がつきました。PHP (multiple statement disabling) | 5.5.9 (more information) PHP versions higher than 5.6.5 or 5.5.21 provide built-in SQL injection protection for mysql databases. It is recommended to update. |
multiple statement disabling …ですと?
この情報から、PDO::MYSQL_ATTR_MULTI_STATEMENTSというオプションが追加されたことに気がつきました。
オプションの使い方
マニュアルから、このオプション PDO::MYSQL_ATTR_MULTI_STATEMENTS の説明を引用します。PDO::MYSQL_ATTR_MULTI_STATEMENTS (integer)すなわち、new PDOする際に、driver_options配列に上記を設定すればよいことになります。下記は、Drupalのソースコードを参考に、PDO::MYSQL_ATTR_MULTI_STATEMENTS が存在する場合のみ、このオプションを指定しています。
FALSE にすると、PDO::prepare() や PDO::query() でのマルチクエリの実行を無効にします。
この定数が使えるのは、データベースハンドルを新規作成する際の driver_options 配列内だけであることに注意しましょう。
これが使えるようになった PHP のバージョンは 5.5.21 および PHP 5.6.5。
PHP: MySQL (PDO) - Manual より引用
上記オプションが有効な状態で複文を実行しようとすると、以下のようなエラーになります。$opt = array(/* 様々な接続時オプション */); if (defined('PDO::MYSQL_ATTR_MULTI_STATEMENTS')) { $opt[PDO::MYSQL_ATTR_MULTI_STATEMENTS] = false; } $db = new PDO("mysql:host=DBHOSTNAME;dbname=DBNAME;charset=utf8", DBUSER, DBPASSWORD, $opt);
PDO Error:SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; ...
PDO::MYSQL_ATTR_MULTI_STATEMENTS を FALSE にする効果
この設定により、SQLインジェクション攻撃で複文を使用することができなくなります。Drupageddonに効果があることは前述のとおりですが、これは現実的には意味がありません。このオプションの真意は、Drupageddonのある古いDrupalを延命させることではないでしょう。むしろ、今後、SQLの複文を使った攻撃を緩和することにあります。複文が使えなくなると、SQLインジェクションによる改ざんがほぼできなくなると考えられますので、情報漏えいによる実害があまりなく、改ざんが主な脅威であるようなサイトには特に有力な緩和策になります。
0 件のコメント:
コメントを投稿