私はいくつかのWordPress Admin AJAXスクリプト(Adminパネルでのみ実行される)を設定しました。それらは現在すべて{別々のアクション、関数そしてnonceを使用しています。
これらのスクリプトの唯一の「本当の」違いはそれらのPHP関数です。そのため、システムを合理化するために、これらすべてを処理するために1つのJS関数と1つのmain PHP関数を作成しました。
インクルードへのパスとともに$ _POST値が送信されます。したがって、wp_ajax_custom_func()
が実行されると、PHPファイルが含まれ、locate_template()
でラップされます。
うまく機能しますが、これによりセキュリティホールが生じるかどうか心配ですか?
私は、攻撃者が偽造を試みることができることを知っています、偽のPOSTデータをadmin-ajax.php
に送信、XSS /クロススクリプト攻撃、その他...
私はインクルードをlocate_template()
でラップしたので、これはシステムを保護するのに役立つと私は思っています。 (長辺SSL、もちろんwp_verify_nonceとcurrent_user_can)
これがコアの概念です。
セットアップ
wp_enqueue_script( 'ajax_js_class',
get_template_directory_uri() . '/theme/ajax_js_class.js'
);
wp_localize_script( 'ajax_js_class', 'custom_settings', array(
'my_ajaxurl' => admin_url( 'admin-ajax.php' )
// nonce and action are attached at the form level
) );
関数
add_action( 'wp_ajax_run_ajax_class_func', 'run_ajax_class_func' );
// wp_ajax_nopriv_run_ajax_class_func is not used
function run_ajax_class_func() {
if(isset($_POST['nonce'])) {
$nonce= $_POST['nonce']; // the nonce from the form
$action = $_POST['action_hash']."-special-string"; // changes on each form
$verify_nonce = wp_verify_nonce($nonce, $action);
if( $verify_nonce !== false ) {
if(isset($_POST['path']) && current_user_can('administrator') ) {
$path = $_POST['path']; // <= this is my concern...
include locate_template($_POST['path']);
} else {
$output = json_encode( array( "success" => "false", "message" => "fail") );
}
} else {
$output = json_encode( array( "success" => "false", "message" => "fail") );
}
} else {
$output = json_encode( array( "success" => "false", "message" => "fail") );
}
echo $output; // this is handled in the include above
// always die
die();
}
HTMLエッセンシャル
<?php $nonce = wp_create_nonce( $random_hash."-special-string" ); ?>
<form>
<input type="hidden" name="path" value="in/theme/run_this.php" >
<input type="hidden" name="nonce" value="<?php echo $nonce; ?>" >
<input type="hidden" name="action_hash" value="<?php echo $random_hash; ?>" >
ローカライズされたJs Essentials
$.post(custom_settings.my_ajaxurl, data, function(response) {
私はフォームを攻撃しようとしました(ヘッダーを修正しデータを投稿するためにFiddler2を使用します)が、私は確認バイアスに苦しんでいると思います。
私はこの考えが悪いか良いかを確かめるために地域社会に相談したいと思います。 (もちろん悪い考えは批判に値する)
質問:
最後に、それぞれのnonce、enqueue、form、actionを完全に別々のスクリプトとして作成するほうが安全な場合は、その理由について詳しく説明してください。
参照と研究
あなたが正しくナンスを使用するならば、それは偽の要求を処理するためにサイトを作ることは可能ではないでしょう...だからこの部分は安全であるべきです...しかしあなたのアプローチにはまだ1つのセキュリティ欠陥があります...
Adminとしてログインしている間に、自分のブラウザでJSスクリプトを実行できるようにすることができたらどうなりますか。可能です。
このようにnonceは検証エラーを引き起こさず、あなたのコードは私が欲しいものを実行するでしょう - あなたはユーザーからの入力を検証しないので...
だからあなたのセキュリティはすべてあなたのサイトにいくつかのJSを注入する可能性に基づいています - そしてそれはかなり一般的です - ちょうどWPのマルウェア履歴を見てみるだけで...
検証済みのデータに基づいてテンプレートが読み込まれた場合は、はるかに安全です。それで直接それをロードしないで、正しい、安全なテンプレートのリストを作り、POSTで送られた変数に基づいてそれらをロードしてください。
3つの質問に戻ります。
いいえ。ユーザーが送信したパスに基づいてファイルをロードしても問題ありません。変数を渡してからこの変数をPHPのファイルのパスに変換した方がはるかに安全です。
それほど簡単にはできませんが、そうです - そのようなコードを攻撃することは可能でしょう。
はい、そうです。しかし、いくつか関数を書く必要はありません。あなたはただこれをきちんと安全にして覚えておく必要があります - あなたはユーザーから来るものを決して信頼するべきではありません。