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

当サイトのリンクには広告を含みます。

こんにちは。えいこです。

WordPressの投稿・固定ページ、ウィジェット等にて、ショートコードを利用してphpファイルを呼び出してphpコードを動作させる危険性と、セキュリティリスクを考慮したコードを紹介します。

私が使用しているSWELLテーマで動作確認済みです。

この記事を書いた人

  • WordPressサイトを2つ運営中
  • Googleアドセンスの合格実績あり
  • アフィリエイトにて最高月収5桁達成

目次

PHPファイルをショートコードで読み出す際の注意点

セキュリティの観点から、通常はWordpressでは投稿・固定ページ、ウィジェット等にphpコードを記述して実行することはできません。PHPファイルをショートコードで呼び出す方法は、いくつかのセキュリティリスクに対して注意が必要です。

意図しないファイルが実行されるのを防ぐ

呼び出したいPHPファイル名をショートコードに記載するため、ファイル名を変数として扱います ここでその変数に対して制限を設けないと、「ディレクトリ・トラバーサル(横断)攻撃」を受けたとき、本来読み込むべきでない設定ファイル等が参照・実行される可能性があります。

https://www.ipa.go.jp/security/vuln/websecurity/parameter.html

そのためファイル名に相対パス「../」 を含むものはエラーではじく記述が必要です。

またPHPファイル以外が実行されないようなチェック機能もあるとより安全です。

攻撃者に対して情報が漏れるのを防ぐ

呼び出したいプログラムが見つからなかったり、万が一何かしらの攻撃を受けたりしたとき、エラーメッセージが出ると攻撃者に対してディレクトリ構造等の情報を漏らすことになります。

私は以前、間違って親テーマにPHPファイルを入れてしまい、アップデートで参照したいファイルが消えて、数日エラーでディレクトリ構造まる見えにしてしまったことがあります…。下記のイメージです。

そのためエラーメッセージを出さないように記述すると安全です。

安全にPHPファイルを呼び出すカスタマイズ手順とコード

カスタマイズ前、特にfunctions.phpを編集する際は必ずバックアップを取ってください。

カスタマイズ手順

ファイル構成は下記となっています。

/wp-contents
 │-/theme
 │ │- /swell-child
 │ │ │- /functions.php
 │ │ │- /myphpfiles
 │ │ │ │-/呼び出したいPHPファイル
   
STEP
子テーマディレクトリに「myphpfiles」ディレクトリを作成する

ファイルマネージャにログインして、swell-childディレクトリの中にPHPファイル置き場を作成しました。

STEP
myphpfilesディレクトリに呼出したいphpファイルをアップロード

メモ帳などで作ったPHPファイルを、先程作ったファイル置き場にアップロードします。

STEP
functions.phpに後ほど紹介するコードを追加

アップロードしたファイル名を記載するところがあるので注意してください。

STEP
呼び出したい箇所にショートコードを記載

を、投稿・固定ページ、ウィジェット等に記載します。

【重要】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を呼び出せるとサイトカスタマイズの自由度がぐんと上がるので、ぜひ活用してください。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

WordPressのことなら「わぷや」におまかせ!を目指して、サイト運営・収益化・カスタマイズ方法を勉強中です。本サイトとは別に、Googleアドセンス合格済のWordPressサイトも運営しています。どんぐり好きです。

コメント

目次