¿Por qué el software crucial para la seguridad está escrito en idiomas inseguros?

18

Esta puede ser una pregunta estúpida, pero ...

¿Por qué el software crucial para la seguridad está escrito en lenguajes como C y C ++? Entiendo por qué, digamos, un sistema integrado puede necesitar un lenguaje de bajo nivel para hacer el mayor uso de recursos limitados, pero parece una tontería escribir software de seguridad en lenguajes de bajo nivel.

Estoy preguntando esto porque cada vez que voy a debian.org y veo las soluciones de seguridad más recientes, la mayoría vasta involucra problemas de seguridad de la memoria, que solo aparecen en idiomas inseguros como C y C ++. Como mala reputación que tiene Java, por ejemplo, me imagino que el 90% de los parches de seguridad para OpenSSL serían completamente inútiles. Si se utilizara un lenguaje de nivel superior como Scala o Lisp, supongo que sería aún más fácil mantener las cosas seguras. El desorden de sus arreglos en el peor de los casos dará lugar a un error de tiempo de ejecución.

¿La razón para usar C / C ++ es evitar los ataques de canal lateral? Podría imaginar algunas propiedades de una clave que interfiere con la ejecución de un recolector de basura conservador (como Boehm) y que conduce a ataques de tiempo, pero ningún lenguaje de nivel superior utiliza recolectores de basura inseguros de todos modos.

    
pregunta ithisa 19.10.2013 - 21:11
fuente

7 respuestas

15

La mayoría del software está escrito en los idiomas que el desarrollador sabe usar, y para el software relacionado con la seguridad, eso no es algo malo, siempre que el desarrollador realmente sepa cuál es el idioma de su elección, hasta los detalles, y yo puede argumentar que este no es el caso con C y C ++ (la gran mayoría de los desarrolladores que creen que saben que C o C ++ están realmente equivocados).

En sistemas similares a Unix, en particular Linux (donde se produce una parte sustancial de todo el desarrollo de código abierto), C es "el" lenguaje del sistema. Unix es muy compatible con C (todas las API de bajo nivel están basadas en C, se describen con encabezados en C; las bibliotecas del sistema están escritas en C, por lo que el compilador de C está bien probado y bien integrado). Esto ha resultado en un gran ecosistema basado en C donde los desarrolladores usan C porque conocen C y desean usar bibliotecas que ofrecen una API basada en C. Esto tiene buenos beneficios de portabilidad (por ejemplo, no hay problema en la ejecución de OpenSSL en un PowerPC o Mips, ¡intente hacerlo con Java!).

El uso de otro idioma implica algunos problemas: falta de soporte de tiempo de ejecución, menos portabilidad, una supuesta falta de rendimiento ... (los idiomas "seguros" pueden ser eficientes, pero algunas implementaciones generalizadas serán lentas porque utilizan intérpretes sin < a href="http://en.wikipedia.org/wiki/Just-in-in-time_compilation"> JIT o será un montón de memoria, y también muchas personas simplemente descartan estos idiomas como intrínsecamente lentos porque en realidad no lo hacen Intentado, y piensan en consignas).

Esto lleva a mi conclusión: las personas usan C y C ++ para el software crítico para la seguridad fuera de tradition .

(Escribo todo eso como alguien que escribió su propia VM de Java para ejecutar un servidor SSL escrito completamente en Java, en un pequeño sistema PowerPC de 50 MHz con 16 MB de RAM; era una Autoridad de Certificación, y podría servir 70 clientes simultáneamente. Entonces, cuando digo que se puede usar un lenguaje "seguro" como Java para ejecutar software de seguridad crítica en sistemas de bajo consumo y con un rendimiento decente, lo digo en serio.)

    
respondido por el Tom Leek 20.10.2013 - 01:20
fuente
6

Puedes escribir software inseguro en cualquier idioma. C y C ++ pueden hacer que sea fácil cometer un error crítico, especialmente para programadores inexpertos ...

but

... incluso como el programador más experimentado y cuidadoso, no tendría control sobre un problema de seguridad que reside dentro de la complejidad de un lenguaje de alto nivel.

Con C y C ++ tienes mucho control sobre lo que está sucediendo dentro de tu código. Los compiladores pueden ser relativamente simples y con frecuencia están bien revisados. Esto significa que cualquier error que cometas es probablemente tuyo. En los idiomas de alto nivel, a menudo tiene que confiar en la seguridad de la API y las características de idioma que está utilizando, esto conduce a un sistema más complejo que es más difícil de auditar.

