| Title: | Scan R Packages for Vulnerabilities |
| Version: | 0.1.0 |
| Date: | 2026-10-23 |
| Description: | Scan R package dependencies for known security vulnerabilities using the OSV database, with support for renv.lock, installed libraries, and user-supplied package versions. |
| License: | MIT + file LICENSE |
| URL: | https://github.com/Dschaykib/vulnr |
| BugReports: | https://github.com/Dschaykib/vulnr/issues |
| Imports: | data.table, httr, jsonlite (≥ 1.8.8), stats, tools, utils |
| Suggests: | testthat |
| Config/roxygen2/version: | 8.1.1 |
| Encoding: | UTF-8 |
| NeedsCompilation: | no |
| Packaged: | 2026-10-23 14:53:39 UTC; jakobgepp |
| Author: | Jakob Gepp [cre, aut, cph] |
| Maintainer: | Jakob Gepp <jakob.gepp@yahoo.de> |
| Repository: | CRAN |
| Date/Publication: | 2026-11-07 14:50:02 UTC |
Add recursive package dependencies
Description
Resolves strong recursive dependencies from the latest CRAN metadata and appends dependencies that are not already present in 'data'.
Usage
add_dependencies(data)
Arguments
data |
Data frame containing a 'Package' column. |
Value
A data table containing the input packages and their dependencies.
Examples
## Not run:
add_dependencies(data.frame(Package = "jsonlite"))
## End(Not run)
Send a request to the OSV API
Description
Send a request to the OSV API
Usage
api_request(url, verb = c("GET", "POST"), body = NULL)
Arguments
url |
API endpoint URL. |
verb |
HTTP method, either 'GET' or 'POST'. |
body |
Optional request body, converted to JSON for 'POST' requests. |
Value
The parsed API response.
Examples
## Not run:
api_request("https://api.osv.dev/v1/vulns/RUSTSEC-2020-0001")
## End(Not run)
Check R dependencies for known vulnerabilities
Description
Scans explicitly supplied package data, an 'renv.lock' file, and installed libraries, then queries the OSV database for known vulnerabilities.
Usage
check(
data = NULL,
renv_file = NULL,
lib = NULL,
dcf = NULL,
error_level = "LOW",
group = TRUE,
return_cves = FALSE,
dependencies = FALSE
)
Arguments
data |
Optional data frame with 'Package' and 'Version' columns or a vector with package names. |
renv_file |
Path to an 'renv.lock' file, or 'NULL' to skip it. |
lib |
Character vector of library paths, or 'NULL' to skip installed libraries. |
dcf |
Path to a DESCRIPTION file, or 'NULL' to skip it. |
error_level |
Minimum severity that causes an error. One of 'CRITICAL', 'HIGH', 'MEDIUM', or 'LOW'. |
group |
Logical; if 'TRUE', group findings by package in the report. |
return_cves |
Logical; if 'TRUE', return the CVE data table instead of reporting findings with a warning or error. |
dependencies |
Logical; if 'TRUE', include recursive strong package dependencies in the scan. |
Value
Invisibly returns 'NULL' by default. If 'return_cves' is 'TRUE', returns the CVE data table.
Examples
# check specific packages
check(data = "data.table")
## Not run:
# check a renv.lock file
check(renv_file = "renv.lock")
## End(Not run)
Query OSV for package vulnerabilities
Description
Query OSV for package vulnerabilities
Usage
check_packages(check_data)
Arguments
check_data |
Data frame containing 'Package' and 'Version' columns. |
Value
A data table of vulnerabilities and severity information, or 'NULL'.
Examples
## Not run:
check_packages(data.frame(Package = "jsonlite", Version = "1.8.0"))
## End(Not run)
Compare a package version with a constraint
Description
Compare a package version with a constraint
Usage
compare_version(x, y)
Arguments
x |
Package version to compare. |
y |
Version constraint using '>', '>=', '<', '<=', '=' or '=='. |
Value
A logical value indicating whether 'x' satisfies 'y'.
Examples
compare_version("1.2.3", ">= 1.0.0")
Create a batch OSV query body
Description
Create a batch OSV query body
Usage
create_body_list(pkg = NULL, version = NULL)
Arguments
pkg |
Character vector of package names. |
version |
Optional character vector of package versions. |
Value
A list suitable for the OSV batch query endpoint, or 'NULL'.
Examples
create_body_list("jsonlite", "1.8.0")
Calculate a CVSS 3.1 base score
Description
Calculate a CVSS 3.1 base score
Usage
cvss31_score(vector)
Arguments
vector |
A CVSS 3.1 vector string. |
Value
A numeric score between 0 and 10.
Examples
cvss31_score("CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H")
Convert a CVSS score to a severity label
Description
Convert a CVSS score to a severity label
Usage
cvss31_severity(score)
Arguments
score |
Numeric CVSS score. |
Value
One of 'NONE', 'LOW', 'MEDIUM', 'HIGH', or 'CRITICAL'.
Examples
cvss31_severity(9.8)
Format vulnerability findings for display
Description
Format vulnerability findings for display
Usage
format_vulnerabilities(x = NULL, group = TRUE, refs = NULL)
Arguments
x |
Data frame containing vulnerability findings. |
group |
Logical; group findings by package when 'TRUE'. |
refs |
Character vector of source paths referenced by the findings. |
Value
A list with 'summary' and 'details' strings, or a single clean-result string when there are no findings.
Examples
format_vulnerabilities()
Retrieve upstream identifiers and fixed versions
Description
Retrieve upstream identifiers and fixed versions
Usage
get_cveid(resc_dt)
Arguments
resc_dt |
Data table of OSV result identifiers. |
Value
A data table linking packages to upstream vulnerability identifiers.
Examples
## Not run:
get_cveid(data.table::data.table(
package = "jsonlite", installed = "1.8.0", id = "OSV-EXAMPLE",
fix = NA_character_
))
## End(Not run)
Extract vulnerability identifiers from OSV results
Description
Extract vulnerability identifiers from OSV results
Usage
get_rsecid(body_list, results)
Arguments
body_list |
Batch query body used to create 'results'. |
results |
Parsed OSV batch results. |
Value
A data table of packages, installed versions, and OSV identifiers.
Examples
get_rsecid(
body_list = list(queries = list(
list(package = list(name = "jsonlite"), version = NULL)
)),
results = list(list())
)
Retrieve CVSS severity for vulnerability identifiers
Description
Retrieve CVSS severity for vulnerability identifiers
Usage
get_severity(ids)
Arguments
ids |
Character vector of upstream vulnerability identifiers. |
Value
A data table with identifiers, CVSS scores, and severity labels.
Examples
## Not run:
get_severity("CVE-2024-99999")
## End(Not run)
Normalize package data
Description
Normalize package data
Usage
normalize_packages(x)
Arguments
x |
A data frame with 'Package' and 'Version' columns, or a character vector of package names. A missing or empty version is treated as an unversioned package query. |
Value
A normalized data frame with 'Package', 'Version', 'source', and 'path' columns.
Examples
normalize_packages(c("jsonlite", "httr"))
Parse package dependencies from DESCRIPTION files
Description
Reads 'Depends', 'Imports', and 'Suggests' fields and returns one row per package, excluding the base R dependency.
Usage
parse_dcf(file = "DESCRIPTION")
Arguments
file |
Character vector of existing DESCRIPTION file paths. |
Details
For the output, the source is set to 'DESCRIPTION' and the path are the packages that depend on it.
Value
A data table with 'Package', 'Version', 'source', and 'path'.
Examples
## Not run:
parse_dcf("DESCRIPTION")
## End(Not run)
Parse installed packages from library paths
Description
Parse installed packages from library paths
Usage
parse_library(lib = .libPaths())
Arguments
lib |
Character vector of existing library paths. |
Value
A data frame of installed packages and their source paths.
Examples
## Not run:
parse_library(.libPaths()[1])
## End(Not run)
Parse package records from renv lock files
Description
Parse package records from renv lock files
Usage
parse_renv_lock(renv_file = "renv.lock")
Arguments
renv_file |
Character vector of paths to 'renv.lock' files. |
Value
A data frame containing package names, versions, source, and path.
Examples
## Not run:
parse_renv_lock("renv.lock")
## End(Not run)
Build an OSV package query
Description
Build an OSV package query
Usage
set_query(pkg, version = NULL, eco = "CRAN")
Arguments
pkg |
Package name. |
version |
Optional package version. |
eco |
Package ecosystem, defaulting to 'CRAN'. |
Value
A list representing one OSV query.
Examples
set_query("jsonlite", "1.8.0")