Ek indirmeyi belirli bir kullanıcıyla nasıl kısıtlayabilirim?


12

Bir avukat için inşa edilen sitenin ve müşterilerinin her birinin wp-admin vb.'ye erişme yeteneği olmadan kendi 'belirli sayfa / portalına (özel yazı tipi) giriş yapabileceği çok özel bir kullanım durumum var. giriş / kayıt / profil düzenleme sayfaları). Bu sayfada / portalda avukat , müşterinin indirmesi için mesajlar ve dosyalar bırakacak , şimdi teorik olarak, bir müşteri diğer dosya adlarını tahmin edebilir (veya başka bir müşterinin dosyaları hakkında bilgi sahibi ise) ve indirebilir ve böylece gizlilik / güvenlik ile ilgili bir sorun oluşturabilir / gizli materyal vb.

Bir çözüm için fikirler / kavramlar arıyorum, ilk düşüncem bazı indirme.php indirme bağlantı noktası eki kimliği, kullanıcı kimliği, sayfa / portal kimliği ve nonce gönderme ve diğer ucunda işleme sahip oldu. .

ne düşünüyorsun? doğru yolda mıyım yoksa bu yaklaşım kusurlu mu?

Teşekkürler!


Bunun için bir çözüm buldunuz mu?
brasofilo

@brasofilo, no ..
Amit

Yanıtlar:


6

Gerçekleşmesi gereken şey, WordPress aracılığıyla istediğiniz dosya türleri için indirme isteklerini proxy'ye almanız gerektiğidir. ".Doc" dosyalarına erişimi kısıtlayacağınızı varsayalım.

1. İstenen dosyayı gösteren bir sorgu değişkeni tanımlayın

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

2. Kısıtlanmış dosyalar için istekleri WordPress'e iletmek için .htaccess dosyasını güncelleyin

Bu, kısıtlamak istediğiniz dosyalara yönelik istekleri yakalar ve yukarıdaki özel sorgu değişkenini kullanarak bunları WordPress'e geri gönderir. Aşağıdaki kuralı RewriteCondsatırların önüne ekleyin .

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

3. Özel sorgu değişkeninde istenen dosya adını yakalayın; ve dosyaya erişimi doğrulayın:

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' );

Not Bu çözüm yalnızca tek site yüklemelerinde kullanılabilir ! Bunun nedeni, WordPress MU'nın zaten yüklenen dosya isteklerini alt sitelerde iletmesidir wp-includes/ms-files.php. WordPress MU için de bir çözüm var, ancak biraz daha dahil.


1
Merhaba, adımda bu işlevi kanca intercept_file_requestveya herhangi bir yerde denir görmüyorum görmüyorum, bu işlev nasıl ateşlenir?
Bobz

İyi bir nokta, bağımlı olmalıyım wp, örneği güncelledim.
Bendoh

3

Son zamanlarda ilgili bir sorun yaşadım ve bu makaleyi yazdım .

İndirmelerin WordPress'in medya kullanımı yoluyla yüklendiğini varsayacağım - aksi takdirde indirme için bir ek kimliğiniz var.

Çözümün ana hatları

  • (Bu anlamda yüklemeler dizin 'güvenli' Make sadece ortalama kullanım .htaccess- örn yoluyla) yüklenenler dizindeki dosyaların doğrudan erişmek için herhangi bir girişimde (ya da bunların bir alt dizini engellemek için mysite.com/wp-content/uploads/conf/2012/09/myconfidentialfile.pdf)
  • Ek kimliği içeren bir indirme bağlantısı oluşturun - bu, kullanıcının eki görüntüleme iznini kontrol etmek için WordPress üzerinden geçmesine izin verir / erişimi engeller.

Uyarılar

  • Bu .htaccessgüvenlik sağlamak için kullanır . Bu kullanılamıyorsa / açık değilse (örneğin nginx sunucuları), fazla güvenlik elde edemezsiniz. Kullanıcının uplods dizinine göz atmasını önleyebilirsiniz . Ancak doğrudan erişim işe yarayacaktır.
  • Yukarıdaki gibi. Mutlak güvenliğe ihtiyacınız varsa, dağıtımda kullanılmamalıdır . Özel kurulumunuz işe yararsa iyi olur - ancak genel olarak garanti edilemez. Bağlantılı makalem kısmen bunu ele almaya çalışıyor.
  • Küçük resimleri kaybedeceksiniz . Bir klasöre veya alt klasöre doğrudan erişimi engellemek, o klasördeki dosyaların küçük resimlerinin görüntülenemeyeceği anlamına gelir. Bağlantılı makalem kısmen bunu ele almaya çalışıyor.

Doğrudan erişimi engelleme

Bunu yüklemeler klasörünüzde (veya bir alt klasörde) yapmak için tüm gizli materyallerin herhangi bir derinlikte, bu klasörün içinde bulunması gerekir). .htaccessAşağıdakileri içeren bir dosya yerleştirin:

Order Deny,Allow
Deny from all

