Como servir documentos de fora da raiz da web usando o PHP?

Por segurança, estou movendo uma coleção de arquivos e pastas para fora da raiz da Web em um servidor apache, e então vou atendê-los dinamicamente. Isso parece melhor do que 2 alternativas:

  1. Deixe-os acessíveis à Internet e apenas crie uma página de login do php que seja adicionada a todos os arquivos. O problema é que eles não são todos os arquivos php, e não consigo prepender um arquivo de login php para um pdf, imagem, etc.
  2. Deixe-os acessíveis à Internet e use a autenticação HTTP para restringir o access ao diretório inteiro. Mas isso apresenta problemas, incluindo senhas de texto claro, nenhum método de logout gracioso, etc.

Então, estamos de volta para tê-los fora da raiz da Web, mas atendendo dinamicamente. O problema que estou tendo é, uma vez que são todos tipos de arquivos diferentes (scripts php, txt, pdf, jpg). Não tenho certeza se devo usar include() ou readfile() . E me deparo com o envio dos headers apropriados para cada arquivo para que o navegador os exiba corretamente.

Estou faltando com outra solução mágica? Existe uma estrutura que me eludiu que lida com o serviço de arquivos dynamics e headers?

(FYI estou executando Linux, Apache e PHP em um host compartilhado)

   

Eu acho que algo assim funcionaria:

 < ?php $path = realpath(dirname(__FILE__) . '/../my_files/' . $_GET['file']); $parts = explode('/', pathinfo($path, PATHINFO_DIRNAME)); if (end($parts) !== 'my_files') { // LFI attempt exit(); } if (!is_file($path)) { // file does not exist exit(); } header('Content-Type: ' . mime_content_type($path)); header('Content-Length: ' . filesize($path)); readfile($path); 

A maneira mais simples em que posso pensar é usando os arquivos .htaccess. Supondo que seu servidor web seja o Apache, é claro.

Você pode negar o access a qualquer tipo de arquivos e / ou diretórios para todos e permitir apenas o localhost. Desta forma, eles não serão atendidos ao público, mesmo que eles conheçam o caminho / URL correto, mas o servidor e o PHP poderão atendê-los.

Para diferentes servidores web, deve haver soluções equivalentes. Além disso, você sempre pode mudar para o Apache 🙂