{"id":16208434,"url":"https://github.com/g-rath/osv-detector","last_synced_at":"2025-04-06T08:15:16.427Z","repository":{"id":37021383,"uuid":"465015144","full_name":"G-Rath/osv-detector","owner":"G-Rath","description":null,"archived":false,"fork":false,"pushed_at":"2025-03-27T12:44:32.000Z","size":2201,"stargazers_count":62,"open_issues_count":11,"forks_count":9,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-03-30T07:10:02.737Z","etag":null,"topics":["dependencies","dependency-audit","osv","security","security-audit","security-tools","vulnerability-detection","vulnerability-scanners"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/G-Rath.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-03-01T18:42:29.000Z","updated_at":"2025-03-12T19:09:51.000Z","dependencies_parsed_at":"2023-10-14T18:10:16.662Z","dependency_job_id":"13f8fc5e-c907-4741-b4aa-b8faedc99b35","html_url":"https://github.com/G-Rath/osv-detector","commit_stats":{"total_commits":259,"total_committers":5,"mean_commits":51.8,"dds":"0.10424710424710426","last_synced_commit":"fe20f58ff17842e0e8301153d5d6c574d3462e6c"},"previous_names":[],"tags_count":27,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/G-Rath%2Fosv-detector","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/G-Rath%2Fosv-detector/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/G-Rath%2Fosv-detector/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/G-Rath%2Fosv-detector/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/G-Rath","download_url":"https://codeload.github.com/G-Rath/osv-detector/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247451667,"owners_count":20940944,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["dependencies","dependency-audit","osv","security","security-audit","security-tools","vulnerability-detection","vulnerability-scanners"],"created_at":"2024-10-10T10:16:56.854Z","updated_at":"2025-04-06T08:15:16.401Z","avatar_url":"https://github.com/G-Rath.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Open Source Vulnerability Detector\n\n[![OpenSSF Scorecard](https://api.scorecard.dev/projects/github.com/G-Rath/osv-detector/badge)](https://scorecard.dev/viewer/?uri=github.com/G-Rath/osv-detector)\n\nAn auditing tool for detecting vulnerabilities, powered by advisory databases\nthat follow the [OSV specification](https://ossf.github.io/osv-schema/).\n\nCurrently, this uses the ecosystem databases provided by\n[osv.dev](https://osv.dev/).\n\n## Installation\n\nTo install locally:\n\n1. Download [a release](https://github.com/G-Rath/osv-detector/releases)\n2. Rename it to `osv-detector`\n3. Make it executable\n4. Put it somewhere that's on your PATH (optional)\n   - `/usr/local/bin` is usually a good place on Ubuntu\n\nYou can use this script to install the latest version from GitHub (make sure to\nchange the binary architecture if you're on macOS or Windows):\n\n```shell\nOSV_DETECTOR_VERSION=$(curl -s \"https://api.github.com/repos/G-Rath/osv-detector/releases/latest\" | perl -nle'print substr($\u0026, 1) while m#\"tag_name\": \"\\K[^\"]*#g')\nOSV_DETECTOR_BINARY=\"osv-detector_${OSV_DETECTOR_VERSION}_linux_amd64\"\n\ncurl -fL \"https://github.com/G-Rath/osv-detector/releases/download/v$OSV_DETECTOR_VERSION/$OSV_DETECTOR_BINARY\" --output /tmp/osv-detector\nchmod +x /tmp/osv-detector\nsudo mv /tmp/osv-detector /usr/local/bin/osv-detector\n```\n\nIf you're using GitHub Actions, you can use the\n[check-with-osv-detector](https://github.com/marketplace/actions/check-with-osv-detector)\naction.\n\n## Usage\n\nThe detector accepts a path to a \"lockfile\" which contains information about the\nversions of packages:\n\n```shell\nosv-detector path/to/my/package-lock.json\nosv-detector path/to/my/composer.lock\n\n# you can also pass multiple files\nosv-detector path/to/my/package-lock.json path/to/my/composer.lock\n\n# or a directory which is expected to contain at least one supported lockfile\nosv-detector path/to/my/\n```\n\nThe detector supports parsing the following lockfiles:\n\n| Lockfile                      | Ecosystem   | Tool       |\n| ----------------------------- | ----------- | ---------- |\n| `buildscript-gradle.lockfile` | `Maven`     | `gradle`   |\n| `Cargo.lock`                  | `crates.io` | `cargo`    |\n| `packages.lock.json`          | `NuGet`     | `dotnet`   |\n| `package-lock.json`           | `npm`       | `npm`      |\n| `yarn.lock`                   | `npm`       | `yarn`     |\n| `bun.lock`                    | `npm`       | `bun`      |\n| `pnpm-lock.yaml`              | `npm`       | `pnpm`     |\n| `composer.lock`               | `Packagist` | `composer` |\n| `Gemfile.lock`                | `RubyGems`  | `bundler`  |\n| `go.mod`                      | `Go`        | `go mod`   |\n| `gradle.lockfile`             | `Maven`     | `gradle`   |\n| `gradle.lockfile`             | `CRAN`      | `renv`     |\n| `mix.lock`                    | `Hex`       | `mix`      |\n| `poetry.lock`                 | `PyPI`      | `poetry`   |\n| `uv.lock`                     | `PyPI`      | `uv`       |\n| `Pipfile.lock`                | `PyPI`      | `pipenv`   |\n| `pdm.lock`                    | `PyPI`      | `pdm`      |\n| `pubspec.lock`                | `Pub`       | `pub`      |\n| `pom.xml`\\*                   | `Maven`     | `maven`    |\n| `requirements.txt`\\*          | `PyPI`      | `pip`      |\n\n\\*: `pom.xml` and `requirements.txt` are technically not lockfiles, as they\ndon't have to specify the complete dependency tree and can have version\nconstraints/ranges. When parsing these files, the detector will assume the\n_lowest_ version possible for non-exact dependencies, and will ignore anything\nthat is not a dependency specification (e.g. flags or files in the case of\n`requirements.txt`, though `\u003cproperties\u003e` _is_ supported for `pom.xml`)\n\nThe detector will attempt to automatically determine the parser to use for each\nfile based on the filename - you can also explicitly specify the parser to use\nby prefixing it to the start of the given path, seperated with an `:` symbol:\n\n```shell\nosv-detector requirements.txt:path/to/my/requirements/ requirements.txt:path/to/my/file.txt\n```\n\nIf you have a path with a colon in its name, you can with just a colon to\nexplicitly signal to the detector that it should infer the parser based on the\nfilename:\n\n```shell\nosv-detector ':/path/to/my:projects/package-lock.json'\n```\n\nYou can also set the default parser to use for all files with the `--parse-as`\nflag:\n\n```shell\nosv-detector --parse-as 'package-lock.json' path/to/my/file.lock\n```\n\nBy default, the detector attempts to detect known vulnerabilities by checking\nthe versions of packages specified by the OVSs in the loaded OSV databases,\ncomparing based on the version ordering rules for the specific ecosystem being\nchecked as closely as possible (see\n[this section](#version-parsing-and-comparing) for more details about version\nhandling).\n\nThis allows the detector to be very fast and work offline, but does not support\ncommits which means the detector can report false positives when using git-based\ndependencies.\n\nYou can disable dynamically loading the ecosystem databases by passing\n`--use-dbs=false`.\n\nYou can also have the detector use the `osv.dev` API to check for known\nvulnerabilities by supplying the `--use-api` flag. The API is very fast,\ntypically a few hours ahead of the offline databases, and supports commits;\nhowever it currently can produce false negatives for some ecosystems.\n\n\u003e While the API supports commits, the detector currently has limited support for\n\u003e extracting them - only the `composer.lock`, `Gemfile.lock`,\n\u003e `package-lock.json`, `yarn.lock`, \u0026 `pnpm.yaml` parsers include commit details\n\u003e\n\u003e See [this section](#passing-arbitrary-package-details-advanced-usage) for how\n\u003e you can provide the detector with arbitrary commits to check\n\nYou cannot use the API in `--offline` mode, but you can use both the offline\ndatabases and the API together; the detector will remove any duplicate results.\n\nOnce all the lockfiles have been pared, the detector will then determine all the\ndatabases to load - if `--use-dbs` is `true` (which it is by default) then this\nwill include ecosystem specific databases based on the parsed packages.\n\nSee [this section](#extra-databases) for details on how to configure extra\ndatabases for the detector to use.\n\n\u003e Remotely sourced databases will be cached along with their etag and\n\u003e last-modified date for future checks, to determine if those databases need to\n\u003e be updated.\n\nBy default, the detector will output the results to `stdout` as plain text, and\nexit with an error code of `1` if at least one vulnerability is found. See\n[here](#ignoring-certain-vulnerabilities) for how to configure the detector to\nignore certain vulnerabilities.\n\nYou can use the `--json` flag to have the detector output its results as JSON:\n\n```shell\nosv-detector --json path/to/my/package-lock.json\n```\n\nThis will result in a JSON object being printed to `stdout` with a `results`\nproperty that has an array containing the results of each lockfile that was\npassed:\n\n```json\n{\n  \"results\": [\n    {\n      \"filePath\": \"path/to/my/go.mod\",\n      \"parsedAs\": \"go.mod\",\n      \"packages\": [\n        {\n          \"name\": \"github.com/BurntSushi/toml\",\n          \"version\": \"1.0.0\",\n          \"ecosystem\": \"Go\",\n          \"vulnerabilities\": [],\n          \"ignored\": []\n        }\n      ]\n    },\n    {\n      \"filePath\": \"path/to/my/package-lock.json\",\n      \"parsedAs\": \"package-lock.json\",\n      \"packages\": [\n        {\n          \"name\": \"wrappy\",\n          \"version\": \"1.0.2\",\n          \"ecosystem\": \"npm\",\n          \"vulnerabilities\": [],\n          \"ignored\": []\n        }\n      ]\n    }\n  ]\n}\n```\n\nErrors are always sent to `stderr` as plain text, even if the `--json` flag is\npassed.\n\n### Config files\n\nThe detector supports loading configuration details from a YAML file, which\nmakes it easy to provide advanced settings (such as extra databases), provide a\nconsistent results whenever the detector is run on a project, and provide an\naudit trail of ignored vulnerabilities (through version control).\n\nBy default, the detector will look for a `.osv-detector.yaml` or\n`.osv-detector.yml` in the same folder as the current lockfile it's checking,\nand will _merge_ the config with any flags being passed.\n\nYou can also provide a path to a specific config file that will be used for all\nlockfiles being checked with the `--config` flag:\n\n```shell\nosv-detector --config ruby-ignores.yml path/to/my/first-ruby-project path/to/my/second-ruby-project\n```\n\nYou can have the detector ignore specific parts of the config with the\n`--no-config-ignores` and `--no-config-databases` flags, or ignore any configs\nall together with the `--no-config` flag.\n\n#### Ignoring certain vulnerabilities\n\n\u003e Ignored vulnerabilities won't be included in the text output, and won't be\n\u003e counted when determined the code to exit with.\n\nYou can provide the detector with a list of IDs for OSVs to ignore when checking\nlockfiles with the `ignore` property:\n\n```yaml\nignore:\n  - GHSA-4 # \"Prototype pollution in xyz\"\n  - GHSA-5 # \"RegExp DDoS in abc\"\n  - GHSA-6 # \"Command injection in hjk\"\n```\n\nYou can also use the `--ignore` flag:\n\n```\nosv-detector --ignore GHSA-896r-f27r-55mw package-lock.json\n\n# you can pass multiple ignores\nosv-detector --ignore GHSA-896r-f27r-55mw --ignore GHSA-74fj-2j2h-c42q package-lock.json\n```\n\nIgnores provided via the flag will be combined with any ignores specified in the\nloaded config file.\n\nYou can use `--update-config-ignores` to have the detector update configs being\nused for lockfiles to ignore any vulnerabilities that were found; it will also\nremove ignores for vulnerabilities that are no longer present.\n\nAlternatively, you can use `jq` to generate a list of OSV ids if you want to\nignore all current known vulnerabilities found by the detector:\n\n```shell\nosv-detector --json . | jq -r  '[.results[].packages | map(\"- \" + .vulnerabilities[].id)] | flatten | unique | sort | .[]'\n```\n\n#### Extra Databases\n\nYou can configure the detector to use extra databases with the `extra-databases`\nproperty:\n\n```yaml\nextra-databases:\n  - url: https://github.com/github/advisory-database/archive/refs/heads/main.zip\n    name: GitHub Advisory Database\n    working-directory: 'advisory-database-main/advisories/github-reviewed' # only load the reviewed advisories\n```\n\nEach extra database must have a `url` property which specifies the source of the\ndatabase (for local databases this must begin with `file:`), but all other\nproperties are optional.\n\nThe `url` should be either:\n\n- the path to a local directory, in which case the `url` must start with `file:`\n- a url for a remote zip archive; if the url does not end with `.zip`, you must\n  specify the `type` as `zip`\n  - if you host your OSV database as a repository on GitHub, it can be consumed\n    as a zip archive\n- a url for a rest API that implements the [osv.dev](https://osv.dev/docs/) API\n  - the `url` _should_ include the `/v1` e.g. if you wanted to use the `osv.dev`\n    staging API you would specify `https://api-staging.osv.dev/v1` as the `url`\n\n\u003e The detector will attempt to detect the type of each database based on the\n\u003e above, however you can explicitly provide the type if needed with the `type`\n\u003e property (such as if you have a zip archive whose url does not end with\n\u003e `.zip`)\n\nFor the file based database sources (`dir` and `zip`), the detector will\nrecursively load all `.json` files from the `working-directory` relative to the\nroot of the database as OSVs.\n\n\u003e The detector assumes that you trust the source of the configuration file and\n\u003e thus the databases that it points to.\n\u003e\n\u003e If you are using the detector in a way that allows users to provide arbitrary\n\u003e config files that you don't trust, you can use the `--no-config-databases`\n\u003e flag to have the detector load the rest of the config without any extra\n\u003e databases it may define\n\nThis is a very powerful feature as it enables you to create custom OSVs that can\nbe easily consumed by multiple projects and that cover anything you want - for\nexample you could write OSVs to check if you're using versions of packages that\nare now considered end of life.\n\nThis can also be useful for drafting new OSVs or modifications to existing ones,\nand becomes even more powerful when combined with the ability to pass arbitrary\npackage details, as you can have custom ecosystems and write custom tools to\nhandle extracting the package details.\n\nHere are some further examples of `extra-databases`:\n\n```yaml\nextra-databases:\n  # include a specific osv.dev ecosystem database for any lockfiles being checked\n  - url: https://osv-vulnerabilities.storage.googleapis.com/OSS-Fuzz/all.zip\n    name: OSS-Fuzz\n\n  # include all the unreviewed advisories\n  - url: https://github.com/github/advisory-database/archive/refs/heads/main.zip\n    name: GitHub Advisory Database (unreviewed)\n    working-directory: 'advisory-database-main/advisories/unreviewed'\n\n  # include the osv staging api\n  - url: https://api-staging.osv.dev/v1\n    name: GitHub Advisory Database (unreviewed)\n\n  # include a local directory database (relative)\n  - url: file:/../relative/path/to/dir\n    name: My local database (relative)\n\n  # include a local directory database (root)\n  - url: file:////root/path/to/dir\n    name: My local database (root)\n```\n\n### Offline mode\n\nYou can have the detector run purely in offline mode with the `--offline` flag:\n\n```shell\nosv-detector --offline path/to/my/file.lock\n```\n\nRemotely sourced databases can only be used in offline mode if they have been\ncached by the detector as part of a previous run, and API-based databases will\nbe skipped entirely.\n\nThe cache is based on the source `url` of the database, meaning databases that\nhave the same source but different working directories will use the same cache.\n\n### Passing arbitrary package details (advanced usage)\n\nThe detector supports being passed arbitrary package details in CSV form to\ncheck for known vulnerabilities.\n\nThis is useful for one-off manual checks (such as when deciding on a new\nlibrary), or if you have packages that are not specified in a lock (such as\nvendored dependencies). It also allows you to check packages in ecosystems that\nthe detector doesn't know about, such as `NuGet`.\n\nYou can either pass in CSV rows:\n\n```\nosv-detector --parse-as csv-row 'npm,,@typescript-eslint/types,5.13.0' 'Packagist,sentry/sdk,2.0.4'\n```\n\nor you can specify paths to csv files:\n\n```\nosv-detector --parse-as csv-file path/to/my/first-csv path/to/my/second-csv\n```\n\nEach CSV row represents a package and is made up of at least four fields:\n\n1. The ecosystem that the package is from, which is used as part of identifying\n   if an OSV is about the given package\n   - This does not have to be one of the ecosystems referenced in the detector,\n     or in the OSV specification\n   - This should be omitted if you are wanting to compare a commit using an API\n     database\n2. The ecosystem whose version comparison semantics to use when determining if\n   an OSV applies to the given package\n   - This has to be an ecosystem for which the detector supports comparing\n     versions of; this field can be blank if the first field refers to an\n     ecosystem the detector supports comparing, otherwise it should be the\n     ecosystem whose version semantics most closely match that of your arbitrary\n     ecosystem\n   - This should be omitted if you are wanting to compare a commit using an API\n     database\n3. The name of the package\n4. The version of the package, or the SHA of a `git` commit\n   - If you are providing a commit, then you must leave the first two fields\n     empty and ensure an API-based database is loaded i.e. via `--use-api`\n\n\u003e **Warning**\n\u003e\n\u003e Do not include a header if you are using a CSV file\n\nThe `ecosystem` does _not_ have to be one listed by the detector as known,\nmeaning you can use any ecosystem that [osv.dev](https://osv.dev/) provides.\n\n\u003e Remember to tell the detector to use the `osv.dev` API via the `--use-api`\n\u003e flag if you're wanting to check commits!\n\nYou can also omit the version to have the detector list all known\nvulnerabilities in the loaded database that apply to the given package:\n\n```\nosv-detector --parse-as csv-row 'NuGet,,Yarp.ReverseProxy,'\n```\n\nWhile this uses the `--parse-as` flag, these are _not_ considered standard\nparsers so the detector will not automatically use them when checking\ndirectories for lockfiles.\n\n### Auxiliary output commands\n\nThe detector supports a few auxiliary commands that have it output information\nwhich can be useful for debugging issues and general exploring.\n\n#### `--list-ecosystems`\n\nLists all the ecosystems that the detector knows about (aka there is a parser\nthat results in packages from that ecosystem):\n\n```\n$ osv-detector --list-ecosystems\nThe detector supports parsing for the following ecosystems:\n  npm\n  crates.io\n  RubyGems\n  Packagist\n  Go\n  PyPI\n```\n\n#### `--list-packages`\n\nLists all the packages that the detector was able to parse out of the given\nlockfile. This can be useful for sense-checking parsers and can also be used for\nbuilding other tools.\n\nEach package is outputted on its own line, in the format of\n`\u003cecosystem\u003e: \u003cname\u003e@\u003cversion\u003e`:\n\n```\n$ osv-detector --list-packages /path/to/my/Gemfile.lock\nLoaded 6532 vulnerabilities (including withdrawn, last updated Fri, 04 Mar 2022 00:11:50 GMT)\nThe following packages were found in /path/to/my/Gemfile.lock:\n  RubyGems: ast@2.4.2\n  RubyGems: parallel@1.21.0\n  RubyGems: parser@3.1.1.0\n  RubyGems: rainbow@3.1.1\n  RubyGems: regexp_parser@2.2.1\n  RubyGems: rexml@3.2.5\n  RubyGems: rubocop@1.25.1\n  RubyGems: rubocop-ast@1.16.0\n  RubyGems: ruby-progressbar@1.11.0\n  RubyGems: unicode-display_width@2.1.0\n```\n\n## Version parsing and comparing\n\nVersions are compared using an internal `semantic` package which aims to support\ncompare versions accurately per the version semantics of each ecosystem, falling\nback to a relaxed version of SemVer that supports unlimited number components\nfollowed by a build string.\n\nComponents are numbers broken up by dots, e.g. `1.2.3` has the components\n`1, 2, 3`. Anything that is not a number or a dot is considered to be the start\nof a build string, and anything afterwards (including numbers and dots) are\nlikewise considered to be part of the build string.\n\nVersions are compared by their components first, in order. Versions are not\nrequired to have the same number of components to be comparable.\n\nIf all components are equal, then the build string is compared (if present).\n\nBuild string comparison is not guaranteed to be correct, since they can be in\nany format. Generally, the comparer attempts to extract numbers from the build\nstrings which are then compared.\n\nHere are examples of versions with build strings that _can_ be accurately\ncompared:\n\n```\n1.0.0.beta.2\n1.0.0-rc.0\n1.0.0.v3\n1.0.0a1\n```\n\nCurrently, characters \u0026 words in the build string are not factored into the\ncomparison - this means e.g. `1.0.0a2` will be considered _greater than_\n`1.0.0b1`. Ideally this will be supported in the future.\n\nVersions without a build string are considered to be higher than those with\n(provided they have the same components).\n\nImprovements to the build string comparor are welcome!\n\n## Public packages (`pkg/`)\n\nA couple of the core packages that power the detector have been made public to\nallow others to use in their own projects, and to help encourage improvements.\n\nThese packages will not receive their own versions and so should be constrained\nbased on their commit hash. They should also be considered as \"hopefully\nstable\" - while they're not expected to change, as the detector evolves it might\nbecome necessary to change their api in a manner that could be breaking to\ndownstream consumers.\n\nIt is hoped that someday these packages will be published independently, once\ntheir apis have proven to be truly stable.\n\nImprovements, feature requests, and bug reports for these packages are welcome!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fg-rath%2Fosv-detector","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fg-rath%2Fosv-detector","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fg-rath%2Fosv-detector/lists"}