Foro de elhacker.net

Programación => PHP => Mensaje iniciado por: big_ed en 13 Agosto 2019, 20:35 pm



Título: [Resuelto] ¿por qué es necesaria $_server["php_self"] en el action de un form?
Publicado por: big_ed en 13 Agosto 2019, 20:35 pm
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>


Título: Re: ¿por qué es necesaria $_server["php_self"] en el action de un form?
Publicado por: #!drvy en 13 Agosto 2019, 21:29 pm
Citar
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:

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

Citar
no 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.


Citar
O 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


Título: Re: ¿por qué es necesaria $_server["php_self"] en el action de un form?
Publicado por: big_ed en 13 Agosto 2019, 21:35 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
  1. $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


Título: Re: ¿por qué es necesaria $_server["php_self"] en el action de un form?
Publicado por: #!drvy en 13 Agosto 2019, 21:39 pm
Citar
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?

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


Título: Re: ¿por qué es necesaria $_server["php_self"] en el action de un form?
Publicado por: @XSStringManolo en 13 Agosto 2019, 21:41 pm
#!Drvy es correcto el uso de preg_replace con la misma finalidad?


Título: Re: ¿por qué es necesaria $_server["php_self"] en el action de un form?
Publicado por: #!drvy en 13 Agosto 2019, 21:49 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


Título: Re: ¿por qué es necesaria $_server["php_self"] en el action de un form?
Publicado por: @XSStringManolo en 13 Agosto 2019, 22:18 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.


Título: Re: ¿por qué es necesaria $_server["php_self"] en el action de un form?
Publicado por: big_ed en 13 Agosto 2019, 22:25 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.



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

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:


Código:
<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>

Código:
<?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:



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.


Título: Re: ¿por qué es necesaria $_server["php_self"] en el action de un form?
Publicado por: @XSStringManolo 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.
Citar
The 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"
Se ejecutaría el script. Hasta se podría ejecutar en otras partes para acceder a X contenidos y modificarlos. 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


Título: Re: ¿por qué es necesaria $_server["php_self"] en el action de un form?
Publicado por: big_ed en 14 Agosto 2019, 02:50 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"
Se ejecutaría el script. Hasta se podría ejecutar en otras partes para acceder a X contenidos y modificarlos. 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


Título: Re: ¿por qué es necesaria $_server["php_self"] en el action de un form?
Publicado por: @XSStringManolo en 14 Agosto 2019, 03:31 am
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
No tenía ni idea de que no eran compatibles O.o

Disculpa, no los vi, me cuesta leer códigos sin antes darles formato con alguna herramienta.

Yo menos, no se ni defenderme adecuadamente de ataques que sí se realizar... Por algo no publico mis servers y solo acceden usuarios registrados a través de proxies y tengo 50.000 copias de seguridad en todos sitios, le tengo pendrives puestos para archivos importantes y los voy alternando por si hasta me jodiesen el pendrive que está puesto.

