Comparación de velocidad de herramientas SAST: Snyk Code vs. SonarQube y LGTM
Frank Fischer
22 de julio de 2021
0 minutos de lecturaNos pidieron comparar los tiempos de análisis de Snyk Code y dos herramientas SAST comunes: LGTM y SonarQube. Para nuestra investigación, hicimos varias suposiciones, pero compartimos los detalles para ser transparentes.
En resumen
Las pruebas de seguridad de aplicaciones estáticas (SAST) solo pueden ser amigables para los desarrolladores si ofrecen comentarios casi en tiempo real y no retrasan los procesos de desarrollo. Snyk Code es hasta 106 veces más rápido que LGTM. En promedio, Snyk Code es 5 veces más rápido que SonarQube y 14 veces más rápido que LGTM. En resumen, Snyk Code demuestra ser uno de los motores de análisis semántico más rápidos del mercado.
Entorno de prueba
Seleccionamos 48 repositorios de código abierto de JavaScript (enumerados abajo). La idea era imitar conjuntos de código típicos de desarrolladores actuales, y JavaScript parecía un denominador común adecuado. Elegimos una muestra aleatoria de los repositorios mejor calificados en GitHub para representar desafíos del mundo real.
Como analizadores, usamos la Community Edition de SonarQube, una herramienta de análisis estático de código abierto ampliamente utilizada. Se ejecuta localmente, así que necesitábamos una PC bastante buena. Como mostraron pruebas anteriores con la versión gratuita de SonarCloud, SonarQube en una buena PC es más rápido que la versión gratuita de SonarCloud, por lo que no es injusto usar el motor local en lugar de la versión en la nube. Tuvimos que usar una de las máquinas de desarrollo existentes (detalles abajo). El segundo competidor es LGTM, que proviene de una empresa llamada Semmle, adquirida por GitHub. LGTM usa una búsqueda semántica profunda de código basada en CodeQL. Usamos la oferta SaaS de LGTM.
Por último, Snyk Code es la solución SAST de Snyk. Se basa en el antiguo motor de análisis de DeepCode, que ahora cuenta con varios meses de desarrollo adicional en Snyk. Además de ser amigable para los desarrolladores y muy preciso, uno de los objetivos de diseño de Snyk Code es ser extremadamente rápido. Para lograrlo, usa un motor de restricciones patentado. Elegimos este entorno de prueba porque (1) las licencias nos permiten ejecutar las herramientas y compararlas, (2) son motores semánticos y no linters (como ESLint), (3) son motores comunes y ampliamente utilizados, y (4) incluimos tanto un motor local como uno SaaS.
La velocidad es fundamental para que una solución SAST sea amigable para los desarrolladores. Se sabe que los desarrolladores trabajan con mayor eficiencia cuando los problemas de seguridad se identifican durante el desarrollo, para poder resolverlos antes de registrar el código. Así, todavía lo tienen fresco en la mente. Snyk Code ofrece complementos para IDE que se integran perfectamente en el flujo de trabajo de desarrollo. Además, Snyk Code ofrece diagramas de flujo de datos fáciles de entender y explicaciones detalladas, con ejemplos de soluciones aplicadas en bibliotecas de código abierto con el mismo contexto. Sin embargo, para esta prueba, nos enfocamos en la velocidad.
Para realizar la prueba, ejecutamos un análisis en cada repositorio: SonarQube localmente, y LGTM y Snyk Code como SaaS. Como mencionamos antes, esto determinó la selección de repositorios, ya que no queríamos que los tiempos de análisis dependieran del ancho de banda de la red.
También seleccionamos repositorios de código abierto reales, no pruebas de referencia, porque el objetivo era simular lo que hacen los desarrolladores en la práctica. Usar pruebas de referencia para comparar herramientas SAST tiene sus propios problemas, y en este caso no nos habría ayudado.
Resultados de la prueba
A continuación se muestran los valores estadísticos generales (redondeados) del tiempo de análisis en segundos (n=48, redondeado al entero):
Promedio | Máximo | Mínimo | Percentil 5 | Percentil 95 | Mediana | desv. est. | |
|---|---|---|---|---|---|---|---|
SonarQube | 110 | 895 | 63 | 63 | 257 | 77 | 127 |
LGTM | 312 | 1835 | 2 | 141 | 1046 | 189 | 352 |
Snyk Code | 22 | 162 | 5 | 5 | 72 | 12 | 28 |
Estos son los resultados en un diagrama de dispersión (cuanto menor, mejor; escala logarítmica; elaborado con R y ggplot2):

El eje logarítmico exagera la dispersión en los valores bajos. En realidad, la desviación estándar de Snyk Code es mucho menor que la de SonarQube, por ejemplo.
A continuación se muestra un diagrama de caja de los valores (cuanto menor, mejor; usamos una escala logarítmica para que todos los valores cupieran en el gráfico; elaborado con R y ggplot2; se muestran la mediana y el promedio):

