Warning
💥 Attention please! You've entered our testing ground! ☠ The contents of this repo are purely for testing purposes. Please don't use the files or information here for any other reason. Thank you for your cooperation! 🌟
This chapter contains information on how to use and contribute to the FreeBSD OSV (Open Source Vulnerability) database.
OSV (Open Source Vulnerabilities) is an initiative aimed at creating a common format for describing vulnerabilities. The FreeBSD Foundation, in consultation with Core and Ports Manager teams, carried out a project in 2025 to make it possible for FreeBSD vulnerability information to be stored, managed and presented in the OSV format.
Having FreeBSD vulnerability data in the OSV format will make it easier for downstream users of FreeBSD to access and process this data, especially using available ecosystem tooling.
It also makes it easier for FreeBSD to import vulnerability data for its 3rd-party components where it is provided in the OSV format.
Complete
- Research common vulnerability data formats and choose one.
- Add OSV parsing capagility to
pkg. - Add unit tests to CI to validate OSV content that has been generated.
- Add FreeBSD to the upstream OSV schema.
- Create Lua tool to merge and validate OSV files into a single JSON array.
- Create a script to convert VuXML format to OSV format.
- Convert a test set of VuXML data into OSV.
- Create an OSV database for FreeBSD.
- Remove VuXML handling from
pkg auditand add replacement OSV-handling code. (Pull Request needs reviewing and testing)
Not done (out of scope, but logical next steps)
- Convert all VuXML data to OSV format.
- Transition FreeBSD ports processes to use the OSV format.
- Start updating OSV and leave VuXML for historical purposes only
- Add new targets to Makefile if needed
Lua was chosen as the implementation language because it's available in the FreeBSD base system as FLua, which stands for FreeBSD Lua. Additionally, the JSON module libUCL is available on a fresh install. The VuXML converter was made with Python because XML handling in Lua is more challenging than in Python using the lxml library. Another reason was that there is pypandoc, which converts XHTML to Commonmark. If the OSV database only contains FreeBSD vulnerabilities and supersedes VuXML, the Python script could be retired.
The FreeBSD OSV database uses JSON as its serialization format. Other formats like YAML and TOML were evaluated. However, Lua's YAML module, lyaml, does not support validation with JSON schema or any other schema type, raising concerns about YAML's flexibility and the quality of vulnerability reports. While TOML addresses many issues in YAML and is stricter about formatting serialized documents, FreeBSD does not provide a Lua module for reading TOML within its base system.
When designing the structure of the FreeBSD OSV database, various other OSV Vulnerability databases were examined. As, every OSV database has its own ID and their strong points and weaknesses, a schema for FreeBSD was chosen mainly with simplicity in mind after studying multiple different methods of producing the OSV ID.
The chosen schema template looks like: FreeBSD-YYYY-NNNN where 'Y' stands for year and 'N' stands for running four letter number padded with zeroes. The FreeBSD IDs changing part reset to 0001 start of every year and increments with one each new vulnerability. YYYY is four digits year when vulnerability was reported. With this kind of approach it's easy for humans to understand and maintains unique ID requirements easily for the foreseeable future.
Each vulnerability file is stored under vuln/YYYY directory where 'YYYY' is the same as in vulnerability year. Filenames are FreeBSD vulnerability ID with .json prefix. Whole directory file structure look like vuln/YYYY/FreeBSD-YYYY-NNNN.json. This method ensuring HTTP servers serve them with the correct MIME type. Additionally, keeping each year's files in their own yearly subdirectory avoids overlapping any filesystem directory limits and makes it easy to find the correct file within the directory.
Next chapter goes more deeper how OSV database organize files and structures.
OSV Integration into FreeBSD's main infrastructure is still in progress, with the current implementation available at an unofficial repository outside of FreeBSD. The OSV repository has a slightly different structure than VuXML entries:
Files are organized by year in subdirectories under the vuln directory. The prefix resets to 0001 on January 1st of each year, with directories changing to reflect the current year:
vuln/
2024/
FreeBSD-2024-0001.json
FreeBSD-2024-0002.json
FreeBSD-2024-0003.json
FreeBSD-2024-0004.json
...
2025/
FreeBSD-2025-0001.json
FreeBSD-2025-0002.json
FreeBSD-2025-0003.json
FreeBSD-2025-0004.json
...
A flattened JSON file containing all vulnerabilities is stored as db/freebsd-osv.json, which is consumed by the pkg(8) tool in future. Integration with pkg(8) is currently under review at the Pull Request level.
OSV Schema documentation can be found here. If something in this documentation contradicts the official schema documentation, then the official documentation should be considered correct. Corrections to this documentation are welcome.
This is an example of a VuXML converted to OSV JSON format, which has been chosen as the serialization language for OSV files:
{
"affected": [
{
"package": {
"ecosystem": "FreeBSD:ports",
"name": "foo"
},
"ranges": [
{
"events": [
{
"introduced": "1.6"
},
{
"fixed": "1.9"
}
],
"type": "ECOSYSTEM"
},
{
"events": [
{
"introduced": "2.*"
},
{
"fixed": "2.4_1"
}
],
"type": "ECOSYSTEM"
},
{
"events": [
{
"introduced": "3.0b1"
},
{
"fixed": "3.0b1"
}
],
"type": "ECOSYSTEM"
}
],
"versions": [
"3.0b1"
]
},
{
"package": {
"ecosystem": "FreeBSD:ports",
"name": "foo-devel"
},
"ranges": [
{
"events": [
{
"introduced": "1.6"
},
{
"fixed": "1.9"
}
],
"type": "ECOSYSTEM"
},
{
"events": [
{
"introduced": "2.*"
},
{
"fixed": "2.4_1"
}
],
"type": "ECOSYSTEM"
},
{
"events": [
{
"introduced": "3.0b1"
},
{
"fixed": "3.0b1"
}
],
"type": "ECOSYSTEM"
}
],
"versions": [
"3.0b1"
]
},
{
"package": {
"ecosystem": "FreeBSD:ports",
"name": "ja-foo"
},
"ranges": [
{
"events": [
{
"introduced": "1.6"
},
{
"fixed": "1.9"
}
],
"type": "ECOSYSTEM"
},
{
"events": [
{
"introduced": "2.*"
},
{
"fixed": "2.4_1"
}
],
"type": "ECOSYSTEM"
},
{
"events": [
{
"introduced": "3.0b1"
},
{
"fixed": "3.0b1"
}
],
"type": "ECOSYSTEM"
}
],
"versions": [
"3.0b1"
]
},
{
"package": {
"ecosystem": "FreeBSD:ports",
"name": "openfoo"
},
"ranges": [
{
"events": [
{
"introduced": "0"
}
{
"fixed": "1.10_7"
},
],
"type": "ECOSYSTEM"
},
{
"events": [
{
"introduced": "1.2,1"
},
{
"fixed": "1.3_1,1"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"database_specific": {
"cite": [
"http://j.r.hacker.com/advisories/1"
],
"discovery": "2010-05-25T00:00:00Z",
"references": {
"certvu": [
"740169"
],
"cvename": [
"CVE-2023-48795"
],
"freebsdpr": [
"ports/987654"
],
"freebsdsa": [
"SA-10:75.foo"
]
},
"vid": "f4bc80f4-da62-11d8-90ea-0004ac98a7b9"
},
"details": "J. Random Hacker reports:\n\n> Several issues in the Foo software may be exploited via carefully\n> crafted QUUX requests. These requests will permit the injection of Bar\n> code, mumble theft, and the readability of the Foo administrator\n> account.\n",
"id": "FreeBSD-2010-0001",
"modified": "2010-09-17T00:00:00Z",
"published": "2010-07-13T00:00:00Z",
"references": [
{
"type": "REPORT",
"url": "http://j.r.hacker.com/advisories/1"
},
{
"type": "ADVISORY",
"url": "https://www.freebsd.org/security/advisories/FreeBSD-SA-10:75.foo.asc"
},
{
"type": "REPORT",
"url": "https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=987654"
},
{
"type": "ADVISORY",
"url": "https://api.osv.dev/v1/vulns/CVE-2023-48795"
},
{
"type": "ADVISORY",
"url": "https://www.kb.cert.org/vuls/id/740169"
},
{
"type": "DISCUSSION",
"url": "http://marc.theaimsgroup.com/?l=bugtraq&m=203886607825605"
}
],
"schema_version": "1.7.0",
"summary": "Several vulnerabilities found in Foo"
}
Detailed documentation on tags and structure can be found in the Official OSV Schema documentation, but here are notes for this example:
-
ID Field: The
.idfield is mandatory at the top level of an OSV entry and specifies a unique ID for the entry. For VuXML entries converted to OSV format, it uses UUIDs (found under.database_specific.vid). The ID format should beFREEBSD-YYYY-NNNN, where YYYY is a four-digit year (e.g., 2026), and NNNN is the running number starting at 0001 every year. For example, the third vulnerability of 2026 would beFREEBSD-2026-0004. It should be stored invuln/2026/FREEBSD-2026-0004.json. -
Summary Field: The
.summaryfield is a one-line description of the issue. -
Affected Packages: The
.affectedfield lists all affected packages as an array. Each package object contains:name: The port or base package name.ecosystem: Typically, this will beFreeBSD:portswhich is for FreeBSD Ports packages. It also can beFreeBSD:basewhich is for FreeBSD base package(s) orFreeBSD:kernelwhich is for kernel modules and kernel itself.
-
Versioning: Version information is provided under
.affected[].rangesarray. Each range object contains:- every range objects
eventsarray holds event objects. Those object keys can be:introducedorfixed. Official documentation strongly marks thatlast_affectednorlimitkeys should not be used without a caution and current implementation just ignores them if they appear in events. introduced-key is used like<ge>attribute.introducedshould be used event though it's marked "0". Key should the at the top of events.fixed-key is used like<le>attribute.fixedshould be at the last of events.- VuXML version '*', which means all version are vunerable, is supported with
introduced: "0" - The
type-field should always beECOSYSTEM.
- every range objects
-
Details Field: The
.detailsfield contains a multi-line detailed description of the issue, formatted in CommonMark. -
References Field: The
.referencesarray includes relevant documents with types such asADVISORY,DISCUSSION, andREPORT. See the official OSV documentation for all available types. -
Modified Field: The
.modifiedfield contains the ISO 8601 date when the issue was last modified (YYYY-MM-DDTHH:MM:SSZ). -
Published Field:
.publishedfield contains The ISO 8601 date when the entry was added (YYYY-MM-DDTHH:MM:SSZ). -
Database-Specific Information:
.database_specific.discovery: The ISO 8601 date when the issue was discovered..database_specific.vid: Original VuXML UUID.database_specific.references: Object which contains original references as they are preprensented as URL in.references.database_specific.references.bid[]: Array of SecurityFocus computer security news portal (current offline) numbers as strings.database_specific.references.certsa[]: Array of CERT Advisories reference numbers as strings.database_specific.references.certvu[]: Array of CERT/CC Vulnerability Notes Database reference numbers as strings.database_specific.references.cvename[]: Array of CVE Vulnerabilities connecting for this OSV entry as strings..database_specific.references.freebsdpr[]: Array of FreeBSD bugzilla bug references..database_specific.references.freebsdsa[]: Array of FreeBSD Security Advisories references.
-
Schema Version: The
schema_versionfield indicates the version of the schema in use (FreeBSD uses 1.7.4).
Additional fields like severity, aliases, and withdrawn are mentioned but not currently used.
In the Unofficial outside FreeBSD repository, there is a Makefile that makes it easier to maintain OSV Vulnerabilities. While there aren't many targets, they should be sufficient to:
- Maintain OSV database and convert entries from VuXML XML to OSV (with
convert-vuxml) - Merge OSV files into one JSON array to use in pkg(8)
- Export OSV files to Commonmark
.md-files which can be converted to HTML with Pandoc or a similar tool - In the future, maintain only the OSV repository and have OSV Pull Request 3901 fulfilled to make FreeBSD Vulnerabilities appear through the osv.dev API
Targets in detail are:
commonmark, merge, newentry and validate requires Lua version 5.4. If Flua (FreeBSD Lua) is not available in /usr/libexec/flua then Lua command can be passed with LUA_CMD environment variable. For example LUA_CMD=/usr/bin/lua5.4 make commonmark. Please note that Lua needs libUCL lua module for JSON parsing and validation.
convert-vuxml: Downloads VuXML from FreeBSD vuxml: https://vuxml.freebsd.org/freebsd/vuln.xml.xz, unpacks it withxz, and converts VuXML to OSV format. New files are saved under thevulndirectory. Ifvuxml.xmlis present then conversion is not done. Please not that one needs Python moduleslxmlandpypandocinstalled before usingconvert-vuxmlExample (Please note thatmake convert-vuxmlcan take from couple of minutes to 10 minutes)rm vuxml.xml # Remove old vuxml.xml otherwise the will be error message make convert-vuxml # Converts VuXML to OSV JSON. New files are under vuln directory git status # Check if there is new entries under vuln directory git add vuln/2025/FreeBSD-2025-0001.json # Add new files to git (Please note that this just example and you need to add correct files) make merge # Merge new files to db/freebsd-osv.json for using with pkg(8) command git commit -a # Commit all changes git push # Publish new changes to worldcommonmark: Exports OSV JSON files as CommonMark format into.mdfiles. The directory structure remains unchanged. Example (Please note thatmake commonmarkcan take from couple of minutes to 10 minutes)make commonmark # Convert all OSV entries to .md files under md directory git status # Check if there is new entries under md directory git add md/2025/FreeBSD-2025-0001.md # Add new files to git (Please note that this just example and you need to add correct files) git commit -a # Commit all changes or choose files you want to commit git push # Publish new changes to worldmerge: Merges all OSV files in thevulndirectory intodb/freebsd-osv.json. Validates all OSV files against the JSON schema. For example please seeconvert-vuxmlexample sectionnewentry: Adds a new entry with the next available ID to thevulndirectory. Do not use this if VuXML converting withconvert-vuxmlis still in use Examplemake newentry # Create new entry under correct directory vi vuln/2026/FreeBSD-2026-0001.json # Edit entry git add vuln/2026/FreeBSD-2026-0001.json git commit vuln/2026/FreeBSD-2026-0001.json git pushvalidate: Validate all JSON files against current OSV JSON schema undervulndirectory. Examplemake validate # Validate all OSV JSON file against schema
These are tools that have been proven to be useful when working with JSON files. They are listed in alphabetical order:
- fx — Go language written Terminal JSON viewer & processor. Easy to see multiline strings, for example.
- jq — C language written Command-line JSON processor. Useful for examining JSON if
fxis too much. - yj — Go language written command line tool that converts YAML to JSON/TOML (and back to YAML/TOML). Can be useful when editing multiline JSON details. Convert JSON to YAML, edit and convert back to JSON.