Si es para un sitio serio tuyo o si tienes contrato con alguien ten cuidado que si algún usuario del sitio es estafado debido a que se filtran sus credenciales en tu sitio, si te denuncia lo vas a tener que pagar.  :-(




Título: Re: ¿por qué es necesaria $_server["php_self"] en el action de un form?
Publicado por: big_ed en 14 Agosto 2019, 04:58 am
No tenía ni idea de que no eran compatibles O.o

Disculpa, no los vi, me cuesta leer códigos sin antes darles formato con alguna herramienta.

Yo menos, no se ni defenderme adecuadamente de ataques que sí se realizar... Por algo no publico mis servers y solo acceden usuarios registrados a través de proxies y tengo 50.000 copias de seguridad en todos sitios, le tengo pendrives puestos para archivos importantes y los voy alternando por si hasta me jodiesen el pendrive que está puesto.

Si es para un sitio serio tuyo o si tienes contrato con alguien ten cuidado que si algún usuario del sitio es estafado debido a que se filtran sus credenciales en tu sitio, si te denuncia lo vas a tener que pagar.  :-(




entiendo , no es tu rama
yo en cambio si tengo la necesidad de saber la compatibilidad de una tecnologia en todos los navegadores y sus versiones... cuando hago una web la pruebo en al menos los 5 navegadores mas importantes, en pc de escritorio, tablets, moviles, laptops, etc

si, el editor de codigo de muchos foros solo es blanco y negro...yo queria agregarle color al codigo para que se entendiera mejor pero no me lo permitio

que es eso de las credenciales?
yo por si acaso especifico que mi nivel alto es en diseño desde cero y programacion de animaciones...dejo claro que de seguridad informatica y SEO hago lo basico, para que una web funcione bien y sea etica su elaboracion...pero si quieren algo mas robusto y que se posicione en el primer lugar de google entonces que me paguen mas para contratar a un experto en esa rama o que ellos lo incorporen y que meta mano en mi codigo
No se puede saber de todo, quien mucho abarca poco aprieta , o algo asi era  ;D
Mejor especializarse en algo puntual


Título: Re: ¿por qué es necesaria $_server["php_self"] en el action de un form?
Publicado por: #!drvy en 14 Agosto 2019, 10:04 am
Hola,

En general lo tienes bien aunque supongo que esos datos los estas guardando en una base de datos. En tal caso, te recomiendo usar sentencias preparadas si es que no las estas utilizando ya.
https://www.php.net/manual/es/mysqli.quickstart.prepared-statements.php - MySQLi
https://www.php.net/manual/es/pdo.prepared-statements.php - PDO

De todos modos, te dejo el como lo haría yo por si pillas alguna idea o algo.

Código
  1. <?php
  2.  
  3. function validate($input, $type, $required = false)
  4. {
  5.    if ($required && empty($input)) {
  6.        throw new \Exception('No ha rellenado unos de los campos obligatorios');
  7.    }
  8.  
  9.    // Nos aseguramos de que el input no va a ser mayor de 1024 caracteres.
  10.    if (mb_strlen($input, 'utf-8') > 1024) {
  11.        throw new \Exception('Uno de los campos contiene demasiados caracteres.');
  12.    }
  13.  
  14.    switch ($type) {
  15.        case 'user':
  16.            $valid = preg_match('/^[[:alpha:]\s]{2,50}$/iu', $input);
  17.            $error = 'El campo Nombre permite un máximo de 50 caracteres de solo letras mayusculas o minusculas';
  18.            break;
  19.  
  20.        case 'email':
  21.            $valid = filter_var($input, FILTER_VALIDATE_EMAIL);
  22.            $error = 'El campo Correo no es válido.';
  23.            break;
  24.  
  25.        case 'phone':
  26.            $valid = preg_match('/^[0-9]{1,11}$/', $input);
  27.            $error = 'El campo Teléfono permite un máximo de 11 caracteres numericos';
  28.            break;
  29.  
  30.        case 'text':
  31.            $valid = (mb_strlen($input) <= 900);
  32.            $error = 'El campo Texto no puede contener más de 900 caracteres';
  33.            break;
  34.    }
  35.  
  36.    if (!$valid) {
  37.        throw new \Exception($error);
  38.    }
  39.  
  40.    return htmlspecialchars(trim($input), ENT_QUOTES);
  41. }
  42.  
  43. if (isset($_POST['submit'])) {
  44.    try {
  45.        $user = validate($_POST['text'], 'user', true);
  46.        $email = validate($_POST['mail'], 'email', true);
  47.        $phone = validate($_POST['telf'], 'phone');
  48.        $post = validate($_POST['post'], 'text');
  49.  
  50.        // Guardar datos en base de datos con sentencias preparadas
  51.        echo 'Válido';
  52.  
  53.    } catch (\Exception $error) {
  54.        echo $error->getMessage();
  55.    }
  56. }



Las principales diferencias son:

- Meto toda la validación en una función.

- Uso FILTER_VALIDATE_EMAIL (https://www.php.net/manual/es/filter.filters.validate.php) para validar correo en vez de regex. En tu regex por ejemplo, el correo juan@undominiomuylargo.productions no validaria porque además de sobrepasar los 30 caracteres que le pones de límite en general, sobrepasa los 9 caracteres que le pones de limite al TLD (aquí tienes la lista de TLDS actuales (http://data.iana.org/TLD/tlds-alpha-by-domain.txt)), según estándar se permite hasta 63 caracteres de longitud para un TLD..

- Validó la longitud min/max de los campos en el propio regex ahorrando un IF.

- Garantizo que los caracteres son tratados como UTF-8 (https://www.php.net/manual/es/book.mbstring.php) sobre todo en el campo de Nombre donde si te fijas usó un Character class (https://www.php.net/manual/en/regexp.reference.character-classes.php) de regex para decirle que coja todo carácter alpha (letras) y trato la expresión como unicode. Por defecto, si no tratas los strings como multibyte, los caracteres fuera del ASCII genérico son tratados como dos bytes. Por ejemplo strlen devuelve 2 para la letra Ñ (mb_strlen devuelve 1). Así permites que haya nombres como Iñaki o Jóse.


Si te soy sincero, yo no utilizariá htmlspecialchars para "sanitizar" el input. Dado que las sentencias preparadas ya se encargan de que no haya una inyección SQL por culpa de caracteres raros, guardariá los datos sin "sanitizar" (aparte de los requerimientos como por ejemplo solo números para el teléfono) y la hora de imprimir (mostrar) dicho campo, utilizariá htmlentities.


Citar
Pero ¿cuáles son exactamente los caracteres que debo evitar?
POrque yo podría impedirlos con expresiones regulares, pero quisiera saber cuáles son.


Lo peor que puedes hacer es una lista negra de caracteres. Es mejor hacer una lista blanca y permitir solo los caracteres que tu quieras a hacer una negra y que tengas que estar cada 2x3 metiendo caracteres nuevos porque resulta que ó no es lo mismo que ò pero el sistema los trata igual. Es un poco como el intento de censurar palabras malsonantes en este foro, la palabra ***** esta censurada (te pone las * cuando lo publicas) pero la palabra m.ierda o mierda o mierda no  :laugh:


Citar
yo en cambio si tengo la necesidad de saber la compatibilidad de una tecnologia en todos los navegadores y sus versiones... cuando hago una web la pruebo en al menos los 5 navegadores mas importantes, en pc de escritorio, tablets, moviles, laptops, etc

No se, ya nadie da soporte para IE9.. es un poco absurdo hoy en dia. Nosotros por ejemplo solo damos soporte para las 2 últimas versiones de cada navegador (IE10, IE11). Es una versión que tiene ya 8 años y no es tan vital como IE8. Es decir, si tienes IE 9, no hay ninguna razón para que no tengas IE 10 o IE 11. IE 8 en cambio es un poco más vital en ese sentido porque fue la última versión de IE con soporte para XP. Pero vamos, estamos hablando de navegadores que llevan AÑOS sin actualizarse y con estándares obsoletos cuanto menos.

Saludos


Título: Re: ¿por qué es necesaria $_server["php_self"] en el action de un form?
Publicado por: big_ed en 14 Agosto 2019, 19:14 pm
Hola,

En general lo tienes bien aunque supongo que esos datos los estas guardando en una base de datos. En tal caso, te recomiendo usar sentencias preparadas si es que no las estas utilizando ya.
https://www.php.net/manual/es/mysqli.quickstart.prepared-statements.php - MySQLi
https://www.php.net/manual/es/pdo.prepared-statements.php - PDO

De todos modos, te dejo el como lo haría yo por si pillas alguna idea o algo.

Código
  1. <?php
  2.  
  3. function validate($input, $type, $required = false)
  4. {
  5.    if ($required && empty($input)) {
  6.        throw new \Exception('No ha rellenado unos de los campos obligatorios');
  7.    }
  8.  
  9.    // Nos aseguramos de que el input no va a ser mayor de 1024 caracteres.
  10.    if (mb_strlen($input, 'utf-8') > 1024) {
  11.        throw new \Exception('Uno de los campos contiene demasiados caracteres.');
  12.    }
  13.  
  14.    switch ($type) {
  15.        case 'user':
  16.            $valid = preg_match('/^[[:alpha:]\s]{2,50}$/iu', $input);
  17.            $error = 'El campo Nombre permite un máximo de 50 caracteres de solo letras mayusculas o minusculas';
  18.            break;
  19.  
  20.        case 'email':
  21.            $valid = filter_var($input, FILTER_VALIDATE_EMAIL);
  22.            $error = 'El campo Correo no es válido.';
  23.            break;
  24.  
  25.        case 'phone':
  26.            $valid = preg_match('/^[0-9]{1,11}$/', $input);
  27.            $error = 'El campo Teléfono permite un máximo de 11 caracteres numericos';
  28.            break;
  29.  
  30.        case 'text':
  31.            $valid = (mb_strlen($input) <= 900);
  32.            $error = 'El campo Texto no puede contener más de 900 caracteres';
  33.            break;
  34.    }
  35.  
  36.    if (!$valid) {
  37.        throw new \Exception($error);
  38.    }
  39.  
  40.    return htmlspecialchars(trim($input), ENT_QUOTES);
  41. }
  42.  
  43. if (isset($_POST['submit'])) {
  44.    try {
  45.        $user = validate($_POST['text'], 'user', true);
  46.        $email = validate($_POST['mail'], 'email', true);
  47.        $phone = validate($_POST['telf'], 'phone');
  48.        $post = validate($_POST['post'], 'text');
  49.  
  50.        // Guardar datos en base de datos con sentencias preparadas
  51.        echo 'Válido';
  52.  
  53.    } catch (\Exception $error) {
  54.        echo $error->getMessage();
  55.    }
  56. }



Las principales diferencias son:

- Meto toda la validación en una función.

- Uso FILTER_VALIDATE_EMAIL (https://www.php.net/manual/es/filter.filters.validate.php) para validar correo en vez de regex. En tu regex por ejemplo, el correo juan@undominiomuylargo.productions no validaria porque además de sobrepasar los 30 caracteres que le pones de límite en general, sobrepasa los 9 caracteres que le pones de limite al TLD (aquí tienes la lista de TLDS actuales (http://data.iana.org/TLD/tlds-alpha-by-domain.txt)), según estándar se permite hasta 63 caracteres de longitud para un TLD..

- Validó la longitud min/max de los campos en el propio regex ahorrando un IF.

- Garantizo que los caracteres son tratados como UTF-8 (https://www.php.net/manual/es/book.mbstring.php) sobre todo en el campo de Nombre donde si te fijas usó un Character class (https://www.php.net/manual/en/regexp.reference.character-classes.php) de regex para decirle que coja todo carácter alpha (letras) y trato la expresión como unicode. Por defecto, si no tratas los strings como multibyte, los caracteres fuera del ASCII genérico son tratados como dos bytes. Por ejemplo strlen devuelve 2 para la letra Ñ (mb_strlen devuelve 1). Así permites que haya nombres como Iñaki o Jóse.


Si te soy sincero, yo no utilizariá htmlspecialchars para "sanitizar" el input. Dado que las sentencias preparadas ya se encargan de que no haya una inyección SQL por culpa de caracteres raros, guardariá los datos sin "sanitizar" (aparte de los requerimientos como por ejemplo solo números para el teléfono) y la hora de imprimir (mostrar) dicho campo, utilizariá htmlentities.



Lo peor que puedes hacer es una lista negra de caracteres. Es mejor hacer una lista blanca y permitir solo los caracteres que tu quieras a hacer una negra y que tengas que estar cada 2x3 metiendo caracteres nuevos porque resulta que ó no es lo mismo que ò pero el sistema los trata igual. Es un poco como el intento de censurar palabras malsonantes en este foro, la palabra ***** esta censurada (te pone las * cuando lo publicas) pero la palabra m.ierda o mierda o mierda no  :laugh:


No se, ya nadie da soporte para IE9.. es un poco absurdo hoy en dia. Nosotros por ejemplo solo damos soporte para las 2 últimas versiones de cada navegador (IE10, IE11). Es una versión que tiene ya 8 años y no es tan vital como IE8. Es decir, si tienes IE 9, no hay ninguna razón para que no tengas IE 10 o IE 11. IE 8 en cambio es un poco más vital en ese sentido porque fue la última versión de IE con soporte para XP. Pero vamos, estamos hablando de navegadores que llevan AÑOS sin actualizarse y con estándares obsoletos cuanto menos.

Saludos

. Tú cuando haces un formulario de contacto guardas los datos en una base???
Porque yo los voy a enviar a un correo directamente, con la funcion MAIL.

. Entonces con mi expresion regular sería solo cuestion de aumentarles los caracteres permitidos al correo..
Y tienes razon, creo que puedo meter mas condiciones en el regexp, como por ejemplo la de limite de longitud (y todas las que pueda) y asi  ahorrame codigo

. SI no voy a enviar los datos a una base , y por ende no voy a poder usar las sentencias preparadas ¿entonces esta bien que siga con HTMLSPECIALCHARS?...Aunque francamente no entiendo por que debo repetir la limpieza de datos, ya que mis expresiones regulares de por si ya evitan que se ingresen caracteres extraños ¿acaso las expresiones regulares no son 100% seguras? Digo, para que usar htmlspecialchars y addslashes , si mi expresion ya restringe todo eso...siento que es redundante

. Bueno pero al menos dime los caracteres que debo evitar, no para hacer una lista negra, sino para yo saberlo

. Es verdad que ya casi nadie da soporte a IE9,10 desde que aparecio Edge, aunque igual debe haber gente que aun lo tenga , y bueno no me quiero arriesgar, tampoco es que IE9 Y 10 sean muy antiguos.....en cambio i8 ese si ya fue...yo tengo ese trauma de que por ejemplo alguna vez algun viejito me pida ver mi pagina, ingrese y se vea toda desconfigurada

. En conclusion y para finalizar, para hacer un formulario seguro ¿debo cuidar que no ingresen sentencias en la url y en los campos de inputs?
Yo quiero que me digas en terminos simples cual debe ser mi objetivo para hacer el formulario seguro, que lo digas directamente, para yo asi ingeniarmelas ...porque si solo sigo unos pasos que me dicen pero si saber para que sirven exactamente entonces nunca voy a ser bueno en esto de la seguridad, porque solo estaria repitiendo lo que otros hacen sin saber su verdadera finalidad...
Quiero que me digas por ejemplo "mira, solo debes evitar que en los inputs pongan este signo '>>>'".. ..entonces yo ya sabria cual es mi meta y simplemente invertiria tiempo en mi ingenio

Gracias