Làm cách nào để bảo vệ tải lên, nếu người dùng không đăng nhập?


79

Tôi sử dụng wordpress cho một trang web riêng tư nơi người dùng tải lên các tập tin. Tôi sử dụng "WordPress riêng tư" để ngăn truy cập vào trang web nếu người dùng chưa đăng nhập.

Tôi muốn làm tương tự với các tệp được tải lên trong thư mục tải lên.

Vì vậy, nếu người dùng không đăng nhập, họ sẽ không thể truy cập vào: https://xxxxxxx.com/wp-content/uploads/2011/12/xxxxxxx.pdf nếu họ cố truy cập nhưng họ không đăng nhập được chuyển hướng đến trang đăng nhập chẳng hạn.

Tôi đã tìm thấy một plugin có tên là các tệp riêng tư nhưng lần cập nhật gần đây nhất là vào năm 2009 và nó dường như không hoạt động trên wordpress của tôi.

Bất cứ ai biết phương pháp nào? Phương pháp hotlinking sẽ đủ để bảo vệ điều này?

Tôi cũng tìm thấy phương pháp này:

# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_URI} ^.*uploads/private/.*
RewriteCond %{HTTP_COOKIE} !^.*wordpress_logged_in.*$ [NC]
RewriteRule . /index.php [R,L]
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress

Nhưng sau đó bất kỳ người dùng sao chép cookie có thể vượt qua điều này phải không? Trân trọng


1
Bất kỳ lý do tại sao bạn không thể sử dụng một thư mục tải lên khác nhau, như một bên ngoài của trang web gốc?
onetrickpony

Không thực sự nhưng tôi đã có hàng tấn tệp được đính kèm vào bài viết trong thư mục đó, tôi không ngại di chuyển khắp nơi nếu tôi có thể tìm ra giải pháp thích hợp
chifliiiii

Câu trả lời:


86

Chỉ kiểm tra nếu cookie tồn tại, không có nhiều sự bảo vệ nghiêm ngặt.

Để có được sự bảo vệ mạnh mẽ hơn, bạn có thể chuyển hoặc "proxy" tất cả các yêu cầu vào thư mục đã tải lên (ví dụ uploadstrong ví dụ sau) thông qua tập lệnh php:

RewriteCond %{REQUEST_FILENAME} -s
RewriteRule ^wp-content/uploads/(.*)$ dl-file.php?file=$1 [QSA,L]

Tất cả các yêu cầu đối với các tệp được tải lên (bao gồm hình ảnh trong bài đăng) sẽ được gửi tới dl-file.phpđó sau đó có thể xác minh xem người dùng có đăng nhập hay không.

Nếu người dùng chưa đăng nhập, biểu mẫu đăng nhập trang web của bạn sẽ được hiển thị. Sau khi người dùng đăng nhập, cô ấy sẽ được chuyển hướng trở lại tập tin và có thể tải xuống ngay bây giờ.

Gương mẫudl-file.php .

Một cái gì đó tương tự có thể được tìm thấy trong \wp-includes\ms-files.phpcài đặt wordpress của bạn, nhưng cái đó là dành cho nhiều trang và kiểm tra đăng nhập và chuyển hướng.

Tùy thuộc vào lượng lưu lượng truy cập bạn có, có thể là khôn ngoan để tích hợp tốt hơn với máy chủ của bạn, ví dụ: X-Accel-Redirecthoặc X-Sendfilecác tiêu đề.


1
Làm thế nào để bạn điều chỉnh dl-file.php nếu tôi muốn lưu trữ các tệp vào thư mục con như wp-content / uploads / safe?

Đây là giải pháp thực sự an toàn duy nhất. Bất cứ điều gì khác bạn có thể tìm thấy trên web, như kiểm tra tiêu đề người giới thiệu, kiểm tra cookie, không cho phép danh sách thư mục, là một nửa số đo vì bạn có thể dễ dàng giả mạo các tiêu đề yêu cầu HTTP để có được xung quanh nó.
Luke

Các bạn..có vẻ như là giải pháp hoàn hảo cho tôi .... vấn đề là, tôi đang sử dụng PDFJS từ Mozilla để truy cập một số tệp PDF từ thư mục tải lên và PDFJS sử dụng các tiêu đề nội dung một phần để chỉ lấy các trang mà nó quan tâm .. Vì vậy, giải pháp này là không có người đi cho tôi. bất kỳ đề xuất??
Otto Nrebella

@OttoNrebella: Các yêu cầu Nội dung một phần đối với PHP đã được giải quyết cho đến ngày hôm nay, điều này độc lập với câu hỏi wordpress này. Nguyên vẹn, câu hỏi đã khá cũ rồi: Tải xuống có thể khôi phục khi sử dụng PHP để gửi tệp?
hakre

@hakre Điều gì về một số hình ảnh được sử dụng trên trang nhất của trang web và bất kỳ người dùng nào đến thăm trang web? Nó báo lỗi 404 nếu tôi không đăng nhập.
Dhaval Panchal

