Este es el tercer episodio de un serie de artículos sobre el tipo más frecuente de ataques a la cadena de suministro de software: aquellos que abusan de un registro público de De código abierto componentes de software. Después de analizar en el episodio anterior”Anatomía de los paquetes maliciosos: ¿cuáles son las tendencias?” cómo los malos actores inyectan comportamiento malicioso en componentes publicados nuevos o existentes, estamos listos para ponernos nuestras chaquetas de bombero y examinar cómo podemos bloquear con éxito el software malicioso distribuido de esta manera o, alternativamente, lidiar con un incidente cibernético potencialmente grave porque tomamos el enfoque equivocado.
La mayoría de los profesionales con conciencia de seguridad tienen ideas sobre cómo gestionar esta amenaza. Hemos escuchado a los gerentes de seguridad decir sin dudarlo que SCA Las herramientas ya te avisan cuando una versión de un paquete es malware. O que dependen de componentes de software conocidos y con excelentes reseñas, donde cualquier malware se detectaría y eliminaría rápidamente. Utilizan versiones menores o parches abiertos para obtener automáticamente correcciones de vulnerabilidades, y esa es la forma correcta y recomendada de reducir el riesgo de las dependencias de código abierto, siguiendo el principio de "parche temprano, parche a menudoPrincipio.
En este episodio, revisaremos por qué estas ideas son erróneas y cómo dichos conceptos erróneos están contribuyendo a la popularidad de este mecanismo de ataque y al riesgo abrumador que están experimentando las organizaciones. Terminaremos con lo que sí funciona, y cuál es el esfuerzo y los recursos que implica.
Conceptos erróneos comunes
Durante nuestro recorrido por la seguridad del software, vimos cómo evolucionaban las técnicas de ataque y una amplia gama de ideas de personas preocupadas por la seguridad. Las organizaciones a menudo no entienden qué funciona contra esta amenaza, por lo que primero examinaremos lo que no funciona, condensado en la siguiente lista, no exhaustiva, de conceptos erróneos.
Concepto erróneo # 1: SCA Las herramientas ya informan sobre componentes maliciosos
¡Ciertamente! Pero después del hecho… Cuando probablemente sea demasiado tarde si el elemento se utilizó en una compilación de software y los actores maliciosos ya se han afianzado en un desarrollador o CI/CD Es posible que se hayan exfiltrado secretos, se haya descargado e instalado malware adicional, y quizás el adversario se haya movido lateralmente y ya haya obtenido acceso a otro lugar.
Análisis de composición de software (SCA) Las herramientas se diseñaron para identificar posibles vulnerabilidades conocidas. Las herramientas modernas son eficaces al aumentar la relación señal-ruido, determinando si la vulnerabilidad es realmente accesible o explotable. Sin embargo, son inútiles contra malware nuevo. Consideremos un componente malicioso como una vulnerabilidad de día cero: solo cuando se detecta su comportamiento malicioso, se informa al registro de almacenamiento, que, tras una revisión por parte de un equipo de seguridad, se confirma como malicioso y se elimina del registro. [ 1 ].
En ese momento, el mundo (incluido SCAs) sabe que instalar o usar el componente (o alguna versión de un componente existente) no es recomendable. Pero esto ocurre cuando el componente no está disponible en el registro.Saber que tengo vulnerabilidades en componentes de terceros, o incluso componentes que el registro categorizó como maliciosos, es bueno, pero desafortunadamente... SCA o las herramientas de auditoría comunes no ayudan en este contexto. A menos que el SCA/La herramienta de auditoría puede saber realmente de antemano que un componente es malicioso antes de que se utilice en su organización.
Recuerde, cualquier solución contra componentes maliciosos de código abierto debe detectarlos sobre la marcha, entre el momento en que el componente se publica en el registro y el momento en que el componente (versión) se utiliza por primera vez en su organización. Y eso incluye componentes transitivos.
Concepto erróneo n.º 2: controlar los scripts de instalación en el momento de la compilación evita el comportamiento malicioso de los componentes de código abierto
Varios administradores de paquetes ofrecen la posibilidad de ejecutar scripts (incluidos en el paquete tar). [ 2 ]), por razones legítimas, como compilar elementos requeridos en diferentes plataformas, generar código o ejecutar pruebas, y todos debemos saber que los malos actores pueden abusar de ellos si se incluyen scripts maliciosos en el archivo tar o si el atacante puede crear un archivo malicioso. ejecución del script en lugar del bueno.
Sabiendo esto, podemos configurar el administrador de paquetes para que ignore los scripts. Por ejemplo, con la NGP la –ignorar-scripts bandera (o una propiedad de configuración en el .npmrc file) omite los scripts durante la instalación. Esto puede producir algunos problemas porque la ejecución de scripts es común en muchos ecosistemas: algunos administradores de paquetes ni siquiera permiten deshabilitar la ejecución de scripts (pista: mensaje "¿Qué administradores de paquetes no permiten deshabilitar la ejecución de scripts de instalación?”en tu IA favorita). Pero esto no protege en general (debemos hacer cumplir que la configuración de omisión de desactivación esté en todas partes).
Y cuando el comportamiento malicioso no se localiza en los scripts de instalación sino en el software a ejecutar en tiempo de ejecución, esta opción por sí sola no nos protege.
Concepto erróneo n.º 3: la fijación de versiones impide que se instalen componentes maliciosos
Existe una contrapartida entre aplicar parches temprano y a menudo con versiones abiertas (permitiendo que el administrador de paquetes instale automáticamente nuevas actualizaciones cuando estén disponibles para correcciones de seguridad) y fijación de versión (tener todas las dependencias directas y transitivas de un software en una versión fija). Los principios de seguridad son tercos y a veces contradictorios, como ocurre con “parchear pronto, parchear con frecuencia” y “La actualización no debe tomarse a la ligera”. Algunos administradores de paquetes realizan actualizaciones automáticas con rangos de servidores de la forma recomendada. ¡Genial si también quieres recibir actualizaciones maliciosas! Sí, los componentes deben actualizarse para recibir correcciones de seguridad que cierren las vulnerabilidades lo antes posible, pero… nunca dejes que el administrador de paquetes haga esto automáticamente.
Concepto erróneo n.º 4: utilizar componentes confiables es seguro. Cualquier versión maliciosa sería encontrada, divulgada y eliminada rápidamente.
¿Por qué se confía en un componente? Posiblemente porque es muy popular, hay muchos observadores que buscan vulnerabilidades, una gran cantidad de colaboradores para el mantenimiento y varios encargados de mantenimiento que revisan diligentemente todos los componentes. pull requestsLa realidad es muy distinta. Algunos componentes esenciales son mantenidos por un único desarrollador no remunerado. Los frameworks más utilizados tienen algunos colaboradores habituales, con un número rápidamente decreciente de commits por mantenedor (los proyectos populares tienen una larga lista de contribuyentes que realizan algunas tareas de drive-by). commit y nunca volvio). Y abundan los proyectos populares con un solo mantenedor.
Imagínate diciendo "Oh, estamos usando imágenes de Spring Boot/Angular/React/PyTorch/base oficial de Docker, por lo que el riesgo del que estás hablando es bastante bajo". Quizás eso sea cierto, nosotros, los proveedores de seguridad, alarmamos todo el tiempo e interferir con los equipos de desarrollo para mitigar un riesgo discutible no tiene sentido. Es posible que tenga la tentación de saltar al párrafo de aceptación de riesgos (en la siguiente sección) y listo. Desafortunadamente, los componentes más populares son el objetivo de los malos actores y, por ejemplo, los populares La biblioteca PyTorch fue atacada en el pasado.
“Encontrado, divulgado y eliminado rápidamente”. Se necesitan días para eliminar un nuevo componente malicioso del registro público. Los registros son cautelosos a la hora de eliminar una versión de componente, para siempre. Nuestra experiencia es que una vez informado por nuestra parte, el tiempo medio que tarda el registro en eliminar la versión afectada es de 39 horas, más de un día y medio. Hay componentes maliciosos que se encuentran una semana después de nuestro informe inicial en el registro antes de eliminarlos. Y en algunos casos, el componente se elimina sólo después de que una víctima o una empresa de respuesta a incidentes informa un incidente que involucra al componente.
Lo que NO funciona contra componentes maliciosos
Cualquier enfoque no específico fracasará estrepitosamente. Esto es seguro, no está proporcionando contramedidas efectivas para el riesgo asociado con esta amenaza.
Tradicional SCA Las herramientas informan sobre malware conocido, pero tienen una amplia ventana de exposición. A menos que detecten malware de forma proactiva y bloqueen los componentes maliciosos, no son eficaces contra esta amenaza.
Deshabilitar los scripts de instalación podría ayudar, pero debe aplicarse en todos los lugares donde sea necesario instalar un componente. Lo mismo ocurre con la fijación de versiones, ya que las versiones no se pueden fijar desde un estado inicial seguro para siempre.
Suponer que los componentes populares reciben suficiente atención como para que no se les pueda inyectar un comportamiento no deseado en un ataque a la cadena de suministro sin una detección casi instantánea para evitar cualquier daño es ingenuo y arriesgado. No quieres vivir al límite, ¿verdad?
Si te detienes en este punto, entonces aceptación de riesgo es lo único que puedes hacer: Esto es un decisInformación que debe documentarse en su modelo de amenazas/evaluación de riesgos, incluyendo la justificación para aceptar el riesgo y sus posibles implicaciones. Concientice comunicándoselo a la gerencia y otras partes relevantes. Algunos contingencia Se podría planificar cuando se instala o incluye un componente malicioso en su software, pero esto es difícil porque los atacantes tienen muchos caminos a seguir. Los detalles de un ataque a la cadena de suministro basado en el uso de un componente malicioso cambiarán drásticamente la divulgación pública del incidente, que probablemente sea obligatoria según el marco regulatorio de su organización. También puede dirigirse controles compensadores or riesgo de transferencia por ejemplo con seguro.
Sin embargo, existen controles que abordan la amenaza y deben considerarse si no está satisfecho con la aceptación del riesgo. Por favor sigue leyendo.
¿Qué funciona contra ataques que utilizan componentes maliciosos?
Manejo de versiones sólidas
La fijación de versiones con mejoras de versión controladas e informadas es el camino a seguir para equilibrar la necesidad de eliminar vulnerabilidades sin recibir malware. Pero recuerde el error número 3: la fijación de versiones por sí sola no es suficiente para bloquear el código malicioso proveniente de nuevas versiones, porque en el futuro necesitará actualizar las versiones en cualquier dependencia directa o indirecta. En ese momento se necesitan pruebas lo suficientemente sólidas de que todas las versiones modificadas no contienen malware.
Alerta temprana
Una solución al problema de los componentes maliciosos es un sistema de alerta temprana (denominado aquí como Alerta temprana de malware o MEW), donde las nuevas versiones publicadas (para componentes nuevos o existentes) son analizadas por un motor de detección, que cuando se encuentra evidencia suficiente puede clasificar la nueva versión como potencialmente maliciosa.
La automatización es esencial aquí, ya que es imposible revisar manualmente todos los componentes nuevos al ritmo de publicación actual. Por lo tanto, el motor de detección necesita combinar una variedad de técnicas, incluyendo quizás análisis estático, dinámico y de capacidad, reputación del usuario y evidencia proveniente de discrepancias entre los metadatos del componente y el contenido del tarball, o entre el tarball y el repositorio de origen donde supuestamente se encuentra el componente. viene de.
Hay un zona oscura entre el momento de la publicación y el momento en que el motor analiza el contenido del componente, pero no debe exceder unos pocos minutos. El esquema se puede modificar, por ejemplo, esperando a que se analicen los nuevos componentes antes de permitir su instalación y uso en la compilación del software. pipelines, o analizarlos bajo demanda cuando sea necesario. Un componente en una versión determinada es inmutable. [ 3 ], por lo que es necesario analizarlo solo una vez.
La automatización total no es posible y se necesita una revisión de seguridad para detectar componentes potencialmente maliciosos. Cuidado con los defensores de la panacea digital: La IA y el aprendizaje automático no están lo suficientemente desarrollados como para tener la última palabra a la hora de confirmar si un componente sospechoso tiene malware. Claro, el aprendizaje automático juega un papel clave en el motor de detección al clasificar el componente de entrada a partir de la evidencia sin procesar capturada, pero una vez que el componente se "pone en cuarentena", la última palabra la tiene la revisión manual por parte de un equipo de seguridad con experiencia en componentes maliciosos. Esto confirma cualquier posible malware o lo reclasifica como seguro. Y el período de tiempo está en el rango de horas.
El registro informa sobre la versión/componente malicioso; Luego, el registro realiza su revisión para confirmar y procede a la divulgación pública y la eliminación del registro. Algunos registros mantienen un paquete de retención de seguridad. El rango de tiempo aquí son los días o semanas desde la publicación, que es el 'tiempo de permanenciaOventana de exposición' para la mayoría de los componentes maliciosos.
¿Es posible saber si la versión de un componente es maliciosa?
Entonces, para una alerta temprana, debemos dar una respuesta satisfactoria a esta pregunta: ¿Cómo puedo saber que una biblioteca o paquete es (no) malicioso? ¿Cómo reunir suficientes pruebas de comportamiento malicioso? Posible, pero difícil, ya que los adversarios utilizan mucho ingenio para evitar ser detectados. Existen diferentes enfoques, cada uno con sus pros y sus contras.
Análisis estático puede examinar todas las rutas de ejecución, comprobar las técnicas utilizadas por los atacantes sin ejecutar el componente y realizar tareas de preprocesamiento como desofuscación o descifrado. Mientras los atacantes intentan ocultar sus travesuras, los intentos de ofuscación son de hecho evidencia de malware (pero tenga en cuenta que los componentes legítimos ofuscan el código para preservar la propiedad intelectual, lo que contradice "Open Source”). Solo una minoría de ataques altamente sofisticados con una fuerte ofuscación necesitan un entorno aislado, pero una ofuscación tan fuerte es un signo revelador de malicia. Tenga en cuenta que los ataques convencionales SAST Las herramientas fueron diseñadas para vulnerabilidades no intencionales, no para intenciones maliciosas como las puertas traseras.
Análisis dinámico ejecuta el componente y examina la respuesta instrumentando el tiempo de ejecución, generalmente proporcionando un entorno de espacio aislado. El comportamiento malicioso desencadenado bajo ciertas condiciones puede pasar desapercibido: tenga en cuenta que el malware puede utilizar técnicas de evasión como Evasión de Virtualización/Sandbox para activarse sólo cuando no está bajo escrutinio, y también es un signo revelador de actividad maliciosa para cualquier motor de análisis estático.
Análisis de capacidades considera lo que hace el componente: dónde se conecta, a qué archivos accede, qué comandos o programas se ejecutan, la terminal o dispositivo de E/S realizada o qué llamadas al sistema se invocan. Esta huella digital del comportamiento podría compararse (para un componente existente) entre versiones, de modo que cuando se detecte un comportamiento inesperado, esa evidencia podría generar sospechas de una posible actividad maliciosa inyectada en la nueva versión. Este enfoque sigue los pasos de clasificación que siguen los analistas de seguridad cuando se enfrentan a malware potencial: una inspección utilizando instrumentos de cuerda o herramientas similares. Este enfoque detecta comportamiento malicioso independientemente de las condiciones desencadenantes y funciona cuando no hay código fuente disponible.
Análisis de contexto recopila información sobre cómo se publicó el componente y por quién. Las campañas de los malos actores suelen utilizar cuentas de usuario nuevas que no están sujetas a ningún proceso de investigación estricto. El seguimiento de la actividad pasada puede brindar información sobre el usuario subyacente, principalmente en busca de anomalías que puedan indicar un posible compromiso. ¡La reputación es tan difícil de ganar y tan fácil de perder! Un usuario sin actividad pasada es neutral, pero el karma persigue a los malévolos. Se debe realizar un seguimiento cuidadoso de los hacktivistas, o usuarios normales a quienes les roban sus credenciales de publicación.
Otra información contextual es cualquier discrepancia entre el repositorio fuente supuestamente utilizado para crear el componente tarball y el contenido del propio tarball. Y también seguir buenas prácticas, como crear etiquetas o lanzamientos en el repositorio de origen que coincidan con las versiones del componente publicadas en el registro público. Cuando el repositorio de origen en un determinado commit está etiquetado con lanzamiento y, de repente, una versión no lo sigue, eso por sí solo es una fuerte evidencia de que el componente podría estar contaminado: el mal actor podría haber comprometido la cuenta utilizada para publicar el componente, pero no tiene permisos de escritura en el código fuente. repositorio). Muchos ataques se detectan de forma rutinaria utilizando estas reglas: por ejemplo, el Ataque al libro mayor podría detectarse fácilmente en este sentido. Por lo tanto, el análisis del contexto identifica tales anomalías en el proceso de publicación.
Cortafuegos de dependencia
Un enfoque diferente es tener una lista blanca completa de componentes para todos los gráficos de dependencia utilizados en su software, de modo que en cualquier compilación pipeline ejecutado en su organización, solo se pueden instalar y utilizar versiones de componentes aprobadas. El "cortafuegos”se aplica mediante un registro interno donde se sirven los archivos tar para las versiones permitidas de los componentes (en caché o proxy). Tenga en cuenta que cualquier lista blanca no funcionará a menos que tenga la tecnología para clasificar cualquier versión nueva como razonablemente segura para poder agregarla a la lista blanca.
Tenga en cuenta que la alerta temprana (detección rápida lo antes posible después de la publicación de la nueva versión) debe combinarse con alguna forma de utilizar esa información de forma proactiva para bloquear el componente que afecta la compilación. pipelines o las máquinas de los desarrolladores [ 4 ]. A esto lo llamamos “firewall de dependencia”: un mecanismo de cuarentena para proteger compilaciones automatizadas de paquetes maliciosos. Los paquetes internos y los registros de imágenes son buenos para aislar a las organizaciones del mal externo, pero se necesita evidencia lo suficientemente sólida para que la cuarentena sea efectiva.
Zona de pruebas en tiempo de ejecución
Un enfoque alternativo para la detección en el momento de la publicación es analizar el comportamiento en tiempo de ejecución. La idea es capturar el comportamiento esperado del software y detectar (o bloquear) cualquier anomalía que se encuentre. Esta línea de actuación tiene el problema de tener que instrumentar el runtime para su monitorización o bloqueo, y es una idea prometedora que se sumará al arsenal de mecanismos de protección contra la plaga de componentes maliciosos.
Establecer una estrategia integral
La estrategia recomendada debe combinar diferentes técnicas en el proceso de desarrollo de software, tomando el control de las actualizaciones de versión para bloquear los componentes maliciosos entrantes. Debemos adaptar la fijación de versiones para evitar la infección automática al actualizar las versiones para obtener correcciones para las vulnerabilidades importantes; una evaluación rápida y eficiente de las dependencias directas e indirectas durante las actualizaciones de versiones para tener evidencia suficiente de que no están plagadas de malware. Se deben bloquear las compilaciones de software que dependen de componentes maliciosos conocidos. Y todo debe hacerse cumplir.
Utilice la fijación de versiones, cuando sea posible, ya que hace que las compilaciones sean más reproducibles. Fijación de versión con topes de versión controlados y aprobados manualmente y asistido por tecnología auxiliar, deben evaluar si la actualización trae malware o daña el software, y conciliar la actualización para corregir vulnerabilidades con evitar la infección de malware. Las herramientas pueden ayudar aquí, al (1) priorizar qué vulnerabilidades realmente importan (alcanzables y explotables, con un alto riesgo de ser atacadas por atacantes), (2) seleccionar las versiones de destino que sean compatibles con los usos actuales de los componentes y que no rompan el software, (3) elegir versiones de destino que no contengan comportamiento malicioso y (4) hacer que la actualización de la versión para dependencias directas e indirectas sea muy sencilla, sugiriendo cambios en los archivos de manifiesto que podrían aprobarse rápidamente. El paso (3) necesita información específica sobre los componentes maliciosos lo más cerca posible de su fecha de publicación.
Este proceso de actualización de dependencias debe ser forzado y verificadas En todos los lugares. El proceso debe documentarse y todas las partes involucradas deben recibir capacitación, ya que a menudo el desarrollo y la creación/implementación del software se externalizan. CI/CD pipelines deben modificarse en consecuencia, de modo que la automatización no permita que una dependencia indirecta maliciosa se introduzca en la compilación: guardrails La forma recomendada de hacerlo es bloquear la compilación si hay suficiente evidencia de posible malware en una dependencia.
Si su organización tiene un registro interno que actúa como proxy de seguridad para mantener las versiones permitidas de los componentes, debe obtener inteligencia sobre los componentes maliciosos (además de otros criterios) para examinar un componente solicitado antes de agregarlo a la lista permitida.
Consumir software de código abierto de forma segura no es fácil y el factor malware debe tenerse plenamente en cuenta, con un esfuerzo similar puesto en el manejo de vulnerabilidades.
Una nota final: Procedencia de la fuente, en forma de certificaciones de software, generadas en el momento de la compilación del componente, es otra pieza clave en el esfuerzo por rastrear el artefacto (tarball del componente) con las fuentes y el proceso de compilación que lo produjo. Tenga en cuenta que este vínculo entre la instantánea de origen + el entorno de compilación y el artefacto de software asociado (firmado por el sistema de compilación confiable) no impide per se que el componente no contenga comportamiento malicioso, pero dificulta que los malos inyecten malware. . Y hacer de la validación de procedencia un requisito común para consumir componentes de código abierto llevará mucho tiempo, y solo agregado recientemente a NPM. Hacer que esos sistemas confiables de construcción e implementación sean a prueba de manipulaciones o permitir la detección de cualquier manipulación en la construcción es una historia diferente, que está fuera del alcance de esta publicación.
Seguí leyendo
El siguiente episodio Paquetes maliciosos de código abierto: el enfoque Xygeni presentará la estrategia que seguimos en Xygeni para nuestra Alerta temprana de malware (MEW) sistema. Se escanean nuevas versiones de paquetes en los registros públicos de paquetes e imágenes y se obtiene evidencia utilizando una combinación de análisis estático, dinámico, de capacidades y contextual. La evidencia, combinada con la reputación del usuario y el historial de cambios en los repositorios de código fuente, permite una clasificación totalmente automatizada de un componente en categorías de alto riesgo y probablemente maliciosas. El sistema aprende de la evidencia anterior recopilada de los paquetes para reducir los falsos positivos al mínimo.
Las organizaciones suscritas reciben una notificación de advertencia sobre los componentes que están utilizando, directa o indirectamente, cuando se clasifica una versión maliciosa. Luego nuestros analistas realizan un análisis manual que confirma o rechaza la clasificación. Para el malware confirmado, se notifica al registro público para que pueda realizar su propio análisis y, normalmente, eliminar la versión maliciosa o tomar medidas adicionales, como bloquear o eliminar la cuenta de usuario en cuestión.
Explicaremos cómo estamos ayudando a NPM, PyPI, GitHub y otras infraestructuras clave en el ecosistema de código abierto a reducir el tiempo de permanencia que un nuevo componente malicioso publicado permanece activo hasta que se confirma que es malware y se elimina del registro. Y cómo las organizaciones pueden beneficiarse del sistema MEW para tener una protección mucho mejor contra los ataques a la cadena de suministro de software que involucran componentes de código abierto.
- [ 1 ] De todos modos, los usuarios del componente deben verificar si el archivo tar del componente está almacenado en caché o registrado en algún lugar, por ejemplo en un registro interno, para erradicar el problema.
- [ 2 ] El componente empaquetado incluye un manifiesto que declara su contenido y metadatos, código fuente o compilado, scripts de instalación y elementos adicionales, como conjuntos de pruebas, según un formato de empaquetado y normalmente en forma comprimida. Esto se llama "tarball de componentes".
- [ 3 ] Incluso si el actor malintencionado puede modificar un componente publicado debido a una infracción en el propio registro, un resumen criptográfico simple puede detectar cualquier cambio en el archivo tar una vez realizado el análisis.
- [ 4 ] Recuerde que algunos componentes maliciosos se ejecutan en el momento de la instalación, por lo que puede afectar a los nodos de desarrollador que, sin saberlo, ejecutan "npm install X" con X como componente malicioso.




