添付ファイルのダウンロードを特定のユーザーに制限する方法は?


12

私は弁護士のために構築されたサイトと彼の各クライアントがwp-adminなどにアクセスすることなく自分の「特定のページ/ポータル」(カスタム投稿タイプ)にログインできる非常に具体的なユースケースを持っています(私はすべてを作成しましたフロントエンドのログイン/登録/プロファイル編集ページ)。このページ/ポータルでは、弁護士がクライアントにダウンロードするメッセージとファイルを残しますが、理論的には、1人のクライアントが他のファイル名を推測して(または別のクライアントのファイルの知識がある場合)ダウンロードして、プライバシー/セキュリティの問題を作成します/機密資料など

私はソリューションのアイデア/コンセプトを探しています、私の最初の考えは、添付ファイルID、ユーザーID、ページ/ポータルID、ノンスを送信するdownload.phpへのダウンロードリンクを持ち、もう一方の端でそれを処理することでした。 。

どう思いますか?私は正しい軌道に乗っていますか、それともこのアプローチには欠陥がありますか?

ありがとう!


これに対する解決策を見つけましたか?
ブラソフィロ

@brasofilo、いいえ。–
アミット

回答:


6

発生する必要があるのは、WordPressを介して必要なファイルタイプのダウンロードリクエストをプロキシする必要があるということです。「.doc」ファイルへのアクセスを制限すると仮定しましょう。

1.要求されたファイルを示すクエリ変数を定義します

function add_get_file_query_var( $vars ) {
    $vars[] = 'get_file';
    return $vars;
}
add_filter( 'query_vars', 'add_get_file_query_var' );

2. .htaccessを更新して、制限されたファイルのリクエストをWordPressに転送します

これにより、制限するファイルへの要求をキャプチャし、上記のカスタムクエリ変数を使用してWordPressに送り返します。RewriteCond行の前に次のルールを挿入します。

RewriteRule ^wp-content/uploads/(.*\.docx)$ /index.php?get_file=$1

3.カスタムクエリ変数で要求されたファイル名をキャプチャします。ファイルへのアクセスを確認します。

function intercept_file_request( $wp ) {
    if( !isset( $wp->query_vars['get_file'] ) )
        return;

    global $wpdb, $current_user;

    // Find attachment entry for this file in the database:
    $query = $wpdb->prepare("SELECT ID FROM {$wpdb->posts} WHERE guid='%s'", $_SERVER['REQUEST_URI'] );
    $attachment_id = $wpdb->get_var( $query );

    // No attachment found. 404 error.  
    if( !$attachment_id ) {
        $wp->query_vars['error'] = '404';
        return;
    }

    // Get post from database 
    $file_post = get_post( $attachment_id );
    $file_path = get_attached_file( $attachment_id );

    if( !$file_post || !$file_path || !file_exists( $file_path ) ) {
        $wp->query_vars['error'] = '404';
        return;
    }

    // Logic for validating current user's access to this file...
    // Option A: check for user capability
    if( !current_user_can( 'required_capability' ) ) {
        $wp->query_vars['error'] = '404';
        return;
    }

    // Option B: check against current user
    if( $current_user->user_login == "authorized_user" ) {
        $wp->query_vars['error'] = '404';
        return;
    }

    // Everything checks out, user can see this file. Simulate headers and go:
    header( 'Content-Type: ' . $file_post->post_mime_type );
    header( 'Content-Dispositon: attachment; filename="'. basename( $file_path ) .'"' );
    header( 'Content-Length: ' . filesize( $file_path ) );

    echo file_get_contents( $file_path );
    die(0);
}
add_action( 'wp', 'intercept_file_request' );

NBこのソリューションは、単一サイトのインストールでのみ機能します!これは、WordPress MUがサブサイトにアップロードされたファイルリクエストをを介して既に転送しているためwp-includes/ms-files.phpです。WordPress MUにもソリューションがありますが、もう少し複雑です。


こんにちは、ステップでこの関数をフックしintercept_file_requestたり、どこで呼び出されているのかわかりませんが、その関数はどのように起動されますか?
ボブ

良い点は、フックする必要がありますwp、例を更新しました。
ベンドー

3

私は最近、関連する問題を抱えており、それについてこの記事書きました

