php include include-guards

Evite el acceso directo a un archivo de inclusión php



include include-guards (30)

1: Comprobación del recuento de archivos incluidos

if( count(get_included_files()) == ((version_compare(PHP_VERSION, ''5.0.0'', ''>=''))?1:0) ) { exit(''Restricted Access''); }

Lógica: PHP sale si no se cumple el conteo mínimo de inclusión. Tenga en cuenta que antes de PHP5, la página base no se considera una inclusión.

2: Definir y verificar una constante global

// In the base page (directly accessed): define(''_DEFVAR'', 1); // In the include files (where direct access isn''t permitted): defined(''_DEFVAR'') or exit(''Restricted Access'');

Lógica: si la constante no está definida, entonces la ejecución no comenzó desde la página base, y PHP dejaría de ejecutarse.

3: autorización de dirección remota

// Call the include from the base page(directly accessed): $includeData = file_get_contents("http://127.0.0.1/component.php?auth=token"); // In the include files (where direct access isn''t permitted): $src = $_SERVER[''REMOTE_ADDR'']; // Get the source address $auth = authoriseIP($src); // Authorisation algorithm if( !$auth ) exit(''Restricted Access'');

El inconveniente de este método es la ejecución aislada, a menos que se proporcione un token de sesión con la solicitud interna. Verifique a través de la dirección de bucle invertido en el caso de una configuración de servidor único, o una lista blanca de direcciones para una infraestructura de servidor multiservidor o equilibrado de carga.

4: autorización del token

Similar al método anterior, uno puede usar GET o POST para pasar un token de autorización al archivo de inclusión:

if($key!="serv97602"){header("Location: ".$dart);exit();}

Un método muy complicado, pero también quizás el más seguro y versátil al mismo tiempo, cuando se usa de la manera correcta.

5: configuración específica del servidor web

La mayoría de los servidores le permiten asignar permisos para archivos o directorios individuales. Puede colocar todas sus inclusiones en dichos directorios restringidos y tener el servidor configurado para denegarlos.

Por ejemplo, en APACHE, la configuración se almacena en el archivo .htaccess . Tutorial here .

Sin embargo, tenga en cuenta que no recomiendo las configuraciones específicas del servidor porque son malas para la portabilidad en diferentes servidores web. En los casos en que el algoritmo de denegación es complejo o la lista de directorios denegados es bastante grande, podría hacer que las sesiones de reconfiguración sean más bien horripilantes. Al final, es mejor manejar esto en código.

6: Colocar incluye en un directorio seguro FUERA de la raíz del sitio

Menos preferido debido a las limitaciones de acceso en los entornos de servidor, pero un método bastante poderoso si tiene acceso al sistema de archivos.

//Your secure dir path based on server file-system $secure_dir=dirname($_SERVER[''DOCUMENT_ROOT'']).DIRECTORY_SEPARATOR."secure".DIRECTORY_SEPARATOR; include($secure_dir."securepage.php");

Lógica:

  • El usuario no puede solicitar ningún archivo fuera de la carpeta htdocs ya que los enlaces estarían fuera del alcance del sistema de direcciones del sitio web.
  • El servidor php accede al sistema de archivos de forma nativa y, por lo tanto, puede acceder a los archivos en una computadora de la misma manera que un programa normal con los privilegios necesarios.
  • Al colocar los archivos de inclusión en este directorio, puede asegurarse de que el servidor de php acceda a ellos, mientras que el hotlinking se deniega al usuario.
  • Incluso si la configuración de acceso del sistema de archivos del servidor web no se realizó correctamente, este método evitaría que esos archivos se vuelvan públicos accidentalmente.

Disculpe mis pobres convenciones de codificación. No soy un desarrollador experimentado de PHP. Mejores métodos tal vez existen por ahí. Cualquier comentario sobre mi respuesta es apreciado.

Tengo un archivo php que usaré exclusivamente como una inclusión. Por lo tanto, me gustaría lanzar un error en lugar de ejecutarlo cuando se accede directamente escribiendo la URL en lugar de incluirla.

Básicamente tengo que hacer un control de la siguiente manera en el archivo php:

if ( $REQUEST_URL == $URL_OF_CURRENT_PAGE ) die ("Direct access not premitted");

¿Hay una forma fácil de hacer esto?


¡Que Joomla! does es definir una constante en un archivo raíz y verificar si el mismo está definido en los archivos incluidos.

defined(''_JEXEC'') or die(''Restricted access'');

si no

