Cara mengamankan direktori di Apache menggunakan sesi PHP

8

Saya memiliki situs yang menggunakan sesi PHP untuk otentikasi. Ada satu direktori yang saya ingin membatasi akses ke yang tidak menggunakan PHP apa pun, itu hanya penuh dengan konten statis.

Saya hanya tidak tahu cara membatasi akses tanpa setiap permintaan melalui skrip PHP. Apakah ada cara agar Apache memeriksa kredensial sesi dan membatasi akses seperti Auth Dasar?

Cogsy
sumber

Jawaban:

5

Kecuali Anda telah mengubah pengaturan, data sesi PHP disimpan dalam variasi pada format serialize () sendiri dalam direktori sementara, dan tidak mudah untuk mendapatkannya tanpa menggunakan PHP itu sendiri.

Sayangnya, Anda tampaknya menginginkan kecepatan file yang dilayani secara statis sambil mengotorisasi setiap permintaan secara dinamis, yang sebenarnya bukan tujuan yang kompatibel. Anda dapat melakukan kompromi dengan memiliki skrip PHP super-ringan yang kemudian Anda gunakan mod_rewrite untuk menulis ulang permintaan ke file di dalamnya, yang melewati hal-hal yang baik-baik saja. Contoh super sederhana:

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

terutama, skrip PHP itu berjalan selamanya, jadi Anda harus me-restart apache jika Anda mengubahnya, saya pikir.

Ini semua belum diuji, tapi itu kira-kira arah yang saya pikir Anda harus masuk.

Referensi:

Aquarion
sumber
Saya suka pendekatan ini, tetapi saya bertanya-tanya apakah skrip RewriteMap memiliki akses ke apa pun selain stdin? Apakah ada konteks cookie dll?
Cogsy
Sebenarnya, ya, Anda benar. Anda dapat mengirimkan nilai cookie menggunakan sintaks variabel lingkungan mod_rewrite (Jadi saya pikir sintaks akan menjadi sesuatu seperti $ {auth: $ 1 $ COOKIES} dan Anda harus membagi garis stdin dengan argumen, dengan metode ini Anda bisa ambil konten sesi
Aquarion
Bagaimana jika Anda menetapkan cookie dengan login dengan id auth konstan (banyak panjang bit), dan Anda memeriksanya dengan akses direktori? Bukan solusi terbaik, tetapi ini bisa berfungsi pada halaman admin ... (Menurut halaman berbagi file, ini tidak berfungsi karena pengguna dapat membagikan cookie ...)
inf3rno
1

Jika Anda memiliki cookie tertentu yang dapat Anda harapkan, maka Anda dapat menguji ketidakhadirannya dengan mod_rewrite dan memberikan 403 Forbidden.

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

Tetapi, jika ada yang tahu bahwa mereka membutuhkan set cookie dengan "LoggedIn = true", maka mereka dapat dengan mudah menyiasati "perlindungan" Anda.

Sesi PHP khusus untuk PHP. Apache tidak memiliki cara untuk menggunakan informasi apa pun dalam sesi PHP. Anda harus memiliki beberapa modul otentikasi khusus untuk melakukan verifikasi sesi.

Apa yang saya lihat kebanyakan orang lakukan adalah memiliki skrip PHP yang menangani penyajian konten statis sehingga mendapat permintaan, memverifikasi sesi, membaca dalam file dan mengirimkan konten dengan informasi MIME yang sesuai.

Rugmonster
sumber
Atau Anda dapat mengubah file .htaccess dengan setiap login, logout, dan gc ...
inf3rno
1

Solusi konvensional untuk masalah itu adalah mengarahkan ulang setiap panggilan pada folder itu ke file php, yang memeriksa izin pengguna, dan setelah itu membaca file, dan mengirimkannya ke aliran output atau mengarahkan pengguna ke "tanpa izin" situs Sebagai contoh...

Cara rumit lain untuk melindungi file Anda adalah membuat token dari session_id, dan garam statis (dan secara optis dari jalur file statis), dan memeriksanya dengan mengakses file. Jadi Anda harus membuat ulang token itu di file htaccess Anda. Saya tidak tahu apakah hanya mungkin dengan .htaccess, atau Anda harus menggunakan php untuk itu. Saya menemukan solusi serupa di sini. Saya 99% yakin, bahwa md5 bukan fitur mod menulis ulang bawaan.

inf3rno
sumber
1
Saya suka ide dari tautan Blogspot untuk digunakan RewriteMapke prg://…sumber daya skrip shell yang melakukan semua enkripsi dan verifikasi MD5 yang sebenarnya. Saya perlu menguji ini dan memastikan itu berfungsi pada pengaturan saya, tetapi sepertinya itu harus bekerja dengan vanilla Apache + modul mod_rewrite.
thirdender
1

Rencana saya untuk menyelesaikan masalah ini adalah sekarang

  1. Redirect permintaan ke PHP

    RewriteEngine on
    RewriteRule ([0-9a-z-_]+)$ authenticateUser.php?&file=$1 [L]
    
  2. Otentikasi pengguna dalam PHP (semua metode otentikasi lainnya mungkin terlalu lemah atau mengharuskan penulisan ke dalam file sepanjang waktu)

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

Rainer Rillke
sumber