ダウンロードは、WordPressのメディア処理を介してアップロードされると仮定します-または、ダウンロード用の添付ファイルIDを持っていることを前提としています。

ソリューションの概要

  • (この意味でI「確保」アップロードディレクトリを作成するだけで平均使用.htaccess-などを経由してアップロードディレクトリ(またはそのサブディレクトリ)内のファイルに直接アクセスしようとする試みを阻止するためにmysite.com/wp-content/uploads/conf/2012/09/myconfidentialfile.pdf
  • 添付ファイルIDを含むダウンロードリンクを作成します-これはWordPressを通過して、添付ファイルを表示するユーザーのアクセス許可を確認し、アクセスを許可/拒否します。

注意事項

  • これは.htaccessセキュリティを提供するために利用します。これが利用できない/オンになっていない場合(nginxサーバーなど)、セキュリティはあまり得られません。ユーザーがuplodsディレクトリを参照しないようにすることができます。ただし、直接アクセスは機能します。
  • 上記の通り。絶対的なセキュリティが必要な場合は、これを配布で使用しないでください。特定の設定が機能する場合は問題ありませんが、一般的には保証できません。私のリンクされた記事は部分的にこれに対処しようとしています。
  • サムネイルを失います。フォルダーまたはサブフォルダーへの直接アクセスをブロックすると、そのフォルダー内のファイルのサムネイルを表示できなくなります。私のリンクされた記事の一部はこれに対処しようとしています。

直接アクセスのブロック

アップロードフォルダー(またはサブフォルダー-すべての機密資料は、このフォルダー内の任意の深さで存在する必要があります)でこれを行うには。.htaccess次のファイルを配置します。

Order Deny,Allow
Deny from all

以下では、投稿タイプ「クライアント」に機密資料を添付することを想定しています。クライアント編集ページにアップロードされたメディアはすべてuploads/conf/フォルダーに保存されます

保護されたアップロードディレクトリをセットアップする機能

function wpse26342_setup_uploads_dir(){

    $wp_upload_dir = wp_upload_dir();
    $protected_folder = trailingslashit($wp_upload_dir['basedir']) . 'conf';    

    // Do not allow direct access to files in protected folder
    // Add rules to /uploads/conf/.htacess
    $rules = "Order Deny,Allow\n";
    $rules .= "Deny from all";

    if( ! @file_get_contents( trailingslashit($protected_folder).'.htaccess' ) ) {
            //Protected directory doesn't exist - create it.
        wp_mkdir_p( $protected_folder);
    }
    @file_put_contents( trailingslashit($protected_folder).'.htaccess', $rules );

     //Optional add blank index.php file to each sub-folder of protected folder.
}

機密資料のアップロード

   /**
    * Checks if content is being uploaded on the client edit-page
    * Calls a function to ensure the protected file has the .htaccess rules
    * Filters the upload destination to the protected file
    */
    add_action('admin_init', 'wpse26342_maybe_change_uploads_dir', 999);
    function wpse26342_maybe_change_uploads_dir() {
        global $pagenow;

        if ( ! empty( $_POST['post_id'] ) && ( 'async-upload.php' == $pagenow || 'media-upload.php' == $pagenow ) ) {
                if ( 'client' == get_post_type( $_REQUEST['post_id'] ) ) {
                       //Uploading content on the edit-client page

                       //Make sure uploads directory is protected
                       wpse26342_setup_uploads_dir();

                       //Change the destination of the uploaded file to protected directory.
                       add_filter( 'upload_dir', 'wpse26342_set_uploads_dir' );
                }
        }

    }

それが完了したら、アップロードされたコンテンツは内部にuploads/confあり、ブラウザを使用して直接アクセスしようとしても機能しません。

コンテンツをダウンロードする

これは簡単です。ダウンロードURLには何かを指定できますwww.site.com?wpse26342download=5(5はアップロードされたコンテンツの添付IDです)。これを使用して、添付ファイルを識別し、現在のユーザーの権限を確認し、ダウンロードを許可します。

まず、クエリ変数を設定します

/**
 * Adds wpse26342download to the public query variables
 * This is used for the public download url
 */
add_action('query_vars','wpse26342_add_download_qv');
function wpse26342_add_download_qv( $qv ){
    $qv[] = 'wpse26342download';
    return $qv;
}}

