Cita de: #!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 (php) [Seleccionar]<?php
function validate($input, $type, $required = false)
{
if ($required && empty($input)) {
throw new \Exception('No ha rellenado unos de los campos obligatorios');
}
// Nos aseguramos de que el input no va a ser mayor de 1024 caracteres.
if (mb_strlen($input, 'utf-8') > 1024) {
throw new \Exception('Uno de los campos contiene demasiados caracteres.');
}
switch ($type) {
case 'user':
$valid = preg_match('/^[[:alpha:]\s]{2,50}$/iu', $input);
$error = 'El campo Nombre permite un máximo de 50 caracteres de solo letras mayusculas o minusculas';
break;
case 'email':
$valid = filter_var($input, FILTER_VALIDATE_EMAIL);
$error = 'El campo Correo no es válido.';
break;
case 'phone':
$valid = preg_match('/^[0-9]{1,11}$/', $input);
$error = 'El campo Teléfono permite un máximo de 11 caracteres numericos';
break;
case 'text':
$valid = (mb_strlen($input) <= 900);
$error = 'El campo Texto no puede contener más de 900 caracteres';
break;
}
if (!$valid) {
throw new \Exception($error);
}
return htmlspecialchars(trim($input), ENT_QUOTES);
}
if (isset($_POST['submit'])) {
try {
$user = validate($_POST['text'], 'user', true);
$email = validate($_POST['mail'], 'email', true);
$phone = validate($_POST['telf'], 'phone');
$post = validate($_POST['post'], 'text');
// Guardar datos en base de datos con sentencias preparadas
echo 'Válido';
} catch (\Exception $error) {
echo $error->getMessage();
}
}
Las principales diferencias son:
- Meto toda la validación en una función.
- Uso FILTER_VALIDATE_EMAIL 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), 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 sobre todo en el campo de Nombre donde si te fijas usó un Character class 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
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