Aşağıda yazı tipi 'müşteri'ye gizli materyal ekleyeceğinizi varsayıyorum. İstemci düzenleme sayfasına yüklenen ortamlar uploads/conf/klasörde saklanır

Korumalı yüklemeler dizinini ayarlama işlevi

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

Gizli materyal yükleme

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

    }

Bunu yaptıktan sonra, yüklenen içerik içeride olmalı uploads/confve tarayıcınızı kullanarak doğrudan erişmeye çalışmamalı.

İçerik İndirme

Bu kolay. İndirme URL'si bir şey olabilir www.site.com?wpse26342download=5(burada 5, yüklenen içeriğin ek kimliğidir). Bunu, eki tanımlamak, geçerli kullanıcının izinlerini kontrol etmek ve indirmelerine izin vermek için kullanırız.

İlk olarak, sorgu değişkenini ayarlayın

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

Şimdi indirmeyi tetiklemek için (belki) bir dinleyici ayarlayın ...

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

Son Yorumlar

Yukarıdaki kod hatalar / sözdizimi hataları içerebilir ve test edilmemiştir ve bunu kullanmak kendi sorumluluğunuzdadır :).

İndirme URL'si, yeniden yazma işlemleri kullanılarak 'önizlenebilir'. Yorumlarda belirtildiği gibi, index.phptaramayı önlemek için korumalı klasörün her altına bir boşluk ekleyebilirsiniz - ancak bu .htaccessyine de kurallar tarafından engellenmelidir .

Daha güvenli bir yöntem, genel dosyaları bir genel dizinin dışında saklamaktır. Veya Amazon S3 gibi harici bir hizmette. İkincisi için, dosyayı Amazon'dan almak için geçerli bir URL oluşturmanız gerekir (özel anahtarınızı kullanarak). Bunların her ikisi de Ana Bilgisayar / üçüncü taraf hizmetinize belirli bir güven düzeyi gerektirir.

'Korumalı indirmeler' sunduklarını öneren herhangi bir eklentiyi kullanma konusunda dikkatli olurum. Yeterince iyi güvenlik sağlayan bir şey bulamadım. Lütfen bu çözümün uyarılarını da dikkate almayın - herhangi bir öneri veya eleştiriyi memnuniyetle karşılarım.


1

Muhtemelen, bu hileyi biliyor olabilirsiniz, Bu kod, kullanıcının oturum açmış olduğu geçerli kullanıcı adını kontrol eder ve eşleşirse, o dosyaya indirme bağlantısı gösterecektir, aksi takdirde hiçbir şey göstermez.

İşte kod:

<?php 
    global $current_user;
    get_currentuserinfo();

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

Ancak, bu dosyalar iyi bir yaklaşım olmayacaktır, dosyalar sunucularda saklandığından, bağlantısı olan herkes bu dosyayı indirebilir.


0

Bu bilgilerin gizli olduğunu varsayıyorum ve bu nedenle, dosya bağlantılarını gizlemenin yanı sıra, kullanıcının URL'yi tahmin etseler bile, URL'yi tahmin edecek olsalar bile, onları tamamen web üzerindeki herkes için erişilemez hale getirmek isteyeceksiniz. dosyalar.

Amazon S3'teki dosyaları güvenli bir şekilde saklayın ve ardından doğru güvenlik kontrollerinin yerine getirilmesi koşuluyla önceden imzalanmış (zaman sınırlı) URL'ler sağlayın (yani, kullanıcı sitenize giriş yapmış ve kim olduklarını söyledikleri).

Bunu yapmayı çok kolaylaştıran çok iyi bir AWS SDK var.

Araştırmanız gereken, WP yükleme arayüzü üzerinden yüklenen dosyaların S3'e nasıl gönderileceği, alternatif olarak kendi yükleyicinizi nasıl oluşturacağınızdır .

Başka bir seçenek de WP e-ticaret koduna bakmak olacaktır . Yazılım dosyalarının güvenli bir şekilde indirilmesini sağlarlar (örn. MP3'ler). Ben dosyaları satın alma başına kullanıcı başına oluşturulan bir şifreleme anahtarı ile karma dönüştürülür inanıyorum. Bu, nasıl çalıştığını görmek için biraz deşifre olurdu, ancak süreç bu eklentiye özgü olmayacak, bu nedenle diğer örnekler (bir yerlerde) mevcut olacak.


0

Bence dosyaların şifrelenmesi yukarıdaki cevap gibi gitmenin bir yolu. Wordpress.org'da indirmeleri korumanıza izin veren bir eklenti var. http://wordpress.org/extend/plugins/download-protect/ Amazon hizmetini veya google sürücüsünü de kullanabilirsiniz. Drop box gibi korumalı indirmeler sunan birçok hizmet de vardır.


müstehcenlik yoluyla güvenlik kötü bir yaklaşımdır. Herkes http isteğini görmek ve url bu şekilde almak mümkün olacak.
mulllhausen
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.