No he oído a nadie describir Java como “seguro” antes. La gente ciertamente se refiere a Java como un “lenguaje seguro”. “Seguro” y “seguro” significan algo diferente aquí. Abordaré ambos en esta respuesta por si acaso, en particular porque están relacionados.
¿QUÉ SIGNIFICA QUE UNA LENGUA ES SEGURA?
Cardelli define “idiomas seguros” como idiomas en los que se garantiza que no se produce ningún error sin atrapar [1]. Es decir, es una propiedad del lenguaje donde cuando se produce algún error en su programa, deja de ejecutarse.
- ¿Cuántos números de seguridad social fueron robados en el ataque cibernético de Anthem?
- ¿WhatsApp está encriptado para iPhone?
- ¿Linux (por ejemplo, Ubuntu) realmente no necesita ningún software antivirus?
- ¿Qué es el cifrado de la base de datos? ¿Por qué es importante?
- ¿Se debe hacer una copia de seguridad de una computadora que está infectada con un virus?
Considere la siguiente pieza de código:
int [5] números = [1, 2, 3, 4, 5];
int elegido = números [10];
pantalla (elegida);
Declara que `números` es una secuencia de 5 números. Luego selecciona el décimo número de esa secuencia y muestra ese número en la pantalla. El problema es que realmente no podemos elegir un décimo número en la secuencia porque dicha entrada no existe.
Un lenguaje que permita que la operación “números [10]” tenga éxito, leer datos desde fuera de la memoria que ocupan los “números” no es seguro. Este caso particular se llama Lectura fuera de límites [2], y es una vulnerabilidad de seguridad común que fue responsable de errores de software muy grandes, como Heartbleed [3], y puede hacer que un atacante pueda leer memoria privilegiada
Un lenguaje seguro detiene la ejecución del programa en la instrucción “números [10]”, por lo que es imposible que se pierda memoria privilegiada. Si ha visto una “Excepción fuera de límites”, “RangeError”, o una excepción similar que se planteó anteriormente, ese es un ejemplo de esta propiedad en acción.
Por supuesto, “seguro” es un término muy genérico, por lo que clasificamos la seguridad en muchas categorías diferentes. Un lenguaje puede ser “seguro para la memoria”, si asegura que el programador nunca pueda usar la memoria [4]. Puede ser “tipo seguro”, si asegura que todas las propiedades probadas por el sistema de tipos no pueden ser violadas durante el tiempo de ejecución [5].
La seguridad como propiedad se puede garantizar en tiempo de ejecución, con controles dinámicos. Esto es lo que generalmente hacen las excepciones. Cuando ve que se genera una excepción, se realizó una verificación dinámica para garantizar que las propiedades garantizadas por su idioma se mantengan y que no esté introduciendo vulnerabilidades en su código sin saberlo. La seguridad también se puede verificar en tiempo de compilación, utilizando herramientas de análisis. Algunos lenguajes tienen sistemas de tipos muy potentes que les permiten demostrar, por ejemplo, que su programa nunca puede hacer mal uso de un protocolo en particular al emitir las operaciones en el orden incorrecto [6]. Por cierto, este tipo de seguridad generalmente se denomina “seguridad estática”.
Un lenguaje inseguro es más difícil de escribir en programas seguros, pero no hay una manera simple de responder “cuánto más difícil”.
¿QUÉ SIGNIFICA QUE UNA LENGUA ES SEGURA?
Nunca antes había escuchado que este término se usara así, por lo que la siguiente definición es específica de esta respuesta: un lenguaje es seguro si garantiza que los usos de su semántica no pueden ser subvertidos / explotados por código no confiable en el lenguaje. Por ejemplo, en un idioma seguro, tiene la garantía de que si instala la Biblioteca A, escrita por algunas personas al azar, y la usa, esa biblioteca no puede hacer ciertas cosas en su programa.
Al igual que con la “seguridad”, la seguridad viene en diferentes categorías. Una categoría común aquí es “capacidad de lenguaje seguro”. En dicho lenguaje, tiene la garantía de que cualquier código en su programa tiene precisamente los derechos que le otorga, y nada más. El lenguaje más famoso de esta categoría es probablemente E [7], un lenguaje diseñado específicamente para esto (no inventó el concepto, pero hizo contribuciones importantes. Ver la tesis de Miller [8]). Pony [9], Newspeak [10] y mi propio idioma Purr también tienen capacidad segura. Es posible que haya escuchado el término “Seguridad de capacidad de objetos” antes, ese es un modo particular de este concepto. De lo contrario, debería leer esta página: Computación de capacidad
Java no es un lenguaje con capacidad segura. En Java, hay un espacio de nombres global, y todo el código tiene acceso a este espacio de nombres. Cualquier código que llame tiene acceso al sistema de archivos, por ejemplo. Cualquier código puede eliminar archivos en su HDD. Java proporciona un poco de seguridad a través de la Inspección de pila [11] [12], que evita que el código no privilegiado / no confiable llame a un código privilegiado, garantizando así que parte del sistema no se pueda subvertir desde adentro, a costa de verificar la pila para verificar si no se realizó una llamada desde un código no confiable.
¿QUÉ IDIOMAS DE PROGRAMACIÓN SON REALMENTE SEGUROS?
Esta es una pregunta mucho más difícil (no solo por el hecho de que parece estar preguntando acerca de un tipo diferente de “seguro” que el que describí anteriormente). Hay demasiados vectores de ataque para resolver este problema solo en el lenguaje.
E es un lenguaje seguro, en E esto significa que ningún código puede tener más privilegios que los que usted les otorga explícitamente. Esto es importante cuando se habla de la confianza en las bibliotecas externas, pero no ayuda a evitar fugas de datos de las políticas de datos que ha definido en su código.
Jeeves [13], por otro lado, ayuda a prevenir fugas de datos. Está diseñado para que pueda definir políticas para la privacidad de los datos, y el lenguaje hace cumplir esas políticas a través de su código y en los sistemas con los que interactúa. Sin embargo, Jeeves no lo ayudará a garantizar que las páginas web que genere en su servidor web estén libres de ataques XSS.
Los idiomas Yesod de Haskell [14] garantizan que sus páginas web no pueden caer en ataques XSS, pero no le ayuda a garantizar que una biblioteca externa que instaló no pueda ejecutar código peligroso que no quería / esperaba ( Sin embargo, Safe Haskell puede mitigar esto).
Espero que puedas ver lo difícil que es esto. En particular, si solo está considerando el lenguaje de programación en sí, y no sus bibliotecas, herramientas, la plataforma en la que se está ejecutando, los sistemas con los que está interactuando, …
La respuesta literal a esta pregunta sería “ninguna”. Sin embargo, tenemos muchos idiomas que se esfuerzan por hacer que las clases comunes de errores sean más difíciles de cometer y, por lo tanto, provoquen menos vulnerabilidades o vulnerabilidades menos críticas. Se podría decir que esos idiomas son “más seguros” en esos aspectos particulares.
Notas al pie
[1] http://lucacardelli.name/Papers/…
[2] CWE-125: lectura fuera de límites
[3] Insecto sangrante
[4] Es hora de una intervención de seguridad de memoria • Tony Arcieri
[5] Tipo de seguridad – Wikipedia
[6] edwinb / Protocolos
[7] De los objetos a las capacidades
[8] Hacia un enfoque unificado para el control de acceso y el control de concurrencia
[9] Pony – Pony
[10] Newspeak
[11] http://sip.cs.princeton.edu/pub/…
[12] Permisos en el Kit de desarrollo de Java (JDK)
[13] https://projects.csail.mit.edu/j…
[14] Plantillas de Shakespeare