crear enlaces seguros para las paginas php

Iniciado por gAb1, 24 Septiembre 2014, 13:16 PM

0 Miembros y 1 Visitante están viendo este tema.

MinusFour

Cita de: WHK en 25 Septiembre 2014, 23:48 PMTe ahorras tener que tocar esos archivos cada ves que tengas secciones nuevas.

No necesitas tocar los .htaccess para nada, con las reglas por default de wordpress te bastan. El ruteador hace todo por tí.. y las reglas del mod_rewrite pueden ser tan sencillas como:

Código (apache) [Seleccionar]

DirectoryIndex entry.php

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^entry\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /entry.php [L]
</IfModule>


Y no necesitas modificar tus rutas para nada en el .htaccess, las modificas en el archivo entry.php

Código (php) [Seleccionar]

<?php

$string 
$_SERVER['REQUEST_URI'];

if(
$string == '/hola'){
echo 'hey';
}
elseif(
$string == '/test'){
echo 'test';
}
elseif(
$string == '/hey'){
echo 'hrm';
}
elseif(
$string == '/'){
echo 'home';
} else {
echo 'Error 404';
}

?>

gAb1

Vaya, dos maneras diferentes... Me gustaría probar las dos para ver que tal, pero tengo algunas dudas:

1º ¿Donde tengo que poner este codigo? Perdonar mi ignorancia :P

Código (php) [Seleccionar]
    if(isset($_SERVER['PATH_INFO']))
    $rutaInfo = trim((string)$_SERVER['PATH_INFO'], '/');
     
    elseif(isset($_SERVER['ORIG_PATH_INFO']))
    $rutaInfo = trim((string)$_SERVER['ORIG_PATH_INFO'], '/');


2º El metodo redirigiendo a entry.php,  que pasa en el caso de usar un archivo.php que existe para usar un link? Por ejemplo, si test.php existe y escribo test.php/site/login: daria error, no?

Porque cualquier cosa que escribas se redirige a entry.php y se compara con la lista? O solo se compara lo que hay despues de ?, o de esta manera se compara todo lo que escribas despues de la url? awww.site.com/'---> a partir de aqui se compara todo?

Volvemos a lo de antes, que pasa con las variables como login.php?error=1?? se seguirian ejecutando? site.com/site/login&error=1?

Gracias!

MinusFour

Si test.php existe y escribes test.php/site/login, se ejecuta test.php, pero el URI cambia, ya no es /site/login ahora es /test.php/site/login. Claro que si tu script no está leyendo el URI o el path, no afecta en nada.

Para el queryString puede ser un problema, porque no hace un match exacto con la ruta. PATH_INFO sería una solución más adecuada si quieres conservar el QueryString o hacer alguna manipulación de texto con el REQUEST_URI. También puedes optar por "reescribir" tu queryString dentro de una ruta.

Por ejemplo:


/site/login/error/1

gAb1

¿Por que no funciona esto?

Código (php) [Seleccionar]
preg_match('/^([\w\/]+)=?(\w+)?&?/', $_SERVER['REQUEST_URI'], $matches);
$matches[1] = isset($matches[1]) ? $matches[1] : null;


Es más complicado de lo que parece porque index.php es lo que llama la estructura y esta llama los views. Si se cambia de pagina ya no funcionaria...

Lo intento de ese modo porque me gustaría tener el tipo de links -> site.com/site/login&error=1 y que funcionara.

MinusFour

Cita de: gAb1 en 26 Septiembre 2014, 02:29 AM
¿Por que no funciona esto?

Código (php) [Seleccionar]
preg_match('/^([\w\/]+)=?(\w+)?&?/', $_SERVER['REQUEST_URI'], $matches);
$matches[1] = isset($matches[1]) ? $matches[1] : null;


Es más complicado de lo que parece porque index.php es lo que llama la estructura y esta llama los views. Si se cambia de pagina ya no funcionaria...

Lo intento de ese modo porque me gustaría tener el tipo de links -> site.com/site/login&error=1 y que funcionara.

Te refieres a:
site.com/site/login?error=1

No te va a funcionoar el regex.
Código (php) [Seleccionar]

$_SERVER['REQUEST_URI']
tiene un valor de /site/login?error=1Lo que podrías hacer es algo como lo que puse antes:

Código (php) [Seleccionar]

foreach ($includes as $key => $val){
if(preg_match("@^/$key@", $_SERVER["REQUEST_URI"])){
include $val;
}
}

gAb1

#25
Lo siento fallo mio, si que funcionaba, se me olvido el .htaccess

Lo unico es que en lugar de entry.php uso index.php.

Código (php) [Seleccionar]

