Programacion Segura.

Leyendo el articulo Enseñanza de la programación segura, por MattBishop y Deborah Frincke de la revista b:Secure, Enero-Febrero. Me que de muy interesado en el tema en el ellos hablan en resumen de la capacidad especifica para escribir un código seguro y los principios que fundamenta la escritura de código seguro, también hablan de:
¿qué es el aseguramiento?, el diseño de la seguridad como componente básico ya integrado, la importancia de lo general, el acercamiento a la base de los principios, ¿qué papel hacen las listas de control?.
Y me pregunto si alguien pueda aconsejarme con este tema dirigido a Java.
Noto la diferencia entre lo escrito en los manuales, pero también lo veo que en la practica todo es muy personal, con respecto de como escribir código seguro.

Opciones de visualización de comentarios

Seleccione la forma que prefiera para mostrar los comentarios y haga clic en «Guardar las opciones» para activar los cambios.
Imagen de ezamudio

En general

En general es muy cierto eso de que la seguridad debe ser parte del diseño de cualquier sistema o aplicación desde el principio, para que sea efectiva. Cuando se quiere poner después es un problema y por lo general no funciona. Los conceptos aplican a cualquier lenguaje.

Alguna vez di una plática sobre seguridad en aplicaciones Java y posteriormente publiqué algunos ejemplos en mi blog. Son ejemplos muy simples para ilustrar un concepto, un tipo de ataque, y posibles soluciones (también simples pero no por eso menos efectivas, aunque obviamente hay cosas más elaboradas). Algo que hay que considerar muy importante es que no siempre la solución está en meter código, usar ciertas librerías, etc, sino también en la manera de diseñar las cosas, identificar vulnerabilidades desde el principio, y conocer herramientas que ayuden a incrementar la seguridad por fuera de la aplicación (VPN, SSH, IDS, etc).

Ejemplo de DoS

Ejemplo de inyección de SQL (tristemente sigue ocurriendo en el mundo Java a pesar de tener todas las herramientas para evitarlo)

Ejemplo de XSS (también otro popular en aplicaciones web).

Algunos libros que recomiendo son The Art of Intrusion de Kevin Mitnick y Secrets & Lies de Bruce Schneier (el Chuck Norris de la criptografía).

Imagen de rodrigo salado anaya

Entiendo.

Jejeje estas un poco loco Ezamudio jajaja (es broma :P), las entradas de tu blog que me pasaste son geniales gracias. También me preocupa mucho el tema de desbordamiento temporal de memoria, o los accesos no deseados por poner un 'public' en ves de un 'private' y todo eso. Por ejemplo en el caso del desbordamiento de memoria temporal en java, ¿qué es necesario hacer, para lograrlo?, por ejemplo declarar un arreglo de 100 x 100 y que por mera x o y razón se creen 10,000 objetos que contengan un arreglo definido así en una maquina muy modesta, en realidad no se. Cuales son los errores mas comunes en Java, como en 'c' un puntero mal echo te jode por completo. Recuerdas de algo que no se deba hacer nunca en Java, que en tu experiencia te allá costado un par de noches en vela :P.

Imagen de ezamudio

Inputs

Los problemas que yo he tenido es por no validar entradas de usuario (o incluso de otros sistemas).

Un ejemplo: En un socket de ISO8583 primero me envian 2 bytes con el encabezado del mensaje; se interpretan como un numero entero sin signo, es decir de 0 a 65535. En la práctica sé que no habrá mensajes ni siquiera de 1000 bytes, pero si alguien se conecta y envia caracteres, se pueden interpretar como números muy largos, de modo que si no valido la longitud, puedo estar creando buffers de varios KB que ocupan memoria de manera innecesaria, lo cual vuelve a la aplicación vulnerable a un DoS (solamente tienen que abrir muchas conexiones y enviar 0xffff para que se termine la memoria de la app), por lo cual valido la longitud leida antes de crear el buffer.

En general cuando tienes puertos abiertos para recibir conexiones y recibir datos, o tienes un objeto que puede recibir cosas por RMI, etc, tienes que ser algo paranoico y programar las cosas de manera que si te envian algo que de plano no puedes validar, rechaces por completo los datos y cierres la conexión. Esto es porque en la realidad sí puede haber alguien tratando de meterse a un servidor, escaneando puertos abiertos, detecta un puerto y empiezan a enviar datos a ver si responde a algún protocolo conocido, o arroja información de lo que hay del otro lado (hay protocolos que requieren que el server arroje algo de info al cliente en cuanto se conecta, por ejemplo).

En aplicaciones web, tienes que considerar que no todo mundo utilizará un navegador para enviarte datos. Alguien puede crear un cliente de HTTP que por código se conecte a tu aplicación y te envíe un POST a una forma donde tú esperas ciertos datos; si solamente validas con Javascript y confías en que todo el mundo tiene JS corriendo en su navegador, estás perdido. Alguien puede conectarse y enviarte datos inválidos (por ejemplo el campo "nombre" enviarte ahí una cadena de 1MB; qué vas a hacer en ese caso?)

