[Resuelto] ¿por qué es necesaria $_server["php_self"] en el action de un form?

Iniciado por big_ed, 13 Agosto 2019, 20:35 PM

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

big_ed

Hola.

En muchos tutoriales de PHP enseñan que, cuando vas a recibir datos de usuarios (via formulario) en la misma pagina en donde te encuentras, lo mejor es hacer lo siguiente:

<form method="post" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>">
</form>


Entiendo que si no rodeo a la superglobal $_SERVER('PHP_SELF') con HTMLSPECIALCHARS alguien podria poner codigo java script en la url y conseguir cosas...Pero lo que no entiendo es ¿por que es necesaria esa super global? Es decir, no seria mejor hacer simplemente esto?:

<form method="post" action="miweb.php">
</form>

AL hacer esto ya no funciona el codigo java script escrito en la URL.

O esto:
<form method="post">
</form>

#!drvy

CitarEn muchos tutoriales de PHP enseñan que, cuando vas a recibir datos de usuarios (via formulario) en la misma pagina en donde te encuentras, lo mejor es hacer lo siguiente:

Sinceramente, esos tutoriales o están escritos por inútiles o están obsoletos. Hoy en dia nadie te recomendaria semejante cosa.

Citarno seria mejor hacer simplemente esto?:

La idea es que no necesites saber el nombre del archivo .php ni la query ni nada. Que se rellene sólo en base al baseurl que tiene PHP. Viene siendo una comodidad.


CitarO esto:

Antes de HTML5, el action era obligatorio según el estándar W3C, por lo tanto no lo podías dejar vacío ni omitir. A partir de HTML5, ya no es obligatorio por lo tanto lo puedes omitir (aunque no puedes dejarlo vació).


Pero de ser necesario, lo más adecuado es un sistema de templates donde ya se implementan ese tipo de funciones. Pero lo dicho, a partir de HTML5, puedes omitir el action.

Saludos

big_ed

Cita de: #!drvy en 13 Agosto 2019, 21:29 PM
Sinceramente, esos tutoriales o están escritos por inútiles o están obsoletos. Hoy en dia nadie te recomendaria semejante cosa.

La idea es que no necesites saber el nombre del archivo .php ni la query ni nada. Que se rellene sólo en base al baseurl que tiene PHP. Viene siendo una comodidad.


Antes de HTML5, el action era obligatorio según el estándar W3C, por lo tanto no lo podías dejar vacío ni omitir. A partir de HTML5, ya no es obligatorio por lo tanto lo puedes omitir (aunque no puedes dejarlo vació).


Pero de ser necesario, lo más adecuado es un sistema de templates donde ya se implementan ese tipo de funciones o en su defecto, filtrar el input para validar la URL:

Código (php) [Seleccionar]
$action = filter_input(INPUT_SERVER, 'PHP_SELF', FILTER_SANITIZE_URL);

Lo dicho, a partir de HTML5, puedes omitir el action.

Saludos

Pero que seria mejor entonces ¿omitir el ACTION como yo he dicho, O usarlo con ese codigo que tú me has puesto de sanitizar la URL?

Aunque si dices que la idea es ocultar el destino del action, si no lo pongo, en el codigo fuente apareceria vacio, y el hacker se daria cuenta que los datos van a la misma pagina, no?? ¿o me equivoco? Por otra parte, con el ECHO ¿se veria algo en el codigo fuente o en el inspector? Se supone que no

#!drvy

CitarPero que seria mejor entonces ¿omitir el ACTION como yo he dicho, O usarlo con ese codigo que tú me has puesto de sanitizar la URL?

Omitirlo. No se trata de ocultarlo, no tiene ningún sentido ocultarlo, se trata de no darle vías de input al que intente hacer el mal xD

PD: El codigo que he puesto estaba mal y lo he retirado, al parecer valida caracteres como <>"  lo cual lo hace inútil en estos casos. Quizás lo suyo seria utilizar FILTER_SANITIZE_STRING en ves de FILTER_SANITIZE_URL.

Saludos

@XSStringManolo

#!Drvy es correcto el uso de preg_replace con la misma finalidad?

#!drvy

Cita de: string Manolo en 13 Agosto 2019, 21:41 PM
#!Drvy es correcto el uso de preg_replace con la misma finalidad?

Es un poco overkill pero si, puedes usarlo. Lo único, dado que regex tiende a ser algo lento y para evitar males mayores, limitaría los caracteres (un substr o parecido) para evitar así que me pasen cadenas de 20MB a filtar xD

Saludos

@XSStringManolo

Cita de: #!drvy en 13 Agosto 2019, 21:49 PM
Es un poco overkill pero si, puedes usarlo. Lo único, dado que regex tiende a ser algo lento y para evitar males mayores, limitaría los caracteres (un substr o parecido) para evitar así que me pasen cadenas de 20MB a filtar xD

Saludos
No lo había pensado xDDD.

big_ed