次に、(おそらく)ダウンロードをトリガーするリスナーを設定します...

add_action('request','wpse26342_trigger_download');
function wpse26342_trigger_download( $query_vars ){

        //Only continue if the query variable set and user is logged in...
    if( !empty($query_vars['wpse26342download']) && is_user_logged_in() ){

        //Get attachment download path
        $attachment = (int) $query_vars['wpse26342download'];
        $file = get_attached_file($attachment);

        if( !$file )
             return;

        //Check if user has permission to download. If not abort.       
        header('Content-Description: File Transfer');
        header('Content-Type: application/octet-stream');
        header('Content-Disposition: attachment; filename='.basename($file));
        header('Content-Transfer-Encoding: binary');
        header('Expires: 0');
        header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
        header('Pragma: public');
        header('Content-Length: ' . filesize($file));

        ob_clean();
        flush();
        readfile($file);
        exit();
    }
    return $query_vars;
}

最終コメント

上記のコードにはバグ/構文エラーが含まれている可能性があり、テストされていません。ご自身の責任で使用してください:)。

ダウンロードURLは、書き換えを使用して「プリティ」にすることができます。コメントで述べたように、index.php閲覧を防ぐために保護されたフォルダのすべての子の内側に空白を追加することができます-しかし、これは.htaccessとにかくルールによって防止されるべきです。

より安全な方法は、パブリックディレクトリの外部にパブリックファイルを保存することです。または、Amazon S3のような外部サービスで。後者の場合、有効なURLを生成してAmazonからファイルを取得する必要があります(秘密キーを使用)。これらは両方とも、ホスト/サードパーティサービスに対する一定レベルの信頼を必要とします。

私は、それらが「保護されたダウンロード」を提供することを示唆するプラグインを使用することには警戒します。十分なセキュリティを提供するものは見つかりませんでした。このソリューションの注意事項も避けてください-提案や批判を歓迎します。


1

おそらく、あなたはこのトリックを知っているかもしれません。このコードは、現在ログインしているユーザーのユーザー名をチェックし、一致する場合はそのファイルへのダウンロードリンクを表示し、そうでなければ何も表示しません。

コードは次のとおりです。

<?php 
    global $current_user;
    get_currentuserinfo();

    if ( 'username' == $current_user->user_login ) {
        echo 'Download Link';
    } else {
        // nothing
    }
?>

ただし、これは良い方法ではありません。ファイルはサーバーに保存されるため、リンクを知っている人なら誰でもそのファイルをダウンロードできます。


0

この情報は機密情報であり、ファイルへのリンクを非表示にすることに加えて、ダウンロードする明示的な許可がない限り、たとえURLを推測したとしても、Web上のだれもが完全にアクセスできないようにする必要がありますファイル。

ファイルをAmazon S3に安全に保存し、正しいセキュリティチェックが満たされている場合(つまり、ユーザーがサイトにログインし、そのユーザーが本人である場合)に、ファイルに事前署名(時間制限)URLを提供します。

これを行うのが非常に簡単な非常に優れたAWS SDKがあります。

調査する必要があるのは、WPアップロードインターフェースからアップロードされたファイルを代わりにS3に送信する方法、または独自のアップローダーを構築する方法です。

別のオプションは、WP e-commerceのコードを詳しく調べることです。ソフトウェアファイル(MP3など)の安全なダウンロードを提供します。ファイルは、購入時にユーザーごとに生成される暗号化キーを使用してハッシュに変換されると思います。これがどのように機能するかを理解するには多少の解読が必要ですが、プロセスはこのプラグインに固有のものではないため、他の例が利用可能になります(どこか)。


0

ファイルの暗号化は、上記の答えのように進む方法だと思います。Wordpress.orgには、ダウンロードを保護できるプラグインがあります。 http://wordpress.org/extend/plugins/download-protect/ Amazonsサービスまたはgoogleドライブも使用できます。ドロップボックスなどの保護されたダウンロードを提供するサービスも多数あります。


あいまいさによるセキュリティは悪いアプローチです。誰でもhttpリクエストを確認し、この方法でURLを取得できます。
mulllhausen
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.