web-dev-qa-db-ja.com

WordPress 'is_user_logged_in()は安全ですか?

私はしばらくこれについて疑問に思っています。次のifステートメントは十分安全ですか?ログインしていないときにコードを突破してコンテンツにアクセスするのは簡単ですか。

<?php if ( is_user_logged_in() ) { 
     // SECURE CONTENT
} else { 
     // LANDING PAGE
} ?>
4

さて、あなたは自分自身に "何のために十分に安全なのか?"と自問しなければなりません。私はあなたが銀行や他の機関で非常に高い安全性を必要としているのではないかと思います。もしあなたがこの質問に答えるには、年間10万ドル以上の専門家チームが必要でした。

それを念頭に置いて...

あなたはそのコードを乗り越えるためにWordPressログインシステムを破壊する必要があるでしょう。私はそれが可能であると確信しています、しかしあなたのパスワードがしっかりしていればそれはかなり難しいはずです。 「クエリ文字列にnullバイトを入れる」ようなハックにはなりません。ほとんどの目的には十分に安全であるべきです。

心配しなければならないのは、is_user_logged_inとそれが依存するwp_get_current_userは両方ともプラグ可能 (つまり私の考えでは無意味)であるということです。一つは、あなたの安全を完全に破壊することです。

4
s_ha_dum

要するに - そして一般的な使用のために - はい。 @s_ha_dumが指摘したように、それは本当にあなたがそれを使っているものに依存します。

機能は安全ですか?

@kaiserと@s_ha_dumが述べているように、この関数はプラグイン可能です - つまり、どんなプラグインでも(notテーマでも)再定義して何でもできるということです。しかし、プラグインがほとんど何でもできるということであれば、これは実際には問題ではありません。プラグインは、サーバー上でコードを実行しています。

その「プラガブル」が実際には問題にならないという事実。あなたはallplugins - そしてあなたが使用するテーマ - を信頼することが合理的であることを確実にするべきです。セキュリティが非常に重要な場合、企業は独自のプラグインを作成してそれらを使用する傾向があります。

(そのプラガブルなので、必要に応じて企業はより安全な認証システムを実装できます)。

認証方法は安全ですか?

関数がWordPressコアのように定義されていると仮定しましょう。安全ですか? (はい)。

is_user_logged_in() 関数は、有効なcookieについてユーザーのブラウザを確認します。そこにない、無効である、または期限切れになっている - 彼らは再びログインすることを強制されます。

Cookieは以下から生成されます。

  • ユーザーのユーザー名
  • パスワードハッシュから取られた8文字
  • クッキーの有効期限が切れるときのタイムスタンプ

Cookie自体には、プレーンテキストのユーザー名とタイムスタンプが含まれています。 HMAC( ハッシュメッセージ認証コード )も含まれています。これは推測が困難な部分であり、ユーザー名とタイムスタンプによって異なります。そのため、攻撃者が期限切れのCookieまたは自分のアカウントのCookieを入手した場合、有効なHMACを生成せずに管理者アカウントにログインするような有効なCookieを生成することはできません。

HMACは上記の3つの要素のハッシュから生成されます。今8文字はあまり思われません - それは1週間以内に強引になる可能性があります。しかし実際にはハッシュはあなたのサイトのSALTを使った 塩味のハッシュ です。これで、そして彼らが安全である限り、総当たり攻撃のあらゆる試みは無効にされます。

...本当にその機能の安全性はあなたのウェブサイトのSALTの安全性にあります。これらはデータベースの認証情報とともにwp-config.phpに格納されています。 あなたはそれを公にするべきではありません。

関数がプラガブル関数の定義を変更したかどうかを検出できますか?

上記のKaiserの機能は、MUプラグインが機能を上書きした場合にのみ機能します。これはより一般的な解決策で、プラグイン可能な関数を上書きしないプラグインは not ではなく、プラグインが安全であることを示しています。

/**
 * Do not use in production.
 * 
 * Checks if any plug-ins have overwritten a pluggable function in 
 * `wp-includes/pluggable.php` with a custom function.
 * 
 * Prints list and kills processing if a function has been overwritten.
 * 
 * Based on Kaiser's answer (link below).
 * @link http://wordpress.stackexchange.com/questions/105637/is-wordpress-is-user-logged-in-secure/105667#105667
 */
