Jump to content
Jonno

Configurar Apache para poder enviar variables PHP

Recommended Posts

Estoy haciendo una web en la que necesito enviar una variable P a una página llamada "pagina.php" mediante la URL.

 

Algo así:

http://www.dominio.com/pagina.php?P=abcdef

 

Cuando subo la web al servidor funciona. Pero quiero probarlo en local en mi Mac con Mac OS X 10.6 y no funciona.

 

Da un par de errores:

- Warning: include() [function.include]: Filename cannot be empty in (aquí la ruta del archivo pagina.php)

- Warning: include() [function.include]: Failed opening '' for inclusion (include_path='.:') in (aquí la ruta del archivo pagina.php)

 

El resto de la página en local no me da ningún problema, es sólo al enviar esa variable.

 

Imagino que tendré que tocar algo del archivo httpd.conf, igual que tuve que hacer para activar PHP. Supongo que es algún tipo de medida de seguridad y está desactivado algo por defecto.

O a lo mejor es otra cosa, que lo mío no es el PHP y no sé por dónde me da el aire :D

 

¿Sabéis qué tengo que hacer para que funcione en local? No quiero instalar MAMP ni nada, quiero que sea con el Apache por defecto.

Share this post


Link to post
Share on other sites

Hola,

 

Para recoger la variable en 'pagina.php' tendrías que

$p = $_GET['P'];

 

Quizás en el servidor el php.ini está configurado como "register_globals = ON" y en local "OFF" y creo que por eso allí te funciona sin recogerla.

 

Yo no usaría mayúsculas "P" (aunque eso no quiera decir que con mayúsculas no funcione)

 

Supongo que en el include tienes alguna referencia a la variable P?

 

saludos!

Share this post


Link to post
Share on other sites

No recuerdo exáctamente cómo es el código PHP (estoy en casa y no tengo acceso a la web) pero creo que es únicamente el include con ($p) como parámetro, sin ese GET que me dices. En el servidor funciona, porque carga la página que le indico en la variable p.

 

¿No usar ese $p = $_GET['p']; me puede causar algún problema? ¿Hay alguna forma mejor de hacer lo mismo? Porque me ha parecido entender leyendo por ahí sobre activar register_globals que podría comprometer la seguridad de la web de alguna manera.

 

Por cierto, sí que estaba OFF, pero lo he puesto ON y no ha funcionado, supongo que porque no he reiniciado el Mac. Mañana lo haré cuando vuelva al curro, a ver.

Share this post


Link to post
Share on other sites

Por cuestiones de seguridad el register_globals se pone OFF, es entonces cuando para recoger el valor de la variable se ha de usar $_GET

 

Por lo que entiendo, más o menos el código que te hace falta sería algo así:

<?php
if (isset($_GET['p'])) {
  $pagina = $_GET['p'];
  include($pagina);
  // o directamente include($_GET['p']);
} else {
  exit("La variable p está vacía");
}
?>

 

saludos!

Share this post


Link to post
Share on other sites

Entendido :)

 

Mi include es así: <?php include ($p);?>

Recoge la variable p que le mando con la URL e incluye la página indicada en el resto del diseño.

Tu código es más largo, pero si es más adecuado creo que lo usaré.

 

Muchas gracias, lo voy a probar ahora mismo.

Share this post


Link to post
Share on other sites

Probado, y funciona :) Muchas gracias.

 

Pero el código me crea otro problema: cuando la variable p está vacía, me sale el mensaje que pones en el exit ( )... pero no me carga el resto de la página :unsure:

 

Si pongo echo ( ) en vez de exit ( ) funciona... pero no sé si eso puede crear más problemas :lol: (no hay nada peor que un ignorante metiéndose a ingeniero :P)

Share this post


Link to post
Share on other sites

Otra cosa:

 

¿Es posible incluir alguna comprobación para que en caso de que en la variable p se mande una página inexistente salga un mensaje de aviso en vez del error del PHP?

Share this post


Link to post
Share on other sites

Le puse el exit por si, al estar vacía la variable, la cosa quedaba coja. Si no importa, mejor con echo ;)

 

Lo mismo comprobando que la página existe

<?php
if (isset($_GET['p'])) { 
if (!include($_GET['p'])) {
	echo "La página enviada no existe";
}
} else {
echo "la variable p esta vacia";
}
?>

 

saludos!

Share this post


Link to post
Share on other sites

No me funciona :unsure:

 

Le pongo "?p=lapaginanoexiste.html" en la URL y me devuelve el siguiente error en vez del aviso:

 

