La validación de entrada de datos siempre fue una lucha interna para mí.
A punto de agregar un marco de seguridad real y un código a nuestro proyecto de reescritura de aplicaciones heredadas (que hasta ahora mantiene el código de seguridad heredado y la validación de datos heredados), me pregunto nuevamente cuánto debería validar, donde, etc.
Durante mis 5 años como desarrollador profesional de Java, creé y perfeccioné mis reglas personales para la validación de entrada de datos y medidas de seguridad. Como me gusta mejorar mis métodos, me gustaría que algunos escuchen algunas ideas de ustedes. Las reglas y procedimientos generales están bien, y los específicos de Java también.
En resumen, estas son mis pautas (expuestas en un estilo de aplicación web de 3 niveles), con breves explicaciones:
1.o nivel del lado del cliente (navegador): validación mínima, solo reglas invariables (campo de correo electrónico obligatorio, debe seleccionar un elemento y similares); uso de validación adicional como "entre 6 y 20 caracteres" menos frecuente, ya que esto aumenta el trabajo de mantenimiento en los cambios (se puede agregar una vez que el código comercial es estable);
Lado del servidor de primer nivel (manejo de comunicación web, "controladores"): no tengo una regla para este, pero creo que solo se deben manejar aquí los errores de manipulación de datos y ensamblaje / análisis (el campo de cumpleaños no es una fecha válida); agregar más validación aquí fácilmente lo convierte en un proceso realmente aburrido;
2do nivel (capa empresarial): validación sólida como una roca, nada menos; formato de datos de entrada, rangos, valores, verificación interna del estado si el método no se puede llamar en cualquier momento, roles / permisos del usuario, etc. use la menor cantidad posible de datos de entrada del usuario, recupere nuevamente de la base de datos si es necesario; si consideramos también los datos recuperados de la base de datos como entrada, solo los validaría si se sabe que algunos datos específicos no son confiables o están lo suficientemente corruptos en la base de datos: la escritura fuerte hace la mayor parte del trabajo aquí, en mi humilde opinión;
3er nivel (capa de datos / DAL / DAO): nunca creí que se necesitara mucha validación aquí, ya que solo se supone que la capa empresarial tiene acceso a los datos (validar quizás en algún caso como "param2 no debe ser nulo si param1 es verdadero"); observe, sin embargo, que cuando me refiero a "aquí" me refiero a "código que accede a la base de datos" o "métodos de ejecución de SQL", la base de datos en sí es completamente lo contrario;
la base de datos (modelo de datos): debe ser tan bien pensada, fuerte y autoejecutable como para evitar datos incorrectos y corruptos en la base de datos tanto como sea posible, con buenas claves primarias, claves externas, restricciones, tipo / longitud / tamaño de datos / precisión y así sucesivamente: estoy dejando de lado los desencadenantes, ya que tienen su propia discusión privada.
Sé que la validación de datos temprana es buena y en cuanto al rendimiento, pero la validación de datos repetida es un proceso aburrido, y admito que la validación de datos en sí misma es bastante molesta. Es por eso que tantos codificadores lo omiten o lo hacen a mitad de camino. Además, cada validación duplicada es un posible error si no están sincronizados todo el tiempo. Esas son las principales razones por las que hoy en día prefiero dejar que la mayoría de las validaciones lleguen a la capa empresarial, a expensas del tiempo, el ancho de banda y la CPU, excepciones manejadas caso por caso.
Entonces, ¿qué piensas sobre esto? Opiniones opuestas? ¿Tienes otros procedimientos? ¿Una referencia a ese tema? Cualquier contribución es válida.
Nota: si está pensando en la manera Java de hacer las cosas, nuestra aplicación está basada en Spring con Spring MVC y MyBatis (el rendimiento y el modelo de base de datos incorrecto descartan las soluciones ORM); Planeo agregar Spring Security como nuestro proveedor de seguridad más JSR 303 (¿Validador de Hibernación?)
¡Gracias!
Editar: algunas aclaraciones adicionales en la tercera capa.
Respuestas:
Su validación debe ser consistente. Entonces, si un usuario ingresa algunos datos en el formulario web que se determina que es válido, la capa de base de datos no debe rechazarlo debido a algunos criterios que no implementó en el lado del cliente.
Como usuario, nada sería más molesto que ingresar una página llena de datos aparentemente correctamente solo después de un importante viaje de ida y vuelta a la base de datos que algo está mal. Esto sería particularmente cierto si hubiera tropezado con alguna validación del cliente en el proceso.
Debe tener la validación en varios niveles, ya que los está exponiendo y potencialmente no tiene control sobre quién los está llamando. Por lo tanto, debe organizar (en la medida de lo posible) para que su validación se defina en un lugar y se llame desde donde sea necesario. Cómo se arregla esto dependerá de su idioma y marco. En Silverlight (por ejemplo) puede definirlo en el lado del servidor y con los atributos adecuados se copiará en el lado del cliente para su uso allí.
fuente
En un sistema relacional, lo veo como un enfoque de tres capas. Cada capa está limitada por las siguientes:
La respuesta ideal a esto sería un sistema que le permita definir las restricciones en las tres capas en un solo lugar. Esto implicaría cierta generación de código para SQL, y al menos una validación basada en datos para el cliente y el servidor.
No sé si hay una bala de plata aquí ... pero como estás en la JVM, te sugiero que mires a Rhino para al menos compartir el código de validación de JavaScript entre el cliente y el servidor. No escriba su validación de entrada dos veces.
fuente
Esto esta muy mal. El lugar más importante para tener la validación es en la propia base de datos. Los datos casi siempre se ven afectados por algo más que la aplicación (incluso cuando cree que no lo será) y, en el mejor de los casos, es irresponsable no colocar los controles adecuados en la base de datos. Hay una mayor pérdida de integridad de datos de una decisión de no hacer esto que cualquier otro factor. La integridad de los datos es crítica para el uso a largo plazo de la base de datos. Nunca he visto ninguna base de datos que no haya aplicado reglas de integridad a nivel de base de datos que contengan buenos datos (y he visto los datos en literalmente miles de bases de datos).
Lo dice mejor que yo: http://softarch.97things.oreilly.com/wiki/index.php/Database_as_a_Fortress
fuente
Todo lo anterior supone que los desarrolladores y mantenedores son perfectos y escriben código perfecto que siempre se ejecuta perfectamente. Las futuras versiones de software conocen todas las suposiciones que hizo y nunca documentó, y los usuarios y piratas informáticos que introducen datos en el sistema de formas que nunca imaginó.
Claro, demasiada validación es algo malo, pero suponiendo que los programas, las redes y los sistemas operativos sean perfectos, los piratas informáticos no atravesarán su firewall, un DBA no "ajustará" manualmente la base de datos probablemente sea peor.
Dibuje círculos de límites alrededor de las cosas, identifique los modos de falla contra los que protege e implemente un nivel apropiado de verificación para ese límite. Por ejemplo, su base de datos nunca debería ver datos no válidos, pero ¿cómo podría suceder y qué sucede si lo hace? ¿Quién es su usuario, cuál es el costo del fracaso?
Estudie los modelos de seguridad física mundial, la seguridad debe estar en capas, como una cebolla. Una pared gruesa se considera poca seguridad. La validación de datos debe considerarse de la misma manera.
fuente
Dos breves reglas generales para la validación:
Si va a llamar a cualquier cosa que no garantice que devolverá algo (error, excepción) para informarle sobre una entrada no válida de una manera que pueda devolverle a la persona que llama, valídela.
Si va a hacer algo más con los datos (tomar decisiones, hacer cálculos matemáticos, almacenarlos, etc.), valídelos.
fuente