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

Por Arthur Hiken

Domingo, 12 de mayo de 2023

9  min leer

Un falso positivo surge cuando una herramienta de análisis estático afirma falsamente que se infringió una regla estática. Este artículo entra en gran detalle sobre los falsos positivos y el análisis de código estático.

“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 análisis estático de software estaba tratando de encontrar más y más cosas interesantes para comprobar. En el producto CodeWizard original de Parasoft a principios de los 90, teníamos unas 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 él no lo había pensado 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, de endurecer el código a buscar 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: "Desearí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 una organización de prueba de software, es nuestro trabajo continuar resolviendo ese problema para nuestros clientes, continuar brindando herramientas y funciones que lo ayuden a clasificar los resultados que está obteniendo y comprender qué problemas representan el mayor riesgo.

Análisis de código estático: beneficios y limitaciones

Las herramientas de análisis estático benefician a los desarrolladores al encontrar errores, vulnerabilidades de seguridad y desviaciones estándar de codificación que de otro modo serían tediosas de encontrar o aplicar.

Beneficios

Las herramientas de análisis estático y prueba de seguridad de aplicaciones estáticas (SAST) brindan a los equipos de desarrollo los siguientes beneficios.

  • Mejor calidad de código. El análisis estático ayuda a eliminar los defectos en las primeras etapas del desarrollo, lo que proporciona una mejor calidad del código justo en el punto de creación y, al mismo tiempo, mejora la calidad posterior en las etapas posteriores del desarrollo.
  • Código más seguro. Además de la detección de defectos, el análisis estático y SAST mejoran la seguridad al detectar vulnerabilidades que conducen a riesgos de seguridad. Las soluciones como Parasoft imponen prácticas y estándares de codificación más seguras que otras.
  • Cumplimiento de los estándares de codificación de la industria y la organización. Hacer cumplir los estándares de codificación manualmente es tedioso, si no imposible. El análisis estático automatiza la verificación, la aplicación y el cumplimiento de los estándares de codificación. Esto incluirá estándares de codificación de seguridad y protección de la industria como MISRA y estándares de seguridad como OWASP Top 10, CWE Top 25 y SEI CERT C/C++.
  • Mejorar la productividad. Las pruebas de análisis estático al principio de la implementación y dentro del IDE del desarrollador y/o dentro del flujo de trabajo de CI/CD del equipo promueven la calidad del código y aceleran el desarrollo al desplazar las pruebas más hacia la izquierda. Además, Parasoft incorpora AI/ML para organizar automáticamente los problemas de análisis estático identificados y mejorar aún más la productividad.
  • Reducir riesgos y costes. La aplicación de análisis estático reduce sustancialmente la seguridad en el campo y los problemas informados sobre seguridad. Las organizaciones también reconocen un aumento en la confiabilidad del producto, lo que reduce los costos de mantenimiento y promueve una reputación de alta calidad.

Limitaciones

El análisis estático y SAST no son balas de plata. De hecho, Parasoft alienta a los clientes a usar el análisis estático junto con otros métodos de prueba, como pruebas unitarias, pruebas de regresión y más. Las soluciones de análisis estático como Parasoft tienen excelentes retornos de la inversión, sin embargo, tiene sentido comprender las limitaciones.

  • Falsos positivos. Cada análisis estático puede interpretar erróneamente una construcción de codificación oscura e informar un error. Estos errores en los informes son falsos positivos e inevitables con el análisis estático, como se explica a continuación.
  • Falsos negativos. Al igual que los falsos positivos, las herramientas pueden pasar por alto errores reales en el código fuente. Estos defectos perdidos son falsos negativos y se tratan con más detalle a continuación.
  • Alcance y contexto limitados. El alcance del análisis estático se limita al código fuente que está disponible en el momento del análisis. Cuanto más código, mejor el alcance y los resultados. El análisis estático también carece de contexto en términos de para qué está diseñado el código. Analiza la fuente sobre la base de un conjunto de reglas o verificadores, que no necesariamente entienden la intención del programador.
  • Rendimiento de la herramienta. El análisis estático, dependiendo de la profundidad del análisis, puede tomar tiempo para analizar grandes bases de código. Aunque el hardware de servidor moderno ha hecho que esto sea menos preocupante, los desarrolladores suelen limitar el análisis a gran escala a las compilaciones de software. Las herramientas modernas de análisis estático como C/C++test han mitigado este problema hasta cierto punto con el análisis incremental realizado dentro de los IDE, por ejemplo. Las infracciones del código se informan para su reparación solo al ingeniero que desarrolla su código a medida que se realizan pasos incrementales durante cada compilación y creación de código.
  • Costo. La licencia de las herramientas comerciales de análisis estático cuesta dinero. Sin embargo, las herramientas de análisis estático tienen excelentes retornos de la inversión para organizaciones y proyectos pequeños o grandes.

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

En el contexto del análisis estático, se produce un falso positivo 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 gusta como un 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 la situación o no creen que sea importante en general. llamaría a esto ruido, en lugar de un falso positivo. Lo divertido que he encontrado aquí es que cuanto más inteligente es la herramienta, más probable es 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 se violó, 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 violación de regla reportada indique la presencia de un defecto. Una violación significa que se encontró el patrón, lo que indica una debilidad en el código, una susceptibilidad a tener un defecto.

Cuando observo 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 violación. Es mejor suprimir las infracciones de 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á constantemente revisando la misma infracción una y otra vez; es como tratar de revisar la ortografía pero nunca agregar sus palabras "especiales" a su diccionario.

