Tengo un archivo php que usaré de forma tan exclusiva 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 ser incluido.
Básicamente, necesito hacer una verificación 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?
php
include
include-guards
Alterlife
fuente
fuente
Respuestas:
La forma más fácil para la situación genérica de "aplicación PHP que se ejecuta en un servidor Apache que puede o no controlar completamente" es colocar sus inclusiones en un directorio y denegar el acceso a ese directorio en su archivo .htaccess. Para ahorrarle a la gente la molestia de buscar en Google, si está usando Apache, coloque esto en un archivo llamado ".htaccess" en el directorio al que no desea que esté accesible:
Si realmente tiene el control total del servidor (más común en estos días incluso para aplicaciones pequeñas que cuando escribí esta respuesta por primera vez), el mejor enfoque es pegar los archivos que desea proteger fuera del directorio desde el que está sirviendo su servidor web . Entonces, si su aplicación está activada
/srv/YourApp/
, configure el servidor para que sirva los archivos/srv/YourApp/app/
y agregue las inclusiones/srv/YourApp/includes
, para que literalmente no haya ninguna URL que pueda acceder a ellas.fuente
<Files ~ "\.inc$">
Order Allow,Deny
Deny from All
</Files>
Agregue esto a la página que desea incluir solo
luego en las páginas que lo incluyen agregue
fuente
somefile.php
en su servidor y agregaron su definición en él, eso todavía no les permite acceder directamente al archivo de inclusión. Les permitirá "incluir" sus archivos de biblioteca, pero si llegan lo suficientemente lejos como para crear archivos en su servidor y conocer sus scripts de definición / inclusión, tiene otros problemas que probablemente nieguen escribir su propio archivo con su definición en primer lugar .Tengo un archivo que necesito para actuar de manera diferente cuando se incluye vs cuando se accede directamente (principalmente un
print()
vsreturn()
) Aquí hay un código modificado:El archivo al que se accede siempre es un archivo incluido, de ahí el == 1.
fuente
La mejor manera de evitar el acceso directo a los archivos es colocarlos fuera de la raíz de documentos del servidor web (generalmente, un nivel por encima). Todavía puede incluirlos, pero no hay posibilidad de que alguien acceda a ellos a través de una solicitud http.
Por lo general, hago todo el camino y coloco 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 comienza a enrutar todo el sitio web / aplicación.
fuente
1: comprobación del recuento de archivos incluidos
Lógica: PHP se cierra si no se cumple el recuento 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
Lógica: si la constante no está definida, la ejecución no comenzó desde la página base y PHP dejaría de ejecutarse.
Tenga en cuenta que, en aras de la portabilidad a través de actualizaciones y cambios futuros, hacer que este método de autenticación sea modular reduciría significativamente la sobrecarga de codificación, ya que los cambios no necesitarán ser codificados en cada archivo.
De esta forma, se puede agregar código adicional para
checkdefined.php
fines de registro y análisis, así como para generar respuestas apropiadas.Crédito donde se debe: la brillante idea de portabilidad surgió de esta respuesta .
3: autorización de dirección remota
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 de retorno en caso de una configuración de servidor único o una lista blanca de direcciones para una infraestructura de servidor con varios servidores o con equilibrio de carga.
4: autorización de token
Similar al método anterior, uno puede usar GET o POST para pasar un token de autorización al archivo de inclusión:
Un método muy desordenado, 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 configurar el servidor para que las denegue.
Por ejemplo, en APACHE, la configuración se almacena en el
.htaccess
archivo. Tutorial aquí .Sin embargo, tenga en cuenta que las configuraciones específicas del servidor no son recomendadas por mí porque son malas para la portabilidad en diferentes servidores web. En casos como Content Management Systems donde el algoritmo denegado es complejo o la lista de directorios denegados es bastante grande, solo puede hacer que las sesiones de reconfiguración sean bastante horripilantes. Al final, es mejor manejar esto en código.
6: La colocación incluye en un directorio seguro FUERA de la raíz del sitio
Menos preferido debido a las limitaciones de acceso en entornos de servidor, pero es un método bastante poderoso si tiene acceso al sistema de archivos.
Lógica:
htdocs
carpeta ya que los enlaces estarían fuera del alcance del sistema de direcciones del sitio web.Disculpe mis convenciones de codificación poco ortodoxas. Cualquier comentario es apreciado.
fuente
Una alternativa (o complemento) a la solución de Chuck sería negar el acceso a archivos que coincidan con un patrón específico al poner algo como esto en su archivo .htaccess
fuente
En realidad, mi consejo es hacer todas estas mejores prácticas.
De esta manera, si los archivos se extravían de alguna manera (una operación ftp errante), todavía están protegidos.
fuente
Tuve este problema una vez, resuelto con:
pero la solución ideal es colocar el archivo fuera de la raíz del documento del servidor web, como se menciona en otra respuesta.
fuente
Será mejor que compile la aplicación con un punto de entrada, es decir, todos los archivos deben alcanzarse desde index.php
Coloque esto en index.php
Esta verificación debe ejecutarse en cada archivo vinculado (a través de require o include)
fuente
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í.fuente
La forma más fácil es establecer algunas variables en el archivo que incluyen las llamadas, como
Luego, en el archivo que se incluye, verifique la variable
fuente
Además de la forma .htaccess, he visto un patrón útil en varios marcos, por ejemplo, en ruby on rails. Tienen un directorio pub / 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):
Configura su servidor web para usar pub / como documento raíz. Esto ofrece una mejor protección a sus scripts: si bien pueden llegar 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 "acceso no permitido" es una pista para los atacantes, y es mejor que la configuración .htaccess porque no se basa en una lista blanca: si arruinas las extensiones de archivo no será visible en los directorios lib /, conf / etc.
fuente
¡Qué joomla! does es definir una constante en un archivo raíz y verificar si la misma está definida en los archivos incluidos.
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 marcos como CodeIgniter.
o incluso colocando un archivo .htaccess dentro de la carpeta de inclusión y escribiendo reglas, puede evitar el acceso directo.
fuente
fuente
Mi respuesta es algo diferente en el enfoque, pero incluye muchas de las respuestas proporcionadas aquí. Yo recomendaría un enfoque múltiple:
defined('_SOMECONSTANT') or die('Hackers! Be gone!');
SIN EMBARGO, el
defined or die
enfoque tiene una serie de fallas. En primer lugar, es un verdadero dolor en los supuestos para probar y depurar. En segundo lugar, implica una refactorización terriblemente aburrida y abrumadora si cambia de opinión. "¡Encontrar y reemplazar!" tu dices. Sí, pero ¿qué tan seguro estás de que está escrito exactamente igual en todas partes, hmmm? Ahora multiplique eso con miles de archivos ... oOY luego está .htaccess. ¿Qué sucede si su código se distribuye en sitios donde el administrador no es tan escrupuloso? Si confía solo 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 es la "más fácil", pero creo que lo que esto requiere es más "codificación defensiva".
Lo que sugiero es:
require('ifyoulieyougonnadie.php');
( noinclude()
y como reemplazo dedefined or die
)En
ifyoulieyougonnadie.php
, haga algunas cosas lógicas (verifique las diferentes constantes, el script de llamada, las pruebas de host local y demás) y luego implemente sudie(), throw new Exception, 403
, etc.Estoy creando mi propio marco con dos posibles puntos de entrada: el index.php principal (marco de Joomla) y ajaxrouter.php (mi marco), por lo que, dependiendo del punto de entrada, verifico si hay cosas diferentes. Si la solicitud
ifyoulieyougonnadie.php
no proviene de uno de esos dos archivos, ¡sé que se están haciendo travesuras!¿Pero qué pasa 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é sucede si decidí mover algunos de mis scripts para hacer un marco diferente que no tenga las mismas constantes
defined()
? ... ¡Hurra! ^ _ ^Descubrí que esta estrategia hace que el desarrollo sea mucho más divertido y mucho menos:
fuente
Si es más preciso, debe usar esta condición:
get_included_files () devuelve una matriz indexada que contiene los nombres de todos los archivos incluidos (si el archivo se ejecuta correctamente, se incluyó y su nombre está en la matriz). Entonces, cuando se accede directamente al archivo, su nombre es el primero en la matriz, se incluyen todos los demás archivos en la matriz.
fuente
coloca el código de arriba en la parte superior de tu archivo php incluido.
ex:
fuente
El siguiente código se utiliza en Flatnux CMS ( http://flatnux.altervista.org ):
fuente
Encontré esta solución invariable y solo para php que funciona tanto con http como con cli:
Definir una función:
Llame a la función en el archivo que desea evitar el acceso directo a:
La mayoría de las soluciones dadas anteriormente a esta pregunta no funcionan en modo Cli.
fuente
fuente
fuente
El almacenamiento de sus archivos de inclusión fuera del directorio web accesible se ha mencionado varias veces, y sin duda es una buena estrategia siempre que sea posible. Sin embargo, otra opción que aún no he visto mencionada: asegúrese de que sus archivos de inclusión no contengan ningún código ejecutable . Si sus archivos de inclusión simplemente definen funciones y clases, y no tienen otro código que ese, simplemente generarán una página en blanco cuando se acceda directamente.
De todos modos, permita el acceso directo a este archivo desde el navegador: no hará nada . Define algunas funciones, pero ninguna se llama, por lo que ninguna se ejecuta.
Lo mismo se aplica a los archivos que contienen solo clases PHP y nada más.
Sigue siendo una buena idea mantener sus archivos fuera del directorio web siempre que sea posible.
system
, porque eso entraría en conflicto con una ruta utilizada para el código. Esto me resulta molesto.fuente
Haz algo como:
fuente
Puede usar el siguiente método a continuación, aunque tiene una falla, ya que 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 JavaScript. Puede colocar este código en la sección Cuerpo de su código HTML, por lo que el error se muestra allí.
Coloque su otro código HTML aquí
Termine así, para que la salida del error siempre se muestre dentro de la sección del cuerpo, si así es como quiere que sea.
fuente
Sugiero que no lo use
$_SERVER
por razones de seguridad.Puede usar una variable como
$root=true;
en el primer archivo que incluye otra.y usar
isset($root)
al comienzo del segundo archivo que se incluirá.fuente
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 en el momento de incluir la contraseña no será necesaria, ya que solo será necesario para el acceso http. lo que hará es proporcionarle también 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
fuente
La forma más fácil es almacenar sus inclusiones fuera del directorio web. De esa manera, el servidor tiene acceso a ellos pero no tiene 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.
fuente
No encontré las sugerencias con .htaccess tan buenas porque puede bloquear otro contenido en esa carpeta a la que le gustaría permitir que el usuario acceda, esta es mi solución:
fuente
hará el trabajo sin problemas
fuente
BASEPATH
const
se establece en unindex.php
archivo que se encuentra en la parte inferior de la estructura de árbol. CI reescribe las URL para que no haya necesidad de acceder a los scripts directamente de todos modos.Solución mencionada anteriormente con verificación de versión de PHP agregada:
fuente