Validar la entrada es comprobar antes de usar
Validar la entrada es comprobar que los datos que llegan a un programa tienen la forma esperada antes de usarlos. Así un error o un ataque se detiene en la puerta.
Piensa en el formulario de inscripción a un curso de idiomas. Pide una edad y alguien escribe "veinte" o un texto larguísimo.
Al final de esta lección
Nota
Puedo comprobar con una lista de permitidos que un dato es válido antes de que el programa lo use.
Palabras clave
| Palabra | Qué significa | Ejemplo |
|---|---|---|
| Validar | comprobar que un dato cumple las reglas | |
| Lista de permitidos | lista de lo único que se acepta | ["Fisica", "Quimica"] |
| Lista de prohibidos | lista de lo que se rechaza; lo demás pasa | |
| Tipo | clase de dato: texto, número, fecha | |
| Longitud | cuántos caracteres tiene un texto |
Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.
Una lista de permitidos acepta solo lo previsto
Hay dos maneras de filtrar. La lista de prohibidos rechaza lo que se sabe que es malo. La lista de permitidos acepta solo lo que se sabe que es bueno.
La segunda es más segura. Nadie puede inventar una entrada rara que tu lista de prohibidos olvidó.
Ejemplo resuelto: el campo "grado" del formulario
| El visitante escribe | Con lista de prohibidos | Con lista de permitidos |
|---|---|---|
| Fisica | Pasa | Pasa: está en la lista |
| Fisica; DROP | Pasa si nadie pensó en ";" | Rechazada: no está en la lista |
| Fìsica | Pasa | Rechazada: no coincide |
Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.
Comprobar con una lista de permitidos
degrees = ["Fisica", "Quimica", "Historia"]
# Cambia choice por "Quimica" y luego por "Magia", y pulsa Run.
choice = "Fisica"
if choice in degrees:
print("valido")
else:
print("rechazado")
Comprueba el tipo, la longitud y el rango
Para cada campo pregunta tres cosas. ¿Es del tipo esperado, por ejemplo solo dígitos? ¿Tiene la longitud razonable? ¿Está dentro de un rango sensato?
Un código postal español son cinco dígitos. Una edad de inscripción va de 16 a 99.
Tipo, rango y longitud de dos campos
age = "19"
postal = "28013"
# Cambia age por "1x" y luego por "150", y pulsa Run.
if age.isdigit() and 16 <= int(age) <= 99:
print("edad valida")
else:
print("edad invalida")
if len(postal) == 5 and postal.isdigit():
print("codigo postal valido")
El servidor debe repetir las comprobaciones del navegador
El navegador puede avisar al visitante de un error antes de enviar el formulario. Es una comodidad. Pero el visitante puede saltarse el navegador y enviar la petición directamente.
Por eso la validación que protege es la del servidor. La del navegador solo ayuda.
Mira cómo trata la tienda lo raro
La tienda de tu laboratorio no comprueba casi nada de lo que le llega. Ejecuta estos tres comandos. Solo miran. El primero busca una palabra que no existe y cuenta los caracteres de la respuesta. El segundo envía la búsqueda sin ninguna palabra. El tercero cuenta los caracteres de un nombre.
La regla única
Advertencia
Ataca solo tu copia privada del laboratorio, que no tiene salida a internet. Probar un sistema ajeno, o sin permiso, es delito en casi todos los países.
Una palabra que no existe
curl -s -G --data-urlencode "q=zzz" http://app:8000/search | wc -cSe muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Sin ninguna palabra de búsqueda
curl -s http://app:8000/search | wc -lSe muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Contar los caracteres de un nombre
printf '%s' "Baker's apron" | wc -cSe muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Qué te dicen las tres respuestas
El primero imprime 0: no hay respuesta, y la tienda no se queja. El segundo imprime 5: sin palabra, la tienda devuelve cinco productos. El tercero imprime 13, la longitud de ese nombre.
La tienda acepta una búsqueda vacía y una de cualquier longitud. Una regla de longitud y de caracteres sería un primer filtro.
Un error frecuente
Advertencia
Mucha gente cree que validar es lo mismo que evitar la inyección. No es así. Validar reduce lo que entra, pero un nombre válido como "O'Brien" lleva un apóstrofo. La validación no sustituye a los parámetros: úsalas las dos.