PHP: ¿comprueba si un archivo se carga directamente en lugar de incluir?

¿Hay alguna manera de evitar que un usuario vea un archivo pero aún lo use como incluido en otro archivo en PHP ?

Si utiliza

define('APP_RAN'); 

en el archivo que lo incluye y luego poner

 if(!defined('APP_RAN')){ die(); } 

o alternativamente

 defined('APP_RAN') or die(); 

(que es más fácil de leer)

en los archivos incluidos, moriría si accede a ellos directamente.


Sin embargo, probablemente sea mejor colocar todos sus archivos incluidos encima de su DocumentRoot.

Por ejemplo, si su página de índice está en

 /my/server/domain/public_html 

Deberías poner los archivos incluidos en

 /my/server/domain/ 

No use ningún código global en sus archivos, solo funciones y métodos. Entonces no habrá necesidad de preocuparse por el uso directo vs.

Mi propuesta:

 \r\n\r\n404 Not Found\r\n\r\n

Not Found

\r\n

The requested URL " . $_SERVER['SCRIPT_NAME'] . " was not found on this server.

\r\n"); } else { // your code } ?>

1.) comprueba si se llama directamente si no arroja un error

2.) emite una página de error estándar de apache 404 (compárela con la página 404 original o simplemente incluya esa página) para agregar seguridad a través de la oscuridad

3.) La parte else evita la ejecución parcial mientras el archivo se carga al entorno en vivo (PHP no espera el “?>”). No lo necesita si su archivo incluido contiene solo una función / una clase.

Simplemente almacene el archivo fuera de su raíz web.

 if (!defined('FLAG_FROM_A_PARENT')) // Works in all scenarios but I personally dislike this if (__FILE__ == get_included_files()[0]) // Doesn't work with PHP prepend unless calling [1] instead. if (__FILE__ == $_SERVER['DOCUMENT_ROOT'] . $_SERVER['SCRIPT_FILENAME']) // May break on Windows due to mixed DIRECTORY_SEPARATOR if (basename(__FILE__) == basename($_SERVER['SCRIPT_FILENAME'])) // Doesn't work with files with the same basename but different paths if (realpath(__FILE__) == realpath($_SERVER['DOCUMENT_ROOT'].$_SERVER['SCRIPT_NAME'])) // Seems to do the trick 
 if (__FILE__ == $_SERVER['DOCUMENT_ROOT'].$_SERVER['PHP_SELF']){ die("Direct access forbidden"); } 

Funciona independientemente de dónde se encuentre. (Saludos a @ col-sharpnel por señalar una solución incompleta pero buena).

Está la función get_included_files . Podrías usarlo así:

 if ( empty(get_included_files()) ) die("Direct access forbidden"); 

En Apache, esto es fácil: agregue una directiva en su .htaccess para evitar el acceso a ella desde un navegador web. Esto no se aplica a PHP includes , y es una buena práctica esconder varios archivos del acceso al navegador (aunque generalmente intentará juntar todos los archivos no accesibles en un solo directorio).

  deny from all  

En un servidor web diferente, puede ocultar el archivo de la raíz de su documento, pero en algunos casos (como si sus scripts están open_basedir ‘d de manera estricta), no funcionará.

 if($argv[0] == basename(__FILE__)) include_once('/path/to/file.php'); 

Verifique cuántos archivos incluidos hay allí …

 if(count(get_required_files()) < 2) { die(); } 

O cuántos mínimos debería haber en lugar de 2

Si desea evitar que se muestre cuando no esté incluido, aquí hay una manera más automática.

 if (basename(__FILE__) == basename($_SERVER['PHP_SELF'])) header("HTTP/1.0 404 Not Found"); 

De esta forma, seguirá funcionando si terminas cambiando el nombre del archivo o algo así.

Hay muchas buenas respuestas en este hilo: esta es una que aún no se ha mencionado.

Puede someincludedfile.phpi un nombre a los archivos PHP incluidos con una i en la extensión, por ejemplo, someincludedfile.phpi y luego configurar Apache para que no sirva archivos phpi . Voila.

Contras:

  • (!) altamente dependiente de la configuración de Apache (por lo que eres vulnerable si alguien descuida esa línea) – y en ese caso, el navegador podría ver toda la secuencia de comandos PHP en texto plano, ya que no se pasará a PHP (¡muy mal!)
  • puede ser molesto cambiar el nombre de tus archivos incluidos

Pros:

  • deja en claro qué archivos deben incluirse y cuáles no están en su código
  • no tiene que mover su jerarquía de archivos alrededor

Personalmente, prefiero simplemente mover los archivos a un directorio fuera de la raíz del documento, pero si tiene una aplicación heredada grande, esto podría ser más rápido de cambiar.

Enlace: http://www.ducea.com/2006/07/21/apache-tips-tricks-deny-access-to-certain-file-types/

Iré por la solución de Chacha102 .

Además, como su título de pregunta dice « cómo verificar », también puede hacer esto sin tener que definir una variable mediante el uso de

 // secret.php is the name of this file. if($_SERVER["SCRIPT_FILENAME"]=='secret.php') die(); 

Solo para ampliar las soluciones con las variables $_SERVER , a continuación se muestra un pequeño archivo .php, y en los comentarios hay una copia de una prueba de bash que hice en Ubuntu; el punto es que estas variables pueden cambiar un poco dependiendo del tipo de acceso, y si se usan enlaces simbólicos ( nótese también que en el código de abajo tengo que escapar del ‘ ?\> ‘ en la statement del eco, sino la syntax saltos de color; elimine la barra diagonal inversa si prueba el código ):

 ' > varcheckincl.php # ... and in a separate terminal, run # php (>5.4) cli server at same (/tmp/ptest) location: ptest$ php-5.4.10 -S localhost:8000 # back to first terminal, the test - and output: ptest$ php varcheck.php DOCUMENT_ROOT.PHP_SELF: varcheck.php SCRIPT_FILENAME: varcheck.php __FILE__: /real/path/to/varcheck.php PHP_SAPI: cli ptest$ php -r 'require_once "varcheck.php";' DOCUMENT_ROOT.PHP_SELF: - SCRIPT_FILENAME: __FILE__: /real/path/to/varcheck.php PHP_SAPI: cli ptest$ php varcheckincl.php DOCUMENT_ROOT.PHP_SELF: varcheckincl.php SCRIPT_FILENAME: varcheckincl.php __FILE__: /real/path/to/varcheck.php PHP_SAPI: cli ptest$ wget http://localhost:8000/varcheck.php -q -O - DOCUMENT_ROOT.PHP_SELF: /tmp/ptest/varcheck.php SCRIPT_FILENAME: /tmp/ptest/varcheck.php __FILE__: /real/path/to/varcheck.php PHP_SAPI: cli-server ptest$ wget http://localhost:8000/varcheckincl.php -q -O - DOCUMENT_ROOT.PHP_SELF: /tmp/ptest/varcheckincl.php SCRIPT_FILENAME: /tmp/ptest/varcheckincl.php __FILE__: /real/path/to/varcheck.php PHP_SAPI: cli-server */ ?> 

Debes usar una extensión PHP de codificador y cargador:

Comercial

  • codificador de ionCube PHP
  • Zend Guard
  • phpSHIELD
  • SourceGuardian

Gratis