function showContent() {
$views = 'views/';
$site = $views . 'site/';
$user = $views . 'user/';

if($_SERVER['REQUEST_URI'] == '/')
$_SERVER['REQUEST_URI'] = '/home';

$includes = array(
'/home' => $views . 'home.php',
'/login' => $site . 'login.php',
'/logout' => $site . 'logout.php',
'/contact' => $site . 'contact.php',
'/about' => $site . 'about.php',
'/register' => $user . 'register.php',
'/referral' => $user . 'referral.php',
'/friend' => $user . 'friend.php',
'/register_success' => $user . 'register_success.php'
);

preg_match('/^([\w\/]+)=?(\w+)?&?/', $_SERVER['REQUEST_URI'], $matches);
$matches[1] = isset($matches[1]) ? $matches[1] : null;

if(array_key_exists($matches[1], $includes)){
$content = include($includes[$matches[1]]);
} else $content = "Error 404";
return $content;
}


Y efectivamente los links son: site.com/login?error=1

Al final de la manera mas simple posible, directamente el nombre del archivo, sin carpeta.

¿Podrías decirme alguna manera de comprobar si es vulnerable? Como por ejemplo lo de poner una larga cadena de caracteres y crear agujeros de esos. ¿O no se puede si hay una whitelist?

MinusFour

Bueno, la expresión regular si te va a capturar la parte que necesitas, pero lo demás realmente es innecesario. De hecho, ahora que me pongo a pensar un poco en mi expresión, realmente no necesitas el "?=(\w+)?&?' para nada, está de más.

También podrias adaptar la expresión regular para que funcione através del archivo.php. Como lo tienes ahora:


http://www.site.com/inicio
//Funciona

http://www.site.com/index.php/inicio
//No funciona

gAb1

#27
¿Te refieres a que funcionen los links con el index.php? Si es eso, es justo lo que no queria, usar nombres completos, el objetivo era este, con un simple nombre sin extension llamar la pagina.

Asi tal cual lo tengo funciona perfectamente.

JorgeEMX

Sería más simple irse por lo que debería ser que estar evitando lo que no. Como se supone que debería de ser es, cualquier inclusión que se vaya hacer se parte de un directorio padre y común para iniciar. A éste directorio padre lo único que podría incluir es un archivo o más directorios, y archivos. Por regla general, los nombres de estos archivos y directorios sólo puede ser nombrados por letras de la A-Z y por mucho usar - y _ (/ para delimitar directorios). Cualquier otro carácter se omite y se parte de ahí para incluir cualquier cosa hacía adelante del directorio padre (nunca hacía atrás y mucho menos de algún otro origen que no sea el sistema de ficheros actual). Esto pensando que el "ruteo" sea del tipo /uno/dos/tres. Después sólo bastaría confirmar que el archivo exista.

Una disculpa si no pongo un ejemplo pero sólo paso por acá un rato y ya es de noche (me estoy haciendo viejo). Lo que es cierto es que ya hay bastante proyectos robustos que serían fácil de implementar y evitar reinventar la rueda como bien te comentaron.

WHK

#29
CitarSería más simple irse por lo que debería ser que estar evitando lo que no. Como se supone que debería de ser es

Permitir solo de la A a la Z mas - y _ no es irse por lo que debería ser, de hecho te contradices en parte ya que con ese filtro te estás saliendo de norma, que tal si una carpeta se llama por ejemplo admin.mensajes ? según tu modelo dejará de funcionar. Tanto en los sistemas Unix como Linux y Windows tienen diferentes estándares en cuanto a que carácter es permitido como nombre de carpeta y nombre de archivo, por lo cual si tu haces un desarrollo no estandarizado omitiendo caracteres que si están permitidos por el sistema entonces dejará de ser una aplicación escalable ya que otros desarrolladores o el mismo administrador del sistema no podrá utilizar el sistema de archivos común del mismo sistema operativo. Recuerda que un directorio o archivo puede incluir incluso caracteres como acentos, espacios en blanco, puntos, signos especiales, paréntesis, arrobas, etc.

Bajo este contexto mi modelo es el mas eficiente porque cumple con todos los estándares de posibles reales carpetas y archivos bajo una lista blanca como únicos permitidos y sin la necesidad de tener que modificar el código si agregas secciones nuevas, tampoco usa expresiones regulares, o sea, usa menos memoria, menos cpu, menos lineas de código, no es vulnerable, o sea tal como dijiste tu, irse por lo que debería ser en ves de estar evitando lo que no es, no se porque aun le dan tantas vueltas al tema buscando opciones menos inseguras, mas pesadas y con problemas de seguridad.