Skip to content
OpenAdvisories

Guide

How to use it

Practical recipes: check a server, scan a project, block vulnerable dependencies in CI and follow what matters to you.

1. Scan a Linux server

Distributions backport security fixes, so what matters is the exact installed package version compared with your distribution's own advisories — not the upstream version number. The server scan does this for every installed package at once.

Whole server, from the terminal

Run this on the server. It prints /etc/os-release (so the release is detected) and every installed package with its exact version, then sends the list to the API and prints a report. No root needed; the list is processed in memory and not stored.

{ cat /etc/os-release; if command -v dpkg-query >/dev/null; then dpkg-query -W -f='${db:Status-Abbrev}${source:Package} ${source:Version}\n'; elif command -v rpm >/dev/null; then rpm -qa --qf '%{NAME} %{EPOCHNUM}:%{VERSION}-%{RELEASE}\n'; elif command -v apk >/dev/null; then apk list -I; fi; } | curl -s --data-binary @- "https://www.openadvisories.org/api/scan/server?format=text"
Debian 12 — 612 packages checked, 9 with known vulnerabilities (41 CVEs: 2 critical, 11 high, 1 exploited)

PACKAGE   INSTALLED            UPGRADE TO            CVES  WORST     EXPLOITED
openssl   3.0.11-1~deb12u2     3.0.17-1~deb12u2      12    high
glibc     2.36-9+deb12u4       2.36-9+deb12u10       6     high      1
…

No direct internet access on the server? Save the list instead (replace the pipe with > packages.txt), copy the file to your machine and upload it on the scan page. Distribution-specific commands and a variant for container images are listed there.

Automate it

A weekly cron job that mails the report only when something needs updating:

#!/bin/sh
# /etc/cron.weekly/vulnscan  (chmod +x)
report=$({ cat /etc/os-release; if command -v dpkg-query >/dev/null; then dpkg-query -W -f='${db:Status-Abbrev}${source:Package} ${source:Version}\n'; elif command -v rpm >/dev/null; then rpm -qa --qf '%{NAME} %{EPOCHNUM}:%{VERSION}-%{RELEASE}\n'; elif command -v apk >/dev/null; then apk list -I; fi; } | curl -sf --data-binary @- "https://www.openadvisories.org/api/scan/server?format=text") || exit 0
echo "$report" | grep -q " 0 with known vulnerabilities" || echo "$report" | mail -s "Security updates on $(hostname)" root

For fleets, use the JSON output (drop format=text) and alert on .summary.exploited > 0 or .vulnerable — see the API reference.

One package

To check a single package, you need the distribution release, the package name and its full version:

Find the release

. /etc/os-release && echo "$ID $VERSION_ID"
# debian 12 · ubuntu 22.04 · rhel 9.4 · sles 15.6 · alpine 3.19.1

Pick the matching release on the version check page: RHEL 9.4 is "RHEL 9" (unless you are on an EUS stream), SLES 15.6 is "SLES 15 SP6", Alpine 3.19.1 is "v3.19".

Debian / Ubuntu

Debian and Ubuntu advisories are written per source package (for example openssl, which builds libssl3). Ask dpkg for the source name and version of any installed binary package:

dpkg-query -W -f='${source:Package} ${source:Version}\n' libssl3
# openssl 3.0.11-1~deb12u2

curl -s https://www.openadvisories.org/api/check/debian/12/openssl/3.0.11-1~deb12u2 | jq '.vulnerable, [.vulnerabilities[].id]'

Red Hat, Rocky, AlmaLinux, SUSE

rpm -q --qf '%{NAME} %{EPOCHNUM}:%{VERSION}-%{RELEASE}\n' openssl
# openssl 1:3.0.7-24.el9

curl -s https://www.openadvisories.org/api/check/red-hat/rhel-9/openssl/1:3.0.7-24.el9 | jq '.vulnerabilities | length'

An epoch of 0: may be left out. Rocky Linux and AlmaLinux have their own advisories — use rocky-linux/9 or almalinux/9 rather than Red Hat for them.

Alpine

apk version -v curl     # or: apk info -v curl → curl-8.5.0-r0
curl -s https://www.openadvisories.org/api/check/alpine/v3-19/curl/8.5.0-r0 | jq .vulnerable

The result lists the advisories that ship a fix and the version to upgrade to. If it says "fixed in" a version you already have, you are patched.

2. Scan a project's dependencies