uno puede mantener todos los archivos fuera del alcance de una solicitud http colocándolos fuera del directorio webroot como recomiendan la mayoría de los frameworks como CodeIgniter.

o incluso al colocar un archivo .htaccess dentro de la carpeta de inclusión y las reglas de escritura, puede evitar el acceso directo.


Además del camino .htaccess, he visto un patrón útil en varios marcos, por ejemplo en Ruby on Rails. Tienen un pub / directorio por separado en el directorio raíz de la aplicación y los directorios de la biblioteca viven en directorios al mismo nivel que pub /. Algo como esto (no es ideal, pero entiendes la idea):

app/ | +--pub/ | +--lib/ | +--conf/ | +--models/ | +--views/ | +--controllers/

Configura su servidor web para usar pub / como raíz del documento. Esto ofrece una mejor protección para sus scripts: aunque pueden acceder desde la raíz del documento para cargar los componentes necesarios, es imposible acceder a los componentes desde Internet. Otro beneficio además de la seguridad es que todo está en un solo lugar.

Esta configuración es mejor que simplemente crear comprobaciones en cada archivo incluido porque el mensaje "no permitir acceso" es una pista para los atacantes, y es mejor que la configuración .htaccess porque no está basada en listas blancas: si arruinas las extensiones de archivo no será visible en los directorios lib /, conf / etc.


Agregue esto a la página que desea que solo se incluya

<?php if(!defined(''MyConst'')) { die(''Direct access not permitted''); } ?>

luego en las páginas que lo incluyen agregar

<?php define(''MyConst'', TRUE); ?>


El siguiente código se usa en el CMS de Flatnux ( http://flatnux.altervista.org ):

if ( strpos(strtolower($_SERVER[''SCRIPT_NAME'']),strtolower(basename(__FILE__))) ) { header("Location: ../../index.php"); die("..."); }


En realidad, mi consejo es hacer todas estas mejores prácticas.

  • Coloque los documentos fuera de la raíz web O en un directorio al que el servidor web deniega el acceso
  • Use una definición en sus documentos visibles que verifiquen los documentos ocultos:

if (!defined(INCL_FILE_FOO)) { header(''HTTP/1.0 403 Forbidden''); exit; }

De esta forma, si los archivos se extravían de alguna manera (una operación ftp errante) aún están protegidos.


Encontré esta solución invariable solo php que funciona tanto con http y cli:

Definir una función:

function forbidDirectAccess($file) { $self = getcwd()."/".trim($_SERVER["PHP_SELF"], "/"); (substr_compare($file, $self, -strlen($self)) != 0) or die(''Restricted access''); }

Llame a la función en el archivo que desea evitar el acceso directo a:

forbidDirectAccess(__FILE__);

La mayoría de las soluciones dadas anteriormente para esta pregunta no funcionan en modo Cli.


Es mejor que compile la aplicación con un punto de entrada, es decir, todos los archivos deben ser alcanzados desde index.php

Coloque esto en index.php

define(A,true);

Esta comprobación debe ejecutarse en cada archivo vinculado (a través de requerir o incluir)

defined(''A'') or die(header(''HTTP/1.0 403 Forbidden''));


Haz algo como:

<?php if ($_SERVER[''SCRIPT_FILENAME''] == ''<path to php include file>'') { header(''HTTP/1.0 403 Forbidden''); exit(''Forbidden''); } ?>


La forma más fácil es almacenar sus incluye fuera del directorio web. De esa forma, el servidor tiene acceso a ellos pero no a una máquina externa. El único inconveniente es que necesita poder acceder a esta parte de su servidor. Lo bueno es que no requiere configuración, configuración o estrés adicional de código / servidor.


La forma más fácil es establecer alguna variable en el archivo que incluye las llamadas, como

$including = true;

Luego, en el archivo que se está incluyendo, verifique la variable

if (!$including) exit("direct access not permitted");


La forma más fácil para la "aplicación PHP genérica que se ejecuta en un servidor Apache que usted puede o no puede controlar por completo" es poner sus inclusiones en un directorio y denegar el acceso a ese directorio en su archivo .htaccess. Para ahorrarle a la gente el problema de buscar en Google, si está usando Apache, colóquelo en un archivo llamado ".htaccess" en el directorio al que no desea acceder:

Deny from all

Si realmente tiene el control total del servidor (más común hoy en día, incluso para aplicaciones pequeñas que cuando escribí esta respuesta por primera vez), lo mejor es pegar los archivos que desea proteger fuera del directorio desde el que está sirviendo su servidor web. . Entonces, si su aplicación está en /srv/YourApp/ , configure el servidor para que sirva archivos desde /srv/YourApp/app/ y coloque los includes en /srv/YourApp/includes , de modo que literalmente no haya ninguna URL que pueda acceder a ellos .


La mejor manera de evitar el acceso directo a los archivos es colocarlos fuera de la raíz del documento del servidor web (por lo general, un nivel más arriba). Aún puede incluirlos, pero no hay posibilidad de que alguien acceda a ellos mediante una solicitud http.

Suelo recorrer todo el camino y colocar todos mis archivos PHP fuera de la raíz del documento, aparte del archivo de arranque , un index.php solitario en la raíz del documento que inicia el enrutamiento de todo el sitio web / aplicación.


La solución mencionada anteriormente con verificación de versión de PHP agregó:

$max_includes = version_compare(PHP_VERSION, ''5'', ''<'') ? 0 : 1; if (count(get_included_files()) <= $max_includes) { exit(''Direct access is not allowed.''); }


Lo que también puede hacer es proteger con contraseña el directorio y mantener todos sus scripts php allí, por supuesto, excepto el archivo index.php, ya que al momento de incluir la contraseña no será necesario, ya que solo se requerirá para el acceso http. lo que hará es también proporcionarle la opción de acceder a sus scripts en caso de que lo desee, ya que tendrá una contraseña para acceder a ese directorio. Necesitará configurar el archivo .htaccess para el directorio y un archivo .htpasswd para autenticar al usuario.

bueno, también puede usar cualquiera de las soluciones proporcionadas anteriormente en caso de que sienta que no necesita acceder a esos archivos normalmente porque siempre puede acceder a ellos a través de cPanel, etc.

Espero que esto ayude


Mi respuesta es algo diferente en el enfoque, pero incluye muchas de las respuestas proporcionadas aquí. Recomendaría un enfoque múltiple:

  1. .htaccess y las restricciones de Apache con seguridad
  2. defined(''_SOMECONSTANT'') or die(''Hackers! Be gone!'');

SIN EMBARGO el enfoque defined or die tiene una serie de fallas. En primer lugar, es un verdadero dolor en los supuestos para probar y depurar con. En segundo lugar, implica una refactorización terriblemente aburrida y aburrida si cambias de opinión. "¡Encontrar y reemplazar!" tu dices. Sí, pero ¿qué tan seguro está usted de que está escrito exactamente igual en todas partes, hmmm? Ahora multiplique eso con miles de archivos ... oO

Y luego está .htaccess. ¿Qué sucede si su código se distribuye en sitios donde el administrador no es tan escrupuloso? Si solo confía en .htaccess para proteger sus archivos, también necesitará a) una copia de seguridad, b) una caja de pañuelos para secar sus lágrimas, c) un extintor de incendios para apagar las llamas en todo el correo de odio de las personas usando tu código

