{"id":4521,"date":"2025-06-17T19:59:02","date_gmt":"2025-06-17T10:59:02","guid":{"rendered":"https:\/\/blog.derrylab.com\/?p=4521"},"modified":"2025-06-17T19:59:02","modified_gmt":"2025-06-17T10:59:02","slug":"how-to-osv-vulnerabilities-api-scanners-and-a-bit-of-hope","status":"publish","type":"post","link":"https:\/\/blog.derrylab.com\/index.php\/2025\/06\/17\/how-to-osv-vulnerabilities-api-scanners-and-a-bit-of-hope\/","title":{"rendered":"How to OSV: Vulnerabilities API, Scanners, and a Bit of Hope"},"content":{"rendered":"\n<p>Security vulnerabilities in open-source dependencies are like background radiation, mostly ignorable, until they&#8217;re not. Since we are currently working on vulnerability detection research, today, I decided to see how much trouble I could get into by poking around Google&#8217;s <a href=\"https:\/\/osv.dev\/\">Open Source Vulnerabilities<\/a> database and its scanner.<\/p>\n\n\n\n<p>Spoiler: not much. But it&#8217;s interesting trouble.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">What is OSV?<\/h3>\n\n\n\n<p>OSV is Google\u2019s attempt to make sense of the mess that is vulnerability reporting. You give it a dependency, say, Flask 2.0.1, and it tells you if it\u2019s known to be a dumpster fire.<\/p>\n\n\n\n<p>The data is normalized across ecosystems (npm, PyPI, Go, etc), so it doesn\u2019t matter whether you write JavaScript, Python, Rust, or Go: your dependencies are all equally broken.<\/p>\n\n\n\n<p>There\u2019s a <a href=\"https:\/\/osv.dev\/docs\/#\/api\">REST API<\/a> for querying it. There\u2019s also a CLI tool. And yes, both are as unglamorous and utilitarian as you\u2019d expect.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">The API: A Surprisingly Honest Conversation<\/h3>\n\n\n\n<p>The first step: ask the OSV API if a package is vulnerable. No tokens, no rate limits (that I could find). Just JSON in, JSON out.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>curl -X POST https:\/\/api.osv.dev\/v1\/query -H 'Content-Type: application\/json' -d '{\n  \"package\": {\n    \"name\": \"flask\",\n    \"ecosystem\": \"PyPI\"\n  },\n  \"version\": \"2.0.1\"\n}'<\/code><\/pre>\n\n\n\n<p>The response looks like this:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"439\" src=\"https:\/\/i0.wp.com\/blog.derrylab.com\/wp-content\/uploads\/2025\/06\/image-1.png?resize=1024%2C439&#038;ssl=1\" alt=\"\" class=\"wp-image-4523\" srcset=\"https:\/\/i0.wp.com\/blog.derrylab.com\/wp-content\/uploads\/2025\/06\/image-1.png?resize=1024%2C439&amp;ssl=1 1024w, https:\/\/i0.wp.com\/blog.derrylab.com\/wp-content\/uploads\/2025\/06\/image-1.png?resize=300%2C129&amp;ssl=1 300w, https:\/\/i0.wp.com\/blog.derrylab.com\/wp-content\/uploads\/2025\/06\/image-1.png?resize=768%2C329&amp;ssl=1 768w, https:\/\/i0.wp.com\/blog.derrylab.com\/wp-content\/uploads\/2025\/06\/image-1.png?resize=1536%2C659&amp;ssl=1 1536w, https:\/\/i0.wp.com\/blog.derrylab.com\/wp-content\/uploads\/2025\/06\/image-1.png?w=1919&amp;ssl=1 1919w\" sizes=\"auto, (max-width: 1000px) 100vw, 1000px\" \/><\/figure>\n\n\n\n<p>It doesn\u2019t try to be clever. It tells you exactly what\u2019s wrong, and then stops talking.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">The Scanner: Letting a Tool Judge Your Code<\/h3>\n\n\n\n<p>Next: the <code>osv-scanner<\/code>. This is a Go CLI tool that scans your project via lockfiles, SBOMs, or raw directories, and tells you how many of your dependencies are already known to be bad ideas.<\/p>\n\n\n\n<p>Install it like this:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>go install github.com\/google\/osv-scanner\/v2\/cmd\/osv-scanner@latest<\/code><\/pre>\n\n\n\n<p>And run it on something depressing:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>osv-scanner scan source -r \/path\/to\/your\/dir<\/code><\/pre>\n\n\n\n<p>You\u2019ll get a list of vulnerabilities that will, depending on your maturity as a developer, either be a wake-up call or just another Tuesday.<\/p>\n\n\n\n<p>You can also scan for container:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>osv-scanner scan image my-image-name:tag<\/code><\/pre>\n\n\n\n<p>Now you know everything that\u2019s broken all this time.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Remediation: Letting the Tool Tell You How to Fix It<\/h3>\n\n\n\n<p>You\u2019ve scanned your project. The scanner has stared into its soul and spat out a list of vulnerabilities. Now it\u2019s time to fix them, so what happens next?<\/p>\n\n\n\n<p>Good thing is that they not only gives you bad news but they provide the cure.<\/p>\n\n\n\n<p>OSV\u2011Scanner includes a feature called <strong>guided remediation<\/strong>, a bit like a patient colleague handing you the needle and thread:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>It examines your <code>package.json<\/code>\/<code>package-lock.json<\/code> (or Maven <code>pom.xml<\/code>).<\/li>\n\n\n\n<li>It analyzes the <strong>transitive dependency graph<\/strong>, so you don\u2019t blindly upgrade nested packages and break the world. It prioritizes upgrades that will knock out <strong>the most vulnerabilities with the least change<\/strong>. You can filter by <strong>severity<\/strong>, <strong>dependency depth<\/strong>, or whether it\u2019s prod vs dev and even choose between.<\/li>\n<\/ul>\n\n\n\n<p>This isn\u2019t magic. It\u2019s math: figure out which upgrade gives the biggest \u201cbang for your byte\u201d and offer it in a CLI or (in interactive mode) a simple UI .<\/p>\n\n\n\n<p>To try it for <code>npm<\/code>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>osv-scanner fix --non-interactive \\\n    --strategy=in-place \\\n    -L path\/to\/package-lock.json<\/code><\/pre>\n\n\n\n<p>Or go <strong>interactive <\/strong>for more control:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>osv-scanner fix \\\n   -M path\/to\/package.json \\\n   -L path\/to\/package-lock.json<\/code><\/pre>\n\n\n\n<p>For Maven:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>osv-scanner fix --non-interactive \\\n   --strategy=override \\\n   -M path\/to\/pom.xml<\/code><\/pre>\n\n\n\n<p>You\u2019ll get a list of proposed changes, each designed to resolve the most vulnerabilities without wreaking havoc.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">What Limits to Expect<\/h4>\n\n\n\n<p>Currently, npm and Maven are the only ecosystems with guided fixes, though support is expanding. Some features are labeled <strong>experimental<\/strong> like in-place Maven changes or interactive screens, so expect some updates.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Last words<\/h3>\n\n\n\n<p>The OSV ecosystem is clean, practical, and deeply pessimistic about the state of software security exactly as it should be. It fix your code for you, but for now, only npm and Maven.<\/p>\n\n\n\n<p>But, since we are currently working on code vulnerability detection framework, this would be useful for us. \ud83d\ude42<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Security vulnerabilities in open-source dependencies are like background radiation, mostly ignorable, until they&#8217;re not. Since we are currently working on vulnerability detection research, today, I decided to see how much trouble I could get into by poking around Google&#8217;s Open Source Vulnerabilities database and its scanner. Spoiler: not much. But it&#8217;s interesting trouble. What is [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":4524,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[1],"tags":[287,273,284,277,281,36,280,279,286,270,271,272,276,282,278,288,269,285,283,275,64,66,274],"class_list":["post-4521","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized","tag-code-security-tools","tag-dependency-scanning","tag-go-dependencies","tag-google-osv","tag-guided-remediation","tag-linux","tag-maven-security","tag-npm-security","tag-open-source-risk","tag-open-source-security","tag-osv","tag-osv-scanner","tag-package-vulnerabilities","tag-pypi-vulnerabilities","tag-sbom-scanning","tag-security-automation","tag-software-remediation","tag-software-supply-chain","tag-static-analysis","tag-supply-chain-security","tag-tutorial","tag-ubuntu","tag-vulnerability-detection"],"jetpack_featured_media_url":"https:\/\/i0.wp.com\/blog.derrylab.com\/wp-content\/uploads\/2025\/06\/pexels-photo-96612.jpeg?fit=1880%2C1253&ssl=1","jetpack-related-posts":[{"id":2555,"url":"https:\/\/blog.derrylab.com\/index.php\/2023\/01\/31\/how-to-find-and-connect-to-hidden-wifi-network\/","url_meta":{"origin":4521,"position":0},"title":"How to Find and Connect to Hidden Wifi Network","author":"derry","date":"January 31, 2023","format":false,"excerpt":"Suppose you have a device that communicates using wifi, and you already know the password, but you can't find the SSID name on your phone or computer. How can you connect? In this post, I will show you how to find and connect to the hidden network using Kali Linux.\u2026","rel":"","context":"In &quot;Hardware&quot;","block_context":{"text":"Hardware","link":"https:\/\/blog.derrylab.com\/index.php\/category\/hardware\/"},"img":{"alt_text":"photo of a wi fi tower under a blue sky","src":"https:\/\/i0.wp.com\/blog.derrylab.com\/wp-content\/uploads\/2023\/01\/pexels-photo-7862565.jpeg?fit=1200%2C800&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/blog.derrylab.com\/wp-content\/uploads\/2023\/01\/pexels-photo-7862565.jpeg?fit=1200%2C800&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/blog.derrylab.com\/wp-content\/uploads\/2023\/01\/pexels-photo-7862565.jpeg?fit=1200%2C800&ssl=1&resize=525%2C300 1.5x, https:\/\/i0.wp.com\/blog.derrylab.com\/wp-content\/uploads\/2023\/01\/pexels-photo-7862565.jpeg?fit=1200%2C800&ssl=1&resize=700%2C400 2x, https:\/\/i0.wp.com\/blog.derrylab.com\/wp-content\/uploads\/2023\/01\/pexels-photo-7862565.jpeg?fit=1200%2C800&ssl=1&resize=1050%2C600 3x"},"classes":[]},{"id":3171,"url":"https:\/\/blog.derrylab.com\/index.php\/2023\/12\/18\/how-to-enable-browsing-when-you-have-ssh-access\/","url_meta":{"origin":4521,"position":1},"title":"How to Enable Browsing when You Have SSH Access","author":"derry","date":"December 18, 2023","format":false,"excerpt":"Introduction If you have access to SSH into a machine, it means you have full control of that machine. However if not all of the things can be done via terminal SSH, sometimes you need to browse some sites using that machine connection. The simplest solution for this is to\u2026","rel":"","context":"In &quot;linux&quot;","block_context":{"text":"linux","link":"https:\/\/blog.derrylab.com\/index.php\/category\/linux\/"},"img":{"alt_text":"view of tunnel","src":"https:\/\/i0.wp.com\/blog.derrylab.com\/wp-content\/uploads\/2023\/12\/pexels-photo-249097.jpeg?fit=1200%2C800&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/blog.derrylab.com\/wp-content\/uploads\/2023\/12\/pexels-photo-249097.jpeg?fit=1200%2C800&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/blog.derrylab.com\/wp-content\/uploads\/2023\/12\/pexels-photo-249097.jpeg?fit=1200%2C800&ssl=1&resize=525%2C300 1.5x, https:\/\/i0.wp.com\/blog.derrylab.com\/wp-content\/uploads\/2023\/12\/pexels-photo-249097.jpeg?fit=1200%2C800&ssl=1&resize=700%2C400 2x, https:\/\/i0.wp.com\/blog.derrylab.com\/wp-content\/uploads\/2023\/12\/pexels-photo-249097.jpeg?fit=1200%2C800&ssl=1&resize=1050%2C600 3x"},"classes":[]},{"id":244,"url":"https:\/\/blog.derrylab.com\/index.php\/2021\/03\/12\/the-riscv-isa-documentation-is-better-than-riscv-green-card\/","url_meta":{"origin":4521,"position":2},"title":"The RISCV ISA Documentation Is Better than RISCV Green Card","author":"derry","date":"March 12, 2021","format":false,"excerpt":"I hosted the RISCV ISA Documentation. This is really helpful if you want to learn about the assembly syntax or learning the RISCV itself. As a beginner, this documentation is more effective instead of constantly checking at the green card. :) RISCV ISA Documentation:https:\/\/blog.derrylab.com\/riscv-isa-documentation You can host it yourself, it\u2026","rel":"","context":"In &quot;linux&quot;","block_context":{"text":"linux","link":"https:\/\/blog.derrylab.com\/index.php\/category\/linux\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":120,"url":"https:\/\/blog.derrylab.com\/index.php\/2020\/11\/04\/install-xilinx-in-batch-mode\/","url_meta":{"origin":4521,"position":3},"title":"How to Install Xilinx using Command Line in Four Steps","author":"derry","date":"November 4, 2020","format":false,"excerpt":"I just got some problem with Xilinx 2020.1 installation on my Pop OS. The installer was stuck and gives me an error message: ibndias@shaheen:~\/Downloads$ .\/Xilinx_Unified_2020.1_0602_1208_Lin64.bin Verifying archive integrity... All good. Uncompressing Xilinx Installer............................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................... Exception in thread \"SPLASH_LOAD_MESSAGE\" java.lang.IllegalStateException: no splash screen available at java.desktop\/java.awt.SplashScreen.checkVisible(Unknown Source) at java.desktop\/java.awt.SplashScreen.getBounds(Unknown Source) at java.desktop\/java.awt.SplashScreen.getSize(Unknown\u2026","rel":"","context":"In &quot;linux&quot;","block_context":{"text":"linux","link":"https:\/\/blog.derrylab.com\/index.php\/category\/linux\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":71,"url":"https:\/\/blog.derrylab.com\/index.php\/2020\/04\/05\/high-quality-al-quran-pdf\/","url_meta":{"origin":4521,"position":4},"title":"High Quality Al-Quran PDF","author":"derry","date":"April 5, 2020","format":false,"excerpt":"Recently I found an interesting site which is open-source, it was globalquran.com. The site is perfect, they home page is complete, and also the have download pages for high quality PDF. I have been searching around google for high quality pdf for Al-Qur'an, I even opened the second page of\u2026","rel":"","context":"In &quot;Islam &amp; Sunnah&quot;","block_context":{"text":"Islam &amp; Sunnah","link":"https:\/\/blog.derrylab.com\/index.php\/category\/islam-sunnah\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":2242,"url":"https:\/\/blog.derrylab.com\/index.php\/2022\/10\/18\/how-to-do-buffer-overflow-attack-on-64bit-machine\/","url_meta":{"origin":4521,"position":5},"title":"How to Do Buffer Overflow Attack on 64bit Machine","author":"derry","date":"October 18, 2022","format":false,"excerpt":"Professor's course material was out of date. He made an example of a buffer overflow attack several years ago. Then here I am, asked to fix the code to work on a modern machine, 64bit Kali Linux. There should be no difference with other Linux; you can practice this on\u2026","rel":"","context":"In &quot;linux&quot;","block_context":{"text":"linux","link":"https:\/\/blog.derrylab.com\/index.php\/category\/linux\/"},"img":{"alt_text":"giant tsunami wave","src":"https:\/\/i0.wp.com\/blog.derrylab.com\/wp-content\/uploads\/2022\/10\/pexels-photo-9156792.jpeg?fit=1200%2C737&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/blog.derrylab.com\/wp-content\/uploads\/2022\/10\/pexels-photo-9156792.jpeg?fit=1200%2C737&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/blog.derrylab.com\/wp-content\/uploads\/2022\/10\/pexels-photo-9156792.jpeg?fit=1200%2C737&ssl=1&resize=525%2C300 1.5x, https:\/\/i0.wp.com\/blog.derrylab.com\/wp-content\/uploads\/2022\/10\/pexels-photo-9156792.jpeg?fit=1200%2C737&ssl=1&resize=700%2C400 2x, https:\/\/i0.wp.com\/blog.derrylab.com\/wp-content\/uploads\/2022\/10\/pexels-photo-9156792.jpeg?fit=1200%2C737&ssl=1&resize=1050%2C600 3x"},"classes":[]}],"jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/blog.derrylab.com\/index.php\/wp-json\/wp\/v2\/posts\/4521","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.derrylab.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.derrylab.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.derrylab.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.derrylab.com\/index.php\/wp-json\/wp\/v2\/comments?post=4521"}],"version-history":[{"count":1,"href":"https:\/\/blog.derrylab.com\/index.php\/wp-json\/wp\/v2\/posts\/4521\/revisions"}],"predecessor-version":[{"id":4525,"href":"https:\/\/blog.derrylab.com\/index.php\/wp-json\/wp\/v2\/posts\/4521\/revisions\/4525"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blog.derrylab.com\/index.php\/wp-json\/wp\/v2\/media\/4524"}],"wp:attachment":[{"href":"https:\/\/blog.derrylab.com\/index.php\/wp-json\/wp\/v2\/media?parent=4521"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.derrylab.com\/index.php\/wp-json\/wp\/v2\/categories?post=4521"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.derrylab.com\/index.php\/wp-json\/wp\/v2\/tags?post=4521"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}