X
BLOG

Falsos positivos en el análisis de código estático

Falsos positivos en el análisis de código estático Tiempo de leer: 5 minutos
“Demasiados falsos positivos” es probablemente la excusa más común para evitar el análisis estático. Pero el análisis estático no tiene por qué ser tan ruidoso.

Hace años, el mayor desafío en el análisis de código estático era tratar de encontrar más y más cosas interesantes para verificar. En el producto CodeWizard original de Parasoft a principios de los 90, teníamos 30 reglas basadas en elementos del libro de Scott Meyers, C ++ eficaz. Era lo que me gusta pensar en "Derecho asustado para programadores ". Le mencioné esto una vez a Scott, y aunque no había pensado en si de esa manera… le hizo reír bastante.

Desde entonces, los investigadores del análisis estático han trabajado constantemente para ampliar los límites de lo que se puede detectar, expandiendo lo que puede hacer el análisis estático e identificando defectos en lugar de solo un fragmento de código débil. Pero todavía sufre de falsos positivos. El análisis estático ha cambiado el enfoque del usuario, desde el endurecimiento del código hasta la búsqueda de errores, lo cual es genial, pero ahora uno de los obstáculos más comunes con los que se encuentran las personas con el análisis de código estático es tratar de dar sentido a los resultados que obtienen.

Aunque la gente dice "Me gustaría que el análisis estático detectara ____" (nombre su error favorito que no se puede encontrar), es mucho más común escuchar "¡Vaya, tengo demasiados resultados!" o "¡El análisis estático es ruidoso!" o "¡Los falsos positivos del análisis estático son abrumadores!" Entonces, como organización de pruebas de software, nuestro trabajo es continuar resolviendo ese problema para nuestros clientes, continuar brindando herramientas y características que lo ayuden a clasificar los resultados que está obteniendo y comprender qué problemas representan el mayor riesgo.

¿Qué es un falso positivo en análisis estático?

En el contexto del análisis estático, un "falso positivo" ocurre cuando una herramienta de análisis estático informa incorrectamente que se violó una regla de análisis estático. Por supuesto, esto puede ser subjetivo. A veces, los desarrolladores caen en la trampa de etiquetar cualquier mensaje de error que no les guste como "falso positivo", pero esto no es realmente correcto. En muchos casos, simplemente no están de acuerdo con la regla, no entienden cómo se aplica en esta situación o no creen que sea importante en general (o en este caso en particular). Yo llamaría a esto ruido, en lugar de un falso positivo. Lo curioso que he encontrado aquí es que cuanto más inteligente es la herramienta, más probabilidades hay de que produzca un hallazgo que un desarrollador podría no entender a primera vista.

Falsos positivos en el análisis basado en patrones

El análisis estático basado en patrones en realidad no tiene falsos positivos. Si la herramienta informa que se violó una regla de análisis estático cuando en realidad no lo fue, esto indica un error en la regla (porque la regla no debe ser ambigua). Si la regla no tiene un patrón claro que buscar, es una mala regla.

No estoy diciendo que cada infracción de las reglas denunciada indique la presencia de un defecto. Una violación simplemente significa que se encontró el patrón, lo que indica una debilidad en el código, una susceptibilidad a tener un defecto.

Cuando veo una infracción, me pregunto si esta regla se aplica o no a mi código. Si aplica, arreglo el código. Si no es así, suprimo la infracción. Es mejor suprimir las violaciones del análisis estático en el código directamente para que sea visible para los miembros del equipo y no tenga que revisarlo por segunda vez. De lo contrario, estará revisando constantemente la misma infracción una y otra vez; es como intentar revisar la ortografía pero nunca agregar sus palabras “especiales” a su diccionario. La belleza de la supresión en código es que es independiente del motor de análisis estático. Cualquiera puede mirar el código y ver que el código ha sido revisado y que este patrón se considera aceptable en este código. Esto es particularmente útil si necesita demostrar el cumplimiento de un estándar de codificación. Y si realmente necesita cumplimiento, es fácil usar una configuración existente para esos estándares como CWE, MISRA, IEC 62304, DO-178B / C, y más.

Falsos positivos en el análisis basado en flujo

Con el análisis basado en flujo, los falsos positivos no solo son inherentes al método, sino que también son relevantes y deben abordarse. El análisis de flujo no puede evitar falsos positivos por la misma razón que las pruebas unitarias no pueden generar casos de prueba unitarios perfectos. El análisis debe tomar determinaciones sobre el comportamiento esperado del código. A veces hay demasiadas opciones para saber cuál es realista; a veces simplemente no tiene suficiente información sobre lo que está sucediendo en otras partes del sistema.

Lo importante aquí es que el verdadero falso positivo es algo que está completamente mal. Por ejemplo, suponga que la herramienta de análisis estático que está utilizando dice que está leyendo un puntero nulo. Si miras el código y ves que en realidad es imposible, entonces tienes un falso positivo.