Entonces sé que la pregunta pide la "más fácil", pero creo que lo que esto requiere es más "codificación defensiva".

Lo que sugiero es:

  1. Antes de que cualquiera de tus scripts require(''ifyoulieyougonnadie.php''); ( no include() y como un reemplazo para defined or die )
  2. En ifyoulieyougonnadie.php , haga algo lógico - verifique las diferentes constantes, invocando script, prueba localhost y tal - y luego implemente su die(), throw new Exception, 403 ejecute die(), throw new Exception, 403 , etc.

    Estoy creando mi propio marco con dos puntos de entrada posibles: el index.php principal (framework Joomla) y ajaxrouter.php (mi framework), así que dependiendo del punto de entrada, busco diferentes cosas. Si la solicitud a ifyoulieyougonnadie.php no proviene de uno de esos dos archivos, sé que se están cometiendo chanchullos.

    Pero, ¿y si agrego un nuevo punto de entrada? Sin preocupaciones. Solo cambio ifyoulieyougonnadie.php y estoy ordenado, además de no ''buscar y reemplazar''. ¡Hurra!

    ¿Qué pasa si decidí mover algunos de mis scripts para hacer un marco diferente que no tiene las mismas constantes defined() ? ... ¡Hurra! ^ _ ^

Descubrí que esta estrategia hace que el desarrollo sea mucho más divertido y mucho menos:

