PHP: Compruebe 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?

Author: Peter Mortensen, 2010-03-07

15 answers

Si usa

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 accedes a ellos directamente.


Probablemente sería mejor poner todos sus archivos incluidos por encima de su DocumentRoot sin embargo.

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

/my/server/domain/public_html

Debe poner los archivos incluidos en

/my/server/domain/
 50
Author: Tyler Carter,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-09-17 15:50:52

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

 14
Author: user187291,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-11-03 17:08:25

Mi propuesta:

<?php
if (__FILE__ == $_SERVER['SCRIPT_FILENAME']) {
    header($_SERVER['SERVER_PROTOCOL'] . ' 404 Not Found');
    exit("<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\r\n<html><head>\r\n<title>404 Not Found</title>\r\n</head><body>\r\n<h1>Not Found</h1>\r\n<p>The requested URL " . $_SERVER['SCRIPT_NAME'] . " was not found on this server.</p>\r\n</body></html>");
}
else {
   // your code
}
?>

1.) comprueba si se llama directamente de lo contrario lanza un error

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

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

 13
Author: mgutt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-10-20 17:59:09

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

 9
Author: Erik,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-03-07 16:46:58
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
 7
Author: tim,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-02-16 19:38:27
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.)

 6
Author: moebius_eye,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-05-18 12:48:49

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

if ( empty(get_included_files()) ) die("Direct access forbidden");
 4
Author: moebius_eye,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-12-27 13:58:37

Bajo Apache, esto es fácil: agregue una directiva <Files> en su .htaccess para impedir el acceso desde un navegador web. Esto no se aplica a PHP includes, y es una buena práctica ocultar varios archivos del acceso del navegador (aunque generalmente intentará poner todos los archivos no accesibles juntos en un solo directorio).

<Files="myprivatefile.php">
    deny from all
</Files>

Bajo un servidor web diferente, puede ocultar el archivo fuera de la raíz de su documento, pero en algunos casos (como si sus scripts son open_basedir'd de una manera estricta), no lo hará trabajo.

 2
Author: zneak,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-03-07 16:47:09
if($argv[0] == basename(__FILE__))
    include_once('/path/to/file.php');
 2
Author: mechimdi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-05-21 07:08:51

Compruebe cuántos archivos incluidos hay...

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

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

 2
Author: HelpNeeder,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-10-30 04:17:19

Si desea evitar que se muestre cuando no se incluye, aquí hay una forma más automatizada.

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

De esta manera seguirá funcionando si termina cambiando el nombre del archivo o algo así.

 1
Author: ZeekDaGeek,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-06-08 10:01:18

Hay muchas buenas respuestas en este hilo - aquí hay una que aún no se ha mencionado.

Puede nombrar sus archivos PHP incluidos con un 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) and y en tal caso, el navegador podría llegar a ver todo el script PHP en texto plano, ya que no lo hará pasar a PHP (realmente malo!)
  • puede ser molesto cambiar el nombre de los archivos incluidos

Ventajas:

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

Personalmente, preferiría simplemente mover 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 /

 1
Author: Chris Middleton,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-12-11 03:09:33

Yo iría por la solución de Chacha102.

Además, como el título de su pregunta dice " cómo comprobar", también puede hacer esto sin tener que definir una variable usando

// secret.php is the name of this file.
if($_SERVER["SCRIPT_FILENAME"]=='secret.php') die();
 0
Author: Daan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:34:09

Solo para ampliar las soluciones con $_SERVER variables-a continuación es un pequeño.php, y en los comentarios es una copia de una prueba bash que hice en Ubuntu; el punto es, que estas variables pueden cambiar un poco dependiendo del tipo de acceso, y si se utilizan enlaces simbólicos (tenga en cuenta también, en el código de abajo tengo que escapar de la '?\> ' en la instrucción echo, de lo contrario el color de la sintaxis se rompe; elimine la barra invertida si):

<?php

function report($label, $value) {
  printf ("%23s: %s\n", $label, $value);
}

report("DOCUMENT_ROOT.PHP_SELF",  $_SERVER['DOCUMENT_ROOT'].$_SERVER['PHP_SELF'] );
report("SCRIPT_FILENAME",         $_SERVER['SCRIPT_FILENAME'] );
report("__FILE__",                __FILE__ );
report("PHP_SAPI",                PHP_SAPI );

/*
# the test (bash):

home~$ mkdir /tmp/ptest
home~$ cd /tmp/ptest/
ptest$ ln -s /real/path/to/varcheck.php .
ptest$ echo '<? require_once "varcheck.php"; ?\>' > 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
*/
?>
 0
Author: sdaau,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-11-24 16:01:23

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

Comercial

Libre

 -7
Author: clyfe,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-07-04 19:38:00