La base del código en la que se encuentra un error crítico de seguridad es, en última instancia, más manejable que en un lenguaje de alto nivel.

    
respondido por el Paul Hänsch 20.10.2013 - 00:50
fuente
2

En realidad, en algunos casos, uno tiene que usar dichos idiomas para estar seguro, ya que los idiomas de nivel superior no proporcionan suficiente acceso al hardware. Por ejemplo, borrar las claves de cifrado de la memoria después de que ya no sean necesarias. O asegurarse de que las múltiples rutas de código tengan la misma longitud y que tomen la misma cantidad de tiempo para evitar ataques de canales laterales.

    
respondido por el ewanm89 19.10.2013 - 23:00
fuente
2

Esta es una excelente pregunta.

Si le preguntara a los autores de dicho software, la mayoría diría rendimiento. Para algunas cosas, como el kernel de Linux, este rendimiento es esencial. Pero para una gran cantidad de software, el rendimiento es menos crítico, y esto hace que sea una mala razón. Imagine un servidor web que era un 50% más lento, pero que nunca había tenido una vulnerabilidad de seguridad. Una gran cantidad de usuarios estarían encantados de cambiar el rendimiento por seguridad.

El uso de un lenguaje administrado no garantiza la seguridad. Considere Java o C # - estos son seguros para la memoria; es imposible (aparte de los errores de VM) tener una vulnerabilidad de desbordamiento de búfer. Pero pueden tener fallas de inyección, debilidades de control de acceso, etc. Sin embargo, este tipo de vulnerabilidad es algo más fácil de detectar y prevenir. Una de las preocupaciones particulares de los lenguajes que no son seguros para la memoria (como C / C ++) es que es increíblemente difícil detectar fallas sutiles de corrupción de memoria en una aplicación compleja.

Si empezáramos hoy, creo que se escribiría mucho más software en idiomas administrados. Pero nunca empezamos con una hoja en blanco, y una gran cantidad de software está escrito en C. Y la cuestión es que una gran cantidad de software tiene la seguridad. Mira a Apache, por ejemplo: tenía muchos problemas serios si retrocedes una década o más, pero ha tenido una historia reciente mucho mejor. Con este historial, la motivación para volver a escribir completamente el código en otro idioma se ha ido.

Tenga en cuenta que si bien una gran cantidad de software comercial no está administrado, la mayoría del software a medida (que incluye una gran cantidad de aplicaciones web personalizadas) está escrito en idiomas administrados.

En este momento, el peor lugar para la seguridad del software es el escritorio, con los navegadores web y los complementos siendo los peores delincuentes. Desafortunadamente, la mayoría de las fallas de los navegadores web están asociadas a lenguajes de espacio aislado (JavaScript, Java, Flash, etc.) y escribir la VM en un lenguaje administrado sería un éxito significativo.

Sería un proyecto interesante crear un conjunto de software informático que se haya creado desde cero para que sea seguro. Sé que OpenBSD ha estado presionando ese mantra durante años, pero su enfoque no parece correcto. Si alguien más tomara esto, usar un lenguaje administrado para casi todo tendría mucho sentido.

    
respondido por el paj28 20.10.2013 - 16:20
fuente
1

Si todas las bibliotecas son de código abierto y están firmadas, no hay beneficios de seguridad en el uso de un lenguaje de nivel inferior. De hecho, existe el riesgo de errores de codificación y KLOC el tamaño de la lógica de negocios para auditar disminuye la seguridad efectiva como usted correctamente postula.

Los idiomas de nivel inferior no protegerán contra virus de compilación u otras subversiones de código o binarios donde las firmas de archivos no tengan ha sido firmado por una clave privada que se mantiene separada del servidor y utilizada solo por auditores; y donde no exista firmware en la ROM del hardware para verificar las firmas.

La codificación de las aplicaciones de seguridad en C / C ++ es un subproducto de dos cosas:

  • Un espíritu pirata informático de la década de 1990 para rodar los tuyos, ya que la mayoría de las bibliotecas de terceros eran de código cerrado.
  • El deseo de mejorar la velocidad de los algoritmos de seguridad a menudo lentos, a pesar de las limitaciones inherentes de complejidad de tiempo del algoritmo de seguridad que superan el beneficio O(1) de un lenguaje de nivel inferior.
  • La suposición de que las bibliotecas de un lenguaje de nivel superior no se pueden anclar a una versión de auditoría.
respondido por el LateralFractal 20.10.2013 - 01:26
fuente
0

La gran mayoría de los errores provienen de prácticas de desarrollo deficientes y desarrolladores inexpertos, no del lenguaje elegido.