Siempre hay que validar en el servidor aunque tengas validaciones en el cliente. Eso aplica si tu cliente es una página web con Javascript, o una aplicación Swing o JavaME o lo que sea. Qué pasa si recibes caracteres en un protocolo de red para un campo donde esperas números? Ese tipo de cosas. A veces alguien ataca tu aplicación solamente para tirarla, causando que se arroje una excepción que no manejas por ningún lado; puede que esa excepción genere una página web donde viene demasiada info que no deberías publicar pero se te olvidó quitar eso para producción; puede que tu aplicación se muere porque nadie cacha la excepción, puede que solamente un hilo se muere pero ese hilo debería estar leyendo de una cola de mensajes y como ya no la lee, la cola se llena y se acaba la memoria, etc.

Imagen de rodrigo salado anaya

Cierto!!!

Y claro que si mi aplicación como en muchos casos esta conviviendo con otras, por ejemplo SAP, puedo incluso provocar un vectores de ataque, al que se le pueda inyectar código que regrese información confidencial.

Creo que una aplicación de misión critica, solo debe trabajar para lo que fue pensada, pero no nos aleja de las personas que saben mucho y tienen mucha experiencia en los típicos arquetipos que se aprenden en las escuelas y en libros e incluso en Internet. Y pues agradezco mucho tu información y tiempo, que si bien saber mucho del lenguaje no garantiza la máxima seguridad en la aplicación, tal ves si las malas experiencias lo hagan, como se dice por todos lados de los errores se aprenden, pero esto sera cierto con los Framework!!!.

Por otro lado como consideran (al que guste comentar algo :P) el hecho de que existen librerías, aplicaciones, códigos, bueno en fin como en el caso de Javassist, que de lejos se ve muy peligrosa en las manos tentadas por el de abajo y que la mayoría simplemente programamos sin saber que estas existen. ¿Será imposible prevenir todo tipo de ataque, durante un periodo de trabajo en producción, digamos dos años?

Y cuando un programa convive con muchos más, e incluso si el la locura mas extraña una aplicación hecha para Plan 9 en java (es solo una suposición), fuera exitosa y se exportara a FreeBSD de manera exitosa, que garantía hay de que la forma de pensar para Plan 9 sea la misma para un Unix, a lo que voy es que el comportamiento del JVM puede traer problemas en la seguridad al sistema completo? como en el caso de Mac, segun acabo de ver aquí que salvo una vulnerabilidades.

Ya para no cihgnar más y que no parezca entrevista, por que lo pregunto a todo el que responda, que método recomiendas para testear aplicaciones...
o como saber ver la luciérnaga que podría viajar del país del incendio en el que se puede convertir mi aplicación?

Y chido por responder Ezamudio, luego unas cheves frías con la banda va jajajaja.
Nos leemos pronto bonita fin de semana a todos.

Imagen de ezamudio

acceso a código

Estás planteando un caso muy específico que es acceso al código. Para hacer ataques con javassist y cosas así, o que si te preocupas porque tu método es public en vez de protected o private, ya es demasiado. Para poder aplicar un ataque de ese tipo se necesita primero tener acceso al server y poder suplantar alguna de las librerías que utiliza, o tener acceso directo a la JVM. Es como cuando alguien tiene acceso directo a tu equipo; no importa el password que utilices en ese momento, puede ser el más seguro del mundo y de todas maneras alguien puede usar un CD de arranque y leer tu disco duro como cualquier otro y pasarse cualquier privilegio por el arco del triunfo. Solamente te protegería tener tus datos encriptados y que la llave resida en un token que no se encuentre en tu equipo en ese momento.

En un sistema debes primero identificar el paisaje de vulnerabilidad y con eso podrás fortalecer y proteger mejor los puntos más débiles y/o críticos de tu sistema. No va a ser a prueba de todo, pero es similar a la seguridad de mundo real. Suponte que dejas tu auto en un estacionamiento público y le pones 40 alarmas, candados, etc. Si alguien quiere robarse un auto, cualquier auto, y los autos junto al tuyo tienen menos alarmas y candados y demás, intentarán llevarse uno de esos. Pero si alguien quiere llevarse TU auto, lo hará, ya sea en el estacionamiento, con mil gadgets para burlar todas esas alarmas y candados, o simplemente te esperan para ponerte una pistola en la cabeza y pedirte amablemente que lo abras y que manejes con ellos a bordo.

Cuando pienses en la seguridad de tu aplicación, tienes que ser muy paranoico y ponerte a pensar en todos los vectores de ataque que pueda haber, cuáles son factibles, cuáles no, etc (eso es construir tu paisaje de vulnerabilidad).

Imagen de rodrigo salado anaya

A ya veo.

Perfecto gracias por el tiempo y me queda claro el punto, bueno estuvo padre esto bye :).