Warning: include(lapaginanoexiste.html) [function.include]: failed to open stream: No such file or directory in (la ruta de la web) on line 18

 

 

Bueno, tampoco es importante. Me conformo con lo que había pedido al principio ;)

¡Muchas gracias!

Share this post


Link to post
Share on other sites

mmm, sip

 

es un aviso, puedes saltarlo cambiando esta línea

if (@!include($_GET['p'])) {

 

añadiendo el @

 

saludos!

Share this post


Link to post
Share on other sites

Ah, funciona perfecto! Simple y elegante :)

 

Muchísimas gracias (de nuevo ;))

Share this post


Link to post
Share on other sites

Al final tu

 

echo "La página enviada no existe";

 

Se ha convertido en:

 

echo "<h1>La página solicitada no existe</h1><ul><img src='img/icn-inicio.gif' align='absmiddle' border='0' /> <a href='index.php'>Volver a la página principal</a><br><img src='img/icn-anterior.gif' align='absmiddle' border='0' /> <a href='javascript:window.history.back();'>Volver a la página anterior</a></ul>";

 

Y queda de lo más molón:

 

post-517-068952100 1324031152.png

 

:D

Share this post


Link to post
Share on other sites

Ahora voy y la casco, pero con el código de Quim y con una pueba en mi ordenador he podido acceder a un log de sistema simplemente con lo siguiente:

http://localhost/proves/provaexploit.php?p=../../../Logs/unlogcualquiera.log

Así que yo diría que no se debería hacer de esta forma, ya que en manos de alguien con más conocimientos que los mios puede ser una bomba. Lo que yo hago en estos casos es o acceder a los datos de la URL desde una base de datos o un array; o montar la URL comprobando que el usuario no ha puesto ningún carácter extraño, como detallo a continuación:

 

<?php
$laurl = $_GET['p'];
if (isset($laurl) && preg_match ("/^[0-9a-zA-Z]+$/",$laurl)) {
       $laurlcompleta = $laurl.".php";
       if (@!include($laurlcompleta)) {
               echo "Mensaje de error";
       }
} else {
       echo "Mensaje de error";
}
?>

Y otra vuelta de tuerca... Tampoco debería ser una solución poner un @ para saltarse un warning, mejor poner una comprobación de error que "tapar" un error, ya que acostumbrarse a esto también es peligroso. Lo dejaría así:

<?php
$laurl = $_GET['p'];
if (isset($laurl) && preg_match ("/^[0-9a-zA-Z_]+$/",$laurl)) {
       $laurlcompleta = $laurl.".php";
       if (file_exists($laurlcompleta)) {
           include($laurlcompleta);    
       } else {
       	echo "Mensaje de error";
       }
} else {
       echo "Mensaje de error";
}
?>

Edited by pintix
Edito para decir que la seguridad de serie de Apache en Mac es nula y por eso fuciona el exploit. Pero siempre hay que ponerse en el caso peor...

Share this post


Link to post
Share on other sites

Gracias Pintix, lo pruebo el lunes :)

Share this post


Link to post
Share on other sites

De nada!

 

He encontrado en uno de mis proyectos la versión paranoica, ya que comprueba incluso que estamos en la raiz de documentos del servidor web y comprueba la carpeta que se supone que tienen que estar los includes. La pongo a efectos informativos ya que no se si es necesaria esta seguridad redundante (no soy experto en seguridad), deberíamos pedir a los expertos en seguridad de la casa que se pasen por aquí para estar seguros.

 

<?php
// Las dos variables que se pueden modificar
$laextension = ".php"; // si la extension esta aqui y no en la variable no damos pistas de lo que hacemos
$carpetaincludes = "/proves/"; // la carpeta donde deben estar los includes

$elnombrearchivo = $_GET['p'];
$raizservidor = $_SERVER["DOCUMENT_ROOT"];

if (isset($elnombrearchivo) && preg_match ("/^[0-9a-zA-Z_]+$/",$elnombrearchivo)) {
       $laurlcompleta = $raizservidor.$carpetaincludes.$elnombrearchivo.$laextension;
       if (file_exists($laurlcompleta)) {
           include($laurlcompleta);    
       } else {
       	echo "Mensaje de error archivo no encontrado";
       }
} else {
       echo "Mensaje de error variable no válida";
}
?>

Share this post


Link to post
Share on other sites

Algo debo hacer mal, porque la versión paranoide no me funciona.

 

He creado el directorio proves.

He metido dentro un documento llamado proves.php

La página desde la que hago la llamada está en el directorio raíz.

En la URL pongo www.dominio.com/pagina.php?p=proves