La belleza de la supresión en el código es que es independiente del motor de análisis estático. Cualquiera puede mirar el código y ver que se ha revisado y que este patrón se considera aceptable en este código. Esto es particularmente útil si debe 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-178C, 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 valores nulos en este fragmento de código porque se manejan en otra parte, entonces el mensaje, aunque no es importante para usted, no es un falso positivo. Es cierto y pasa a ser sin importancia. Los mensajes de una herramienta de análisis de flujo varían de "verdadero e importante" a "verdadero y sin importancia" y de "verdadero e improbable" a "falso". Hay mucha variación aquí y cada uno 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 realidad. Si es importante para su aplicación, asegúrese de verificar y posiblemente protegerse contra esto.

Es fundamental entender que hay tanto poder como 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 luego encuentra problemas alrededor de los puntos calientes. La debilidad es que tiene que hacer suposiciones para tratar de atravesar el código, y cuanto más avanza, más probable es 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 ++, puntoPRUEBAo jprueba que tiene ambos tipos de análisis estático, si está creando software crítico para la seguridad

Cómo elegir una herramienta de análisis estático moderna

Falsos positivos frente a falsos negativos en el análisis de código estático

A pesar de las afirmaciones en contrario, todas las herramientas de análisis estático producen falsos positivos y pasan por alto defectos reales: falsos negativos. Hay que hacer concesiones entre la falta de defectos y la obtención de demasiados informes.

En cambio, las herramientas de análisis estático deben evaluarse según lo que encuentran, y qué tan bien se presenta, y cuántos defectos pasan por alto. Las herramientas ajustadas para reducir los falsos positivos inevitablemente tienen más falsos negativos. ¿Vale la pena perder errores reales para tener menos informes?

Aquí hay algunas cosas a considerar al sopesar el equilibrio entre falsos positivos y negativos.

  • Utilice las capacidades de las herramientas para priorizar los hallazgos. Los falsos positivos son inherentes a las herramientas de análisis estático, pero la mayoría ha desarrollado herramientas sofisticadas para manejar los resultados. Las herramientas de análisis estático agrupan los informes por gravedad y tienen la capacidad de ignorar y/o filtrar los resultados no deseados de forma rápida y sencilla.

Entonces, el primer paso es configurar su análisis de código de manera adecuada y reducir el ruido innecesario. Asegúrese de que las fichas correctas se estén ejecutando en el código correcto. Por ejemplo, si no soluciona un problema de un verificador en particular, desactívelo. O si tiene un código heredado que ha estado en el campo durante muchos años y solo un error informado puede obligarlo a realizar modificaciones, ¿por qué molestarse en ejecutar un análisis?

Sin embargo, si ejecuta un análisis estático en una gran base de código y obtiene una enorme lista de infracciones, no se sienta abrumado. No lleva mucho tiempo aprender a priorizar los resultados en función del riesgo y el impacto y concentrarse primero en la prioridad más alta. Muchas quejas sobre las herramientas de análisis estático surgen de las impresiones de las herramientas y capacidades de generaciones anteriores.

  • Los falsos positivos no duran para siempre. Cualquier resultado que no sea de interés se puede filtrar y no volver a informar nunca más. Si el tipo de error no es de alta prioridad para solucionarlo, toda la clase de error puede eliminarse de los informes futuros. Si se determina que los informes individuales son verdaderos falsos positivos, se pueden marcar como tales. La clave es que, con un poco de esfuerzo, el ruido desaparece a medida que los desarrolladores se acostumbran más a usar las herramientas.
  • Los falsos negativos afectan la calidad y la seguridad del producto. Los falsos negativos, por el contrario, son desconocidos ya que no se detectan y su existencia puede no revelarse hasta que el cliente tiene el producto en la mano. Es con esta perspectiva que los desarrolladores deben sopesar el impacto de los falsos positivos en su carga de trabajo: ¿Vale la pena pasar por alto defectos importantes?

Las organizaciones necesitan hacer su propia determinación de riesgos y costos asociados. La compensación ideal es tener la menor cantidad posible de falsos positivos y minimizar los falsos negativos.

  • Generar confianza en las capacidades de la herramienta. Los falsos positivos pueden parecer problemáticos al principio, pero encontrar y corregir defectos reales genera confianza en las herramientas con el tiempo. Por el contrario, la falta de errores reales que se detectan más tarde en las pruebas se refleja mal en las herramientas utilizadas durante el desarrollo. Los desarrolladores quieren herramientas en las que puedan confiar, y no vale la pena enfatizar la reducción de falsos positivos a costa de pasar por alto defectos reales.

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 DTP de Parasoft 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.

Introducción al análisis estático

“MISRA”, “MISRA C” y el logotipo del triángulo son marcas comerciales registradas de The MISRA Consortium Limited. © The MISRA Consortium Limited, 2021. Todos los derechos reservados.

Por Arthur Hiken

Arthur Hicken es un evangelista de Parasoft, donde ha estado involucrado en la automatización de varias prácticas de desarrollo de software durante más de 30 años. Ha trabajado en proyectos que incluyen el ciclo de vida del desarrollo de software, seguridad de aplicaciones, seguridad funcional y seguridad de software en industrias como la automotriz, aeroespacial y médica. El popular blog de Arthur, Code Curmudgeon, es conocido por sus listas del Salón de la vergüenza que cubren la inyección de SQL y las vulnerabilidades de IoT. También tiene un canal de YouTube con videos de desarrollo de software y AppSec. Como experto en su campo, Arthur habla con frecuencia en conferencias sobre estrategias de desarrollo, cumplimiento y mejores prácticas de seguridad. Está involucrado con los estándares de seguridad y protección del software como miembro de organizaciones como CERT, IEEE, UL y ASQ.

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