osv-scanner

Activity, over time

Daily observations from the public event archive.

Attention

Daily stars & forks

Loading attention chart

Star accumulation

Cumulative stars

Loading star accumulation chart

Pull requests

Daily opens & merges

Loading pull requests chart

Conversations

Daily issues & comments

Loading conversations chart

Community

Daily accounts & reviews

Loading community chart

Releases

Daily releases

Loading releases chart

Mentions

11posts · 30d
Nov 30 posts
  1. Hacker News · · on Linode Security Incident · suidpit

    Not a full fledged app, but you might wrap something around google/osv-scanner

  2. DEV · · @lu1tr0n

    Extensiones de código: qué revisar antes de instalar Kevin Beaumont, el investigador que rastreó WannaCry y publica como @GossiTheDog, escribió en Mastodon que la extensión de Claude Code habría sido comprometida. Anthropic no confirmó el reporte y la publicación no aporta indicadores técnicos verificables. Da igual que esa denuncia puntual se confirme o no: el mismo patrón, código oficial que termina filtrando credenciales, explica por qué cada vez más equipos tratan cada extensión, plugin o paquete como código no confiable hasta probar lo contrario. Y ese patrón ya tiene un caso confirmado este año: LiteLLM 1.107.0 en PyPI. TL;DR - Revisar permisos, red y dependencias antes de instalar detecta backdoors como el de LiteLLM 1.107.0 en PyPI.- Un postinstall script en npm o un hook de importación en pip puede exfiltrar credenciales sin mostrar ningún error.- La bandera --ignore-scripts de npm y pip-audit detectan o bloquean código de instalación sin revisar.- osv-scanner cruza tu lockfile contra la base pública de OSV.dev antes de que el ataque llegue a producción.- Una extensión marcada como oficial no garantiza ausencia de telemetría oculta ni de dependencias comprometidas. ¿Qué es auditar extensiones de código? Auditar extensiones de código es el proceso de revisar permisos, llamadas de red y dependencias de un plugin o paquete antes de instalarlo, aunque venga de un marketplace oficial. Busca detectar robo de credenciales, telemetría oculta o código inyectado antes de que se ejecute en tu máquina o en un pipeline de CI/CD. El término "oficial" genera una falsa sensación de seguridad. Un marketplace de extensiones, un registro de paquetes como npm o PyPI, o la cuenta verificada de un proyecto open source certifican la identidad de quien publica, no la ausencia de código malicioso en cada versión. La auditoría llena exactamente ese espacio: la distancia entre "lo publicó quien dice ser" y "el código que publicó es seguro". LiteLLM 1.107.0, publicado en PyPI, incluía un robacredenciales y una puerta trasera. Por qué importa: de una denuncia en Mastodon a un backdoor confirmado en LiteLLM La publicación de Beaumont no incluye hashes ni un análisis técnico público. Es la afirmación de un investigador reconocido, no una auditoría publicada ni una confirmación de Anthropic. Tratarla como hecho consumado repetiría el mismo error que cualquier guía de seguridad critica: aceptar una fuente sin corroborarla. El riesgo real no depende de si esa denuncia puntual se confirma. Ya existe un caso documentado con el mismo patrón: LiteLLM, el proxy open source para unificar APIs de modelos de lenguaje, publicó en PyPI la versión 1.107.0 con un robacredenciales y una puerta trasera incluidos en el paquete. Quien instaló esa versión con un simple pip install litellm==1.107.0 ejecutó ese código con los mismos permisos que su propia aplicación. La lección no es "no uses LiteLLM" ni "no confíes en Anthropic": es que ninguna plataforma (PyPI, npm, un marketplace de extensiones) revisa línea por línea cada publicación antes de distribuirla. El control de calidad recae, en la práctica, en quien instala. Cómo funciona una extensión maliciosa por dentro La mayoría de los ataques por este canal no explotan una vulnerabilidad de memoria ni un exploit sofisticado. Abusan de un mecanismo legítimo que casi todos los gestores de paquetes ofrecen: ejecutar código automáticamente durante la instalación. Scripts de instalación automática En npm, el campo scripts.postinstall de un package.json corre apenas termina de descargarse el paquete, sin que el usuario lo apruebe explícitamente. En pip, el equivalente clásico es un setup.py con código a nivel de módulo, fuera de cualquier función, que Python ejecuta durante el build. Ambos mecanismos existen por razones legítimas, como compilar una dependencia nativa, pero son indistinguibles a simple vista de un script que exfiltra variables de entorno. Telemetría no declarada Una extensión de editor (VS Code, JetBrains) puede declarar permisos amplios, como acceso a archivos o a red, que el marketplace aprueba porque son parte del modelo de negocio del propio editor. Nada impide que, además de la función anunciada, la extensión envíe eventos a un dominio de analítica propio sin romper ninguna regla formal del marketplace. Dependencias transitivas comprometidas El paquete que instalás a propósito casi nunca es el problema. El problema suele estar dos o tres niveles abajo, en una dependencia de una dependencia que nadie en tu equipo revisó nunca. Un npm ls --all en un proyecto mediano fácilmente devuelve varios cientos de paquetes transitivos. Permisos amplios en extensiones de asistentes de código Las extensiones de asistentes de IA para programar, como Claude Code, GitHub Copilot o Cursor, son un caso particular porque su función misma requiere acceso amplio: leer el repositorio completo, ejecutar comandos de shell y, en muchos flujos, leer variables de entorno donde suelen vivir tokens de API y credenciales de nube. Ese nivel de acceso no es un error de diseño, es necesario para que la herramienta funcione, pero convierte a cualquier extensión de este tipo en un objetivo de alto valor: comprometerla una sola vez da acceso a todo lo que el desarrollador podría tocar. sequenceDiagram participant Dev as Desarrollador participant Reg as Registro de paquetes participant Script as Script de instalación participant C2 as Servidor del atacante Dev->>Reg: pip install litellm 1.107.0 Reg-->>Dev: entrega el paquete Dev->>Script: ejecuta instalación Script->>C2: envía variables de entorno Note over Dev,C2: la exfiltración ocurre antes del primer uso del paquete > ⚠️ Ojo: el flag --ignore-scripts de npm bloquea los scripts de instalación de TODAS las dependencias, no solo las sospechosas. Puede romper paquetes legítimos que compilan binarios nativos durante el install. Cómo empezar: auditar una extensión paso a paso Esta checklist asume que ya tenés Node.js y npm instalados, cualquier versión reciente de Node incluye npm. Si trabajás en Python, los comandos equivalentes usan pip y se indican entre paréntesis. Checklist para auditar extensiones de código antes de instalar Antes de correr npm install o agregar una extensión desde un marketplace, cuatro pasos reducen la mayoría del riesgo: - Leer el manifiesto sin instalar. npm view express scripts --json muestra los scripts declarados sin descargar ni ejecutar nada. Salida esperada para un paquete sin scripts de instalación: {}. Si aparece una clave postinstall o preinstall, revisá ese script antes de seguir.- Revisar el árbol de dependencias. npm ls --all (o pip show -f <paquete> en Python) lista cada dependencia transitiva. Un paquete chico con cientos de líneas de dependencias es una señal de que auditarlo a mano no es viable y conviene apoyarse en una herramienta automatizada.- Escanear contra vulnerabilidades conocidas. osv-scanner, de Google, cruza tu package-lock.json o requirements.txt contra la base pública de OSV.dev: osv-scanner scan source --lockfile=package-lock.json. Si no hay coincidencias, el comando termina sin listar vulnerabilidades y devuelve código de salida 0.- Observar el tráfico de red en una instalación aislada. Corré la instalación dentro de un contenedor o una VM descartable y capturá las conexiones salientes con strace -f -e trace=network -o salida.log npm install. Un paquete que solo contacta registry.npmjs.org es lo esperado; una conexión a un dominio desconocido en ese log es la señal de alarma que justifica no seguir. Para extensiones de editor (VS Code, JetBrains) El mismo principio aplica a extensiones de editor, con una diferencia práctica: la mayoría no expone un manifiesto tan legible como package.json. code --list-extensions --show-versions lista lo que ya tenés instalado; antes de agregar una nueva, revisar su página en el marketplace por los permisos declarados y, sobre todo, por quién la publica (la cuenta del propio proyecto frente a un fork de un tercero) evita la mayoría de los casos de suplantación. flowchart TD A["Extensión nueva a instalar"] --> B{"Publicador verificado?"} B -->|"No"| X["Rechazar"] B -->|"Si"| C{"Scripts de instalación declarados?"} C -->|"Si"| D["Revisar el script línea por línea"] C -->|"No"| E{"Dependencias transitivas excesivas?"} D --> E E -->|"Si"| F["Escanear con osv-scanner"] E -->|"No"| G["Instalar y monitorear tráfico de red"] F --> G Corea del Norte comprometió 1.700 paquetes en npm, PyPI, Go y Rust con malware, según reportes de seguridad de 2026. Qué hacer si ya instalaste una extensión sospechosa Si la auditoría llega tarde y la extensión ya está instalada y en uso, el orden de las acciones importa más que la velocidad de cada una. - Rotar credenciales primero, investigar después. Cualquier token de API, clave de nube o contraseña accesible desde el entorno donde corrió la extensión se considera comprometido. Rotarlas no espera a confirmar si hubo exfiltración real.- Revisar logs de red salientes. Si tenés un firewall de salida o un proxy corporativo, buscá conexiones hacia dominios que no correspondan a los registros oficiales del paquete (registry.npmjs.org, pypi.org, el dominio propio del proyecto) en la ventana en que la extensión estuvo activa.- Buscar persistencia. Un backdoor que solo roba credenciales una vez es grave pero acotado; uno que instala una tarea programada, un hook de git o un servicio que sobrevive a la desinstalación es un incidente de otra escala. Revisar crontab -l, hooks en .git/hooks/ y servicios nuevos del sistema cubre los vectores de persistencia más comunes.- Documentar la cadena completa. Versión exacta instalada, fecha y qué credenciales estaban accesibles en ese momento. Esa información es la que necesita cualquier reporte posterior al equipo de seguridad o al propio proyecto afectado. flowchart LR A["Extensión sospechosa detectada"] --> B["Rotar credenciales"] B --> C["Revisar logs de red"] C --> D["Buscar persistencia"] D --> E["Documentar el incidente"] > 📌 Nota: una extensión de IA para programar suele pedir acceso de lectura y escritura a todo el repositorio y a las variables de entorno del shell donde corre. Ese nivel de acceso es exactamente lo que vuelve atractivo a este vector de ataque. Casos de uso reales: más allá de LiteLLM El patrón no es exclusivo de un ecosistema. En 2026, investigadores documentaron una campaña atribuida a actores de Corea del Norte que infectó más de 1.700 paquetes distribuidos entre npm, PyPI, Go y Rust con malware, aprovechando el mismo mecanismo: un script de instalación o un hook de importación que corre sin revisión humana. La escala cambia, el vector es el mismo. El caso de Claude Code que denuncia Beaumont, confirmado o no, encaja en esa misma categoría de riesgo: una extensión con acceso directo al entorno de desarrollo (variables de entorno, tokens de API, archivos del proyecto) es un objetivo de alto valor precisamente porque corre con los mismos permisos que el desarrollador que la instaló. Para equipos en LATAM que integran agentes de IA en su flujo de trabajo sobre repositorios con información de clientes, el costo de una credencial filtrada no es solo técnico: puede implicar una notificación obligatoria a usuarios según la legislación local de protección de datos. La auditoría previa, en ese contexto, es tanto parte del cumplimiento como de la seguridad. Errores comunes y buenas prácticas - Confiar en el badge de "verificado" sin revisar el contenido. Un marketplace certifica identidad del publicador, no la ausencia de código malicioso en cada actualización.- No fijar versiones exactas. Un rango como ^1.107.0 en vez de 1.107.0 exacto en el lockfile permite que una actualización comprometida se instale sola en el próximo npm install.- Ignorar los scripts de instalación por costumbre. La mayoría de los desarrolladores nunca leyó un postinstall de una dependencia que usa todos los días.- No monitorear tráfico de salida. Sin un registro de qué dominios contacta una herramienta, una exfiltración de credenciales puede pasar meses sin detectarse.- Auditar una sola vez y olvidarse. Una extensión limpia hoy puede recibir una actualización comprometida la semana próxima; la auditoría es un proceso continuo, no un trámite único. Comparativa de herramientas de auditoría HerramientaQué detectaCuándo usarlaLimitaciónnpm auditVulnerabilidades conocidas en dependencias de Node.jsAntes de cada release, integrado en CISolo cubre el ecosistema npm y vulnerabilidades ya reportadaspip-auditVulnerabilidades conocidas en paquetes de PythonEn el pipeline de CI de proyectos PythonNo analiza comportamiento en tiempo de ejecuciónosv-scannerCruza lockfiles contra la base OSV.dev multi-ecosistemaAuditorías periódicas en repos con varios lenguajesDepende de que la vulnerabilidad ya esté reportada en OSVSandbox de red (strace, mitmproxy)Conexiones salientes no documentadas durante la instalaciónAntes de aprobar una dependencia nueva, una sola vezRequiere montar el aislamiento manualmente, no es automático Profundizando: procedencia, SBOM y firmas criptográficas Para equipos que gestionan cientos de dependencias, revisar manifiestos a mano no escala. La industria converge en varios mecanismos complementarios. Software Bill of Materials (SBOM) Un SBOM es un inventario formal, en formato SPDX o CycloneDX, de cada componente que compone un artefacto de software, con su versión exacta y su licencia. Herramientas como syft generan un SBOM a partir de una imagen de contenedor o un repositorio, lo que permite responder en segundos a "¿usamos en algún lado la versión comprometida de este paquete?" en vez de revisar proyecto por proyecto. Procedencia verificable con SLSA El marco SLSA (Supply-chain Levels for Software Artifacts) define niveles de garantía sobre cómo se construyó un artefacto, desde "el build corrió en algún lado" hasta "el build corrió en un sistema aislado, con el código fuente y los pasos de build firmados criptográficamente y verificables por un tercero". Un paquete con procedencia SLSA de nivel alto reduce, aunque no elimina, la posibilidad de que alguien inserte código entre el repositorio y el registro de distribución. Firmas con Sigstore Sigstore permite firmar un artefacto sin gestionar una clave privada permanente: usa certificados de corta duración ligados a una identidad, como una cuenta de GitHub, y registra la firma en un log público e inmutable. Verificar esa firma contra una imagen confirma esa cadena. Sin esto, comprobar que un binario publicado corresponde exactamente al código fuente público depende de la buena fe del mantenedor. Builds reproducibles Un build reproducible permite que cualquiera, compilando el mismo código fuente con las mismas herramientas, obtenga exactamente el mismo binario, byte a byte, que el que publicó el mantenedor. Si dos partes independientes reproducen el mismo resultado, la posibilidad de que el binario publicado contenga algo que no está en el código fuente público baja drásticamente. Debian y el proyecto Tor son dos de los ejemplos más antiguos de este enfoque aplicado en producción. 📖 Resumen en Telegram: Ver resumen Tu próximo paso: correr npm view <paquete> scripts --json sobre una dependencia que ya uses todos los días y confirmar que no declara ningún postinstall que no hayas revisado antes. Preguntas frecuentes ¿Cómo hacer control de dependencias de software sin pagar herramientas comerciales? Con herramientas gratuitas alcanza para la mayoría de los casos: npm audit y pip-audit son gratuitos, osv-scanner es open source, y revisar manifiestos con npm view no cuesta nada. El gasto de herramientas comerciales como Socket.dev o Snyk está en el monitoreo continuo automatizado, no en la capacidad básica de detección. ¿La denuncia de Kevin Beaumont sobre Claude Code se confirmó? No, al momento de escribir este artículo Anthropic no publicó una confirmación ni un desmentido público de la publicación en Mastodon. Tratala como una alerta a seguir, no como un hecho establecido. ¿Qué diferencia hay entre un backdoor y telemetría excesiva en una extensión? Un backdoor ejecuta código con la intención explícita de dar acceso no autorizado o robar datos, como el caso de LiteLLM. La telemetría excesiva suele estar declarada en algún lugar de los términos de uso, aunque sea poco visible; sigue siendo un problema de privacidad, pero no es, técnicamente, un ataque. ¿Alcanza con revisar el código fuente en GitHub antes de instalar un paquete? No siempre. El código publicado en el registro (npm, PyPI) no siempre coincide con el del repositorio público; sin procedencia verificable, como SLSA o Sigstore, no hay garantía automática de que ambos sean idénticos. Por eso conviene auditar el paquete que efectivamente se instala, no solo el repositorio. ¿Con qué frecuencia hay que repetir la verificación de paquetes de terceros? Como mínimo, en cada actualización de versión mayor o menor de una dependencia crítica, y de forma automatizada, con osv-scanner u otra herramienta similar, en cada build de CI. Una revisión hecha una sola vez pierde valor en cuanto aparece la próxima actualización. Referencias - Mastodon (@GossiTheDog): la publicación de Kevin Beaumont que denuncia, sin confirmación pública, el presunto compromiso de la extensión de Claude Code.- Repositorio de LiteLLM en GitHub: proyecto open source afectado por el paquete comprometido publicado en PyPI.- osv-scanner: escáner de Google que cruza lockfiles contra la base de datos pública de vulnerabilidades OSV.dev.- Documentación oficial de npm sobre scripts: referencia de cómo y cuándo corren los scripts de instalación como postinstall.- SLSA (Supply-chain Levels for Software Artifacts): marco de niveles de procedencia verificable para artefactos de software. 📱 ¿Te gusta este contenido? Únete a nuestro canal de Telegram @programacion donde publicamos a diario lo más relevante de tecnología, IA y desarrollo. Resúmenes rápidos, contenido fresco todos los días.

  3. @elhackernet Mientras Gemini 4 Carbon llega primero solo a equipos de defensa, osv-scanner de @GoogleOSS ya está abierto para todos. Corres osv-scanner scan source -r . en tu repo y te cruza los lockfiles contra la base OSV de vulnerabilidades conocidas. google/osv-scanner

    1 like · 22 views
  4. Reddit · · r/DiscordAlternatives · u/CinnamonPublishing

    Notice for developers of Discord alternatives Please check your package dependencies! There's a massive amount of vulnerabilities coming out this week that rank at a CVSS score at or above 8. Please use a tool like OSV Scanner by Google to scan your lock/package files: google/osv-scanner

    18 points · 52 comments
  5. Dependabot's now a month late on Python and Go CVEs --- title: "Dependabot's now a month late on Python and Go CVEs" published: true description: "Since May, Dependabot's taken a median of 36 days to pick up new Python and Go CVEs from NVD, and criticals are no quicker." tags: "python, security, github, go" canonical_url: "blog.peng.ly" cover_image: "blog.peng.ly" ai_assisted: true --- Django put out a security release on 4 August. One of the fixes, CVE-2026-15307, stops staff users writing files to disk through GeoDjango lookups, which Django says could be "in some cases enabling remote code execution". Here's what GitHub's advisory API says about it: $ gh api /advisories/GHSA-wvqv-fj8w-qmhm \ --jq '{nvd_published_at, published_at, github_reviewed_at}' { "github_reviewed_at": "2026-09-30T23:25:46Z", "nvd_published_at": "2026-08-04T17:16:46Z", "published_at": "2026-08-04T18:31:27Z" } It was public and on GitHub within an hour and a half. Then it waited 57 days for someone at GitHub to review it, and until then Dependabot doesn't tell anyone. Trivy and Grype didn't spot the ones still waiting either, which I'll get to. GitHub did warn about this. Its June post on the advisory backlog told Dependabot users: > New advisories may take longer to trigger, with critical issues prioritized. I wanted to know how much longer, and whether criticals really do go first. How a CVE gets to Dependabot There are two usual ways into GitHub's Advisory Database. A maintainer can publish an advisory on their own repo, and GitHub reviews that. Or someone else publishes the CVE (Apache, the Django team, the Go team, VulnCheck, a bug bounty platform), NVD lists it, and GitHub imports it automatically as "unreviewed". An unreviewed advisory doesn't say which package or versions it's about, and Dependabot only alerts on reviewed ones, so nothing happens until a curator fills that in. Django's went the second way, and that's the route most of this post is about. May fell off a cliff Here's the share of PyPI and Go CVEs on that route that GitHub reviewed within 30 days of NVD listing them: !NVD-route CVEs reviewed within 30 days, PyPI and Go NVD-route CVEs reviewed within 30 days, PyPI and Go (the data) _By the month NVD listed them. September's left out, as by 15 October PyPA and the Go team had only added 3 from its first fortnight_ Every month from May 2025 to April 2026 was somewhere between 73 and 100%. Then May dropped to 57%, and June and July didn't make it to one in ten. Across May to mid-September it's 31%, against 88% for the same months last year. August's a bit better at 24%, but that's only 37 CVEs and nearly all of them Python, so I wouldn't call it a recovery yet. It's both ecosytems at once, too. PyPI went from 81% to 34%, and Go from 96% to 27%. The typical wait went from same-day to 36 days. You can't see GitHub's queue from its API, as unreviewed advisories don't name a package, so I came at it from the other end. PyPA and the Go team keep their own vulnerability databases on OSV. I took every CVE from 2024 onwards in those, kept the ones that came in through NVD and not a repo advisory, and looked up when GitHub reviewed each. That's about 2,000 CVEs, 450 of them from this May to mid-September. I left out Go's standard library, since GitHub doesn't review those in any year, and openssl-encrypt, a small Python package that got 50 CVEs in two batches in August and would have dragged that month down on its own. npm and Maven don't have a database of their own outside GitHub's, so I can't do this for them. They might be fine, I've no idea. Criticals wait just as long So, "critical issues prioritized": !Reviewed within 30 days, by severity Reviewed within 30 days, by severity (the data) _15 of 20 critical, 35 of 40 high and 126 of 140 medium or low CVEs last year, then 22 of 70, 44 of 130 and 77 of 254 this year_ Criticals were the slowest group last year too, so I doubt it's new. Seven critical golang.org/x/crypto CVEs NVD listed on 22 May (one is the SSH agent not enforcing a key's confirm-before-use constraint) were all reviewed on 25 June, 34 days later. Maybe criticals do jump the queue for other kinds of advisory, but for these I cant see it. Big projects too I half expected a long tail of obscure stuff nobody installs. Here's the share of each project's NVD-route CVEs reviewed within 30 days: | Package | 2024-25 | 2026 | | ------------------- | ------- | ----- | | Mattermost | 154/155 | 18/42 | | Apache Airflow | 27/27 | 5/48 | | Gitea | 10/10 | 0/15 | | golang.org/x/crypto | 3/5 | 0/14 | | Django | 26/26 | 3/13 | The 2026 column is May to mid-September again. Airflow there includes its provider packages, and Mattermost all its modules and plugins. Airflow core on its own went from 21 of 21 to none of 34. They do get there in the end. 99% of June's CVEs have been reviewed by now, 83% of July's and 73% of August's. 36 from May to mid-September still haven't, and when I checked them all again on 16 October, none had moved. Repo advisories wait too The other route isn't any quicker. Once a maintainer publishes an advisory, GitHub's docs say reviewing it and sending Dependabot alerts "can take up to 72 hours". In September someone from GitHub's community team replied to a thread about slow CVE requests: > we're currently processing records in the order they're received, with a turnaround of approximately five weeks. And personally, since mid-August maintainers have published 58 of the advisories I've reported, 51 of them for packages Dependabot covers. GitHubs reviewed 9 so far, which took anywhere from 6 to 38 days, and the oldest one still missing from its database went public on 14 August. NIST changed something the same fortnight Why now? Tbh I don't know. GitHub says that "since mid-April" it hasn't consistently met its own goals for publishing. On 15 April, NIST changed how NVD works: it now only adds its own details, like severity scores and product lists, to CVEs that meet certain criteria (actively exploited, used by the US government and so on), and the rest wait. So maybe GitHub's curators leaned on NVD's details and lost them when NIST stopped. Or maybe they're just burried under everything else coming in - GitHub's June post says its CNA got almost 4,000 CVE requests in May alone, nearly ten times the year before. My repo advisories come with the package and versions already filled in by the maintainer, so they don't need anything from NVD, and they're slow too. That makes me lean towards the queue, but I can't prove it from out here. Quite honestly, this isn't good enough. GitHub - you need to do better. Millions of downstream apps trust you with their security, and you're taking weeks or months to send out Dependabot alerts for known critical bugs. Trivy and Grype don't see them either On 15 October I took 16 of the still-unreviewed PyPI CVEs, pinned each one's affected version in a requirements.txt, and ran Trivy 0.76 and Grype 0.120 on default settings. Neither found a single one. Grype with CPE matching turned on found 5. osv-scanner checks OSV, which has PyPA's database in it, and found all 16, which is a bit of a given since that's where I got them from, but thats also the point. If PyPA has it, osv-scanner will tell you, and it's one line to try: osv-scanner scan source -r . Go's less clear cut. Go's own database had 83% of these CVEs within a month last year and 19% this year, so govulncheck isn't any quicker than GitHub for these right now. I'll run it all again in November and see whether the wait's back under a month.

  6. Just found Google's open-source OSV-Scanner helps detect known vulnerabilities in dependencies, lockfiles, and container images. Pretty handy for Black October... google/osv-scanner

    1 like · 38 views
  7. Do your dependencies have known vulnerabilities? 🔐 OSV-Scanner checks project dependencies against public vulnerability data. Add a security check before shipping. 🛡️ google/osv-scanner #DevSecOps #浇朋友 #蓝朋友 #互关 #fo

    52 views
  8. 依赖更新了,里面有没有已知漏洞?🔐 OSV-Scanner 能扫描项目依赖和锁文件,找出公开记录的安全问题。上线前多一道检查。🛡️ google/osv-scanner #DevSecOps #浇朋友 #蓝朋友 #互关 #fo

    53 views
  9. Qiita · · @vaon-luandv

    GitHub ActionsでPRごとのセキュリティゲートを作る シークレット・依存関係・SASTとブランチ保護の最小構成 プルリクエスト(PR)ごとに、シークレットの混入、既知の脆弱性を持つ依存関係、危ない書き方を自動で調べ、通らないとマージできないようにする最小構成を、GitHub Actionsで作りました。人が書いたコードも、AIが書いたコードも、同じ入口を通します。 使うツールは一例です。gitleaks、osv-scanner、Semgrepを選びましたが、同じ役割のツールに置き換えても考え方は変わりません。ワークフロー全文、手元で動かした結果、ブランチ保護の設定、そして拾えないものを順に書きます。気になるところだけ拾ってください。 環境 動作確認は2026年10月17日、macOS(Apple Silicon)です。 | 役割 | ツール | バージョン | |---|---|---| | シークレットスキャン | gitleaks | 8.30.1 | | 依存関係スキャン | osv-scanner | 2.7.0 | | SAST | Semgrep | 1.181.0 | | ワークフロー検査 | actionlint | 1.7.12 | ワークフローのYAMLはactionlintで検査し、各コマンドは同じバージョンを手元で動かしました。GitHub上の実行環境(ubuntu-latest)でワークフロー全体を回した結果は、この記事には含まれていません。その点は「拾えないもの、確認していないこと」にも書きます。 この記事をざっくり図解 PR作成 / 更新 ├─ secret-scan gitleaks : このPRのコミットにキーが入っていないか ├─ dependency-scan osv-scanner: ロックファイルに既知の脆弱性がないか └─ sast Semgrep : 危ない書き方のパターンがないか │ ▼ ブランチ保護: 3つが緑 かつ レビュー承認 でないとmainにマージできない 1. ワークフロー全文 .github/workflows/pr-security-gate.yml です。 name: pr-security-gate on: pull_request: branches: [main] permissions: contents: read concurrency: group: pr-security-gate-${{ github.event.pull_request.number }} cancel-in-progress: true env: GITLEAKS_VERSION: "8.30.1" GITLEAKS_SHA256: "551f6fc83ea457d62a0d98237cbad105af8d557003051f41f3e7ca7b3f2470eb" OSV_SCANNER_VERSION: "2.7.0" OSV_SCANNER_SHA256: "160c6253e2922e9e0a6a9771c5c4c40a4b3c6090b34a3cdd5e80c96cc2e4218b" SEMGREP_VERSION: "1.181.0" jobs: secret-scan: runs-on: ubuntu-latest timeout-minutes: 10 # リポジトリ変数 GATE_REPORT_ONLY が true の間は、失敗してもPRを止めない continue-on-error: ${{ vars.GATE_REPORT_ONLY == 'true' }} steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: fetch-depth: 0 persist-credentials: false - name: Install gitleaks run: | curl -sSfL -o gitleaks.tar.gz \ "https://github.com/gitleaks/gitleaks/releases/download/v${GITLEAKS_VERSION}/gitleaks_${GITLEAKS_VERSION}_linux_x64.tar.gz" echo "${GITLEAKS_SHA256} gitleaks.tar.gz" | sha256sum -c - tar -xzf gitleaks.tar.gz gitleaks - name: Scan commits in this PR env: BASE_SHA: ${{ github.event.pull_request.base.sha }} HEAD_SHA: ${{ github.event.pull_request.head.sha }} run: ./gitleaks git --no-banner --redact --log-opts="${BASE_SHA}..${HEAD_SHA}" . dependency-scan: runs-on: ubuntu-latest timeout-minutes: 10 continue-on-error: ${{ vars.GATE_REPORT_ONLY == 'true' }} steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - name: Install osv-scanner run: | curl -sSfL -o osv-scanner \ "https://github.com/google/osv-scanner/releases/download/v${OSV_SCANNER_VERSION}/osv-scanner_linux_amd64" echo "${OSV_SCANNER_SHA256} osv-scanner" | sha256sum -c - chmod +x osv-scanner - name: Scan lockfiles run: ./osv-scanner scan source --recursive . sast: runs-on: ubuntu-latest timeout-minutes: 15 continue-on-error: ${{ vars.GATE_REPORT_ONLY == 'true' }} steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - name: Install semgrep run: | python3 -m venv "${RUNNER_TEMP}/venv" "${RUNNER_TEMP}/venv/bin/pip" install --quiet "semgrep==${SEMGREP_VERSION}" - name: Run semgrep run: | "${RUNNER_TEMP}/venv/bin/semgrep" scan \ --config p/default --error --metrics=off --disable-version-check . 2. 設計の理由 ワークフローを書くときに、迷った点とその理由を書いておきます。 gitleaksは公式のActionではなくバイナリを使っています。 gitleaks-actionのREADMEには、組織(Organization)のリポジトリではライセンスキー(無料で取得できる)が必要で、個人アカウントでは不要、と書かれています(2026年10月17日確認)。キーを secrets に登録する手間を避けて、CLIを直接動かしています。ここは好みと運用の問題で、Actionを使う選択もあります。 ダウンロードしたバイナリはSHA-256で検証しています。 gitleaksの値は公式の gitleaks_8.30.1_checksums.txt と、osv-scannerの値は osv-scanner_SHA256SUMS と照合しました。ダウンロード元が書き換えられていた場合に、実行前に止まります。反面、新しい版に上げるたびにハッシュも更新が必要です。 actions/checkout はタグではなくコミットSHAで固定しています。 タグは付け替えられる可能性があるためです(v7.0.1 は 3d3c42e5… を指すことを git ls-remote で確認しました)。コメントで版を残しておくと、更新時に分かりやすいです。 そのほかの小さな設定です。 - permissions: contents: read で、ジョブに渡るトークンの権限を最小にしています。 - persist-credentials: false で、チェックアウト後の認証情報がディスクに残らないようにしています。 - run: の中で ${{ ... }} を直接展開せず、env: 経由で渡しています。PRのタイトルやブランチ名のような、外から入る文字列をシェルに直接埋め込まないためです。ここで使っているのはSHAだけですが、同じ書き方に揃えています。 - トリガーは pull_request です。forkからのPRにはシークレットが渡りません。このワークフローはシークレットを使わないので、それで足ります。 - fetch-depth: 0 は、PRのコミット範囲(base..head)をgitleaksに渡すため、履歴が必要だからです。大きなリポジトリでは時間がかかります。 3つを別々のジョブに分けたのは、ブランチ保護で「必須のチェック」として個別に指定するためです。 ジョブ名(secret-scan、dependency-scan、sast)が、そのままチェック名になります。 3. 手元で動かした結果 ワークフローの各コマンドを、同じバージョンで手元の小さなリポジトリに対して実行しました。リポジトリには、GitHubトークンの形をした架空の文字列、requests==2.19.0 を書いた requirements.txt、SQLを文字列連結で組み立てる関数と shell=True の subprocess.run を含む app.py を入れてあります。 gitleaks gitleaks git --no-banner --redact -v --log-opts="HEAD~1..HEAD" . Finding: GITHUB_TOKEN = "REDACTED Secret: REDACTED RuleID: github-pat File: app.py Line: 6 Fingerprint: <commit>:app.py:github-pat:6 1 commits scanned. leaks found: 1 終了コードは1です。--log-opts に渡した範囲のコミットだけを調べているので、PRで追加した分だけが対象になります。 試すときの罠が一つありました。AWSの公式ドキュメントにある例のキー(末尾が EXAMPLE のもの)を入れても、no leaks found でした。サンプル値は検出から外されているようです。動作確認は、サンプルではなく、実際のトークンの形をした架空の値で行ってください。 osv-scanner osv-scanner scan source --recursive . Total 3 packages affected by 19 known vulnerabilities (0 Critical, 8 High, 11 Medium, 0 Low, 0 Unknown) from 1 ecosystem. 19 vulnerabilities can be fixed. requests==2.19.0 の1行から、直接・間接の依存を含めて19件が出ました(終了コード1)。ロックファイルがなければ、この種のスキャンは何も見つけません。Pythonなら requirements.txt だけでも読めましたが、バージョンが固定(==)されている前提です。 Semgrep semgrep scan --config p/default --error --metrics=off --disable-version-check . Findings: 2 (2 blocking) python.sqlalchemy.security.sqlalchemy-execute-raw-query.sqlalchemy-execute-raw-query 3┆ return conn.execute("SELECT * FROM users WHERE name = '" + name + "'").fetchall() python.lang.security.audit.subprocess-shell-true.subprocess-shell-true 5┆ return subprocess.run(cmd, shell=True) 終了コードは1です。ルール名はSQLAlchemy向けですが、sqlite3 風の conn.execute に文字列連結を渡す形でも検出されました。ちなみに --config p/python では、SQLの連結は検出されず、shell=True の1件だけでした。ルールセットの選び方で、拾える範囲が変わります。 4. ブランチ保護 ワークフローが緑でも、マージできる状態では意味がありません。保護の設定で、3つのジョブを必須にします。GitHubのREST APIでは、次のJSONを PUT /repos/{owner}/{repo}/branches/{branch}/protection に送ります。required_status_checks、enforce_admins、required_pull_request_reviews、restrictions の4つが必須で、使わないものは null を渡します(GitHub Docsより)。 { "required_status_checks": { "strict": true, "checks": [ { "context": "secret-scan" }, { "context": "dependency-scan" }, { "context": "sast" } ] }, "enforce_admins": true, "required_pull_request_reviews": { "required_approving_review_count": 1, "dismiss_stale_reviews": true, "require_code_owner_reviews": false }, "restrictions": null } gh api -X PUT repos/OWNER/REPO/branches/main/protection --input branch-protection.json - strict: true は、mainに追従していないブランチをマージ不可にします。チェックがmainの最新に対して通った状態でマージされます。 - enforce_admins: true は、管理者も同じルールに従わせます。緊急時に迂回したいなら、外す判断もありますが、そのときは記録を残す運用が要ります。 - dismiss_stale_reviews: true は、承認後に新しいコミットが積まれたら承認を取り消します。承認後に中身が変わっても通る、を防ぎます。 - checks の context は、ワークフローのジョブ名と一致させます。名前がずれると、存在しないチェックを待ち続けてマージできなくなるので、適用前に一度PRを作って、チェック名を目で確かめるのが安全です。 ブランチ保護が使えるプランや機能は、リポジトリの公開/非公開、プランで異なります。適用前に、GitHub Docsで自分のプランを確認してください。この記事では実際のリポジトリへの適用はしていません。 5. 最初は「報告のみ」で動かす 既存のコードに指摘が大量に出る状態で、いきなり必須にすると、チェックそのものが外されがちです。ワークフローに入れた continue-on-error: ${{ vars.GATE_REPORT_ONLY == 'true' }} が、そのための仕掛けです。 1. リポジトリの変数 GATE_REPORT_ONLY を true にする。指摘は出るがPRは止まらない 2. 数週間、指摘を見て、誤検知を .gitleaksignore やSemgrepの除外で整理する 3. GATE_REPORT_ONLY を消して、必須のチェックにする continue-on-error を true にしたジョブは、失敗しても「成功」として扱われる、というGitHub Actionsの仕様のため、PRの画面は緑に見えます。結果はジョブのログで確認する運用になります(この表示はGitHub上では確かめていません)。見落としを避けるには、いつまでに必須にするか、期限を先に決めておくのがよいです。 拾えないもの、確認していないこと - 業務ロジックの誤りや認可漏れは拾えません。 3つとも、既知のパターンや既知の脆弱性を見つけるものです。「他人のIDで取得できる」は、どのツールも通します。人のレビューが要る部分です。 - シークレットスキャンは、パターンに合うものだけを見つけます。 パターンに合わない独自形式の鍵や、すでに履歴に入った古いコミットは別の話です。ここでは、PRで追加されたコミットの範囲だけを見ています。キーが入ったときは、スキャンの前に、失効(ローテーション)が必要です。 - 依存関係のスキャンは、ロックファイルがある言語で効きます。 バージョンが固定されていなければ、結果は不安定です。 - SASTは、ルールにあるものしか拾いません。 上のとおり、設定ひとつで検出が変わりました。誤検知(と見逃し)は前提として運用します。 - GitHub上での実行は確認していません。 手元で各コマンドを動かし、YAMLを検査しただけです。ubuntu-latest の環境差や、continue-on-error の表示は、実際に回して確認してください。 - 更新の手間があります。 固定した版とハッシュは、放っておくと古くなります。GitHub Actionsのバージョン更新はDependabotで自動化できます。バイナリの版とハッシュは手動です。 - コードをどこに置くかで、使える機能が変わります。 この記事のツールは、GitHubの追加契約なしで動くものを選びました。GitHub純正の依存関係レビューやコードスキャンは、非公開リポジトリでは追加の契約が必要な場合があります。 最後に 全部を入れなくても、まずは secret-scan だけを「報告のみ」で入れてみてください。実際に自分のリポジトリの過去のコミットに対して動かすと、思ったより反応するものが多いと思います。そこから、必須にするタイミングを決められます。 参考文献 - gitleaks gitleaks/gitleaks - OSV-Scanner google.github.io - Semgrep CLI semgrep.dev - GitHub Docs「REST API endpoints for protected branches」 docs.github.com - GitHub Docs「Security hardening for GitHub Actions」 docs.github.com - rhysd/actionlint rhysd/actionlint

  10. It was the SPDX licence expression parser in Google/osv-scanner. Licence strings come from the metadata of whatever you scan, so the input is untrusted by definition. Merged, and released in v2.6.0. osv-scanner#3032

    2 likes · 8 views

Latest stargazers

The last 10 distinct accounts we observed this year.

Most active participants

PR, issue, comment & review events in the past year.

Packages

Scan pending.

README badges

Embed a badge in your README or website.

  • google/osv-scanner reached #2 in daily stars on gitwal · Dec 18, 2022
Live mentions · last 30 days
google/osv-scanner mentions in the last 30 days