... y me sale el error de archivo no encontrado.

 

Lo de detectar el error de variable no válida sí parece que funciona bien, porque tanto si lo dejo vacío como si pongo caracteres extraños me lo detecta.

Share this post


Link to post
Share on other sites

He probado en local y en el servidor, sin éxito.

 

 

Otra cosa: Si pongo el guión medio en la variable p me la da como incorrecta (con guión bajo sin embargo no). Por ejemplo, supongamos que un archivo se llama prove-cat.php para diferenciarlo de otro prove-esp.php.

 

¿Cómo se mete el guión en la expresión regular de la versión paranóica? Si es complicado (he visto por ahí expresiones regulares para validad emails más largas que un día sin pan...) puedo pasar sin ello ;)

Share this post


Link to post
Share on other sites

Lo del que no funcione la versión paranoide puede ser si estás dentro de otra carpeta en el servidor, con lo cual sería "/micarpeta/proves/", ya que utiliza la ruta de carpetas desde la raiz del servidor web.

 

Lo del guión se arregla añadiendo el guión al pattern con lo siguiente (yo también tardé años en controlar las expresiones y aún tengo que tirar de chuleta y ejemplos para utilizarlas):

if (isset($elnombrearchivo) && preg_match ("/^[0-9a-zA-Z_\-]+$/",$elnombrearchivo)) {

Edited by pintix

Share this post


Link to post
Share on other sites

Añado que en mi servidor tambien funciona, desde el directorio raiz como tu y creando la carpeta proves... así que no veo porque no debería funcionar en los tuyos ¿Te da algún error? ¿Si pones un echo $raizservidor."<br>"; que te pone?

Share this post


Link to post
Share on other sites

No da más error que el de tu php: "Mensaje de error archivo no encontrado".

 

Mañana en el trabajo pruebo lo de añadir el directorio principal, porque efectivamente no es el raíz del servidor (aunque sí donde está el índex.php, y por eso no lo he tenido en cuenta).

Share this post


Link to post
Share on other sites

Nada, sigue sin funcionarme :(

Lo del guión está resuelto, pero lo otro me sale siempre "Mensaje de error archivo no encontrado".

 

He probado a añadir en $carpetaincludes = "/proves/"; el directorio donde mi servidor aloja las webs, he probado a eliminar $carpetaincludes de la fórmula "$laurlcompleta = ...", y no sé qué más probar

Share this post


Link to post
Share on other sites

He hecho una versión con la carpeta relativa al script php desde el que se incluye el documento. En mis entornos funciona, aunque también funcionaba la anterior versión... está claro que esto de la programación no es una ciencia exacta. ;)

 

<?php
// Las dos variables que se pueden modificar
$laextension = ".php"; // si la extension esta aqui y no en la variable no damos pistas
$carpetaincludes = "proves/"; // la carpeta donde pueden estar los includes, como es relativa no ponemos la barra inicial

$elnombrearchivo = $_GET['p'];

if (isset($elnombrearchivo) && preg_match ("/^[0-9a-zA-Z_\-]+$/",$elnombrearchivo)) {
       $laurlcompleta = $carpetaincludes.$elnombrearchivo.$laextension;
       if (file_exists($laurlcompleta)) {
           include($laurlcompleta);    
       } else {
       	echo "Mensaje de error archivo no encontrado";
       }
} else {
       echo "Mensaje de error variable no válida";
}
?>

Share this post


Link to post
Share on other sites

:D

 

Muchas gracias, lo pruebo y te digo.

Share this post


Link to post
Share on other sites

¡Aleluya!

Funciona, en local y en el servidor :)

 

Ahora compararé lo que has variado para que funcione, que de estas cosas es de donde más se aprende ;)

Share this post


Link to post
Share on other sites

No creas, yo también aprendo, ya que así puedo ver que no funciona en todos los entornos y estoy sobre aviso.

 

En los comentarios del manual de PHP he visto que el problema puede ser que $_SERVER["DOCUMENT_ROOT"] a veces apunta a un directorio que no es exactamente la raiz. Los ejemplos que ponen son que el valor de la variable sea /htdocs/www, pero en realidad los documentos estén, por ejemplo, dentro de /htdocs/www/public_html. Lo que yo haría para comprobarlo es poner temporalmente un echo $_SERVER["DOCUMENT_ROOT"]; para ver que valor tiene y si coincide con mi ruta de archivos. Después añadiría lo que falta en una variable, pero no deja de ser un apaño.

 

La de tiempo que hacen perder estas inconsistencias...

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.