function wpse105637_was_pluggable_defined_by_plugin(){

    $arr = token_get_all( file_get_contents( ABSPATH.WPINC.'/pluggable.php' ) );
    $functions = array();
    foreach ( $arr as $curr_key => $part ){
        if ( ! is_array( $part ) )
            continue;

        if ( token_name( $part[0] ) === 'T_FUNCTION' ){
            while ( is_array( $arr[ $curr_key ] ) AND 'T_FUNCTION' !== $arr[ $curr_key ][0] )
                ++$curr_key;
            $functions[] = $arr[ --$curr_key ][1];
        }
    }

    $overwritten  = 0;
    foreach ( $functions as $f ){
        $reflFunc = new ReflectionFunction( $f );
        if( ABSPATH.WPINC.'/pluggable.php' !== $reflFunc->getFileName() ){
            $overwritten++;
            printf( '<h1> Functions Overwritten </h1>' );
            print '<code>'.$f .'</code> ' . $reflFunc->getFileName() . ':' . $reflFunc->getStartLine() . '<br/>';
        }
    }

    if( $overwritten )
        wp_die( sprintf( '%d pluggable functions overwritten', $overwritten ) );

}
add_action( 'plugins_loaded', 'wpse105637_was_pluggable_defined_by_plugin' );
6
Stephen Harris

プラグイン可能な機能

まず、プラグインは~/wp-settings.phpファイル内から読み込まれます。それらはすべてのプラグインファイルがインクルードされた後にインクルードされます(ただし before plugins_loadedの前に)ため、どのプラグインでも置き換えることができます。 (mu-pluginsは以前にも含まれているので、それらが優先されます)。

ハックのための障害

デフォルトでコアに追加されていないため、デフォルトのユーザはmupluginsフォルダさえ持っていないかもしれないので、これについて心配することはありません。したがって、「ハッカー」が最初に行う必要があるのは、実際にフォルダを追加することです。これは、彼がすでにあなたのファイルシステムにアクセスしていて、あなたがあなたのインストールされたシステムのハックとは全く異なる問題を抱えていることを意味します。他の、簡単にアクセスできるドアが大きく開いているときに、深刻なハッカーがWordPressに迷惑をかけることはなくなりました。 WPMU_PLUGIN_DIRWPMU_PLUGIN_URLが定義されているかどうかを確認してください。そうでなければ、心配する必要はありません。

次のこと - あなたがmupluginsフォルダを持っている場合 - あなたがやりたいのはそれらのファイルをチェックすることです。これは非常に簡単です。MUプラグインは単一ファイルのプラグインとしてのみ機能します。あなたがファイルよりも多くのプラグインを持っているのであれば、あなたのファイルのうちの1つが既に外部ファイルをロードしています。 muplugins_loadedフックの(0)フックで get_included_files() を使ってファイルの総数を数えてこれを簡単に監視できます。 plugins_loaded-優先順位0のフック。違いはあなたが戻ってくるものと等しくなければなりません

count( glob( WPMU_PLUGIN_DIR.'/*.php' ) );

最後に心配することです。

それで、誰かが本当にあなたにMUプラグインを渡したとしましょう(あなたが自分でフォルダを追加した後にあなた自身でインストールしなければなりませんでした)。あなたはそうするために下記のプラグインを使用することができます。あなたの機能の1つが置き換えられた場合、それは単にdie()になります - あなたとあなたの訪問者を「保護する」のです。それは、可能な限り最新の時点(実際には「最新」のフック優先順位はありません)でフックインし、プラガブルファイルからすべての関数を読み取り、次にそれらの存在を確認します。ファイルの内容を取得するだけなので、それはインクルードされず、したがってそれらの関数は定義されません。こうすることで、関数の数が変わってもMUプラグインは常に最新の状態に保たれますが、それでもプラグインはそれを認識できます。

プラグインには少なくともPHPバージョン5.3が必要であることに注意してください。

<?php
defined( 'ABSPATH' ) OR exit;
/**
 * Plugin Name: (#105637) Check pluggable changes
 */
add_action( 'muplugins_loaded', 'wpse_pluggable_check', pow( 99, 99 ) );
function wpse_pluggable_check()
{
    $arr = token_get_all( file_get_contents( ABSPATH.WPINC.'/pluggable.php' ) );
    $functions = array();
    foreach ( $arr as $curr_key => $part )
    {
        if ( ! is_array( $part ) )
            continue;

        $token = token_name( array_shift( $part ) );
        $token === 'T_FUNCTION'
            AND $functions[] = $arr[ $curr_key + 2 ][1];
    }
    foreach ( $functions as $f )
        function_exists( $f ) AND wp_die( 'pluggable overwritten!' );
}

上記のプラグインは、関数スキームが常にfunction fn_name() {であると仮定しています。これは、以下の配列を検索する、少し強化されたバージョンです。

$arr = token_get_all( file_get_contents( ABSPATH.WPINC.'/pluggable.php' ) );
$functions = array();
foreach ( $arr as $curr_key => $part )
{
    if ( ! is_array( $part ) )
        continue;

    if ( token_name( $part[0] ) === 'T_FUNCTION' )
    {
        while ( is_array( $arr[ $curr_key ] ) AND 'T_FUNCTION' !== $arr[ $curr_key ][0] )
            ++$curr_key;
        $functions[] = $arr[ --$curr_key ][1];
    }
}
foreach ( $functions as $f )
    function_exists( $f ) AND wp_die( 'pluggable overwritten!' );
4
kaiser