Comment limiter le téléchargement de pièces jointes à un utilisateur spécifique?

12

J'ai un cas d'utilisation très spécifique où le site conçu pour un avocat et chacun de ses clients peut se connecter à leur propre "page / portail spécifique" (type de message personnalisé) sans possibilité d'accéder à wp-admin, etc. (I créé toutes les pages de connexion / enregistrement / modification de profil dans le frontal). Dans cette page / portail, l'avocat laissera des messages et des fichiers à télécharger par le client . Désormais, en théorie, un client peut deviner (ou s'il a connaissance des fichiers d'un autre client) d'autres noms de fichiers et les télécharger ensuite. créer un problème avec confidentialité / sécurité / documents confidentiels, etc.

Je recherchais des idées / concepts pour une solution, ma pensée initiale était de faire pointer le lien de téléchargement vers download.php en envoyant l'identifiant de la pièce jointe, l'identifiant de l'utilisateur, l'identifiant de la page / du portail et nonce, et l'autre extrémité. traitement qui ..

qu'en pensez-vous? suis-je sur la bonne voie ou cette approche est-elle défectueuse?

Merci!

    
posée Amit 19.08.2011 - 16:22

5 réponses

5

Ce qu'il faut, c'est que vous ayez besoin de télécharger par proxy des demandes de téléchargement pour les types de fichiers souhaités via WordPress. Supposons que vous allez restreindre l'accès aux fichiers ".doc".

1. Définissez une variable de requête qui indique le fichier demandé

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

2. Mettez à jour .htaccess pour transférer les demandes de fichiers restreints vers WordPress

Cela capturera les demandes relatives aux fichiers que vous souhaitez limiter et les renverra à WordPress à l'aide de la variable de requête personnalisée ci-dessus. Insérez la règle suivante avant les lignes RewriteCond .

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

3. Capturez le nom de fichier demandé dans la variable de requête personnalisée; et vérifiez l'accès au fichier:

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 Cette solution fonctionne pour les installations mono-site uniquement ! En effet, WordPress MU transfère déjà les demandes de fichiers téléchargés dans les sous-sites via wp-includes/ms-files.php . Il existe également une solution pour WordPress MU, mais elle est un peu plus complexe.

    
réponse donnée Bendoh 12.09.2012 - 03:03
3

J'ai récemment rencontré un problème et a écrit cet article à ce sujet. .

Je suppose que les téléchargements sont téléchargés via la gestion des supports de WordPress - ou sinon, vous avez un ID de pièce jointe pour le téléchargement.

Aperçu de la solution

  • Rendez le répertoire de téléchargements 'sécurisé' (en ce sens, je veux juste utiliser .htaccess pour bloquer toute tentative d'accès direct aux fichiers du répertoire uploads (ou de l'un de leurs sous-répertoires) - par exemple via mysite.com/wp-content/uploads/conf/2012/09/myconfidentialfile.pdf )
  • Créez un lien de téléchargement comprenant l’ID de la pièce jointe. Celui-ci passe par WordPress pour vérifier si l’utilisateur est autorisé à afficher la pièce jointe.

Mises en garde

  • Ceci utilise .htaccess pour assurer la sécurité . Si ceci n'est pas disponible / activé (serveurs nginx par exemple), vous n'aurez pas beaucoup de sécurité. Vous pouvez empêcher l'utilisateur de naviguer dans le répertoire uplods. Mais l'accès direct fonctionnera.
  • Comme ci-dessus. Cela ne doit pas être utilisé dans le secteur de la distribution si vous avez besoin d'une sécurité absolue . C'est bien si votre configuration spécifique fonctionne - mais en général, cela ne peut pas être garanti. Mon article lié tente en partie de résoudre ce problème.
  • Vous perdrez des vignettes . Si vous bloquez l’accès direct à un dossier ou à un sous-dossier, les miniatures des fichiers de ce dossier ne pourront plus être visualisées. Mon article lié tente en partie de résoudre ce problème.

Blocage de l'accès direct

Faites-le dans votre dossier de téléchargement (ou dans un sous-dossier - tous les documents confidentiels doivent résider, quelle que soit leur profondeur, dans ce dossier). Placez un fichier .htaccess avec les éléments suivants:

Order Deny,Allow
Deny from all

Dans ce qui suit, je suppose que vous joindrez des informations confidentielles au type de message "client". Tout média téléchargé sur la page de modification du client sera stocké dans le dossier uploads/conf/