Un desarrollador responsable usará Test Driven Development para probar que su software funciona exactamente como se esperaba, sin efectos secundarios ni pérdidas de memoria. Arreglarán inmediatamente cualquier error reportado. Estas prácticas abordan los mismos problemas que intentan abordar los idiomas administrados, pero también producen un conjunto robusto de pruebas unitarias que demuestran la funcionalidad adecuada. También producen diseños modulares que son fáciles de entender y mantener, lo que significa que las futuras mejoras pueden ser tan seguras como el desarrollo original.

Sin embargo, más allá de esto, están los problemas de nivel empresarial que están en la raíz de muchas de las fallas de seguridad modernas. La inyección de SQL, las secuencias de comandos entre sitios, los mensajes de error que revelan demasiada información, las contraseñas de texto no cifrado, todo ese tipo de fallas se deben a la falta de atención a los detalles específicos de seguridad. Los idiomas administrados no tienen propiedades mágicas que eviten este tipo de fallas.

Los desarrolladores también deben comprender las técnicas de codificación segura, como validar la entrada, hacer cumplir la integridad de los datos, garantizar que se cumplan los límites de las reglas de negocios, que los registros estén limpios de datos confidenciales, etc. OWASP es una gran fuente de información allí.

Así que además de seguir las buenas prácticas de desarrollo, los desarrolladores de software deben tragar sus egos y aprovechar las herramientas y personas externas, también. Las herramientas de análisis de código estático como Klocwork de Coverity, Fortify de HP, FindBugs, PMD, FxCop, etc., pueden ayudar a identificar problemas semánticos como CRSF, contraseñas de texto claro, etc. Y los colaboradores y las revisiones de código también son una fuente valiosa de información. p>

Culpar al lenguaje no es productivo. Si debe culpar a alguien, culpe a los desarrolladores no profesionales, a las personas que contratan a los desarrolladores no profesionales, a las personas que proporcionan recursos inadecuados para realizar el trabajo de calidad necesario para producir un código seguro, o que agregan obstáculos de proceso que impiden que se realice un trabajo de calidad.

    
respondido por el John Deters 21.10.2013 - 05:48
fuente
0

Hoy en día, solo hay un puñado de idiomas no seguros; C y C ++ son las opciones más obvias y típicas. Y por más peligroso que sea, todavía hay una serie de razones perfectamente válidas para usarlos:

Interoperabilidad
OpenSSL es un gran ejemplo. OpenSSL es utilizado por Perl, Python, Ruby, Lua, Node.js y prácticamente en cualquier otro marco de nivel superior que exista. Incluso es posible usarlo en marcos administrados como .NET, aunque es menos común hacerlo. Si OpenSSL no estuviera escrito en C o C ++, esto sería esencialmente imposible. Si bien se puede hacer la interoperabilidad entre lenguajes de alto nivel, la fricción es alta y los resultados suelen ser decepcionantes.

Esta sigue siendo la razón principal por la que el código de biblioteca de propósito general todavía está escrito en C o C ++ (normalmente C en este caso).

Velocidad
Esta es una razón menos válida hoy en día, dadas las velocidades de hardware y las mejoras en los compiladores. Pero C sigue siendo el estándar de oro de la velocidad del programa. No importa lo rápido que pueda hacer que cualquier otro idioma funcione, simplemente no puede ser más rápido que C. Mientras que esto es trivialmente cierto por definición, también existen implicaciones del mundo real. Y las comprobaciones de seguridad adicionales que definen un lenguaje "seguro" agregan una penalización de rendimiento mensurable.

Tamaño y complejidad
En ciertos escenarios, como dispositivos integrados u otros entornos restringidos, el equipaje adicional que viene con idiomas seguros es un lujo que el entorno no puede soportar.

Pronosticabilidad
En el caso del kernel y el código del controlador en particular, los idiomas de nivel superior, incluidos los idiomas seguros, agregan un nivel de imprevisibilidad que se convierte en una responsabilidad. El autor del controlador debe saber exactamente cuándo se asignará y destruirá la memoria, por ejemplo. Necesita saber que la máquina ejecutará exactamente el código que escribe, y nada más y nada menos.

Debido a la naturaleza cercana al metal de los kernels OS, los lenguajes seguros simplemente no son una opción. Y el código del kernel es el aspecto más crítico de la ejecución de cualquier computadora, lo que significa que la codificación segura en un entorno intrínsecamente inseguro es una necesidad inevitable.

    
respondido por el tylerl 21.10.2013 - 09:14
fuente

Lea otras preguntas en las etiquetas