feat(fetch/openssl/secjson): add OpenSSL security advisory JSON fetcher - #900
Merged
Conversation
3 tasks
MaineK00n
force-pushed
the
MaineK00n/fetch-openssl-secjson
branch
2 times, most recently
from
July 31, 2026 07:28
c6ef81c to
11f0a57
Compare
MaineK00n
marked this pull request as ready for review
July 31, 2026 07:29
Contributor
There was a problem hiding this comment.
Pull request overview
Adds a new fetch data source (openssl-secjson) to download OpenSSL’s per-CVE CVE JSON 5.x records plus statements.json, writing them into a deterministic on-disk layout under the fetch cache directory and wiring it into the Cobra command tree.
Changes:
- Implement
pkg/fetch/openssl/secjsonfetcher: scrape the HTML index, requirestatements.json, and fetch per-CVE JSON concurrently. - Add OpenSSL secjson golden/fixture test data and a table-driven
httptest-based fetcher test. - Wire the new
openssl-secjsonsubcommand intopkg/cmd/fetch/fetch.go.
Reviewed changes
Copilot reviewed 18 out of 18 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| pkg/fetch/openssl/secjson/secjson.go | New fetcher implementation (index scrape + strict link handling + concurrent CVE downloads). |
| pkg/fetch/openssl/secjson/types.go | CVE JSON 5.x types (plus Statements types) used for lossless JSON decoding/encoding. |
| pkg/fetch/openssl/secjson/secjson_test.go | Golden-style fetcher test using httptest fixtures. |
| pkg/cmd/fetch/fetch.go | Registers openssl-secjson command and hooks it into vuls-data-update fetch. |
| pkg/fetch/openssl/secjson/testdata/fixtures/happy/indexof.html | HTML fixture for a successful index scrape. |
| pkg/fetch/openssl/secjson/testdata/fixtures/happy/statements.json | JSON fixture for statements.json. |
| pkg/fetch/openssl/secjson/testdata/fixtures/happy/cve-2002-0655.json | JSON fixture for a legacy CVE record. |
| pkg/fetch/openssl/secjson/testdata/fixtures/happy/cve-2022-3996.json | JSON fixture for a CVE record with lessThanOrEqual and credits[].user. |
| pkg/fetch/openssl/secjson/testdata/fixtures/happy/cve-2024-6119.json | JSON fixture for a newer CVE record with supportingMedia, etc. |
| pkg/fetch/openssl/secjson/testdata/fixtures/notfound/indexof.html | HTML fixture where a listed CVE link 404s. |
| pkg/fetch/openssl/secjson/testdata/fixtures/notfound/statements.json | JSON fixture used for the “notfound” test case. |
| pkg/fetch/openssl/secjson/testdata/fixtures/no-statements/indexof.html | HTML fixture missing statements.json (expected error). |
| pkg/fetch/openssl/secjson/testdata/fixtures/unexpected/indexof.html | HTML fixture with an unexpected JSON filename (expected error). |
| pkg/fetch/openssl/secjson/testdata/golden/happy/statements.json | Golden output for statements.json in the happy path. |
| pkg/fetch/openssl/secjson/testdata/golden/happy/2002/CVE-2002-0655.json | Golden output for CVE-2002-0655. |
| pkg/fetch/openssl/secjson/testdata/golden/happy/2022/CVE-2022-3996.json | Golden output for CVE-2022-3996. |
| pkg/fetch/openssl/secjson/testdata/golden/happy/2024/CVE-2024-6119.json | Golden output for CVE-2024-6119. |
| pkg/fetch/openssl/secjson/testdata/golden/notfound/statements.json | Golden output asserting statements.json is written before the 404 failure. |
OpenSSL publishes its advisories as per-CVE records in the MITRE CVE Record Format under https://openssl-library.org/news/secjson/, so the schema is shared with fetch/mitre/cve/v5. There is no aggregate feed or index API, so the fetcher scrapes the HTML index for the linked JSON files. statements.json is fetched as well: its disputed entries are the only place recording that OpenSSL does not consider a CVE to affect it, and they exist in no per-CVE file. Since the data set depends on it, both a missing statements.json and an unrecognized JSON file name in the index are errors rather than warnings, so that upstream changes surface instead of silently shrinking the collected data. cveId is validated against the schema pattern before being used as a path element, following fetch/nvd/api/cvehistory. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
MaineK00n
force-pushed
the
MaineK00n/fetch-openssl-secjson
branch
from
July 31, 2026 07:45
11f0a57 to
8ebd44b
Compare
Contributor
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 22 out of 22 changed files in this pull request and generated no new comments.
Suppressed comments (2)
pkg/fetch/openssl/secjson/secjson_test.go:70
- These subtests exercise multiple distinct failure modes (404, missing statements link, unexpected JSON filename, invalid CVE ID), but the test currently only asserts that an error occurred. Adding a small check that the error contains an expected substring per case would ensure each fixture fails for the intended reason (and prevents false positives where an unrelated error happens to occur).
switch {
case err != nil && !tt.hasError:
t.Error("unexpected error:", err)
case err == nil && tt.hasError:
t.Error("expected error has not occurred")
default:
pkg/fetch/openssl/secjson/secjson.go:210
- The expected filename pattern reported in this error message doesn’t match the actual acceptance check (
strings.HasPrefix(b, "cve-")). As written, the message implies onlycve-<year>-<digits>.jsonis allowed, but the code will accept anycve-*.json. Aligning the message with the predicate will make failures easier to diagnose.
return "", nil, errors.Errorf("unexpected json file name. expected: %q, actual: %q", []string{statementsFilename, "cve-yyyy-\\d{4,}.json"}, b)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Add a new fetch data source
openssl-secjsonthat collects OpenSSL's security advisory JSON files from https://openssl-library.org/news/secjson/.pkg/fetch/openssl/secjson/— fetcher + types + golden testspkg/cmd/fetch/fetch.go— wirenewCmdOpenSSLSecJSON()Output layout:
Why
OpenSSL publishes its own advisories as per-CVE records in the MITRE CVE Record Format (
dataType: CVE_RECORD,dataVersion5.0 / 5.1), i.e. the same schema asfetch/mitre/cve/v5, and as the CNA for its own CVEs it is the authoritative source for affected version ranges.statements.jsonis fetched as well because itsdisputedentries (CVE-2002-20001, CVE-2007-6755, CVE-2010-0928) do not exist as per-CVE files — this is the only place in the dataset where "OpenSSL considers this not a vulnerability / not affected" is recorded, which maps naturally ontofixstatus.ClassNotAffectedfor a future extractor. Itsstatementsentries are OpenSSL's own out-of-support declarations per version series, which map ontotypes/eol.How
Types are copied from
pkg/fetch/mitre/cve/v5/types.go(the same duplicationfetch/paloalto/jsonalready does for this schema), plus a smallStatements/Statementtype forstatements.json.Upstream offers no aggregate feed or index API — only the HTML index — so the fetcher scrapes it with goquery (
main a), resolves hrefs viaurl.ResolveReference, and then:statements.json→<dir>/statements.jsoncve-*.json→PipelineGet→<dir>/<year>/CVE-yyyy-nnnn.json, year taken fromcveMetadata.cveIdexactly asmitre/cve/v5doesSince the data set depends on
statements.jsonfor the disputed records, the index scan is strict rather than lenient: a missingstatements.jsonlink and an unrecognized JSON file name in the index are both errors. A quietly shrinking data set is worse than a failed run, and a new upstream file should be a deliberate decision, not a silent drop. Non-JSON links (e.g. thesecadv/*.txtadvisories) are ignored.Defaults:
retry=3,concurrency=5,wait=1s.Testing
GOEXPERIMENT=jsonv2 go build ./...GOEXPERIMENT=jsonv2 go test -race ./pkg/fetch/openssl/...— golden test with four cases, each error case verified to fail for its intended reason:happy— a legacyx_generator.importerrecord, one withlessThanOrEqual+credits[].user+supportingMedia, one full Vulnogram record,statements.json, plus a non-JSON linknotfound— a listed record that 404s; also asserts thestatements.jsonwritten before the failure is correctno-statements— index that no longer linksstatements.jsonunexpected— index carrying an unrecognizedadvisories.jsonGOEXPERIMENT=jsonv2 go vet,gofmt -l,golangci-lint run— cleanvuls-data-update fetch openssl-secjson→ 272 CVE records +statements.jsonstatements.json+ 272cve-*.jsonand nothing else, so the strict path does not trip on the current upstream pageChecklist
util.Write; two independent runs produced byte-identical treespkg/extract/typesNotes for reviewers
vuls-data-dbkeeps theextract-*matrix entries commented out (see feat(ci): add openssl-secjson vulsio/vuls-data-db#206).statements[].basetakes non-version sentinels (none,fips) in addition to version series like0.9.8.🤖 Generated with Claude Code