14

Bạn cũng có thể viết một plugin bằng cách sử dụng inithook và giá trị get $_GET[ 'file' ];. Nếu người dùng có giá trị get này, hãy nhảy vào một chức năng để kiểm tra quyền truy cập trên các tệp: Ví dụ: với hộp kiểm trong Hộp Meta.

add_action( 'init', 'fb_init' );
function fb_init() {
    // this in a function for init-hook
    if ( '' != $_GET[ 'file' ] ) {
        fb_get_file( $_GET[ 'file' ] );
    }
}

hàm get_file ()

function fb_get_file( $file ) {

    $upload     = wp_upload_dir();
    $the_file   = $file; 
    $file       = $upload[ 'basedir' ] . '/' . $file;
    if ( !is_file( $file ) ) {
        status_header( 404 );
        die( '404 &#8212; File not found.' );
    }
    else {
        $image = get_posts( array( 'post_type' => 'attachment', 'meta_query' => array( array( 'key' => '_wp_attached_file', 'value' => $the_file ) ) ) );
        if ( 0 < count( $image ) && 0 < $image[0] -> post_parent ) { // attachment found and parent available
            if ( post_password_required( $image[0] -> post_parent ) ) { // password for the post is not available
                wp_die( get_the_password_form() );// show the password form 
            }
            $status = get_post_meta( $image[0] -> post_parent, '_inpsyde_protect_content', true );

            if ( 1 == $status &&  !is_user_logged_in() ) {
                wp_redirect( wp_login_url( $upload[ 'baseurl' ] . '/' . $the_file ) );
                die();
            }
        }
        else {
            // not a normal attachment check for thumbnail
            $filename   = pathinfo( $the_file );
            $images     = get_posts( array( 'post_type' => 'attachment', 'meta_query' => array( array( 'key' => '_wp_attachment_metadata', 'compare' => 'LIKE', 'value' => $filename[ 'filename' ] . '.' . $filename[ 'extension' ] ) ) ) );
            if ( 0 < count( $images ) ) {
                foreach ( $images as $SINGLEimage ) {
                    $meta = wp_get_attachment_metadata( $SINGLEimage -> ID );
                    if ( 0 < count( $meta[ 'sizes' ] ) ) {
                        $filepath   = pathinfo( $meta[ 'file' ] );
                        if ( $filepath[ 'dirname' ] == $filename[ 'dirname' ] ) {// current path of the thumbnail
                            foreach ( $meta[ 'sizes' ] as $SINGLEsize ) {
                                if ( $filename[ 'filename' ] . '.' . $filename[ 'extension' ] == $SINGLEsize[ 'file' ] ) {
                                    if ( post_password_required( $SINGLEimage -> post_parent ) ) { // password for the post is not available
                                        wp_die( get_the_password_form() );// show the password form 
                                    }
                                    die('dD');
                                    $status = get_post_meta( $SINGLEimage -> post_parent, '_inpsyde_protect_content', true );

                                    if ( 1 == $status &&  !is_user_logged_in() ) {
                                        wp_redirect( wp_login_url( $upload[ 'baseurl' ] . '/' . $the_file ) );
                                        die();
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    $mime       = wp_check_filetype( $file );

    if( false === $mime[ 'type' ] && function_exists( 'mime_content_type' ) )
        $mime[ 'type' ] = mime_content_type( $file );

    if( $mime[ 'type' ] )
        $mimetype = $mime[ 'type' ];
    else
        $mimetype = 'image/' . substr( $file, strrpos( $file, '.' ) + 1 );

    header( 'Content-type: ' . $mimetype ); // always send this
    if ( false === strpos( $_SERVER['SERVER_SOFTWARE'], 'Microsoft-IIS' ) )
        header( 'Content-Length: ' . filesize( $file ) );

    $last_modified = gmdate( 'D, d M Y H:i:s', filemtime( $file ) );
    $etag = '"' . md5( $last_modified ) . '"';
    header( "Last-Modified: $last_modified GMT" );
    header( 'ETag: ' . $etag );
    header( 'Expires: ' . gmdate( 'D, d M Y H:i:s', time() + 100000000 ) . ' GMT' );

    // Support for Conditional GET
    $client_etag = isset( $_SERVER['HTTP_IF_NONE_MATCH'] ) ? stripslashes( $_SERVER['HTTP_IF_NONE_MATCH'] ) : false;

    if( ! isset( $_SERVER['HTTP_IF_MODIFIED_SINCE'] ) )
        $_SERVER['HTTP_IF_MODIFIED_SINCE'] = false;

    $client_last_modified = trim( $_SERVER['HTTP_IF_MODIFIED_SINCE'] );
    // If string is empty, return 0. If not, attempt to parse into a timestamp
    $client_modified_timestamp = $client_last_modified ? strtotime( $client_last_modified ) : 0;

    // Make a timestamp for our most recent modification...
    $modified_timestamp = strtotime($last_modified);

    if ( ( $client_last_modified && $client_etag )
        ? ( ( $client_modified_timestamp >= $modified_timestamp) && ( $client_etag == $etag ) )
        : ( ( $client_modified_timestamp >= $modified_timestamp) || ( $client_etag == $etag ) )
        ) {
        status_header( 304 );
        exit;
    }

    // If we made it this far, just serve the file
    readfile( $file );
    die();
}

Bạn cũng có thể thêm URL tùy chỉnh cho các tệp qua hook generate_rewrite_rules

add_filter( 'generate_rewrite_rules', 'fb_generate_rewrite_rules' );

function fb_generate_rewrite_rules( $wprewrite ) {
        $upload = wp_upload_dir();
        $path = str_replace( site_url( '/' ), '', $upload[ 'baseurl' ] );
        $wprewrite -> non_wp_rules = array( $path . '/(.*)' => 'index.php?file=$1' );
        return $wprewrite;
}

Điều này đã không làm việc về phía tôi bất cứ ai biết tại sao? Tôi sao chép chính xác.
Ryan S

Bảo vệ chỉ làm việc pdf. các phần mở rộng tệp khác không hoạt động như: doc, docx, jpg và vv ...
Patel

1

Nếu bạn muốn một cách tiếp cận dựa trên plugin để giải quyết vấn đề này, đây là một giải pháp hợp lý tốt mà tôi đã tìm thấy (cuối cùng):

  1. Cài đặt plugin 'Tải xuống màn hình', có sẵn tại:
    https://wordpress.org/plugins/doad-monitor/
  2. Trong Bảng điều khiển WordPress, đi tới mục trình đơn 'Tải xuống' mới và thêm một 'Tải xuống' mới, như được mô tả trên trang web tài liệu plugin tại đây: https://www.doad-monitor.com/kb/adding-doads/ . Lưu ý mã ngắn 'Tải xuống' được cung cấp cho bạn (ví dụ: lưu vào Notepad). Lưu ý rằng tệp được lưu trong/wp-content/uploads/dlm_uploads/
  3. Trong metabox của 'Tùy chọn tải xuống', chỉ định 'Chỉ thành viên' (như được ghi lại ở đây https://www.doad-monitor.com/kb/doad-options/ ) và nhấp vào 'Xuất bản'.
  4. Trên trang mà bạn muốn các Thành viên chỉ tải xuống xuất hiện, hãy thêm mã ngắn mà bạn đã ghi chú ở bước # 2 và 'Xuất bản / Cập nhật' trang, như được ghi lại ở đây: https://www.doad-monitor.com / kb / shortcode-download / . Bạn có thể thay đổi mẫu liên kết tải xuống như được mô tả tại đây https://www.doad-monitor.com/kb/content-tem mẫu / hoặc tạo mẫu của riêng bạn (ví dụ: để xóa 'số đếm' của Tải xuống)
  5. Duyệt đến trang của bạn, bạn sẽ thấy một liên kết tải xuống (nhưng không tiết lộ URL cho tệp tải xuống). Nếu bạn duyệt đến cùng một trang trong cửa sổ trình duyệt mới (hoặc cửa sổ Ẩn danh), bạn sẽ thấy rằng tải xuống không còn hoạt động.

Điều này có nghĩa là bất kỳ ai không đăng nhập đều không thể tải xuống tệp hoặc xem URL thực vào tệp. Nếu trong trường hợp ai đó trái phép tìm ra URL vào tệp, thì plugin cũng ngăn người dùng duyệt đến URL tệp thực bằng cách chặn quyền truy cập vào /wp-content/uploads/dlm_uploads/thư mục.

Phần thưởng: nếu bạn làm điều này cho một trang web nơi bạn cần người dùng chỉ có thể đăng nhập với tư cách là 'Thành viên' (nhưng không có quyền WordPress như chỉnh sửa trang hoặc là Quản trị viên), hãy cài đặt plugin 'Thành viên' https: // wordpress .org / plugin / thành viên / , tạo một vai trò người dùng mới gọi là 'Thành viên' và cung cấp cho nó khả năng duy nhất là 'đọc', tạo Người dùng mới trong WordPress và đảm bảo cung cấp cho họ vai trò 'Thành viên'.

Nếu bạn muốn bảo vệ nội dung của các trang, plugin 'Thành viên' cung cấp một số tùy chọn hoặc có các plugin khác ngoài đó. Nếu bạn muốn chủ đề trang đăng nhập để Thành viên trông đẹp hơn biểu mẫu đăng nhập mặc định của WordPress, hãy sử dụng một cái gì đó như 'Theme My Đăng nhập': https://wordpress.org/plugins/theme-my-login/


Quá trình tôi đã mô tả ở trên cũng được giải thích ở đây, mặc dù như bạn có thể thấy nó không nhất thiết chỉ là các tệp PDF: thedigitalcrowd.com/website-development/wordpress/iêu
Matty J
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.