WordPressでPHPファイルをショートコード呼出しする危険性と対策を解説

こんにちは。えいこです。
WordPressの投稿・固定ページ、ウィジェット等にて、ショートコードを利用してphpファイルを呼び出してphpコードを動作させる危険性と、セキュリティリスクを考慮したコードを紹介します。
私が使用しているSWELLテーマで動作確認済みです。
PHPファイルをショートコードで読み出す際の注意点

セキュリティの観点から、通常はWordpressでは投稿・固定ページ、ウィジェット等にphpコードを記述して実行することはできません。PHPファイルをショートコードで呼び出す方法は、いくつかのセキュリティリスクに対して注意が必要です。
意図しないファイルが実行されるのを防ぐ
呼び出したいPHPファイル名をショートコードに記載するため、ファイル名を変数として扱います ここでその変数に対して制限を設けないと、「ディレクトリ・トラバーサル(横断)攻撃」を受けたとき、本来読み込むべきでない設定ファイル等が参照・実行される可能性があります。
https://www.ipa.go.jp/security/vuln/websecurity/parameter.html
そのためファイル名に相対パス「../」 を含むものはエラーではじく記述が必要です。
またPHPファイル以外が実行されないようなチェック機能もあるとより安全です。
攻撃者に対して情報が漏れるのを防ぐ
呼び出したいプログラムが見つからなかったり、万が一何かしらの攻撃を受けたりしたとき、エラーメッセージが出ると攻撃者に対してディレクトリ構造等の情報を漏らすことになります。
私は以前、間違って親テーマにPHPファイルを入れてしまい、アップデートで参照したいファイルが消えて、数日エラーでディレクトリ構造まる見えにしてしまったことがあります…。下記のイメージです。

そのためエラーメッセージを出さないように記述すると安全です。
安全にPHPファイルを呼び出すカスタマイズ手順とコード

カスタマイズ手順
ファイル構成は下記となっています。
/wp-contents
│-/theme
│ │- /swell-child
│ │ │- /functions.php
│ │ │- /myphpfiles
│ │ │ │-/呼び出したいPHPファイル
ファイルマネージャにログインして、swell-childディレクトリの中にPHPファイル置き場を作成しました。
メモ帳などで作ったPHPファイルを、先程作ったファイル置き場にアップロードします。
アップロードしたファイル名を記載するところがあるので注意してください。
を、投稿・固定ページ、ウィジェット等に記載します。
【重要】functions.phpを編集する前に
functions.phpとは、WordPressテーマに必須のファイルのひとつです。編集でミスをしてしまうと、最悪WordPressが表示されなくなることもある、とても重要なファイルです。

「Code Snippets」というプラグインを使用すると、編集ミスを極力抑えることができます。私も直接編集に苦手意識があるので使っています。
functions.phpに追加するコード
以下のコードは、前述のリスクを低減するための工夫を加えたものです。
function include_my_php($params = array()) {
// 許可するファイル名のリスト(拡張子なし)
// あなたのPHPファイル名に変更してください
$allowed_files = array('abc', 'def');
// ショートコードのパラメータを取得
$params = shortcode_atts(array(
'file' => 'default' // デフォルト値
), $params);
// ファイル名をサニタイズ
$file = sanitize_file_name($params['file']);
// ホワイトリストチェック
if (!in_array($file, $allowed_files, true)) {
return '<!-- Invalid file request -->';
}
// ファイルパスを構築(.php を付与)
// 子テーマフォルダ内の「myphpfiles」にファイルを入れる場合
// 子テーマ不使用の場合はget_template_directory
$file_path = get_stylesheet_directory() . "/myphpfiles/{$file}.php";
// ファイルの存在チェック
if (!file_exists($file_path)) {
echo($file_path);
return '<!-- File not found -->';
}
// ファイルの読み込み
ob_start();
include $file_path;
return ob_get_clean();
}
add_shortcode('myphp', 'include_my_php');
コードの安全対策解説

ホワイトリスト方式の採用
許可ファイル名のみを記述するホワイトリストを採用しました。file パラメータがこのリストにない場合は拒否します。さらに安全にするには、別ファイルに分けた方がよいです。
ディレクトリトラバーサル攻撃で「../../../wp-config.php 」のような相対パス等を入れられても、ホワイトリストにないと実行されないため、親ディレクトリのファイル等の意図しないファイルの読み込みを防ぎます。
ホワイトリスト以外の安全対策
1つ目はサニタイズ処理です。このコードの場合、ホワイトリストがあるのでサニタイズ処理は「必須ではない」ですが、万が一file パラメータに意図しない入力が入った場合に備えて、より安全性を高めるために実施しています。
2つ目はファイルパスの構築です。fileパラメータに.phpを付与し、phpファイル以外は参照できないようにしています。
エラーメッセージの抑制
不正なファイルリクエストがあった場合、またファイルが見つからなかった場合、指定のコメントを返すのみでエラーメッセージを出さないようにしました。これにより、攻撃者に対して情報を漏らすのを防ぎます。
まとめ
myphpfiles ディレクトリはパーミッションを適切に設定し(644 や 600 など)、必要最小限のPHPファイルのみを置くようにしましょう。
PHPを呼び出せるとサイトカスタマイズの自由度がぐんと上がるので、ぜひ活用してください。
コメント
コメント一覧 (1件)
[…] https://wapuya.com/wp-php-shortcode/ […]