Tutorial Limpiar formularios post y gets de malintencionados [Novatos]

Estado
No está abierto para más respuestas.
Mensajes
166
Puntuación de reacción
0
Buenas queria compartir con ustedes estos datos que me parecen importantes como medida de seguridad a la hora de enviar datos por formularios, de esta formas evitas ser vulnerado!


Limpiar formularios post y gets de malintencionados [Novatos]





Verificaciones del lado del cliente


Para las verificaciones del lado del cliente tenemos que tener en cuenta los siguientes puntos:

  1. No son seguros para usuarios avanzados en computación.
  2. Pueden ser manipulados desde la consola de los navegadores.
  3. Se pueden implementar en HTML5 verificaciones mas fáciles por ejemplo: Emails y Obligatorio
  4. Es mejor hacer reforzar las validaciones con Javascript

Para nuestro ejemplo primero vamos a hacer un pequeño formulario en HTML con verificaciones basicas como el siguiente:


HTML:
<form method="post">

<input type="text" name="nombre" placeholder="Escribe tu nombre aquí">

<input type="email" name="email" placeholder="Escribe tu E-mail aquí">

</form>

Para verificaciones del lado del cliente mas avanzadas y superiores recomiendo usar Parsley - The ultimate JavaScript form validation library

Sin duda es para mi la mejor librería para este tipo de verificaciones y lo haces con JavaScript.





Verificaciones del lado del servidor


Hay muchos puntos que tratar a la hora de hacer seguros los formularios para evitar que te inyecten por ahí y un punto muy importante es ver la seguridad del lado del servidor.

Hay que revisar siempre los siguientes puntos:

  1. Limpiar los datos recibidos en el servidor.
  2. Limitar el tamaño al justo y necesario para el tipo de entrada que vas a almacenar o que vas a recibir en el archivo procesador.
  3. No uses shorttags <? ?> la mejor manera de programar sin que te de errores de compatibilidad es indicandole al codigo el tag completo <?php ?>
  4. Documenta siempre lo que estas programando porque se te puede olvidar que hace una parte del codigo.
  5. Si se recibe un password lo mejor es encriptarlo con un hash unico ya que MD5 o SHA-1 no son 100% seguros.

A continuación les dejo un código sencillo que recibe los datos del formulario anteriormente creado.


PHP:
<?php

//Recibimos los datos por POST y los almacenamos en las variables correspondientes

$nombre = $_POST["nombre"];
$email = $_POST["email"];


/*Limpiamos lo strings de cualquier intento de hacking.
*strip_tags elimina etiquetas
*trim elimina espacios en blanco
*real_escape_string devuelve un valor real para ser ingresado en la base de datos.
*/

$nombre = strip_tags(trim($mysqli->real_escape_string($nombre)));
$email= strip_tags(trim($mysqli->real_escape_string($email)));

// Calculamos la longitud de cada cadena

$longitud_nombre = strlen($email);
$longitud_email = strlen($email);

//Filtramos que el nombre no sea mayor a 20 por seguridad y para reducir el tamaño en la base de datos y evitar que pongan cosas tontas

if($longitud_nombre < 20){

//Filtramos que el emailno sea mayor a 20 por seguridad y esto incluye ya contando el tamaño del dominio, por ejemplo hotmail.com

   if($longitud_email < 80){

      //Validamos si el email es valido desde el servidor

      if(filter_var($email, FILTER_VALIDATE_EMAIL)){


        //Revisamos en la base de datos si el email esta en uso (Solo para forms de registros o ingreso de datos y no se permite repetir el campo)
	$sql = "SELECT * FROM nombretabla WHERE Email = '$email'";
	$resultado = $mysqli->query($sql);
         if($resultado->num_rows < 1){

            //Si suspera todas las validaciones anteriores puedes ingresar los datos a la BD o sino puedes mostrarlos o guardarlos como tu quieras.

            $insertardatos = "INSERT INTO nombretabla (Nombre,Email) VALUES ('$nombre','$email')";											
            $mysqli->query($insertardatos);

            echo "Datos agregados exitosamente.";

         }else{

         echo "El E-mail ya esta en uso.";

         }

      }else{

      echo "El E-mail no es valido.";

      }

   }else{

   echo "El E-mail excede la longitud permitida.";

   }

}else{

echo "El nombre excede la longitud permitida.";

}


?>

Si tienen dudas con alguna parte del código solo me avisan y estaré complacido de responderles.

Continuando con el tema les doy unos extras y consejos.





Extras y Tips



  • Si no tienen dinero para costear su hosting vps y licencias usen hosting compartidos altamente seguros que les ofrezcan como mínimo Anti-Ddos (Con esto estamos constatando que el serivicio es de calidad).
  • Si van a usar un VPS asegúrate de tener el presupuesto para cubrir el servidor adecuado, la licencia de panel si utilizaras, recomiendo incluir Clouduflare, aparte recomiendo Nginx en vez de apache o lite speed esto para acelerar los servicios webs del servidor y en definitiva un buen antivirus, recuerden que van a tener acceso ftp si asi deciden instalarlo y así mismo sus correos pertinentes creo yo.
  • Si vas a transferir datos de alta importancia no olvides tener tu certificado SSL de buena calidad recomiendo sin duda alguna los certificados de www.comodo.com
  • Se detallista a la hora de buscar errores en el sistema no dejes ni un solo detalle por revisar ya que el mas mínimo error puede ser el acabose de tu sitio web.


