Navegando por Código Inseguro en el Desarrollo de Rust
Un estudio sobre el uso de código inseguro por parte de los desarrolladores en Rust.
― 9 minilectura
Tabla de contenidos
- La Necesidad de Código Inseguro
- Objetivos de la Investigación
- Motivaciones de los Desarrolladores para Usar Código Inseguro
- Rendimiento
- Ergonomía
- Necesidad
- Razonamiento sobre la Seguridad
- Invariantes
- Razonamiento Ad-Hoc
- Herramientas para Validar Código Inseguro
- Herramientas de Análisis Estático
- Herramientas de Análisis Dinámico
- El Papel de la Comunidad de Rust
- Una Cultura de Seguridad
- Retroalimentación Dura
- Conclusión
- Fuente original
- Enlaces de referencia
Rust es un lenguaje de programación que está ganando popularidad, sobre todo para tareas que requieren alto rendimiento y seguridad en la memoria. Asegura ofrecer seguridad en la memoria sin Necesidad de gestión automática, lo cual suele ser un reto en otros lenguajes de programación. Sin embargo, para lograr esta seguridad, Rust tiene reglas estrictas sobre cómo se puede acceder y modificar los datos.
A pesar de estas reglas, hay veces que los desarrolladores necesitan saltárselas para usar ciertos patrones de programación. Aquí es donde entra en juego el "Código Inseguro". El código inseguro permite a los desarrolladores realizar acciones que Rust normalmente protege, como desreferenciar punteros crudos o llamar funciones de otros lenguajes de programación. Entender cómo y por qué los desarrolladores usan código inseguro es esencial para mejorar herramientas y recursos para la comunidad de Rust.
La Necesidad de Código Inseguro
Los desarrolladores a menudo se encuentran en situaciones donde creen que no hay una forma segura de realizar una tarea. Pueden sentir que el rendimiento de su programa está en juego, o pueden estar tratando de implementar una funcionalidad que piensan que no se puede hacer de manera segura. Estos escenarios llevan a muchos desarrolladores a usar código inseguro.
Usar código inseguro puede proporcionar beneficios de rendimiento o permitir a los desarrolladores interactuar con bibliotecas existentes escritas en otros lenguajes. Sin embargo, viene con riesgos. Cuando los desarrolladores usan código inseguro, pueden introducir accidentalmente errores o vulnerabilidades en sus aplicaciones. Esta tensión constante entre seguridad y rendimiento es un aspecto vital de usar Rust.
Objetivos de la Investigación
Para entender mejor cómo los desarrolladores de Rust usan código inseguro, se llevó a cabo un estudio para explorar sus motivaciones, métodos y experiencias. La investigación buscó responder varias preguntas:
- ¿Por qué los desarrolladores eligen usar código inseguro?
- ¿Cómo razonan los desarrolladores sobre la seguridad de su código al usar características inseguras?
- ¿Qué herramientas utilizan los desarrolladores para validar su uso de código inseguro?
- ¿Cómo percibe la comunidad de Rust el código inseguro?
Al recopilar información a través de entrevistas y encuestas, el estudio buscó obtener una imagen más clara del papel del código inseguro en el desarrollo de Rust.
Motivaciones de los Desarrolladores para Usar Código Inseguro
La investigación identificó tres razones principales por las cuales los desarrolladores recurren al código inseguro: rendimiento, Ergonomía y necesidad.
Rendimiento
Una de las razones más comunes para usar código inseguro es la creencia de que puede llevar a un mejor rendimiento. Muchos desarrolladores informaron que optaron por alternativas inseguras solo cuando creían que haría su aplicación más rápida o eficiente. Por ejemplo, algunos desarrolladores evitaron las comprobaciones en tiempo de ejecución en su código, razonando que podían confiar en su comprensión del estado del programa.
Aunque algunos desarrolladores reconocieron que podría haber alternativas seguras, a menudo sentían que esas alternativas implicarían un costo de rendimiento significativo. Como resultado, decidieron apegarse al código inseguro, convencidos de que era la única forma de lograr sus objetivos de rendimiento.
Ergonomía
Además del rendimiento, algunos desarrolladores encontraron que usar código inseguro era más fácil o más ergonómico en comparación con alternativas seguras. Si bien esta fue una motivación menos común, algunos participantes mencionaron que ciertas API seguras eran engorrosas o difíciles de usar, lo que los llevó a recurrir al código inseguro.
Por ejemplo, los desarrolladores a veces recurrían al código inseguro como una forma de eludir reglas complicadas o simplificar la implementación de una función. Esto puede hacer que el proceso de desarrollo sea más rápido, pero también plantea preguntas sobre los compromisos entre la velocidad de desarrollo y la seguridad del código.
Necesidad
Muchos desarrolladores informaron que sentían que no había una alternativa clara para usar código inseguro. A menudo se encontraban en situaciones donde necesitaban interactuar con bibliotecas existentes o APIs que requerían operaciones inseguras. En estos casos, los desarrolladores se sentían limitados por las estrictas características de seguridad de Rust.
Este sentido de necesidad era común entre los desarrolladores que trabajaban en proyectos que requerían interfazar con código no Rust o tratar con operaciones del sistema de bajo nivel. En tales casos, sentían que usar código inseguro era la única solución viable.
Razonamiento sobre la Seguridad
Al usar código inseguro, los desarrolladores a menudo confían en varios métodos para garantizar la corrección de sus operaciones. Si bien las estrictas reglas de Rust brindan cierta orientación, muchos desarrolladores tienen que aplicar su experiencia e intuición para navegar por las complejidades de las operaciones inseguras.
Invariantes
Los desarrolladores suelen razonar sobre la solidez de su código a través del concepto de invariantes. Un invariante es una condición que se espera que sea verdadera en un momento determinado en un programa. Al asegurarse de que se cumplan los invariantes, los desarrolladores pueden tener una idea de la seguridad de su código.
En ciertos contextos de programación, como sistemas embebidos o desarrollo de sistemas operativos, estos invariantes pueden ser dictados por especificaciones de hardware. Los desarrolladores aprovecharían estas garantías para sentirse más seguros sobre la corrección de su código inseguro.
Razonamiento Ad-Hoc
A pesar de tener un enfoque estructurado, muchos desarrolladores también confiaban en el razonamiento ad-hoc al razonar sobre la seguridad. Algunos desarrolladores tenían experiencia extensa con operaciones inseguras de otros lenguajes de programación y aplicaban principios similares en Rust. Esto a menudo llevaba a una mezcla de confiar en sus instintos y seguir las mejores prácticas establecidas.
Sin embargo, esta dependencia de la experiencia personal y la intuición introduce incertidumbre. Mientras que algunos desarrolladores estaban seguros de sus procesos de toma de decisiones, otros expresaron dudas sobre si sus suposiciones sobre la seguridad eran válidas.
Herramientas para Validar Código Inseguro
Para ayudar a garantizar la seguridad de su código, los desarrolladores utilizan una variedad de herramientas diseñadas para validar el código de Rust, incluyendo herramientas de análisis estático y dinámico.
Herramientas de Análisis Estático
Las herramientas de análisis estático examinan el código sin ejecutarlo para detectar problemas potenciales. En el ecosistema de Rust, herramientas como Clippy y cargo-audit se utilizan para identificar errores comunes y vulnerabilidades de seguridad en las dependencias.
Estas herramientas pueden ser instrumentales para fomentar prácticas de codificación seguras. Sin embargo, los desarrolladores no siempre las utilizan a su máximo potencial, y algunos informaron que descuidaron integrar el análisis estático en sus flujos de trabajo diarios.
Herramientas de Análisis Dinámico
Las herramientas de análisis dinámico, como Miri y Valgrind, ayudan a encontrar problemas durante la ejecución del programa. Miri es particularmente interesante porque puede identificar comportamientos indefinidos relacionados con las reglas de seguridad de Rust. Aunque Miri es una herramienta poderosa, muchos desarrolladores informaron que no la usaban con suficiente frecuencia, principalmente debido a sus limitaciones, como la falta de soporte para llamar funciones extranjeras.
Estas herramientas tienen el potencial de mejorar la seguridad del código, pero aún están subutilizadas. Los desarrolladores a menudo enfrentan desafíos para integrar estas herramientas en sus procesos de trabajo, y hay una necesidad de mayor conciencia sobre sus beneficios.
El Papel de la Comunidad de Rust
La comunidad de Rust pone un fuerte énfasis en la seguridad, y este enfoque modela las percepciones y acciones de los desarrolladores al tratar con código inseguro.
Una Cultura de Seguridad
Los participantes notaron que la comunidad de Rust generalmente prefiere prácticas de programación seguras. Los desarrolladores a menudo se sienten presionados para evitar el código inseguro como resultado de esta cultura. Muchos mencionaron que creen que exponer APIs inseguras puede desalentar a otros desarrolladores de usar sus bibliotecas, ya que la seguridad se convierte en una preocupación primaria.
Un número significativo de encuestados priorizó las APIs seguras, reflejando un estándar comunitario que favorece fuertemente la seguridad. Sin embargo, este énfasis puede llevar a un estigma contra el código inseguro, haciendo que los desarrolladores se sientan incómodos o a la defensiva sobre sus decisiones de usarlo.
Retroalimentación Dura
Algunos desarrolladores informaron haber recibido comentarios negativos de miembros de la comunidad cuando buscaban asesoramiento o compartían sus ideas sobre el código inseguro. Los recién llegados particularmente notaron que sus preguntas sobre el uso de código inseguro fueron recibidas con respuestas demasiado críticas, lo que podría desalentarlos de hacer preguntas en el futuro.
Si bien el compromiso de la comunidad con la seguridad es encomiable, la forma en que se entrega la retroalimentación puede impactar las experiencias de los recién llegados. Un ambiente más solidario ayudaría a fomentar el crecimiento y la comprensión en torno al uso de código inseguro.
Conclusión
El estudio resalta las complejidades y desafíos que enfrentan los desarrolladores de Rust al trabajar con código inseguro. Aunque muchos desarrolladores recurren al código inseguro por rendimiento, ergonomía o necesidad, sigue habiendo una incertidumbre general sobre la solidez de sus operaciones.
La investigación revela que, si bien hay herramientas disponibles para ayudar a validar el código inseguro, su uso es inconsistente y a menudo se descuida. Además, el fuerte enfoque de la comunidad de Rust en la seguridad influye en las decisiones y prácticas de los desarrolladores.
En general, hay una necesidad de recursos mejorados, herramientas más eficaces y una cultura comunitaria solidaria que fomente prácticas seguras mientras se abordan los desafíos del mundo real que enfrentan los desarrolladores al involucrarse con código inseguro.
Título: A Mixed-Methods Study on the Implications of Unsafe Rust for Interoperation, Encapsulation, and Tooling
Resumen: The Rust programming language restricts aliasing to provide static safety guarantees. However, in certain situations, developers need to bypass these guarantees by using a set of unsafe features. If they are used incorrectly, these features can reintroduce the types of safety issues that Rust was designed to prevent. We seek to understand how current development tools can be improved to better assist developers who find it necessary to interact with unsafe code. To that end, we study how developers reason about foreign function calls, the limitations of the tools that they currently use, their motivations for using unsafe code, and how they reason about encapsulating it. We conducted a mixed-methods investigation consisting of semi-structured interviews with 19 developers, followed by a survey that reached an additional 160 developers. Our participants were motivated to use unsafe code when they perceived that there was no alternative, and most avoided using it. However, limited tooling support for foreign function calls made participants uncertain about their design choices, and certain foreign aliasing and concurrency patterns were difficult to encapsulate. To overcome these challenges, Rust developers need verification tools that can provide guarantees of soundness within multi-language applications.
Autores: Ian McCormack, Tomas Dougan, Sam Estep, Hanan Hibshi, Jonathan Aldrich, Joshua Sunshine
Última actualización: 2024-10-19 00:00:00
Idioma: English
Fuente URL: https://arxiv.org/abs/2404.02230
Fuente PDF: https://arxiv.org/pdf/2404.02230
Licencia: https://creativecommons.org/licenses/by/4.0/
Cambios: Este resumen se ha elaborado con la ayuda de AI y puede contener imprecisiones. Para obtener información precisa, consulte los documentos originales enlazados aquí.
Gracias a arxiv por el uso de su interoperabilidad de acceso abierto.