Cita de: #!drvy en 13 Agosto 2019, 21:49 PM
Es un poco overkill pero si, puedes usarlo. Lo único, dado que regex tiende a ser algo lento y para evitar males mayores, limitaría los caracteres (un substr o parecido) para evitar así que me pasen cadenas de 20MB a filtar xD

Saludos
Justo iba a preguntar lo de arriba..Me parece que se podrian usar expresiones regulares literales. Voy a hacer un codigo y te lo muestro luego, para que me digas si es seguro o no.




Cita de: #!drvy en 13 Agosto 2019, 21:39 PM
Omitirlo. No se trata de ocultarlo, no tiene ningún sentido ocultarlo, se trata de no darle vías de input al que intente hacer el mal xD

PD: El codigo que he puesto estaba mal y lo he retirado, al parecer valida caracteres como <>"  lo cual lo hace inútil en estos casos. Quizás lo suyo seria utilizar FILTER_SANITIZE_STRING en ves de FILTER_SANITIZE_URL.

Saludos

Cita de: string Manolo en 13 Agosto 2019, 22:18 PM
No lo había pensado xDDD.

Ya programé otra vez el formulario, pero esta vez solo con PHP..díganme si está bien....Sólo falta lo del ACTION...pero ahorita lo hago y se los muestro también:


<form method="POST" autocomplete="off">
<input type="text" name="text" maxlength />
<input type="text" name="mail" maxlength />
<input type="text" name="telf" maxlength />
<textarea name="post" ></textarea>
<input type="submit" value="Enviar Correo" name="SUBMIT" />
</form>


<?php


if ( isset( $_POST['SUBMIT'] ) ) {

//PRIMERA LIMPIEZA
//PRIMERA LIMPIEZA
function _clean $p ) {
$cle trim$p );
$cle stripcslashes$p );
$cle htmlspecialchars$p );
return 
$cle;
}

$text _clean$_POST['text'] );
$mail _clean$_POST['mail'] );
$telf _clean$_POST['telf'] );
$post _clean$_POST['post'] );
$exp1 "/^[a-z\s]+$/i";
$exp2 "/^[a-z0-9._-]+@[a-z0-9.-]+\.[a-z]{2,9}$/";

if ( empty( 
$text ) || empty( $mail ) || empty( $telf ) || empty( $post ) ) {
echo 
"<script>alert( 'Rellena todos los campos!' )</script>";
} else {
    
//SEGUNDA LIMPIEZA
    //SEGUNDA LIMPIEZA
    
if ( strlen$text ) > 50 ) {
        echo 
"El campo Nombre permite un máximo de 50 caracteres";
    } elseif ( 
strlen$mail ) > 30 ) {
        echo 
"El campo Correo permite un máximo de 30 caracteres";
    } elseif ( 
strlen$telf ) > 11 ) {
        echo 
"El campo Teléfono permite un máximo de 11 caracteres";
    } elseif ( 
strlen$post ) > 900 ) {
        echo 
"El campo Mensaje permite un máximo de 900 caracteres";
    } elseif ( !
preg_match$exp1$text ) ) {
        echo 
"En el campo de Nombre ingresa solo letras, mayúsculas o minúsculas<br>";
    } elseif ( !
preg_match$exp2$mail ) ) {
        echo 
"Ingresa un correo válido!<br>";
    } else if ( !
is_numeric$telf ) ) {
        echo 
"Ingresa un número válido. Sólo números";
    } else {
        
//AQUI ENVIO LOS DATOS LIMPIOS AL SERVER
    
}
}
    
}


?>


:rolleyes:




Cita de: #!drvy en 13 Agosto 2019, 21:39 PM
Omitirlo. No se trata de ocultarlo, no tiene ningún sentido ocultarlo, se trata de no darle vías de input al que intente hacer el mal xD

PD: El codigo que he puesto estaba mal y lo he retirado, al parecer valida caracteres como <>"  lo cual lo hace inútil en estos casos. Quizás lo suyo seria utilizar FILTER_SANITIZE_STRING en ves de FILTER_SANITIZE_URL.

Saludos

El SANITIZE STRING me permite el simbolo ">" pero no el "<"
El HTMLSPECIALCHARS permite ambos..o sea que no sirve..
Pero ¿cuáles son exactamente los caracteres que debo evitar?
POrque yo podría impedirlos con expresiones regulares, pero quisiera saber cuáles son.
Si te fijas en el nuevo formulario que te he mandado ahi uso expresiones que solo permite texto ... Eso mismo podría intentar hacer pero en el ACTION.
El problema es que yo no sé nada de hackeo es por eso que no sé que cosa evitar. Si supiera sería más fácil.




Mod: No hacer doble/triple post.

@XSStringManolo