/** * Hmmm... why is my netbeans debugger only showing a blank white page * for this script (that is being tested outside the framework)? * Later... I just don''t understand why my code is not working... * Much later... There are no error messages or anything! * Why is it not working!?! * I HATE PHP!!! * * Scroll back to the top of my 100s of lines of code... * U_U * * Sorry PHP. I didn''t mean what I said. I was just upset. */ // defined(''_JEXEC'') or die(); class perfectlyWorkingCode {} perfectlyWorkingCode::nowDoingStuffBecauseIRememberedToCommentOutTheDie();


No encontré las sugerencias con .htaccess tan buenas porque pueden bloquear otro contenido en esa carpeta a la que le gustaría permitir el acceso del usuario, esta es mi solución:

$currentFileInfo = pathinfo(__FILE__); $requestInfo = pathinfo($_SERVER[''REQUEST_URI'']); if($currentFileInfo[''basename''] == $requestInfo[''basename'']){ // direct access to file }


Puede utilizar el siguiente método a continuación, aunque tiene un defecto, porque puede ser falso, excepto si puede agregar otra línea de código para asegurarse de que la solicitud solo provenga de su servidor mediante el uso de Javascript. Puede colocar este código en la sección Cuerpo de su código HTML, para que el error aparezca allí.

<? if(!isset($_SERVER[''HTTP_REQUEST''])) { include (''error_file.php''); } else { ?>

Coloque su otro código HTML aquí

<? } ?>

Termine así, de modo que la salida del error siempre se mostrará en la sección del cuerpo, si así es como quiere que sea.


Puedes usar el estilo phpMyAdmin:

/** * block attempts to directly run this script */ if (getcwd() == dirname(__FILE__)) { die(''Attack stopped''); }


Quería restringir el acceso al archivo PHP directamente, pero también poder llamarlo a través de jQuery $.ajax (XMLHttpRequest) . Esto es lo que funcionó para mí.

if (empty($_SERVER["HTTP_X_REQUESTED_WITH"]) && $_SERVER["HTTP_X_REQUESTED_WITH"] != "XMLHttpRequest") { if (realpath($_SERVER["SCRIPT_FILENAME"]) == __FILE__) { // direct access denied header("Location: /403"); exit; } }


Si es más preciso, debe usar esta condición:

if (array_search(__FILE__, get_included_files()) === 0) { echo ''direct access''; } else { echo ''included''; }

get_included_files() devuelve una matriz indexada que contiene nombres de todos los archivos incluidos (si el archivo se ejecuta correctamente, entonces se incluyó y su nombre está en la matriz). Entonces, cuando se accede directamente al archivo, su nombre es el primero en la matriz, todos los demás archivos en la matriz fueron incluidos.


Sugiero que no use $_SERVER por razones de seguridad.
Puede usar una variable como $root=true; en el primer archivo que incluyó otro.
y use isset($root) en el comienzo del segundo archivo que se incluirá.


Tengo un archivo que necesito para actuar de manera diferente cuando se incluye vs cuando se accede directamente (principalmente una print() vs return() ) Aquí hay algunos códigos modificados:

if(count(get_included_files()) ==1) exit("Direct access not permitted.");

El archivo al que se accede es siempre un archivo incluido, de ahí el == 1.


Tuve este problema una vez, resuelto con:

if (strpos($_SERVER[''REQUEST_URI''], basename(__FILE__)) !== false) ...

pero la solución ideal es colocar el archivo fuera de la raíz del documento del servidor web, como se menciona en otro artículo.


Una alternativa (o complemento) a la solución de Chuck sería negar el acceso a los archivos que coinciden con un patrón específico al poner algo como esto en su archivo .htaccess

<FilesMatch "/.(inc)$"> Order deny,allow Deny from all </FilesMatch>


<?php if (eregi("YOUR_INCLUDED_PHP_FILE_NAME", $_SERVER[''PHP_SELF''])) { die("<h4>You don''t have right permission to access this file directly.</h4>"); } ?>

coloque el código de arriba en la parte superior de su archivo php incluido.

ex:

<?php if (eregi("some_functions.php", $_SERVER[''PHP_SELF''])) { die("<h4>You don''t have right permission to access this file directly.</h4>"); } // do something ?>


<?php $url = ''http://'' . $_SERVER[''SERVER_NAME''] . $_SERVER[''REQUEST_URI'']; if (false !== strpos($url,''.php'')) { die ("Direct access not premitted"); } ?>


debug_backtrace() || die ("Direct access not permitted");


if ( ! defined(''BASEPATH'')) exit(''No direct script access allowed'');

hará el trabajo sin problemas


if (basename($_SERVER[''PHP_SELF'']) == basename(__FILE__)) { die(''Access denied''); };