Upload the lockfile on the scan page — not the manifest. Lockfiles pin the exact versions that are installed; manifests only contain ranges.

StackUpload thisTip
Node.jspackage-lock.json, yarn.lock, pnpm-lock.yamlnpm-shrinkwrap.json works too
PHPcomposer.lockcommit it, even for applications
Pythonpoetry.lock, uv.lock, Pipfile.lockplain pip: pip freeze > requirements.txt
RubyGemfile.lockplatform suffixes are handled
Gogo.sum (or go.mod)go.sum covers indirect modules
RustCargo.lock
.NETpackages.lock.jsonenable RestorePackagesWithLockFile
Java / Kotlingradle.lockfilegradle dependencies --write-locks

The scan also flags malicious packages. If one appears, do not just upgrade: remove it, treat the machine as compromised and rotate its secrets.

3. Fail the build in CI

One request per build: post the lockfile to /api/scan and fail when vulnerable is true. The examples below fail only on malicious, exploited, critical or high findings and print a short report — adjust the jq filter to your policy.

Shell (any CI)

#!/bin/sh
# usage: ./vulncheck.sh package-lock.json
set -eu
f="${1:-package-lock.json}"
res=$(curl -sf --data-binary @"$f" "https://www.openadvisories.org/api/scan?filename=$(basename "$f")")
echo "$res" | jq -r '.packages[] | "\(.name) \(.version) → \(.recommended_version // "no fix") : \([.vulnerabilities[].id] | join(", "))"'
echo "$res" | jq -e '[.packages[] | select((.malicious | length) > 0 or any(.vulnerabilities[]; .exploited or .severity == "critical" or .severity == "high"))] | length == 0' > /dev/null

GitHub Actions

# .github/workflows/vulncheck.yml
name: Dependency check
on: [push, pull_request]
jobs:
  vulncheck:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Scan lockfile
        run: |
          res=$(curl -sf --data-binary @package-lock.json "https://www.openadvisories.org/api/scan?filename=package-lock.json")
          echo "$res" | jq '.summary'
          echo "$res" | jq -e '.vulnerable | not' > /dev/null

GitLab CI

# .gitlab-ci.yml
vulncheck:
  image: alpine:3.20
  before_script: [apk add --no-cache curl jq]
  script:
    - res=$(curl -sf --data-binary @composer.lock "https://www.openadvisories.org/api/scan?filename=composer.lock")
    - echo "$res" | jq .summary
    - echo "$res" | jq -e '.vulnerable | not' > /dev/null

Git pre-commit hook

# .git/hooks/pre-commit  (chmod +x)
git diff --cached --name-only | grep -qE '(package-lock\.json|composer\.lock|poetry\.lock)$' || exit 0
for f in $(git diff --cached --name-only | grep -E '(package-lock\.json|composer\.lock|poetry\.lock)$'); do
  curl -sf --data-binary @"$f" "https://www.openadvisories.org/api/scan?filename=$(basename "$f")" | jq -e '.summary.malicious_packages == 0' > /dev/null \
    || { echo "Malicious package in $f — commit blocked"; exit 1; }
done

The API allows about 60 requests per minute per IP — plenty for one scan per job. Avoid looping over packages with /api/check in CI.

4. Follow vendors, products and packages

Open the page of whatever you run — a vendor or product, a platform, a package — and narrow it with the severity and "exploited" filters. The URL of that filtered list plus /feed.xml is a feed of exactly those entries:

https://www.openadvisories.org/vendor/microsoft/critical/feed.xml
https://www.openadvisories.org/platform/linux/exploited/feed.xml
https://www.openadvisories.org/ecosystem/npm/lodash/feed.xml

Add the feeds to a feed reader, or to a chat tool that can follow RSS/Atom (Slack, Microsoft Teams, Mattermost and Discord all have feed integrations) to get a message for every new entry. All feeds are listed in the API reference.

5. What to fix first

Not every critical CVE is urgent and not every medium one can wait. A practical order:

  1. Malicious packages — remove immediately, investigate the machine.
  2. Exploited vulnerabilities (CISA KEV, ENISA) on systems reachable from the internet — attackers are already using them.
  3. High EPSS (for example above 10%) — likely to be exploited soon, whatever the CVSS score.
  4. Critical and high CVSS on exposed systems, then on internal ones.
  5. Everything else in your normal patch cycle.

The exploited list is a good weekly check even if you follow nothing else. More on how scores are chosen: methodology.