Usa el input type adecuado solo estás usando text a pesar de soliciar un número y un email.
CitarThe required attribute works with the following input types: text, search, url, tel, email, password, date pickers, number, checkbox, radio, and file.
Usar el tipo de input adecuado aseguro que el usuario no se equivoque al introducir los datos o le de sin querer a enviar y se te envien cosas inútiles al server para evitar que trabaje para nada. También evitas que el usuario envie datos erroneos sin darse cuenta.

exp1 y exp2 no las usas, supongo que porque ahí harás la tercera limpieza.

A parte de eso no veo nada más.





No sé como están implementadas las funciones, yo personalmente le hecharía un ojo a la implementación desde la perspectiva de un atacante para ver si hay alguna manera de saltarse la limpieza. Depende que hagas con lo que recibes. Si vas a publicar en el propio sitio, por ejemplo usando un document.write(Texto) si el filtro no es perfecto se pueden hacer cosas tipo:
Ejemplo de filtro inutil solamente buscando < > para evitar inserción de scripts.
Texto = FiltroAntiScripts(Texto);

//Contenido de texto:
var x = 60;
var y = 62;
x = asciiToChar(x);
y = asciiToChar(y);
var texto ="";
texto += x;
texto += "script";
texto += y;
texto += "alert(\"Soy un codigo malicioso xD\")";
texto += x;
texto += "/script"
texto += y;
//Fin contenido de texto.

//Tu código:
document.write(Texto);

Se pueden hacer muchas mierdas así.
Me imagino que la implementación está más que testeada, pero si por ejemplo tienes un decoder en tu código, podrían conseguir llamarlo pasándole como parámetro un script codificado que pase los filtros, pudiendo ejecutar el script desde una url de tu propio sitio. Tras lo cual enviando una url que a simple vista parece segura tipo https://www.elhacker.net/decode="agjw3ben72bfiwb5wk75fjw71637173jlspeb"/post.html

Ya me encontré fallos similares en muchos sitios. Hasta injectando rutas en el nombre de usuario para subir shells a carpetas con permisos o modificar algún archivo para tirar el server cambiándole el contenido a:
I'm an evil atacker, you should be scared. Buuuu.




Hints:
-Validate username serverside.
-Delete the last account created.
-Stop use the same credentials to share your accounts.


Jajaja

big_ed

Cita de: string Manolo en 14 Agosto 2019, 02:33 AM
Usa el input type adecuado solo estás usando text a pesar de soliciar un número y un email.Usar el tipo de input adecuado aseguro que el usuario no se equivoque al introducir los datos o le de sin querer a enviar y se te envien cosas inútiles al server para evitar que trabaje para nada. También evitas que el usuario envie datos erroneos sin darse cuenta.

exp1 y exp2 no las usas, supongo que porque ahí harás la tercera limpieza.

A parte de eso no veo nada más.





No sé como están implementadas las funciones, yo personalmente le hecharía un ojo a la implementación desde la perspectiva de un atacante para ver si hay alguna manera de saltarse la limpieza. Depende que hagas con lo que recibes. Si vas a publicar en el propio sitio, por ejemplo usando un document.write(Texto) si el filtro no es perfecto se pueden hacer cosas tipo:
Ejemplo de filtro inutil solamente buscando < > para evitar inserción de scripts.
Texto = FiltroAntiScripts(Texto);

//Contenido de texto:
var x = 60;
var y = 62;
x = asciiToChar(x);
y = asciiToChar(y);
var texto ="";
texto += x;
texto += "script";
texto += y;
texto += "alert(\"Soy un codigo malicioso xD\")";
texto += x;
texto += "/script"
texto += y;
//Fin contenido de texto.

//Tu código:
document.write(Texto);

Se pueden hacer muchas mierdas así.
Me imagino que la implementación está más que testeada, pero si por ejemplo tienes un decoder en tu código, podrían conseguir llamarlo pasándole como parámetro un script codificado que pase los filtros, pudiendo ejecutar el script desde una url de tu propio sitio. Tras lo cual enviando una url que a simple vista parece segura tipo https://www.elhacker.net/decode="agjw3ben72bfiwb5wk75fjw71637173jlspeb"/post.html

Ya me encontré fallos similares en muchos sitios. Hasta injectando rutas en el nombre de usuario para subir shells a carpetas con permisos o modificar algún archivo para tirar el server cambiándole el contenido a:
I'm an evil atacker, you should be scared. Buuuu.




Hints:
-Validate username serverside.
-Delete the last account created.
-Stop use the same credentials to share your accounts.


Jajaja
No estoy usando input de tipo mail o telf porque no son compatibles con Internet explorer 9.
Yo ignoro a internet explor 8 para abajo, pero del 9 para arriba siempre debe ser compatible.
tampoco uso placeholder ni required

Exp1 y exp2 si las uso, fijate bien , estan en el preg_match

Entonces solo me limitare a hacer la seguridad basica porque no soy un hacker experto, y si alguien quiere una super seguridad, pues que pague mas para subcontratar y llamar a un experto que refuerce, porque lo que es yo, no es mi rama