Por otro lado, si simplemente no le preocupan los nulos en este fragmento de código porque se manejan en otro lugar, entonces el mensaje (aunque no es importante para usted) no es un falso positivo. Es cierto y resulta que no tiene importancia. Los mensajes de una herramienta de análisis de flujo van desde "verdadero e importante" a "verdadero y sin importancia" y "verdadero e improbable" a "falso". Aquí hay mucha variación y cada una debe manejarse de manera diferente.

Aquí también hay una trampa común. Como en el ejemplo nulo anterior, puede creer que un valor nulo no puede llegar a este punto, pero la herramienta encontró una manera de hacerlo. Si es importante para su aplicación, asegúrese de verificar y posiblemente protegerse contra esto.

Es fundamental comprender que hay poder y debilidad en el análisis de flujo. El poder del análisis de flujo es que pasa por el código e intenta encontrar puntos calientes y problemas alrededor de los puntos calientes. La debilidad es que tiene que hacer suposiciones para intentar atravesar el código, y cuanto más atraviesa, es más probable que produzca una ruta improbable.

El verdadero problema es que si empieza a pensar que ha limpiado todo el código porque su análisis de flujo está limpio, se está engañando a sí mismo. De verdad, has encontrado algunos errores y deberías estar agradecido por ello. La ausencia de errores de análisis de flujo solo significa que no ha encontrado nada, no que el código esté limpio. Es mejor asegurarse de que está utilizando una herramienta como Prueba C / C ++, dotTESTo Jtest que tiene ambos tipos de análisis estático, si está creando software crítico para la seguridad

Guía gratuita: cómo elegir una herramienta de análisis estático moderna

Detección de errores en tiempo de ejecución

Una forma excelente, pero que comúnmente se pasa por alto, de complementar el análisis de flujo es la detección de errores en tiempo de ejecución. La detección de errores en tiempo de ejecución lo ayuda a encontrar problemas mucho más complicados que los que puede detectar el análisis de flujo, y tiene la confianza de que la condición realmente ocurrió. La detección de errores en tiempo de ejecución no tiene falsos positivos como lo hace el análisis estático. Cuando encuentra un defecto, es porque realmente lo observó durante la ejecución; no hay suposiciones involucradas.

Su conjunto de reglas de tiempo de ejecución debe coincidir estrechamente con su conjunto de reglas de análisis estático. Las reglas pueden encontrar los mismos tipos de problemas, pero el análisis en tiempo de ejecución tiene una gran cantidad de rutas de ejecución disponibles. Esto se debe a que, en tiempo de ejecución, los stubs, la configuración, la inicialización, etc., no son un problema como lo son para el análisis de flujo. El único límite es que es tan bueno como su conjunto de pruebas porque verifica las rutas que su conjunto de pruebas ejecuta. Si está programando en C o C ++, especialmente en dispositivos integrados como IoT, eche un vistazo a Asegurar ++ - puede encontrar más errores en tiempo de ejecución que cualquier otra herramienta. En lugar de atascarse con problemas complicados como problemas de subprocesos, pérdidas de memoria y condiciones de carrera, puede encontrarlos con precisión en tiempo de ejecución.

¿Vale la pena el tiempo?

Mi enfoque para los falsos positivos es el siguiente: si se necesitan 3 días para corregir un error, es mejor dedicar 20 minutos a ver un falso positivo ... siempre que pueda etiquetarlo y no tener que volver a mirarlo nunca más. Es cuestión de verlo en el contexto adecuado. Por ejemplo, supongamos que tiene un problema con los hilos. Los problemas con los hilos son dramáticamente difíciles de descubrir. Si desea encontrar un problema relacionado con los hilos, puede llevarle semanas localizarlo. Preferiría escribir el código de tal manera que los problemas no puedan ocurrir en primer lugar. En otras palabras, trato de cambiar mi proceso de detección a prevención.

El análisis estático, cuando se implementa correctamente, no tiene por qué ser una experiencia ruidosa y desagradable. Eche un vistazo a cómo hacemos las cosas de manera diferente en Parasoft, especialmente utilizando todo el poder de Parasoft DTP para administrar los resultados con análisis inteligentes que lo mantienen enfocado en el riesgo de su software en lugar de perseguir problemas sin importancia.

Documento técnico: Introducción al análisis estático
Escrito por

Arthur Hicken

Arthur ha estado involucrado en seguridad de software y automatización de pruebas en Parasoft durante más de 25 años, ayudando a investigar nuevos métodos y técnicas (incluidas 5 patentes) mientras ayuda a los clientes a mejorar sus prácticas de software.

Reciba las últimas noticias y recursos sobre pruebas de software en su bandeja de entrada.

Prueba Parasoft