practices - secure php code
Seguridad de inclusión dinámica (4)
A pesar de lo que indicó acerca de no querer almacenar una lista de páginas disponibles en una matriz, es probable que sea la mejor solución que no sea DB.
$availFiles = array(''index.php'', ''forum.php'');
if(in_array($_GET[''page''].".php", $availFiles))
{
//Good
}
else
{
//Not Good
}
Puede construir fácilmente la matriz de forma dinámica con consultas DB o leyendo un archivo, o incluso leyendo el contenido de un directorio y filtrando las cosas que no desea que estén disponibles.
¿Hay alguna manera de incluir páginas de manera segura sin ponerlas todas en una matriz?
if (preg_match(''/^[a-z0-9]+/'', $_GET[''page''])) { $page = $_GET[''page''].".php"; $tpl = $_GET[''page''].".html"; if (file_exists($page)) include($page); if (file_exists($tpl)) include($tpl); }
¿Qué debería agregar para que esto sea bastante seguro?
Lo estoy haciendo de esta manera porque no me gusta tener que incluir cosas que deben incluirse en todas las páginas. El "incluir encabezado> contenido> incluye pie de página". No quiero usar ningún framework / motor de plantillas tampoco.
Gracias.
La debilidad en su implementación actual es que ...
- la expresión regular simplemente prueba el comienzo de la cadena, por lo que "
images/../../secret
" pasaría, y - sin más validación, "
index
" también sería un valor válido y causaría una recursión.
Para que su implementación sea segura, es una buena práctica incluir todo lo que se pretende incluir en su propio directorio (por ejemplo, " includes
" y " templates
"). En base a esto, solo tiene que asegurarse de que no hay forma de salir de este directorio.
if (preg_match(''/^[a-z0-9]+$/'', $_GET[''page''])) {
$page = realpath(''includes/''.$_GET[''page''].''.php'');
$tpl = realpath(''templates/''.$_GET[''page''].''.html'');
if ($page && $tpl) {
include $page;
include $tpl;
} else {
// log error!
}
} else {
// log error!
}
Nota: realpath
devuelve la ruta absoluta a la ruta relativa dada si el archivo existe y, en caso contrario, es false
. Entonces file_exists
no es necesario.
Nunca debe usar la información proporcionada por el usuario para los includes. Siempre debe tener algún tipo de controlador de solicitudes que haga esto por usted. Si bien una expresión regular puede filtrar algunas cosas, no filtrará todo.
Si no desea que su sitio sea pirateado, no permita que sus usuarios controlen el flujo de la aplicación designando un include.
Estoy de acuerdo con Unkwntech. Esta es una manera tan insegura de incluir archivos en su sitio web, ojalá los programadores de PHP lo eliminen por completo. Aun así, una matriz con todas las coincidencias posibles es ciertamente más segura. Sin embargo, encontrará que el patrón MVC funciona mejor y es más seguro. Descargo el encendedor de código y tomo un tutorial o dos, te encantará por la misma razón por la que quieres usar dynamic includes.