El gráfico muestra claramente que, en la mayoría de los casos, Snyk es mucho más rápido que cualquiera de las otras dos herramientas. La mediana de Snyk es entre 6.7 veces (SonarQube) y 16.4 veces (LGTM) más rápida, lo que demuestra que los resultados no dependen de algunos valores atípicos extraordinariamente buenos, sino que son consistentes.
En el diagrama anterior, destaca la dispersión de los valores de la columna de LGTM. Abarca aproximadamente desde 2 minutos (más o menos aceptable) hasta más de 17 minutos (inaceptable). Los desarrolladores no esperarán varios minutos por los resultados durante su jornada laboral. Por suerte, la mediana de LGTM ronda los 3 minutos.
Al compararlo con la primera prueba de velocidad que hicimos (en ese momento como DeepCode; ahora, Snyk Code), notamos una gran mejora del rendimiento porque optimizamos considerablemente la carga en el servicio en la nube durante los últimos meses. Además, esta vez SonarQube fue más rápido, probablemente porque usamos una PC más potente, con mayor capacidad de paralelismo que en la primera prueba.
Otra observación interesante es que, desde el punto de vista de la velocidad, los motores SaaS y los instalados localmente no son tan diferentes.
Suposiciones y limitaciones
Elegimos SonarQube (Community Edition 8.9.1) y LGTM porque sus licencias nos permiten hacer estas comparaciones y son herramientas ampliamente utilizadas.
Elegimos 48 repositorios medianos de JavaScript porque este entorno de prueba parece reflejar el trabajo de los desarrolladores típicos. Tomamos una muestra aleatoria de los aproximadamente 200 000 repositorios de GitHub con más estrellas. El tamaño del código no fue un criterio.
Forzamos un análisis completo y no usamos un mecanismo de análisis diferencial. Por ejemplo, en el caso de Snyk Code en los complementos para IDE, después de un análisis inicial, el complemento del IDE realiza análisis diferenciales y ahorra ancho de banda.
Usamos un Intel Xeon a 2 GHz, con 16 núcleos y 64 GB de RAM.
Protege tu código con información de vanguardia
Conoce todas las funcionalidades de SAST de Snyk Code en solo 30 minutos.
Datos sin procesar
También queremos compartir los datos sin procesar para que puedas aplicar tus propias estadísticas. (Tiempos en segundos)
Repositorio | SonarQube | LGTM | Snyk Code |
|---|---|---|---|
neumino/chateau | 101 | 259 | 9 |
ecomfe/etpl | 80 | 237 | 24 |
ustwo/ustwo.com-frontend | 77 | 278 | 20 |
node-inspector/node-inspector | 157 | 373 | 21 |
q-nick/npm-gui | 71 | 227 | 8 |
dojo/dojox | 317 | 662 | 53 |
majimboo/node-benchmarks | 63 | 141 | 5 |
prettier/prettier | 84 | 277 | 45 |
d3/d3.github.com | 895 | 1104 | 67 |
adobe/node-smb-server | 79 | 194 | 13 |
noble/bleno | 66 | 141 | 5 |
wagtail/wagtail | 115 | 1462 | 56 |
meteor/blaze | 83 | 194 | 12 |
dwyl/hapi-socketio-redis-chat-example | 68 | 141 | 5 |
chancancode/hn-reader | 64 | 165 | 20 |
shipshapecode/ember-shepherd | 82 | 152 | 30 |
draptik/angulardemorestful | 76 | 163 | 6 |
icebob/vue-express-mongo-boilerplate | 77 | 422 | 9 |
ngryman/ribs | 64 | 193 | 7 |
rjrodger/seneca-examples | 70 | 176 | 12 |
telepat-io/telepat-api | 68 | 173 | 8 |
sematext/logagent-js | 68 | 162 | 8 |
cookpad/elasticfox-ec2tag | 87 | 173 | 11 |
polonel/trudesk | 170 | 1835 | 77 |
saintedlama/passport-local-mongoose | 72 | 173 | 7 |
cholalabs/passport-localapikey | 63 | 3 | 5 |
mozilla/openbadger | 79 | 184 | 20 |
inbasic/turbo-download-manager | 94 | 206 | 31 |
pgherveou/gulp-awspublish | 65 | 152 | 5 |
swagger-api/swagger-socket | 93 | 746 | 7 |
tactivos/jquery-sew | 69 | 225 | 5 |
johansatge/jpeg-autorotate | 63 | 152 | 6 |
mqttjs/mqtt-packet | 65 | 173 | 12 |
fulcrum-agile/fulcrum | 80 | 152 | 18 |
microweber/microweber | 300 | 937 | 162 |
adamhalasz/uniqid | 68 | 151 | 5 |
componentjs/builder2.js | 71 | 142 | 8 |
frankyghost/projekktor | 92 | 195 | 9 |
nielsutrecht/jwt-angular-spring | 88 | 288 | 8 |
petereigenschink/steganography.js | 69 | 141 | 5 |
mixteam/mixsln | 75 | 205 | 48 |
borismus/webvr-boilerplate | 70 | 213 | 42 |
arrix/node-readability | 77 | 152 | 19 |
iamcal/js-emoji | 72 | 412 | 6 |
jbavari/ionic-socket.io-redis-chat | 149 | 384 | 19 |
cheeaun/steepless | 69 | 142 | 5 |
joewalker/devtools.html | 177 | 2 | 74 |
gaearon/react-hot-loader | 80 | 162 | 15 |