Cách bảo mật thư mục trong Apache bằng phiên PHP


8

Tôi có một trang web sử dụng phiên PHP để xác thực. Có một thư mục mà tôi muốn hạn chế quyền truy cập mà không sử dụng bất kỳ PHP nào, nó chỉ chứa đầy nội dung tĩnh.

Tôi chỉ không biết làm thế nào để hạn chế quyền truy cập mà không có yêu cầu nào thông qua tập lệnh PHP. Có cách nào để Apache kiểm tra thông tin đăng nhập phiên và hạn chế quyền truy cập như Basic Auth không?

Câu trả lời:


5

Trừ khi bạn thay đổi cài đặt, dữ liệu phiên PHP được lưu trữ trong một biến thể trên định dạng serialization () của chính nó trong một thư mục tạm thời và không dễ để có được điều đó nếu không sử dụng chính PHP.

thật đáng tiếc, bạn dường như muốn tốc độ của các tệp được phân phát tĩnh trong khi ủy quyền động cho từng yêu cầu, những mục tiêu không thực sự tương thích. Bạn có thể buộc tội bằng cách có một tập lệnh PHP siêu nhẹ mà sau đó bạn sử dụng mod_rewrite để viết lại các yêu cầu vào các tệp trong đó, qua đó mọi thứ đều ổn. Ví dụ siêu đơn giản:

.htaccess:

 RewriteEngine On
 RewriteMap auth prg:auth.php
 RewriteRule (.*) ${auth:$1}

auth.php:

#!/usr/bin/php
 <?PHP
 set_time_limit(0); # This program needs to run forever. 
 $stdin = fopen("php://stdin","r"); # Keeps reading from standard in
 while (true) {
        $line = trim(fgets($stdin));
        if (isset($_SESSION['USER_LOGGED_IN'])) {
                echo $line\n";
        } else {
                echo "authfailed.html\n";
        }
 }

Đáng chú ý, tập lệnh PHP đó đang chạy mãi mãi, vì vậy tôi sẽ cần phải khởi động lại apache nếu bạn thay đổi nó, tôi nghĩ vậy.

Đây là tất cả chưa được kiểm tra, nhưng đó gần như là hướng tôi nghĩ bạn phải đi.

Người giới thiệu:


Tôi thích cách tiếp cận này, nhưng tôi tự hỏi liệu một tập lệnh RewriteMap có quyền truy cập vào bất cứ điều gì khác ngoài stdin không? Nó có bối cảnh của cookie vv?
Cogsy

Trên thực tế, vâng, bạn có một điểm. Bạn có thể gửi giá trị của cookie bằng cú pháp biến môi trường của mod_rewrite (Vì vậy, tôi nghĩ rằng cú pháp sẽ trở thành một cái gì đó như $ {auth: $ 1 $ COOKIES} và bạn phải chia dòng stdin theo các đối số, bằng phương thức này, bạn có thể chọn nội dung phiên.
Aquarion

Điều gì sẽ xảy ra nếu bạn đặt cookie bằng cách đăng nhập với id xác thực không đổi (nhiều độ dài bit) và bạn kiểm tra nó bằng cách truy cập thư mục? Không phải là giải pháp tốt nhất, nhưng nó có thể hoạt động trên các trang quản trị ... (Theo trang chia sẻ tệp, nó không hoạt động vì người dùng có thể chia sẻ cookie ...)
inf3rno

1

Nếu bạn có một cookie cụ thể mà bạn có thể mong đợi, thì bạn có thể kiểm tra sự vắng mặt của nó với mod_rewrite và đưa ra 403 Forbidden.

RewriteCond %{HTTP_COOKIE} !LoggedIn=true
RewriteRule .* - [F,L]

Nhưng, nếu bất cứ ai biết rằng họ cần một bộ cookie với "LoggedIn = true", thì họ có thể dễ dàng nhận được "sự bảo vệ" của bạn.

Một phiên PHP dành riêng cho PHP. Apache không có cách nào sử dụng bất kỳ thông tin nào trong phiên PHP. Bạn sẽ phải có một số mô-đun xác thực đặc biệt để thực hiện xác minh phiên.

Những gì tôi thấy hầu hết mọi người làm là có một tập lệnh PHP xử lý việc cung cấp nội dung tĩnh trong đó nó nhận được yêu cầu, xác minh phiên, đọc trong tệp và gửi nội dung ra với thông tin MIME phù hợp.


Hoặc bạn có thể sửa đổi tệp .htaccess bằng mỗi lần đăng nhập, đăng xuất và gc ...
inf3rno

1

Giải pháp thông thường cho vấn đề đó là chuyển hướng mọi cuộc gọi trên thư mục đó sang tệp php, kiểm tra quyền của người dùng và sau đó đọc tệp đó và gửi nó đến luồng đầu ra hoặc chuyển hướng người dùng đến "không được phép" Địa điểm. Ví dụ...

Một cách khó khác để bảo vệ các tệp của bạn là tạo mã thông báo từ session_id và muối tĩnh (và tối ưu từ đường dẫn tệp tĩnh) và kiểm tra nó bằng cách truy cập tệp. Vì vậy, bạn phải tạo lại mã thông báo đó trong tệp htaccess của bạn. Tôi không biết liệu chỉ có thể với .htaccess hay bạn phải sử dụng php cho việc đó. Tôi tìm thấy một giải pháp tương tự ở đây. Tôi tin chắc 99% rằng md5 không phải là tính năng viết lại mod tích hợp.


1
Tôi thích ý tưởng từ liên kết Blogspot để sử dụng RewriteMapcho prg://…tài nguyên tập lệnh shell thực hiện tất cả mã hóa và xác minh MD5 thực tế. Tôi cần kiểm tra điều này và chắc chắn rằng nó hoạt động trên thiết lập của tôi, nhưng có vẻ như nó sẽ hoạt động với vanilla Apache + mô-đun mod_rewrite.
thứ ba

1

Kế hoạch của tôi để giải quyết vấn đề này bây giờ là

  1. Chuyển hướng yêu cầu đến PHP

    RewriteEngine on
    RewriteRule ([0-9a-z-_]+)$ authenticateUser.php?&file=$1 [L]
    
  2. Xác thực người dùng bằng PHP (tất cả các phương thức xác thực khác có thể quá yếu hoặc yêu cầu ghi vào tệp mọi lúc)

    if ( User::hasPermission() && isSane( $filePath ) ) {
        // 
        header( 'X-Sendfile: ' . $filePath );
    }
    
  3. Sử dụng Apache mod_xsendfile( docs , github )


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.