La fonction pour configurer le répertoire des téléchargements protégés

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.
}

Téléchargement de contenu confidentiel

   /**
    * 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' );
                }
        }

    }

Cela fait, le contenu téléchargé doit se trouver à l'intérieur de uploads/conf et toute tentative d'y accéder directement à l'aide de votre navigateur ne devrait pas fonctionner.

Téléchargement de contenu

C'est facile. L'URL de téléchargement peut être quelque chose de www.site.com?wpse26342download=5 (où 5 est l'ID de pièce jointe du contenu téléchargé). Nous l'utilisons pour identifier la pièce jointe, vérifier les autorisations de l'utilisateur actuel et lui permettre de télécharger.

Tout d'abord, configurez la variable de requête

/**
 * 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;
}}

Configurez un écouteur pour (peut-être) déclencher le téléchargement ...

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;
}

Commentaires finaux

Le code ci-dessus peut contenir des erreurs de syntaxe / bugs et n'a pas été testé. Vous l'utilisez à vos risques et périls :).

L'URL de téléchargement peut être "raffinée" à l'aide de réécritures. Comme indiqué dans les commentaires, vous pouvez ajouter un index.php vierge à l'intérieur de chaque enfant du dossier protégé pour empêcher la navigation - ceci devrait néanmoins être empêché par les règles .htaccess .

Une méthode plus sécurisée consisterait à stocker les fichiers publics en dehors d’un répertoire public. Ou sur un service externe comme Amazon S3. Pour ce dernier, vous devrez générer une URL valide pour extraire le fichier d'Amazon (à l'aide de votre clé privée). Les deux nécessitent un certain niveau de confiance dans votre service hôte / tiers.

Je me méfierais de tout plug-in suggérant de proposer des "téléchargements protégés". Je n'ai trouvé aucun produit offrant une sécurité suffisante. Ne posez pas non plus les réserves de cette solution - et toute suggestion ou critique sera la bienvenue.

    
réponse donnée Stephen Harris 27.09.2012 - 13:23
1

Probablement, vous connaissez peut-être cette astuce. Ce code vérifie le nom d'utilisateur de l'utilisateur actuellement connecté et, le cas échéant, il affiche le lien de téléchargement vers ce fichier. Sinon, rien ne s'affiche.

voici le code:

<?php 
    global $current_user;
    get_currentuserinfo();

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

Cependant, ce ne sera pas une bonne approche, car les fichiers sont stockés sur des serveurs, toute personne disposant d'un lien peut télécharger ce fichier.

    
réponse donnée amit 09.07.2012 - 03:28
0

Je présume que ces informations sont confidentielles. Par conséquent, en plus de masquer les liens vers les fichiers, vous voudrez les rendre totalement inaccessibles à quiconque sur le Web, même s'ils devaient deviner l'URL, à moins que cet utilisateur ne dispose d'une adresse explicite. autorisation de télécharger les fichiers.

Envisagez de stocker les fichiers sur Amazon S3 en toute sécurité, puis de fournir pré-signé (limité dans le temps) URL du fichier à condition que les contrôles de sécurité corrects aient été satisfaits (l'utilisateur s'est connecté à votre site et indique qui il prétend être.) ).

Il existe un très bon kit de développement logiciel (SDK) AWS qui permet de le faire très facilement.

Ce que vous devez rechercher, c'est comment envoyer des fichiers téléchargés via l'interface de téléchargement WP vers S3, ou créez votre propre uploader .

Une autre option serait de consulter le code du WP e-commerce . Ils offrent un téléchargement sécurisé des fichiers logiciels (par exemple, MP3). Je crois que les fichiers sont convertis en hachages avec une clé de cryptage générée par utilisateur lors de l'achat. Cela prendrait un peu de déchiffrement pour voir comment cela fonctionnait, mais le processus ne sera pas spécifique à ce plugin, d'autres exemples seront donc disponibles (quelque part).

    
réponse donnée deadlyhifi 27.08.2012 - 13:37
0

Je pense que le cryptage des fichiers est la voie à suivre, comme dans la réponse ci-dessus. Il existe un plugin sur Wordpress.org qui vous permet de protéger les téléchargements. enlace Vous pouvez également utiliser le service amazon ou google drive. Il existe de nombreux services proposant des téléchargements protégés tels que les boîtes de dépôt.

    
réponse donnée Chris 29.08.2012 - 22:06

Lire d'autres questions sur les étiquettes