"A los programadores que se inician, no tengan miedo de desarrollar por el tema de la seguridad, día a día que avancen mejoraran y se perfeccionaran con el fin de ser mejores"

Hasta aquí llega este tutorial aparte de que ya es muy tarde y tengo sueño, si alguien desea que haga un tutorial sobre un tema de programación en especifico comentelo en este tema y lo realizare si esta dentro de mi posibilidades.

Saludos! :)


 
Última edición:
Mensajes
84
Puntuación de reacción
0
Buen tutorial!

A mi parecer creo que faltarían un par de puntos más que considero esenciales explicando un poquito más el apartado técnico: protección frente a ataques XSS y inyecciones SQL, extendiendo lo que ya explicaste:


  • Saneando los argumentos de las consultas, reemplazando los caracteres especiales por su equivalente textual (utilizando en PHP la función htmlspecialchars(), por ejemplo)
  • Realizando las consultas de esta forma (mysqli sanea la consulta por ti):
Código:
$stmt = mysqli->prepare("SELECT col1 FROM t1 WHERE col2 = ?");
$stmt->bind_param("s", $col2_arg);
$stmt->execute();

De todas formas, te felicito por el tuto :mola:
 
Última edición:

lobogris

Platino
Usuario de Bronce
Mensajes
1,537
Puntuación de reacción
0
Sin ánimo de ofender, y tú no te estás iniciando?

El código deja mucho que desear además de que hay cosas que no son lógicas, como por ejemplo escapar las cadenas para la base de datos y posteriormente eliminar lo que no interesa para después validarlo...

Una regla (que habrá situaciones en las que no aplica, pero en este caso sí) es no modificar los datos introducidos por el usuario, el usuario debe saber lo que tiene que introducir, si lo que introduce parece no ser vaĺido se le dice, no se modifica sin más y todos contentos, que no aplique a tus reglas no quiere decir que sea un hacker, por ejemplo hay webs que no aceptan UTF-8, yo pongo mi nombre "Óscar" y en la mayoría te avisan "eh, tu nombre contiene caracteres no válidos", no es nada adecuado coger y modificar mi nombre por "scar" porque la "Ó" no nos interesa.

El código mejorado:

PHP:
<?php

array_walk_recursive($_POST, function (&$val) { 
    $val = trim($val); 
});

$error = FALSE;

if (mb_strlen($_POST['nombre']) > 20) {
    $error = 'El nombre excede la longitud permitida.';
}
else if (! preg_match('/^[\p{L} ]+$/u', $_POST['nombre'])) {
    $error = 'El nombre contiene caracteres no válidos.';
}
else if (strlen($_POST['email']) > 80) {
    $error = "El E-mail excede la longitud permitida.";
}
else if (! filter_var($_POST['email'], FILTER_VALIDATE_EMAIL)) {
    $error = "El E-mail no es valido.";
}
else {
    # Utilizar PDO, que ya nos ofrece escapado de datos
    # ...

    $sth = $dbh->prepare('INSERT INTO x (Nombre,Email) VALUES (:name, :email)');
    
    $sth->bindParam(':name',  $_POST['nombre'], PDO::PARAM_STR);
    $sth->bindParam(':email', $_POST['email'],  PDO::PARAM_STR);

    $sth->execute();
}

echo $error ?: 'Datos agregados exitosamente.';
 
Mensajes
166
Puntuación de reacción
0
Buen tutorial!

A mi parecer creo que faltarían un par de puntos más que considero esenciales explicando un poquito más el apartado técnico: protección frente a ataques XSS y inyecciones SQL, extendiendo lo que ya explicaste:


  • Saneando los argumentos de las consultas, reemplazando los caracteres especiales por su equivalente textual (utilizando en PHP la función htmlspecialchars(), por ejemplo)
  • Realizando las consultas de esta forma (mysqli sanea la consulta por ti):
Código:
$stmt = mysqli->prepare("SELECT col1 FROM t1 WHERE col2 = ?");
$stmt->bind_param("s", $col2_arg);
$stmt->execute();

De todas formas, te felicito por el tuto :mola:


Si de hecho faltan cosas esenciales pero como lo hice para novatos es para que vean la logica y traveseen un poco.



Sin ánimo de ofender, y tú no te estás iniciando?

El código deja mucho que desear además de que hay cosas que no son lógicas, como por ejemplo escapar las cadenas para la base de datos y posteriormente eliminar lo que no interesa para después validarlo...


Tengo ya rato de andar programando y el código como dice el titulo es para novatos, no me puedo adentrar en enseñarles a caminar sin antes que aprendan a gatear o arrastrarse.


Prácticamente no estoy eliminando nada que no interese, simplemente cuidando lo que ingresa por los inputs, son dos lógicas de programación distintas y pero aun así como ya comente anteriormente es para que los usuarios novatos del foro traveseen el código!
 

TriaSev

Piedra
Usuario de Piedra
Mensajes
52
Puntuación de reacción
0
Lo mejor es utilizar mysqli_real_escape_string();
 
Estado
No está abierto para más respuestas.
Arriba