From 3649396112d76087381ba5cdabb9db2e68447413 Mon Sep 17 00:00:00 2001 From: Sameeh Jubran Date: Wed, 16 Sep 2026 16:58:18 +0300 Subject: [PATCH 1/3] feat(csaf): add wolfSSL 5.9.2 catalogue and CI validation Commit the CNA records and VEX overlay for the 5.9.2 bullet CVEs, plus publish tooling. CI regenerates CSAF/VEX and runs Secvisogram plus CycloneDX strict checks so an incomplete or non-conformant catalogue cannot merge. --- .github/workflows/advisory.yml | 174 +++++++++ .github/workflows/selftest.yml | 9 + .gitignore | 10 + advisories/records/CVE-2026-10097.json | 160 ++++++++ advisories/records/CVE-2026-10098.json | 157 ++++++++ advisories/records/CVE-2026-10512.json | 157 ++++++++ advisories/records/CVE-2026-10592.json | 157 ++++++++ advisories/records/CVE-2026-11310.json | 157 ++++++++ advisories/records/CVE-2026-11703.json | 157 ++++++++ advisories/records/CVE-2026-11999.json | 157 ++++++++ advisories/records/CVE-2026-12340.json | 157 ++++++++ advisories/records/CVE-2026-55958.json | 163 ++++++++ advisories/records/CVE-2026-55960.json | 157 ++++++++ advisories/records/CVE-2026-55961.json | 157 ++++++++ advisories/records/CVE-2026-55962.json | 157 ++++++++ advisories/records/CVE-2026-55964.json | 157 ++++++++ advisories/records/CVE-2026-55967.json | 157 ++++++++ advisories/records/CVE-2026-6091.json | 157 ++++++++ advisories/records/CVE-2026-6092.json | 157 ++++++++ advisories/records/CVE-2026-6094.json | 157 ++++++++ advisories/records/CVE-2026-6291.json | 150 ++++++++ advisories/records/CVE-2026-6325.json | 157 ++++++++ advisories/records/CVE-2026-6329.json | 157 ++++++++ advisories/records/CVE-2026-6330.json | 157 ++++++++ advisories/records/CVE-2026-6331.json | 157 ++++++++ advisories/records/CVE-2026-6412.json | 157 ++++++++ advisories/records/CVE-2026-6450.json | 157 ++++++++ advisories/records/CVE-2026-6678.json | 170 +++++++++ advisories/records/CVE-2026-6679.json | 169 +++++++++ advisories/records/CVE-2026-6681.json | 163 ++++++++ advisories/records/CVE-2026-6731.json | 157 ++++++++ advisories/records/CVE-2026-7511.json | 157 ++++++++ advisories/records/CVE-2026-7531.json | 157 ++++++++ advisories/records/CVE-2026-7532.json | 170 +++++++++ advisories/records/CVE-2026-8720.json | 150 ++++++++ advisories/releases/5.9.2.cves | 37 ++ advisories/vex-overlay.json | 417 ++++++++++++++++++++- central/README.md | 18 +- central/advisory-completeness | 252 +++++++++++++ central/csaf-keygen | 58 +++ central/csaf-publish | 208 ++++++++++ central/csaf-verify | 76 ++++ central/test_advisory_completeness.py | 140 +++++++ central/test_csaf_publish.py | 114 ++++++ tools/csaf-validate/csaf_validate.mjs | 79 ++++ tools/csaf-validate/package.json | 9 + tools/csaf-validate/test_csaf_validate.mjs | 56 +++ 47 files changed, 6711 insertions(+), 9 deletions(-) create mode 100644 .github/workflows/advisory.yml create mode 100644 advisories/records/CVE-2026-10097.json create mode 100644 advisories/records/CVE-2026-10098.json create mode 100644 advisories/records/CVE-2026-10512.json create mode 100644 advisories/records/CVE-2026-10592.json create mode 100644 advisories/records/CVE-2026-11310.json create mode 100644 advisories/records/CVE-2026-11703.json create mode 100644 advisories/records/CVE-2026-11999.json create mode 100644 advisories/records/CVE-2026-12340.json create mode 100644 advisories/records/CVE-2026-55958.json create mode 100644 advisories/records/CVE-2026-55960.json create mode 100644 advisories/records/CVE-2026-55961.json create mode 100644 advisories/records/CVE-2026-55962.json create mode 100644 advisories/records/CVE-2026-55964.json create mode 100644 advisories/records/CVE-2026-55967.json create mode 100644 advisories/records/CVE-2026-6091.json create mode 100644 advisories/records/CVE-2026-6092.json create mode 100644 advisories/records/CVE-2026-6094.json create mode 100644 advisories/records/CVE-2026-6291.json create mode 100644 advisories/records/CVE-2026-6325.json create mode 100644 advisories/records/CVE-2026-6329.json create mode 100644 advisories/records/CVE-2026-6330.json create mode 100644 advisories/records/CVE-2026-6331.json create mode 100644 advisories/records/CVE-2026-6412.json create mode 100644 advisories/records/CVE-2026-6450.json create mode 100644 advisories/records/CVE-2026-6678.json create mode 100644 advisories/records/CVE-2026-6679.json create mode 100644 advisories/records/CVE-2026-6681.json create mode 100644 advisories/records/CVE-2026-6731.json create mode 100644 advisories/records/CVE-2026-7511.json create mode 100644 advisories/records/CVE-2026-7531.json create mode 100644 advisories/records/CVE-2026-7532.json create mode 100644 advisories/records/CVE-2026-8720.json create mode 100644 advisories/releases/5.9.2.cves create mode 100755 central/advisory-completeness create mode 100755 central/csaf-keygen create mode 100755 central/csaf-publish create mode 100755 central/csaf-verify create mode 100644 central/test_advisory_completeness.py create mode 100644 central/test_csaf_publish.py create mode 100644 tools/csaf-validate/csaf_validate.mjs create mode 100644 tools/csaf-validate/package.json create mode 100644 tools/csaf-validate/test_csaf_validate.mjs diff --git a/.github/workflows/advisory.yml b/.github/workflows/advisory.yml new file mode 100644 index 0000000..354d298 --- /dev/null +++ b/.github/workflows/advisory.yml @@ -0,0 +1,174 @@ +name: Advisory catalogue + +# Validates the committed CSAF/VEX catalogue (records + overlay) and the +# publish layout. Generated documents are built in CI, not committed. + +on: + push: + branches: [master] + pull_request: + +jobs: + unit: + name: advisory unit tests + runs-on: ubuntu-24.04 + timeout-minutes: 10 + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-python@v5 + with: + python-version: '3.x' + + - name: Syntax-check advisory tools + run: | + python3 -m py_compile \ + central/gen-advisory \ + central/advisory-completeness \ + central/csaf-publish \ + central/csaf-verify \ + central/csaf-keygen \ + central/test_gen_advisory.py \ + central/test_advisory_completeness.py \ + central/test_csaf_publish.py + + - name: Unit tests + run: | + python3 -m unittest \ + central/test_gen_advisory.py \ + central/test_advisory_completeness.py \ + central/test_csaf_publish.py + + - name: Completeness gate against the pinned 5.9.2 list + run: python3 central/advisory-completeness --cve-list advisories/releases/5.9.2.cves + + catalogue: + name: generate and validate 5.9.2 + runs-on: ubuntu-24.04 + needs: unit + timeout-minutes: 15 + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-python@v5 + with: + python-version: '3.x' + + - uses: actions/setup-node@v4 + with: + node-version: '20' + + - name: Install validators + run: | + python3 -m pip install --user 'cyclonedx-bom==7.*' 'jsonschema==4.*' + echo "$HOME/.local/bin" >> "$GITHUB_PATH" + npm install --no-save --prefix tools/csaf-validate + + - name: Real overlay matches its JSON Schema + run: | + python3 - <<'PY' + import json, jsonschema + schema = json.load(open('central/advisory-vex-overlay.schema.json')) + overlay = json.load(open('advisories/vex-overlay.json')) + jsonschema.Draft202012Validator.check_schema(schema) + jsonschema.Draft202012Validator(schema).validate(overlay) + print('OK: advisories/vex-overlay.json matches schema') + PY + + - name: Generate 5.9.2 CSAF + CycloneDX VEX + run: | + set -e + REC="${RUNNER_TEMP}/rec592" + ADV="${RUNNER_TEMP}/adv592" + mkdir -p "$REC" "$ADV" + while read -r id; do + [ -n "$id" ] || continue + cp "advisories/records/${id}.json" "$REC/" + done < <(grep -E '^CVE-[0-9]{4}-[0-9]{4,}$' advisories/releases/5.9.2.cves) + python3 central/gen-advisory \ + --records-dir "$REC" \ + --vex-overlay advisories/vex-overlay.json \ + --out-dir "$ADV" + python3 central/gen-advisory \ + --records-dir "$REC" \ + --vex-overlay advisories/vex-overlay.json \ + --advisory-id wolfssl-5.9.2 \ + --csaf-out "$ADV/wolfssl-5.9.2.csaf.json" \ + --cdx-vex-out "$ADV/wolfssl-5.9.2.cdx.json" + echo "ADV=$ADV" >> "$GITHUB_ENV" + + - name: Bundle membership matches 5.9.2.cves + run: | + python3 - <<'PY' + import pathlib, os, sys + sys.path.insert(0, 'central') + # Load advisory-completeness as a module (no .py suffix). + import importlib.util + from importlib.machinery import SourceFileLoader + loader = SourceFileLoader('ac', 'central/advisory-completeness') + spec = importlib.util.spec_from_loader('ac', loader) + ac = importlib.util.module_from_spec(spec) + loader.exec_module(ac) + pin = ac.load_cve_list('advisories/releases/5.9.2.cves') + doc = __import__('json').loads( + pathlib.Path(os.environ['ADV'], 'wolfssl-5.9.2.csaf.json').read_text()) + got = [v['cve'] for v in doc['vulnerabilities']] + if set(got) != set(pin) or len(got) != len(pin): + print('pin', pin, file=sys.stderr) + print('got', got, file=sys.stderr) + sys.exit('ERROR: bundle CVE set does not match 5.9.2.cves') + print(f'OK: bundle has {len(got)} CVEs matching 5.9.2.cves') + PY + + - name: CSAF 2.0 strict schema + mandatory tests + run: node tools/csaf-validate/csaf_validate.mjs "${ADV}"/*.csaf.json + + - name: csaf_validate runner contract + run: node tools/csaf-validate/test_csaf_validate.mjs "${ADV}/CVE-2026-11310.csaf.json" + + - name: CycloneDX 1.6 strict schema + run: | + python3 - <<'PY' + import glob, os, sys + from cyclonedx.validation.json import JsonStrictValidator + from cyclonedx.schema import SchemaVersion + v = JsonStrictValidator(SchemaVersion.V1_6) + paths = sorted(glob.glob(os.environ['ADV'] + '/*.cdx.json')) + assert paths, 'no CycloneDX VEX documents were generated' + for p in paths: + errs = v.validate_str(open(p).read()) + if errs: + print(f'INVALID: {p}: {errs}', file=sys.stderr) + sys.exit(1) + print(f'OK: {p}') + PY + + - name: Unsigned publish tree (hashes + self URL) + run: | + python3 central/csaf-publish \ + --docs-dir "${ADV}" \ + --out-root "${RUNNER_TEMP}/publish592" + python3 - <<'PY' + import hashlib, json, os, pathlib, sys + root = pathlib.Path(os.environ['RUNNER_TEMP']) / 'publish592' / '.well-known' / 'csaf' + index = [ln for ln in (root / 'index.txt').read_text().splitlines() if ln] + docs = sorted(p for p in root.glob('*/*/*.json')) + if len(index) != len(docs): + sys.exit(f'ERROR: index has {len(index)} lines, disk has {len(docs)} json files') + for rel in index: + dest = root / rel + if not dest.is_file(): + sys.exit(f'ERROR: index path missing: {rel}') + doc = json.loads(dest.read_text()) + selfs = [r['url'] for r in doc['document']['references'] + if r.get('category') == 'self'] + want = 'https://www.wolfssl.com/.well-known/csaf/' + rel + if selfs != [want]: + sys.exit(f'ERROR: self URL {selfs!r} != {want!r}') + for algo in ('sha256', 'sha512'): + side = dest.with_name(dest.name + '.' + algo) + got = hashlib.new(algo, dest.read_bytes()).hexdigest() + if side.read_text().split()[0] != got: + sys.exit(f'ERROR: {algo} mismatch for {rel}') + print(f'OK: published {len(docs)} unsigned documents') + PY diff --git a/.github/workflows/selftest.yml b/.github/workflows/selftest.yml index 239428c..ba229dc 100644 --- a/.github/workflows/selftest.yml +++ b/.github/workflows/selftest.yml @@ -34,6 +34,12 @@ jobs: share/frontends/zephyr_sbom.py \ central/gen-advisory \ central/test_gen_advisory.py \ + central/advisory-completeness \ + central/test_advisory_completeness.py \ + central/csaf-publish \ + central/csaf-verify \ + central/csaf-keygen \ + central/test_csaf_publish.py \ provenance/bomsh_verify.py \ tools/wolfglass-sync \ tests/test_gen_sbom.py \ @@ -46,6 +52,9 @@ jobs: - name: Run advisory generator unit tests run: python -m unittest central/test_gen_advisory.py + - name: Run advisory completeness and publish unit tests + run: python -m unittest central/test_advisory_completeness.py central/test_csaf_publish.py + - name: Run SBOM identity tests run: python -m unittest tests/test_sbom_identity.py diff --git a/.gitignore b/.gitignore index 0839312..dd1b4d1 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,10 @@ *.spdx.json *.spdx +# Generated CSAF/VEX (rebuild in CI / with gen-advisory + csaf-publish) +advisories/out/ +advisories/publish/ + # Build provenance output omnibor/ *_raw_logfile* @@ -12,8 +16,14 @@ __pycache__/ *.py[cod] .pytest_cache/ .venv/ +.venv-poc/ venv/ +# CSAF PoC: throwaway signing key (never commit a secret key) + node deps +advisories/.poc-key/ +tools/csaf-validate/node_modules/ +tools/csaf-validate/package-lock.json + # Editor / OS .DS_Store *.swp diff --git a/advisories/records/CVE-2026-10097.json b/advisories/records/CVE-2026-10097.json new file mode 100644 index 0000000..c9bddae --- /dev/null +++ b/advisories/records/CVE-2026-10097.json @@ -0,0 +1,160 @@ +{ + "dataType": "CVE_RECORD", + "dataVersion": "5.2", + "cveMetadata": { + "cveId": "CVE-2026-10097", + "assignerOrgId": "50d2cd11-d01a-48ed-9441-5bfce9d63b27", + "state": "PUBLISHED", + "assignerShortName": "wolfSSL", + "dateReserved": "2026-05-29T15:01:16.331Z", + "datePublished": "2026-06-25T19:59:30.848Z", + "dateUpdated": "2026-06-26T16:35:41.759Z" + }, + "containers": { + "cna": { + "providerMetadata": { + "orgId": "50d2cd11-d01a-48ed-9441-5bfce9d63b27", + "shortName": "wolfSSL", + "dateUpdated": "2026-06-26T16:35:41.759Z" + }, + "title": "ML-KEM-1024 x64 AVX2 incomplete cipher text comparison enables IND-CCA2 break and static private-key recovery", + "problemTypes": [ + { + "descriptions": [ + { + "lang": "en", + "cweId": "CWE-697", + "description": "CWE-697 Incorrect Comparison", + "type": "CWE" + } + ] + } + ], + "affected": [ + { + "vendor": "wolfSSL", + "product": "wolfSSL", + "collectionURL": "https://github.com/wolfSSL/wolfssl", + "modules": [ + "ML-KEM (Kyber) AVX2 implementation" + ], + "versions": [ + { + "status": "affected", + "version": "5.7.0", + "lessThanOrEqual": "5.9.1", + "versionType": "semver" + } + ], + "defaultStatus": "unaffected" + } + ], + "descriptions": [ + { + "lang": "en", + "value": "wolfSSL's AVX2-optimized ML-KEM implementation (mlkem_cmp_avx2) compares only 1536 of the 1568 ciphertext bytes during the Fujisaki-Okamoto re-encryption check in ML-KEM-1024 decapsulation. Ciphertexts that differ from the expected re-encryption solely in bytes 1536-1567 bypass implicit rejection and are accepted as valid, breaking IND-CCA2 security. An attacker able to submit chosen ciphertexts to a decapsulation oracle that uses a static ML-KEM-1024 key, and to observe whether the genuine shared secret or the implicit-rejection secret was produced, can use this as a plaintext-checking oracle to recover the private key. A proof of concept recovered a full ML-KEM-1024 private key with approximately 98% success using roughly 350 chosen ciphertexts. The flaw is a deterministic logic error and does not rely on timing measurements.", + "supportingMedia": [ + { + "type": "text/html", + "base64": false, + "value": "

wolfSSL's AVX2-optimized ML-KEM implementation (mlkem_cmp_avx2) compares only 1536 of the 1568 ciphertext bytes during the Fujisaki-Okamoto re-encryption check in ML-KEM-1024 decapsulation. Ciphertexts that differ from the expected re-encryption solely in bytes 1536-1567 bypass implicit rejection and are accepted as valid, breaking IND-CCA2 security. An attacker able to submit chosen ciphertexts to a decapsulation oracle that uses a static ML-KEM-1024 key, and to observe whether the genuine shared secret or the implicit-rejection secret was produced, can use this as a plaintext-checking oracle to recover the private key. A proof of concept recovered a full ML-KEM-1024 private key with approximately 98% success using roughly 350 chosen ciphertexts. The flaw is a deterministic logic error and does not rely on timing measurements.

" + } + ] + } + ], + "references": [ + { + "url": "https://github.com/wolfSSL/wolfssl/pull/10430", + "tags": [ + "patch" + ] + }, + { + "url": "https://www.wolfssl.com/docs/security-vulnerabilities/" + } + ], + "metrics": [ + { + "format": "CVSS", + "scenarios": [ + { + "lang": "en", + "value": "GENERAL" + } + ], + "cvssV4_0": { + "attackVector": "NETWORK", + "attackComplexity": "HIGH", + "attackRequirements": "PRESENT", + "privilegesRequired": "NONE", + "userInteraction": "NONE", + "vulnConfidentialityImpact": "HIGH", + "subConfidentialityImpact": "NONE", + "vulnIntegrityImpact": "LOW", + "subIntegrityImpact": "NONE", + "vulnAvailabilityImpact": "NONE", + "subAvailabilityImpact": "NONE", + "exploitMaturity": "NOT_DEFINED", + "Safety": "NOT_DEFINED", + "Automatable": "NOT_DEFINED", + "Recovery": "NOT_DEFINED", + "valueDensity": "NOT_DEFINED", + "vulnerabilityResponseEffort": "NOT_DEFINED", + "providerUrgency": "NOT_DEFINED", + "version": "4.0", + "baseSeverity": "HIGH", + "baseScore": 8.3, + "vectorString": "CVSS:4.0/AV:N/AC:H/AT:P/PR:N/UI:N/VC:H/VI:L/VA:N/SC:N/SI:N/SA:N" + } + } + ], + "credits": [ + { + "lang": "en", + "value": "007bsd (https://github.com/007bsd)", + "type": "finder" + } + ], + "source": { + "discovery": "UNKNOWN" + }, + "x_generator": { + "engine": "Vulnogram 1.0.2" + } + }, + "adp": [ + { + "metrics": [ + { + "other": { + "type": "ssvc", + "content": { + "timestamp": "2026-06-26T13:51:27.508789Z", + "id": "CVE-2026-10097", + "options": [ + { + "Exploitation": "none" + }, + { + "Automatable": "no" + }, + { + "Technical Impact": "partial" + } + ], + "role": "CISA Coordinator", + "version": "2.0.3" + } + } + } + ], + "title": "CISA ADP Vulnrichment", + "providerMetadata": { + "orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0", + "shortName": "CISA-ADP", + "dateUpdated": "2026-06-26T13:51:46.307Z" + } + } + ] + } +} diff --git a/advisories/records/CVE-2026-10098.json b/advisories/records/CVE-2026-10098.json new file mode 100644 index 0000000..4840720 --- /dev/null +++ b/advisories/records/CVE-2026-10098.json @@ -0,0 +1,157 @@ +{ + "dataType": "CVE_RECORD", + "dataVersion": "5.2", + "cveMetadata": { + "cveId": "CVE-2026-10098", + "assignerOrgId": "50d2cd11-d01a-48ed-9441-5bfce9d63b27", + "state": "PUBLISHED", + "assignerShortName": "wolfSSL", + "dateReserved": "2026-05-29T15:03:08.877Z", + "datePublished": "2026-06-25T21:16:45.850Z", + "dateUpdated": "2026-06-26T10:34:15.421Z" + }, + "containers": { + "cna": { + "providerMetadata": { + "orgId": "50d2cd11-d01a-48ed-9441-5bfce9d63b27", + "shortName": "wolfSSL", + "dateUpdated": "2026-06-25T21:16:45.850Z" + }, + "title": "OCSP CertID serial-number length-confusion in wolfSSL_OCSP_resp_find_status", + "problemTypes": [ + { + "descriptions": [ + { + "lang": "en", + "cweId": "CWE-295", + "description": "CWE-295 Improper Certificate Validation", + "type": "CWE" + } + ] + } + ], + "affected": [ + { + "vendor": "wolfSSL", + "product": "wolfSSL", + "collectionURL": "https://github.com/wolfSSL/wolfssl", + "versions": [ + { + "status": "affected", + "version": "4.6.0", + "lessThanOrEqual": "5.9.1", + "versionType": "semver" + } + ], + "defaultStatus": "unaffected" + } + ], + "descriptions": [ + { + "lang": "en", + "value": "OCSP CertID serial-number length-confusion in wolfSSL_OCSP_resp_find_status allows a same-issuer SingleResponse whose serial is a prefix of the target serial to be reported as the revocation status of a different certificate. The lookup compared serial-number bytes without first requiring the two serial numbers to be of equal length, so a SingleResponse for one certificate (same issuer) whose serial is a prefix of the target's serial would match, returning the wrong certificate's status. The fix requires the serial lengths to be equal before comparing the serial bytes.", + "supportingMedia": [ + { + "type": "text/html", + "base64": false, + "value": "

OCSP CertID serial-number length-confusion in wolfSSL_OCSP_resp_find_status allows a same-issuer SingleResponse whose serial is a prefix of the target serial to be reported as the revocation status of a different certificate. The lookup compared serial-number bytes without first requiring the two serial numbers to be of equal length, so a SingleResponse for one certificate (same issuer) whose serial is a prefix of the target's serial would match, returning the wrong certificate's status. The fix requires the serial lengths to be equal before comparing the serial bytes.

" + } + ] + } + ], + "references": [ + { + "url": "https://github.com/wolfSSL/wolfssl/pull/10554", + "tags": [ + "patch" + ] + }, + { + "url": "https://www.wolfssl.com/docs/security-vulnerabilities/" + } + ], + "metrics": [ + { + "format": "CVSS", + "scenarios": [ + { + "lang": "en", + "value": "GENERAL" + } + ], + "cvssV4_0": { + "attackVector": "NETWORK", + "attackComplexity": "LOW", + "attackRequirements": "PRESENT", + "privilegesRequired": "NONE", + "userInteraction": "NONE", + "vulnConfidentialityImpact": "NONE", + "subConfidentialityImpact": "NONE", + "vulnIntegrityImpact": "LOW", + "subIntegrityImpact": "NONE", + "vulnAvailabilityImpact": "NONE", + "subAvailabilityImpact": "NONE", + "exploitMaturity": "NOT_DEFINED", + "Safety": "NOT_DEFINED", + "Automatable": "NOT_DEFINED", + "Recovery": "NOT_DEFINED", + "valueDensity": "NOT_DEFINED", + "vulnerabilityResponseEffort": "NOT_DEFINED", + "providerUrgency": "NOT_DEFINED", + "version": "4.0", + "baseSeverity": "MEDIUM", + "baseScore": 6.3, + "vectorString": "CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:L/VA:N/SC:N/SI:N/SA:N" + } + } + ], + "credits": [ + { + "lang": "en", + "value": "Kim Youngjoon (Team-Atlanta and Georgia Institute of Technology)", + "type": "finder" + } + ], + "source": { + "discovery": "UNKNOWN" + }, + "x_generator": { + "engine": "Vulnogram 1.0.2" + } + }, + "adp": [ + { + "metrics": [ + { + "other": { + "type": "ssvc", + "content": { + "timestamp": "2026-06-26T10:33:57.969052Z", + "id": "CVE-2026-10098", + "options": [ + { + "Exploitation": "none" + }, + { + "Automatable": "no" + }, + { + "Technical Impact": "partial" + } + ], + "role": "CISA Coordinator", + "version": "2.0.3" + } + } + } + ], + "title": "CISA ADP Vulnrichment", + "providerMetadata": { + "orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0", + "shortName": "CISA-ADP", + "dateUpdated": "2026-06-26T10:34:15.421Z" + } + } + ] + } +} diff --git a/advisories/records/CVE-2026-10512.json b/advisories/records/CVE-2026-10512.json new file mode 100644 index 0000000..dea990a --- /dev/null +++ b/advisories/records/CVE-2026-10512.json @@ -0,0 +1,157 @@ +{ + "dataType": "CVE_RECORD", + "dataVersion": "5.2", + "cveMetadata": { + "cveId": "CVE-2026-10512", + "assignerOrgId": "50d2cd11-d01a-48ed-9441-5bfce9d63b27", + "state": "PUBLISHED", + "assignerShortName": "wolfSSL", + "dateReserved": "2026-06-01T04:32:49.584Z", + "datePublished": "2026-06-25T19:58:16.013Z", + "dateUpdated": "2026-06-26T13:49:49.898Z" + }, + "containers": { + "cna": { + "providerMetadata": { + "orgId": "50d2cd11-d01a-48ed-9441-5bfce9d63b27", + "shortName": "wolfSSL", + "dateUpdated": "2026-06-25T19:58:16.013Z" + }, + "title": "X25519 x86_64 assembly final reduction leaves non-canonical field element", + "problemTypes": [ + { + "descriptions": [ + { + "lang": "en", + "cweId": "CWE-682", + "description": "CWE-682 Incorrect Calculation", + "type": "CWE" + } + ] + } + ], + "affected": [ + { + "vendor": "wolfSSL", + "product": "wolfSSL", + "collectionURL": "https://github.com/wolfSSL/wolfssl", + "versions": [ + { + "status": "affected", + "version": "5.6.4", + "lessThanOrEqual": "5.9.1", + "versionType": "semver" + } + ], + "defaultStatus": "unaffected" + } + ], + "descriptions": [ + { + "lang": "en", + "value": "The X25519 x86_64 assembly implementation fails to clear the most significant bit during the final modular reduction, so the computed result may not be fully reduced modulo the field prime 2^255 - 19. This can leave the field element in a non-canonical form, producing an incorrect result from the scalar multiplication and potentially a wrong shared secret. The final carry-propagation chains in the x64 and AVX2 reduction routines could overflow into the top bit, and the high limb was not masked afterward, so the 255-bit field element was left non-canonical.", + "supportingMedia": [ + { + "type": "text/html", + "base64": false, + "value": "

The X25519 x86_64 assembly implementation fails to clear the most significant bit during the final modular reduction, so the computed result may not be fully reduced modulo the field prime 2^255 - 19. This can leave the field element in a non-canonical form, producing an incorrect result from the scalar multiplication and potentially a wrong shared secret. The final carry-propagation chains in the x64 and AVX2 reduction routines could overflow into the top bit, and the high limb was not masked afterward, so the 255-bit field element was left non-canonical.

" + } + ] + } + ], + "references": [ + { + "url": "https://github.com/wolfSSL/wolfssl/pull/10536", + "tags": [ + "patch" + ] + }, + { + "url": "https://www.wolfssl.com/docs/security-vulnerabilities/" + } + ], + "metrics": [ + { + "format": "CVSS", + "scenarios": [ + { + "lang": "en", + "value": "GENERAL" + } + ], + "cvssV4_0": { + "attackVector": "NETWORK", + "attackComplexity": "HIGH", + "attackRequirements": "PRESENT", + "privilegesRequired": "LOW", + "userInteraction": "NONE", + "vulnConfidentialityImpact": "NONE", + "subConfidentialityImpact": "NONE", + "vulnIntegrityImpact": "NONE", + "subIntegrityImpact": "NONE", + "vulnAvailabilityImpact": "LOW", + "subAvailabilityImpact": "NONE", + "exploitMaturity": "NOT_DEFINED", + "Safety": "NOT_DEFINED", + "Automatable": "NOT_DEFINED", + "Recovery": "NOT_DEFINED", + "valueDensity": "NOT_DEFINED", + "vulnerabilityResponseEffort": "NOT_DEFINED", + "providerUrgency": "NOT_DEFINED", + "version": "4.0", + "baseSeverity": "LOW", + "baseScore": 2.3, + "vectorString": "CVSS:4.0/AV:N/AC:H/AT:P/PR:L/UI:N/VC:N/VI:N/VA:L/SC:N/SI:N/SA:N" + } + } + ], + "credits": [ + { + "lang": "en", + "value": "Haruki Oyama", + "type": "finder" + } + ], + "source": { + "discovery": "UNKNOWN" + }, + "x_generator": { + "engine": "Vulnogram 1.0.2" + } + }, + "adp": [ + { + "metrics": [ + { + "other": { + "type": "ssvc", + "content": { + "timestamp": "2026-06-26T13:49:37.963089Z", + "id": "CVE-2026-10512", + "options": [ + { + "Exploitation": "none" + }, + { + "Automatable": "no" + }, + { + "Technical Impact": "partial" + } + ], + "role": "CISA Coordinator", + "version": "2.0.3" + } + } + } + ], + "title": "CISA ADP Vulnrichment", + "providerMetadata": { + "orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0", + "shortName": "CISA-ADP", + "dateUpdated": "2026-06-26T13:49:49.898Z" + } + } + ] + } +} diff --git a/advisories/records/CVE-2026-10592.json b/advisories/records/CVE-2026-10592.json new file mode 100644 index 0000000..9321df0 --- /dev/null +++ b/advisories/records/CVE-2026-10592.json @@ -0,0 +1,157 @@ +{ + "dataType": "CVE_RECORD", + "dataVersion": "5.2", + "cveMetadata": { + "cveId": "CVE-2026-10592", + "assignerOrgId": "50d2cd11-d01a-48ed-9441-5bfce9d63b27", + "state": "PUBLISHED", + "assignerShortName": "wolfSSL", + "dateReserved": "2026-06-01T21:10:33.519Z", + "datePublished": "2026-06-25T19:40:11.966Z", + "dateUpdated": "2026-06-26T14:03:28.814Z" + }, + "containers": { + "cna": { + "providerMetadata": { + "orgId": "50d2cd11-d01a-48ed-9441-5bfce9d63b27", + "shortName": "wolfSSL", + "dateUpdated": "2026-06-25T19:40:11.966Z" + }, + "title": "Wildcard DNS SAN bypasses CA name-constraint checks", + "problemTypes": [ + { + "descriptions": [ + { + "lang": "en", + "cweId": "CWE-295", + "description": "CWE-295 Improper Certificate Validation", + "type": "CWE" + } + ] + } + ], + "affected": [ + { + "vendor": "wolfSSL", + "product": "wolfSSL", + "collectionURL": "https://github.com/wolfSSL/wolfssl", + "versions": [ + { + "status": "affected", + "version": "3.9.10", + "lessThanOrEqual": "5.9.1", + "versionType": "semver" + } + ], + "defaultStatus": "unaffected" + } + ], + "descriptions": [ + { + "lang": "en", + "value": "Certificates with wildcard DNS SANs (e.g. *.example.com) bypassed CA name-constraint checks. A certificate with a wildcard DNS SAN that should be rejected by the issuing CA's permitted/excluded DNS name constraints could be accepted.", + "supportingMedia": [ + { + "type": "text/html", + "base64": false, + "value": "

Certificates with wildcard DNS SANs (e.g. *.example.com) bypassed CA name-constraint checks. A certificate with a wildcard DNS SAN that should be rejected by the issuing CA's permitted/excluded DNS name constraints could be accepted.

" + } + ] + } + ], + "references": [ + { + "url": "https://github.com/wolfSSL/wolfssl/pull/10549", + "tags": [ + "patch" + ] + }, + { + "url": "https://www.wolfssl.com/docs/security-vulnerabilities/" + } + ], + "metrics": [ + { + "format": "CVSS", + "scenarios": [ + { + "lang": "en", + "value": "GENERAL" + } + ], + "cvssV4_0": { + "attackVector": "NETWORK", + "attackComplexity": "LOW", + "attackRequirements": "PRESENT", + "privilegesRequired": "NONE", + "userInteraction": "NONE", + "vulnConfidentialityImpact": "NONE", + "subConfidentialityImpact": "NONE", + "vulnIntegrityImpact": "LOW", + "subIntegrityImpact": "NONE", + "vulnAvailabilityImpact": "NONE", + "subAvailabilityImpact": "NONE", + "exploitMaturity": "NOT_DEFINED", + "Safety": "NOT_DEFINED", + "Automatable": "NOT_DEFINED", + "Recovery": "NOT_DEFINED", + "valueDensity": "NOT_DEFINED", + "vulnerabilityResponseEffort": "NOT_DEFINED", + "providerUrgency": "NOT_DEFINED", + "version": "4.0", + "baseSeverity": "MEDIUM", + "baseScore": 6.3, + "vectorString": "CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:L/VA:N/SC:N/SI:N/SA:N" + } + } + ], + "credits": [ + { + "lang": "en", + "value": "tonghuaroot", + "type": "finder" + } + ], + "source": { + "discovery": "UNKNOWN" + }, + "x_generator": { + "engine": "Vulnogram 1.0.2" + } + }, + "adp": [ + { + "metrics": [ + { + "other": { + "type": "ssvc", + "content": { + "timestamp": "2026-06-26T14:03:09.936384Z", + "id": "CVE-2026-10592", + "options": [ + { + "Exploitation": "none" + }, + { + "Automatable": "no" + }, + { + "Technical Impact": "partial" + } + ], + "role": "CISA Coordinator", + "version": "2.0.3" + } + } + } + ], + "title": "CISA ADP Vulnrichment", + "providerMetadata": { + "orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0", + "shortName": "CISA-ADP", + "dateUpdated": "2026-06-26T14:03:28.814Z" + } + } + ] + } +} diff --git a/advisories/records/CVE-2026-11310.json b/advisories/records/CVE-2026-11310.json new file mode 100644 index 0000000..a4cd324 --- /dev/null +++ b/advisories/records/CVE-2026-11310.json @@ -0,0 +1,157 @@ +{ + "dataType": "CVE_RECORD", + "dataVersion": "5.2", + "cveMetadata": { + "cveId": "CVE-2026-11310", + "assignerOrgId": "50d2cd11-d01a-48ed-9441-5bfce9d63b27", + "state": "PUBLISHED", + "assignerShortName": "wolfSSL", + "dateReserved": "2026-06-04T17:58:49.009Z", + "datePublished": "2026-06-25T19:38:19.099Z", + "dateUpdated": "2026-06-26T14:02:37.876Z" + }, + "containers": { + "cna": { + "providerMetadata": { + "orgId": "50d2cd11-d01a-48ed-9441-5bfce9d63b27", + "shortName": "wolfSSL", + "dateUpdated": "2026-06-25T19:38:19.099Z" + }, + "title": "X.509 trust-chain bypass in wolfSSL_X509_verify_cert() via untrusted intermediate anchoring", + "problemTypes": [ + { + "descriptions": [ + { + "lang": "en", + "cweId": "CWE-295", + "description": "CWE-295 Improper Certificate Validation", + "type": "CWE" + } + ] + } + ], + "affected": [ + { + "vendor": "wolfSSL", + "product": "wolfSSL", + "collectionURL": "https://github.com/wolfSSL/wolfssl", + "versions": [ + { + "status": "affected", + "version": "5.8.4", + "lessThanOrEqual": "5.9.1", + "versionType": "semver" + } + ], + "defaultStatus": "unaffected" + } + ], + "descriptions": [ + { + "lang": "en", + "value": "X.509 trust-chain bypass in the OpenSSL compatibility certificate verifier (wolfSSL_X509_verify_cert()). This affects only builds with --enable-opensslextra (OPENSSL_EXTRA) and whose application validates certificates by calling X509_verify_cert() with caller-supplied untrusted intermediate certificates; for those users it is critical, otherwise the library is unaffected. In particular, native wolfSSL TLS/DTLS usage is not impacted. wolfSSL's X509_verify_cert() temporarily loads each caller-supplied untrusted intermediate into the certificate manager but failed to drop them before the trusted-store check, so an untrusted intermediate could anchor the path itself. An attacker can present a chain that never reaches a configured trust anchor and have it accepted, resulting in acceptance of an attacker-controlled certificate. This is certificate verification independent of TLS (e.g. S/MIME/CMS, code/firmware signing, JWT/JWS x5c), is not specific to any key type or algorithm, and a single untrusted intermediate suffices. The default wolfSSL TLS handshake (WOLFSSL_VERIFY_PEER) is not affected; only TLS applications doing manual or deferred peer verification through this API are, which also requires --enable-sessioncerts.", + "supportingMedia": [ + { + "type": "text/html", + "base64": false, + "value": "

X.509 trust-chain bypass in the OpenSSL compatibility certificate verifier (wolfSSL_X509_verify_cert()). This affects only builds with --enable-opensslextra (OPENSSL_EXTRA) and whose application validates certificates by calling X509_verify_cert() with caller-supplied untrusted intermediate certificates; for those users it is critical, otherwise the library is unaffected. In particular, native wolfSSL TLS/DTLS usage is not impacted. wolfSSL's X509_verify_cert() temporarily loads each caller-supplied untrusted intermediate into the certificate manager but failed to drop them before the trusted-store check, so an untrusted intermediate could anchor the path itself. An attacker can present a chain that never reaches a configured trust anchor and have it accepted, resulting in acceptance of an attacker-controlled certificate. This is certificate verification independent of TLS (e.g. S/MIME/CMS, code/firmware signing, JWT/JWS x5c), is not specific to any key type or algorithm, and a single untrusted intermediate suffices. The default wolfSSL TLS handshake (WOLFSSL_VERIFY_PEER) is not affected; only TLS applications doing manual or deferred peer verification through this API are, which also requires --enable-sessioncerts.

" + } + ] + } + ], + "references": [ + { + "url": "https://github.com/wolfSSL/wolfssl/pull/10674", + "tags": [ + "patch" + ] + }, + { + "url": "https://www.wolfssl.com/docs/security-vulnerabilities/" + } + ], + "metrics": [ + { + "format": "CVSS", + "scenarios": [ + { + "lang": "en", + "value": "GENERAL" + } + ], + "cvssV4_0": { + "attackVector": "NETWORK", + "attackComplexity": "LOW", + "attackRequirements": "NONE", + "privilegesRequired": "NONE", + "userInteraction": "NONE", + "vulnConfidentialityImpact": "NONE", + "subConfidentialityImpact": "NONE", + "vulnIntegrityImpact": "HIGH", + "subIntegrityImpact": "NONE", + "vulnAvailabilityImpact": "NONE", + "subAvailabilityImpact": "NONE", + "exploitMaturity": "NOT_DEFINED", + "Safety": "NOT_DEFINED", + "Automatable": "NOT_DEFINED", + "Recovery": "NOT_DEFINED", + "valueDensity": "NOT_DEFINED", + "vulnerabilityResponseEffort": "NOT_DEFINED", + "providerUrgency": "NOT_DEFINED", + "version": "4.0", + "baseSeverity": "HIGH", + "baseScore": 8.7, + "vectorString": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:H/VA:N/SC:N/SI:N/SA:N" + } + } + ], + "credits": [ + { + "lang": "en", + "value": "Corban Villa, Sohee Kim and Austin Chu (UC Berkeley, Sky Lab)", + "type": "finder" + } + ], + "source": { + "discovery": "UNKNOWN" + }, + "x_generator": { + "engine": "Vulnogram 1.0.2" + } + }, + "adp": [ + { + "metrics": [ + { + "other": { + "type": "ssvc", + "content": { + "timestamp": "2026-06-26T14:02:17.745614Z", + "id": "CVE-2026-11310", + "options": [ + { + "Exploitation": "none" + }, + { + "Automatable": "yes" + }, + { + "Technical Impact": "partial" + } + ], + "role": "CISA Coordinator", + "version": "2.0.3" + } + } + } + ], + "title": "CISA ADP Vulnrichment", + "providerMetadata": { + "orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0", + "shortName": "CISA-ADP", + "dateUpdated": "2026-06-26T14:02:37.876Z" + } + } + ] + } +} diff --git a/advisories/records/CVE-2026-11703.json b/advisories/records/CVE-2026-11703.json new file mode 100644 index 0000000..2686223 --- /dev/null +++ b/advisories/records/CVE-2026-11703.json @@ -0,0 +1,157 @@ +{ + "dataType": "CVE_RECORD", + "dataVersion": "5.2", + "cveMetadata": { + "cveId": "CVE-2026-11703", + "assignerOrgId": "50d2cd11-d01a-48ed-9441-5bfce9d63b27", + "state": "PUBLISHED", + "assignerShortName": "wolfSSL", + "dateReserved": "2026-06-08T22:32:48.399Z", + "datePublished": "2026-06-25T21:15:20.576Z", + "dateUpdated": "2026-06-26T10:32:05.866Z" + }, + "containers": { + "cna": { + "providerMetadata": { + "orgId": "50d2cd11-d01a-48ed-9441-5bfce9d63b27", + "shortName": "wolfSSL", + "dateUpdated": "2026-06-25T21:15:20.576Z" + }, + "title": "Missing SNI/ALPN binding on stateful (session-ID) TLS session resumption", + "problemTypes": [ + { + "descriptions": [ + { + "lang": "en", + "cweId": "CWE-287", + "description": "CWE-287 Improper Authentication", + "type": "CWE" + } + ] + } + ], + "affected": [ + { + "vendor": "wolfSSL", + "product": "wolfSSL", + "collectionURL": "https://github.com/wolfSSL/wolfssl", + "versions": [ + { + "status": "affected", + "version": "3.15.0", + "lessThanOrEqual": "5.9.1", + "versionType": "semver" + } + ], + "defaultStatus": "unaffected" + } + ], + "descriptions": [ + { + "lang": "en", + "value": "Missing SNI/ALPN binding on stateful (session-ID) resumption, which previously skipped the binding check performed for ticket-based resumption. A cached session could be resumed under a different SNI/ALPN than originally negotiated and, where client-authentication policy differs across virtual hosts, carry the cached peer-authentication state into a context it was not established for. Resumption now verifies the SNI/ALPN binding for all paths and declines (falling back to a full handshake) on mismatch.", + "supportingMedia": [ + { + "type": "text/html", + "base64": false, + "value": "

Missing SNI/ALPN binding on stateful (session-ID) resumption, which previously skipped the binding check performed for ticket-based resumption. A cached session could be resumed under a different SNI/ALPN than originally negotiated and, where client-authentication policy differs across virtual hosts, carry the cached peer-authentication state into a context it was not established for. Resumption now verifies the SNI/ALPN binding for all paths and declines (falling back to a full handshake) on mismatch.

" + } + ] + } + ], + "references": [ + { + "url": "https://github.com/wolfSSL/wolfssl/pull/10489", + "tags": [ + "patch" + ] + }, + { + "url": "https://www.wolfssl.com/docs/security-vulnerabilities/" + } + ], + "metrics": [ + { + "format": "CVSS", + "scenarios": [ + { + "lang": "en", + "value": "GENERAL" + } + ], + "cvssV4_0": { + "attackVector": "NETWORK", + "attackComplexity": "HIGH", + "attackRequirements": "PRESENT", + "privilegesRequired": "LOW", + "userInteraction": "NONE", + "vulnConfidentialityImpact": "NONE", + "subConfidentialityImpact": "NONE", + "vulnIntegrityImpact": "HIGH", + "subIntegrityImpact": "NONE", + "vulnAvailabilityImpact": "NONE", + "subAvailabilityImpact": "NONE", + "exploitMaturity": "NOT_DEFINED", + "Safety": "NOT_DEFINED", + "Automatable": "NOT_DEFINED", + "Recovery": "NOT_DEFINED", + "valueDensity": "NOT_DEFINED", + "vulnerabilityResponseEffort": "NOT_DEFINED", + "providerUrgency": "NOT_DEFINED", + "version": "4.0", + "baseSeverity": "MEDIUM", + "baseScore": 6, + "vectorString": "CVSS:4.0/AV:N/AC:H/AT:P/PR:L/UI:N/VC:N/VI:H/VA:N/SC:N/SI:N/SA:N" + } + } + ], + "credits": [ + { + "lang": "en", + "value": "Dikai Zou", + "type": "finder" + } + ], + "source": { + "discovery": "UNKNOWN" + }, + "x_generator": { + "engine": "Vulnogram 1.0.2" + } + }, + "adp": [ + { + "metrics": [ + { + "other": { + "type": "ssvc", + "content": { + "timestamp": "2026-06-26T10:31:36.908156Z", + "id": "CVE-2026-11703", + "options": [ + { + "Exploitation": "none" + }, + { + "Automatable": "no" + }, + { + "Technical Impact": "partial" + } + ], + "role": "CISA Coordinator", + "version": "2.0.3" + } + } + } + ], + "title": "CISA ADP Vulnrichment", + "providerMetadata": { + "orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0", + "shortName": "CISA-ADP", + "dateUpdated": "2026-06-26T10:32:05.866Z" + } + } + ] + } +} diff --git a/advisories/records/CVE-2026-11999.json b/advisories/records/CVE-2026-11999.json new file mode 100644 index 0000000..e0760fd --- /dev/null +++ b/advisories/records/CVE-2026-11999.json @@ -0,0 +1,157 @@ +{ + "dataType": "CVE_RECORD", + "dataVersion": "5.2", + "cveMetadata": { + "cveId": "CVE-2026-11999", + "assignerOrgId": "50d2cd11-d01a-48ed-9441-5bfce9d63b27", + "state": "PUBLISHED", + "assignerShortName": "wolfSSL", + "dateReserved": "2026-06-11T16:14:10.451Z", + "datePublished": "2026-06-25T16:56:14.163Z", + "dateUpdated": "2026-06-25T17:56:41.168Z" + }, + "containers": { + "cna": { + "providerMetadata": { + "orgId": "50d2cd11-d01a-48ed-9441-5bfce9d63b27", + "shortName": "wolfSSL", + "dateUpdated": "2026-06-25T16:56:14.163Z" + }, + "title": "X.509 trust-chain bypass via path-depth exhaustion in wolfSSL_X509_verify_cert()", + "problemTypes": [ + { + "descriptions": [ + { + "lang": "en", + "cweId": "CWE-295", + "description": "CWE-295 Improper Certificate Validation", + "type": "CWE" + } + ] + } + ], + "affected": [ + { + "vendor": "wolfSSL", + "product": "wolfSSL", + "collectionURL": "https://github.com/wolfSSL/wolfssl", + "versions": [ + { + "status": "affected", + "version": "5.7.4", + "lessThanOrEqual": "5.9.1", + "versionType": "semver" + } + ], + "defaultStatus": "unaffected" + } + ], + "descriptions": [ + { + "lang": "en", + "value": "X.509 trust-chain bypass (path-depth exhaustion) in the OpenSSL compatibility certificate verifier (wolfSSL_X509_verify_cert()). This affects only builds with --enable-opensslextra whose application calls X509_verify_cert() with caller-supplied untrusted intermediates; for those users it is critical, otherwise the library is unaffected. Native wolfSSL TLS/DTLS usage is not impacted. X509_verify_cert() returned success based only on the last verified link rather than on reaching a trust anchor: when the supplied chain is deeper than the verifier's maximum path depth (default 100), path building runs out of depth while still walking untrusted intermediates and the chain is accepted even though it never reaches a configured trust anchor, allowing acceptance of an attacker-controlled certificate. The default TLS handshake (WOLFSSL_VERIFY_PEER) is not affected; only applications doing manual or deferred verification through this API are.", + "supportingMedia": [ + { + "type": "text/html", + "base64": false, + "value": "

X.509 trust-chain bypass (path-depth exhaustion) in the OpenSSL compatibility certificate verifier (wolfSSL_X509_verify_cert()). This affects only builds with --enable-opensslextra whose application calls X509_verify_cert() with caller-supplied untrusted intermediates; for those users it is critical, otherwise the library is unaffected. Native wolfSSL TLS/DTLS usage is not impacted. X509_verify_cert() returned success based only on the last verified link rather than on reaching a trust anchor: when the supplied chain is deeper than the verifier's maximum path depth (default 100), path building runs out of depth while still walking untrusted intermediates and the chain is accepted even though it never reaches a configured trust anchor, allowing acceptance of an attacker-controlled certificate. The default TLS handshake (WOLFSSL_VERIFY_PEER) is not affected; only applications doing manual or deferred verification through this API are.

" + } + ] + } + ], + "references": [ + { + "url": "https://github.com/wolfSSL/wolfssl/pull/10674", + "tags": [ + "patch" + ] + }, + { + "url": "https://www.wolfssl.com/docs/security-vulnerabilities/" + } + ], + "metrics": [ + { + "format": "CVSS", + "scenarios": [ + { + "lang": "en", + "value": "GENERAL" + } + ], + "cvssV4_0": { + "attackVector": "NETWORK", + "attackComplexity": "LOW", + "attackRequirements": "PRESENT", + "privilegesRequired": "NONE", + "userInteraction": "NONE", + "vulnConfidentialityImpact": "NONE", + "subConfidentialityImpact": "NONE", + "vulnIntegrityImpact": "HIGH", + "subIntegrityImpact": "NONE", + "vulnAvailabilityImpact": "NONE", + "subAvailabilityImpact": "NONE", + "exploitMaturity": "NOT_DEFINED", + "Safety": "NOT_DEFINED", + "Automatable": "NOT_DEFINED", + "Recovery": "NOT_DEFINED", + "valueDensity": "NOT_DEFINED", + "vulnerabilityResponseEffort": "NOT_DEFINED", + "providerUrgency": "NOT_DEFINED", + "version": "4.0", + "baseSeverity": "HIGH", + "baseScore": 8.2, + "vectorString": "CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:H/VA:N/SC:N/SI:N/SA:N" + } + } + ], + "credits": [ + { + "lang": "en", + "value": "Corban Villa, Sohee Kim and Austin Chu (UC Berkeley, Sky Lab)", + "type": "finder" + } + ], + "source": { + "discovery": "UNKNOWN" + }, + "x_generator": { + "engine": "Vulnogram 1.0.2" + } + }, + "adp": [ + { + "metrics": [ + { + "other": { + "type": "ssvc", + "content": { + "timestamp": "2026-06-25T17:56:35.192208Z", + "id": "CVE-2026-11999", + "options": [ + { + "Exploitation": "none" + }, + { + "Automatable": "no" + }, + { + "Technical Impact": "partial" + } + ], + "role": "CISA Coordinator", + "version": "2.0.3" + } + } + } + ], + "title": "CISA ADP Vulnrichment", + "providerMetadata": { + "orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0", + "shortName": "CISA-ADP", + "dateUpdated": "2026-06-25T17:56:41.168Z" + } + } + ] + } +} diff --git a/advisories/records/CVE-2026-12340.json b/advisories/records/CVE-2026-12340.json new file mode 100644 index 0000000..8c82ffe --- /dev/null +++ b/advisories/records/CVE-2026-12340.json @@ -0,0 +1,157 @@ +{ + "dataType": "CVE_RECORD", + "dataVersion": "5.2", + "cveMetadata": { + "cveId": "CVE-2026-12340", + "assignerOrgId": "50d2cd11-d01a-48ed-9441-5bfce9d63b27", + "state": "PUBLISHED", + "assignerShortName": "wolfSSL", + "dateReserved": "2026-06-15T16:30:26.001Z", + "datePublished": "2026-06-25T19:36:21.468Z", + "dateUpdated": "2026-06-26T13:59:21.953Z" + }, + "containers": { + "cna": { + "providerMetadata": { + "orgId": "50d2cd11-d01a-48ed-9441-5bfce9d63b27", + "shortName": "wolfSSL", + "dateUpdated": "2026-06-25T19:36:21.468Z" + }, + "title": "Out-of-bounds heap read in SM2/SM3 certificate Subject Key Identifier computation", + "problemTypes": [ + { + "descriptions": [ + { + "lang": "en", + "cweId": "CWE-125", + "description": "CWE-125 Out-of-bounds Read", + "type": "CWE" + } + ] + } + ], + "affected": [ + { + "vendor": "wolfSSL", + "product": "wolfSSL", + "collectionURL": "https://github.com/wolfSSL/wolfssl", + "versions": [ + { + "status": "affected", + "version": "5.6.4", + "lessThanOrEqual": "5.9.1", + "versionType": "semver" + } + ], + "defaultStatus": "unaffected" + } + ], + "descriptions": [ + { + "lang": "en", + "value": "Out-of-bounds heap read during SM2/SM3 certificate signature verification. When parsing a certificate with an SM3wSM2 signature, the Subject Key Identifier computation reads the trailing 65 bytes of the public key without checking that the key is at least that long. A public key shorter than 65 bytes results in an out-of-bounds heap read, leading to a potential crash (denial of service); there is no out-of-bounds write. Note this only affects builds with SM2 support (--enable-sm2 or --enable-all).", + "supportingMedia": [ + { + "type": "text/html", + "base64": false, + "value": "

Out-of-bounds heap read during SM2/SM3 certificate signature verification. When parsing a certificate with an SM3wSM2 signature, the Subject Key Identifier computation reads the trailing 65 bytes of the public key without checking that the key is at least that long. A public key shorter than 65 bytes results in an out-of-bounds heap read, leading to a potential crash (denial of service); there is no out-of-bounds write. Note this only affects builds with SM2 support (--enable-sm2 or --enable-all).

" + } + ] + } + ], + "references": [ + { + "url": "https://github.com/wolfSSL/wolfssl/pull/10641", + "tags": [ + "patch" + ] + }, + { + "url": "https://www.wolfssl.com/docs/security-vulnerabilities/" + } + ], + "metrics": [ + { + "format": "CVSS", + "scenarios": [ + { + "lang": "en", + "value": "GENERAL" + } + ], + "cvssV4_0": { + "attackVector": "NETWORK", + "attackComplexity": "LOW", + "attackRequirements": "PRESENT", + "privilegesRequired": "NONE", + "userInteraction": "NONE", + "vulnConfidentialityImpact": "NONE", + "subConfidentialityImpact": "NONE", + "vulnIntegrityImpact": "NONE", + "subIntegrityImpact": "NONE", + "vulnAvailabilityImpact": "LOW", + "subAvailabilityImpact": "NONE", + "exploitMaturity": "NOT_DEFINED", + "Safety": "NOT_DEFINED", + "Automatable": "NOT_DEFINED", + "Recovery": "NOT_DEFINED", + "valueDensity": "NOT_DEFINED", + "vulnerabilityResponseEffort": "NOT_DEFINED", + "providerUrgency": "NOT_DEFINED", + "version": "4.0", + "baseSeverity": "MEDIUM", + "baseScore": 6.3, + "vectorString": "CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:N/VA:L/SC:N/SI:N/SA:N" + } + } + ], + "credits": [ + { + "lang": "en", + "value": "David Pokora, Trail of Bits (in collaboration with Anthropic)", + "type": "finder" + } + ], + "source": { + "discovery": "UNKNOWN" + }, + "x_generator": { + "engine": "Vulnogram 1.0.2" + } + }, + "adp": [ + { + "metrics": [ + { + "other": { + "type": "ssvc", + "content": { + "timestamp": "2026-06-26T13:59:13.033180Z", + "id": "CVE-2026-12340", + "options": [ + { + "Exploitation": "none" + }, + { + "Automatable": "no" + }, + { + "Technical Impact": "partial" + } + ], + "role": "CISA Coordinator", + "version": "2.0.3" + } + } + } + ], + "title": "CISA ADP Vulnrichment", + "providerMetadata": { + "orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0", + "shortName": "CISA-ADP", + "dateUpdated": "2026-06-26T13:59:21.953Z" + } + } + ] + } +} diff --git a/advisories/records/CVE-2026-55958.json b/advisories/records/CVE-2026-55958.json new file mode 100644 index 0000000..188e396 --- /dev/null +++ b/advisories/records/CVE-2026-55958.json @@ -0,0 +1,163 @@ +{ + "dataType": "CVE_RECORD", + "dataVersion": "5.2", + "cveMetadata": { + "cveId": "CVE-2026-55958", + "assignerOrgId": "50d2cd11-d01a-48ed-9441-5bfce9d63b27", + "state": "PUBLISHED", + "assignerShortName": "wolfSSL", + "dateReserved": "2026-06-17T22:10:55.453Z", + "datePublished": "2026-06-25T19:35:21.155Z", + "dateUpdated": "2026-06-26T13:58:52.483Z" + }, + "containers": { + "cna": { + "providerMetadata": { + "orgId": "50d2cd11-d01a-48ed-9441-5bfce9d63b27", + "shortName": "wolfSSL", + "dateUpdated": "2026-06-25T19:35:21.155Z" + }, + "title": "Renesas TSIP TLS 1.3 transcript buffer out-of-bounds write in tsip_StoreMessage", + "problemTypes": [ + { + "descriptions": [ + { + "lang": "en", + "cweId": "CWE-787", + "description": "CWE-787 Out-of-bounds Write", + "type": "CWE" + }, + { + "lang": "en", + "cweId": "CWE-393", + "description": "CWE-393 Return of Wrong Status Code", + "type": "CWE" + } + ] + } + ], + "affected": [ + { + "vendor": "wolfSSL", + "product": "wolfSSL", + "collectionURL": "https://github.com/wolfSSL/wolfssl", + "versions": [ + { + "status": "affected", + "version": "5.4.0", + "lessThanOrEqual": "5.9.1", + "versionType": "semver" + } + ], + "defaultStatus": "unaffected" + } + ], + "descriptions": [ + { + "lang": "en", + "value": "Out-of-bounds write in the Renesas TSIP TLS 1.3 transcript buffer. In tsip_StoreMessage() the capacity check guarding the fixed message bag (MSGBAG_SIZE) sets an error code but fails to return, so execution falls through to an XMEMCPY that writes past the end of the buffer once the accumulated TLS 1.3 handshake transcript exceeds MSGBAG_SIZE (8 KB), corrupting adjacent heap state and potentially causing a remote denial of service crash. The bag is sized to hold a normal handshake, so this is reached only by an unusually large but valid certificate chain, or by a malicious or man-in-the-middle server sending an oversized handshake message to a client that does not strictly verify the chain. This only affects builds using the Renesas TSIP TLS port (WOLFSSL_RENESAS_TSIP_TLS) as a TLS 1.3 client on Renesas MCUs with TSIP hardware enabled, and is rated High within those builds. All other configurations are unaffected.", + "supportingMedia": [ + { + "type": "text/html", + "base64": false, + "value": "

Out-of-bounds write in the Renesas TSIP TLS 1.3 transcript buffer. In tsip_StoreMessage() the capacity check guarding the fixed message bag (MSGBAG_SIZE) sets an error code but fails to return, so execution falls through to an XMEMCPY that writes past the end of the buffer once the accumulated TLS 1.3 handshake transcript exceeds MSGBAG_SIZE (8 KB), corrupting adjacent heap state and potentially causing a remote denial of service crash. The bag is sized to hold a normal handshake, so this is reached only by an unusually large but valid certificate chain, or by a malicious or man-in-the-middle server sending an oversized handshake message to a client that does not strictly verify the chain. This only affects builds using the Renesas TSIP TLS port (WOLFSSL_RENESAS_TSIP_TLS) as a TLS 1.3 client on Renesas MCUs with TSIP hardware enabled, and is rated High within those builds. All other configurations are unaffected.

" + } + ] + } + ], + "references": [ + { + "url": "https://github.com/wolfSSL/wolfssl/pull/10705", + "tags": [ + "patch" + ] + }, + { + "url": "https://www.wolfssl.com/docs/security-vulnerabilities/" + } + ], + "metrics": [ + { + "format": "CVSS", + "scenarios": [ + { + "lang": "en", + "value": "GENERAL" + } + ], + "cvssV4_0": { + "attackVector": "NETWORK", + "attackComplexity": "LOW", + "attackRequirements": "PRESENT", + "privilegesRequired": "NONE", + "userInteraction": "NONE", + "vulnConfidentialityImpact": "NONE", + "subConfidentialityImpact": "NONE", + "vulnIntegrityImpact": "LOW", + "subIntegrityImpact": "NONE", + "vulnAvailabilityImpact": "HIGH", + "subAvailabilityImpact": "NONE", + "exploitMaturity": "NOT_DEFINED", + "Safety": "NOT_DEFINED", + "Automatable": "NOT_DEFINED", + "Recovery": "NOT_DEFINED", + "valueDensity": "NOT_DEFINED", + "vulnerabilityResponseEffort": "NOT_DEFINED", + "providerUrgency": "NOT_DEFINED", + "version": "4.0", + "baseSeverity": "HIGH", + "baseScore": 8.3, + "vectorString": "CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:L/VA:H/SC:N/SI:N/SA:N" + } + } + ], + "credits": [ + { + "lang": "en", + "value": "NVIDIA Project Vanessa", + "type": "finder" + } + ], + "source": { + "discovery": "UNKNOWN" + }, + "x_generator": { + "engine": "Vulnogram 1.0.2" + } + }, + "adp": [ + { + "metrics": [ + { + "other": { + "type": "ssvc", + "content": { + "timestamp": "2026-06-26T13:58:42.358851Z", + "id": "CVE-2026-55958", + "options": [ + { + "Exploitation": "none" + }, + { + "Automatable": "no" + }, + { + "Technical Impact": "partial" + } + ], + "role": "CISA Coordinator", + "version": "2.0.3" + } + } + } + ], + "title": "CISA ADP Vulnrichment", + "providerMetadata": { + "orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0", + "shortName": "CISA-ADP", + "dateUpdated": "2026-06-26T13:58:52.483Z" + } + } + ] + } +} diff --git a/advisories/records/CVE-2026-55960.json b/advisories/records/CVE-2026-55960.json new file mode 100644 index 0000000..b984a5b --- /dev/null +++ b/advisories/records/CVE-2026-55960.json @@ -0,0 +1,157 @@ +{ + "dataType": "CVE_RECORD", + "dataVersion": "5.2", + "cveMetadata": { + "cveId": "CVE-2026-55960", + "assignerOrgId": "50d2cd11-d01a-48ed-9441-5bfce9d63b27", + "state": "PUBLISHED", + "assignerShortName": "wolfSSL", + "dateReserved": "2026-06-17T22:10:55.453Z", + "datePublished": "2026-06-25T19:31:55.861Z", + "dateUpdated": "2026-06-26T13:58:17.060Z" + }, + "containers": { + "cna": { + "providerMetadata": { + "orgId": "50d2cd11-d01a-48ed-9441-5bfce9d63b27", + "shortName": "wolfSSL", + "dateUpdated": "2026-06-25T19:31:55.861Z" + }, + "title": "Un-negotiated Raw Public Key (RFC 7250) accepted in place of X.509, bypassing chain validation", + "problemTypes": [ + { + "descriptions": [ + { + "lang": "en", + "cweId": "CWE-295", + "description": "CWE-295 Improper Certificate Validation", + "type": "CWE" + } + ] + } + ], + "affected": [ + { + "vendor": "wolfSSL", + "product": "wolfSSL", + "collectionURL": "https://github.com/wolfSSL/wolfssl", + "versions": [ + { + "status": "affected", + "version": "5.6.4", + "lessThanOrEqual": "5.9.1", + "versionType": "semver" + } + ], + "defaultStatus": "unaffected" + } + ], + "descriptions": [ + { + "lang": "en", + "value": "Un-negotiated Raw Public Key (RFC 7250) accepted in place of an X.509 certificate, bypassing chain validation. A raw public key has no chain, so ParseCertRelative() accepts it without performing any trust verification; it must therefore only be accepted when RPK was actually negotiated for that peer. The check now defaults the expected type to X.509 (per RFC 7250/8446) when no type was negotiated, comparing against the received server certificate type on the client and the selected client certificate type on the server, and rejects any mismatch, including an un-negotiated raw public key, with UNSUPPORTED_CERTIFICATE. Only affects builds with Raw Public Key support (HAVE_RPK) enabled - disabled by default in a standalone build, but included in --enable-all.", + "supportingMedia": [ + { + "type": "text/html", + "base64": false, + "value": "

Un-negotiated Raw Public Key (RFC 7250) accepted in place of an X.509 certificate, bypassing chain validation. A raw public key has no chain, so ParseCertRelative() accepts it without performing any trust verification; it must therefore only be accepted when RPK was actually negotiated for that peer. The check now defaults the expected type to X.509 (per RFC 7250/8446) when no type was negotiated, comparing against the received server certificate type on the client and the selected client certificate type on the server, and rejects any mismatch, including an un-negotiated raw public key, with UNSUPPORTED_CERTIFICATE. Only affects builds with Raw Public Key support (HAVE_RPK) enabled - disabled by default in a standalone build, but included in --enable-all.

" + } + ] + } + ], + "references": [ + { + "url": "https://github.com/wolfSSL/wolfssl/pull/10702", + "tags": [ + "patch" + ] + }, + { + "url": "https://www.wolfssl.com/docs/security-vulnerabilities/" + } + ], + "metrics": [ + { + "format": "CVSS", + "scenarios": [ + { + "lang": "en", + "value": "GENERAL" + } + ], + "cvssV4_0": { + "attackVector": "NETWORK", + "attackComplexity": "LOW", + "attackRequirements": "PRESENT", + "privilegesRequired": "NONE", + "userInteraction": "NONE", + "vulnConfidentialityImpact": "NONE", + "subConfidentialityImpact": "NONE", + "vulnIntegrityImpact": "HIGH", + "subIntegrityImpact": "NONE", + "vulnAvailabilityImpact": "NONE", + "subAvailabilityImpact": "NONE", + "exploitMaturity": "NOT_DEFINED", + "Safety": "NOT_DEFINED", + "Automatable": "NOT_DEFINED", + "Recovery": "NOT_DEFINED", + "valueDensity": "NOT_DEFINED", + "vulnerabilityResponseEffort": "NOT_DEFINED", + "providerUrgency": "NOT_DEFINED", + "version": "4.0", + "baseSeverity": "HIGH", + "baseScore": 8.2, + "vectorString": "CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:H/VA:N/SC:N/SI:N/SA:N" + } + } + ], + "credits": [ + { + "lang": "en", + "value": "NVIDIA Project Vanessa", + "type": "finder" + } + ], + "source": { + "discovery": "UNKNOWN" + }, + "x_generator": { + "engine": "Vulnogram 1.0.2" + } + }, + "adp": [ + { + "metrics": [ + { + "other": { + "type": "ssvc", + "content": { + "timestamp": "2026-06-26T13:58:06.794685Z", + "id": "CVE-2026-55960", + "options": [ + { + "Exploitation": "none" + }, + { + "Automatable": "no" + }, + { + "Technical Impact": "partial" + } + ], + "role": "CISA Coordinator", + "version": "2.0.3" + } + } + } + ], + "title": "CISA ADP Vulnrichment", + "providerMetadata": { + "orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0", + "shortName": "CISA-ADP", + "dateUpdated": "2026-06-26T13:58:17.060Z" + } + } + ] + } +} diff --git a/advisories/records/CVE-2026-55961.json b/advisories/records/CVE-2026-55961.json new file mode 100644 index 0000000..5aa4ce1 --- /dev/null +++ b/advisories/records/CVE-2026-55961.json @@ -0,0 +1,157 @@ +{ + "dataType": "CVE_RECORD", + "dataVersion": "5.2", + "cveMetadata": { + "cveId": "CVE-2026-55961", + "assignerOrgId": "50d2cd11-d01a-48ed-9441-5bfce9d63b27", + "state": "PUBLISHED", + "assignerShortName": "wolfSSL", + "dateReserved": "2026-06-17T22:10:55.453Z", + "datePublished": "2026-06-25T16:51:18.157Z", + "dateUpdated": "2026-06-25T17:57:46.226Z" + }, + "containers": { + "cna": { + "providerMetadata": { + "orgId": "50d2cd11-d01a-48ed-9441-5bfce9d63b27", + "shortName": "wolfSSL", + "dateUpdated": "2026-06-25T16:51:18.157Z" + }, + "title": "wolfSSL_PKCS7_verify() reports success for degenerate (certs-only) PKCS#7 with no signer", + "problemTypes": [ + { + "descriptions": [ + { + "lang": "en", + "cweId": "CWE-347", + "description": "CWE-347 Improper Verification of Cryptographic Signature", + "type": "CWE" + } + ] + } + ], + "affected": [ + { + "vendor": "wolfSSL", + "product": "wolfSSL", + "collectionURL": "https://github.com/wolfSSL/wolfssl", + "versions": [ + { + "status": "affected", + "version": "3.15.7", + "lessThanOrEqual": "5.9.1", + "versionType": "semver" + } + ], + "defaultStatus": "unaffected" + } + ], + "descriptions": [ + { + "lang": "en", + "value": "wolfSSL_PKCS7_verify() returning success for a degenerate (certs-only) PKCS#7 object that contains no signer. Such an object has empty signerInfos, so the underlying signed-data verification succeeds without authenticating any content. The compatibility-layer verify path now rejects the object when no signer signature has actually been verified, so a PKCS#7 carrying no valid signature is no longer reported as verified. This is enforced regardless of the PKCS7_NOVERIFY flag, which only suppresses signer certificate chain validation and was never intended to waive the requirement that a signature exist. Only affects OpenSSL compatibility builds that call the PKCS7_verify() compatibility API on potentially degenerate PKCS#7 bundles.", + "supportingMedia": [ + { + "type": "text/html", + "base64": false, + "value": "

wolfSSL_PKCS7_verify() returning success for a degenerate (certs-only) PKCS#7 object that contains no signer. Such an object has empty signerInfos, so the underlying signed-data verification succeeds without authenticating any content. The compatibility-layer verify path now rejects the object when no signer signature has actually been verified, so a PKCS#7 carrying no valid signature is no longer reported as verified. This is enforced regardless of the PKCS7_NOVERIFY flag, which only suppresses signer certificate chain validation and was never intended to waive the requirement that a signature exist. Only affects OpenSSL compatibility builds that call the PKCS7_verify() compatibility API on potentially degenerate PKCS#7 bundles.

" + } + ] + } + ], + "references": [ + { + "url": "https://github.com/wolfSSL/wolfssl/pull/10702", + "tags": [ + "patch" + ] + }, + { + "url": "https://www.wolfssl.com/docs/security-vulnerabilities/" + } + ], + "metrics": [ + { + "format": "CVSS", + "scenarios": [ + { + "lang": "en", + "value": "GENERAL" + } + ], + "cvssV4_0": { + "attackVector": "NETWORK", + "attackComplexity": "LOW", + "attackRequirements": "PRESENT", + "privilegesRequired": "NONE", + "userInteraction": "NONE", + "vulnConfidentialityImpact": "NONE", + "subConfidentialityImpact": "NONE", + "vulnIntegrityImpact": "HIGH", + "subIntegrityImpact": "NONE", + "vulnAvailabilityImpact": "NONE", + "subAvailabilityImpact": "NONE", + "exploitMaturity": "NOT_DEFINED", + "Safety": "NOT_DEFINED", + "Automatable": "NOT_DEFINED", + "Recovery": "NOT_DEFINED", + "valueDensity": "NOT_DEFINED", + "vulnerabilityResponseEffort": "NOT_DEFINED", + "providerUrgency": "NOT_DEFINED", + "version": "4.0", + "baseSeverity": "HIGH", + "baseScore": 8.2, + "vectorString": "CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:H/VA:N/SC:N/SI:N/SA:N" + } + } + ], + "credits": [ + { + "lang": "en", + "value": "NVIDIA Project Vanessa", + "type": "finder" + } + ], + "source": { + "discovery": "UNKNOWN" + }, + "x_generator": { + "engine": "Vulnogram 1.0.2" + } + }, + "adp": [ + { + "metrics": [ + { + "other": { + "type": "ssvc", + "content": { + "timestamp": "2026-06-25T17:57:40.253830Z", + "id": "CVE-2026-55961", + "options": [ + { + "Exploitation": "none" + }, + { + "Automatable": "no" + }, + { + "Technical Impact": "partial" + } + ], + "role": "CISA Coordinator", + "version": "2.0.3" + } + } + } + ], + "title": "CISA ADP Vulnrichment", + "providerMetadata": { + "orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0", + "shortName": "CISA-ADP", + "dateUpdated": "2026-06-25T17:57:46.226Z" + } + } + ] + } +} diff --git a/advisories/records/CVE-2026-55962.json b/advisories/records/CVE-2026-55962.json new file mode 100644 index 0000000..65d2a8c --- /dev/null +++ b/advisories/records/CVE-2026-55962.json @@ -0,0 +1,157 @@ +{ + "dataType": "CVE_RECORD", + "dataVersion": "5.2", + "cveMetadata": { + "cveId": "CVE-2026-55962", + "assignerOrgId": "50d2cd11-d01a-48ed-9441-5bfce9d63b27", + "state": "PUBLISHED", + "assignerShortName": "wolfSSL", + "dateReserved": "2026-06-17T22:10:55.453Z", + "datePublished": "2026-06-25T21:12:38.074Z", + "dateUpdated": "2026-06-26T10:31:12.017Z" + }, + "containers": { + "cna": { + "providerMetadata": { + "orgId": "50d2cd11-d01a-48ed-9441-5bfce9d63b27", + "shortName": "wolfSSL", + "dateUpdated": "2026-06-25T21:12:38.074Z" + }, + "title": "TLS 1.3 post-handshake authentication: server accepts Finished without client Certificate/CertificateVerify", + "problemTypes": [ + { + "descriptions": [ + { + "lang": "en", + "cweId": "CWE-287", + "description": "CWE-287 Improper Authentication", + "type": "CWE" + } + ] + } + ], + "affected": [ + { + "vendor": "wolfSSL", + "product": "wolfSSL", + "collectionURL": "https://github.com/wolfSSL/wolfssl", + "versions": [ + { + "status": "affected", + "version": "5.5.4", + "lessThanOrEqual": "5.9.1", + "versionType": "semver" + } + ], + "defaultStatus": "unaffected" + } + ], + "descriptions": [ + { + "lang": "en", + "value": "TLS 1.3 post-handshake authentication (PHA) issue where a server could accept a client's Finished message without the client having sent a Certificate and CertificateVerify. The post-handshake-auth exemption that allows an empty/absent peer certificate was only intended for the initial handshake, but it was also being applied while a post-handshake CertificateRequest was still outstanding. The check is now scoped to the initial handshake only: on the server, once a post-handshake CertificateRequest has been sent (certReqCtx is set), a peer certificate and a valid CertificateVerify are required again before the Finished is accepted, with empty-certificate handling following the configured verify mode (FAIL_IF_NO_PEER_CERT) just as during first-handshake client authentication. Only affects TLS 1.3 servers built with post-handshake authentication support (WOLFSSL_POST_HANDSHAKE_AUTH / --enable-postauth, included in --enable-all) that enable WOLFSSL_VERIFY_POST_HANDSHAKE and request a client certificate after the handshake via wolfSSL_request_certificate(). Clients, and servers that do not use post-handshake authentication, are unaffected.", + "supportingMedia": [ + { + "type": "text/html", + "base64": false, + "value": "

TLS 1.3 post-handshake authentication (PHA) issue where a server could accept a client's Finished message without the client having sent a Certificate and CertificateVerify. The post-handshake-auth exemption that allows an empty/absent peer certificate was only intended for the initial handshake, but it was also being applied while a post-handshake CertificateRequest was still outstanding. The check is now scoped to the initial handshake only: on the server, once a post-handshake CertificateRequest has been sent (certReqCtx is set), a peer certificate and a valid CertificateVerify are required again before the Finished is accepted, with empty-certificate handling following the configured verify mode (FAIL_IF_NO_PEER_CERT) just as during first-handshake client authentication. Only affects TLS 1.3 servers built with post-handshake authentication support (WOLFSSL_POST_HANDSHAKE_AUTH / --enable-postauth, included in --enable-all) that enable WOLFSSL_VERIFY_POST_HANDSHAKE and request a client certificate after the handshake via wolfSSL_request_certificate(). Clients, and servers that do not use post-handshake authentication, are unaffected.

" + } + ] + } + ], + "references": [ + { + "url": "https://github.com/wolfSSL/wolfssl/pull/10702", + "tags": [ + "patch" + ] + }, + { + "url": "https://www.wolfssl.com/docs/security-vulnerabilities/" + } + ], + "metrics": [ + { + "format": "CVSS", + "scenarios": [ + { + "lang": "en", + "value": "GENERAL" + } + ], + "cvssV4_0": { + "attackVector": "NETWORK", + "attackComplexity": "LOW", + "attackRequirements": "PRESENT", + "privilegesRequired": "LOW", + "userInteraction": "NONE", + "vulnConfidentialityImpact": "NONE", + "subConfidentialityImpact": "NONE", + "vulnIntegrityImpact": "HIGH", + "subIntegrityImpact": "NONE", + "vulnAvailabilityImpact": "NONE", + "subAvailabilityImpact": "NONE", + "exploitMaturity": "NOT_DEFINED", + "Safety": "NOT_DEFINED", + "Automatable": "NOT_DEFINED", + "Recovery": "NOT_DEFINED", + "valueDensity": "NOT_DEFINED", + "vulnerabilityResponseEffort": "NOT_DEFINED", + "providerUrgency": "NOT_DEFINED", + "version": "4.0", + "baseSeverity": "MEDIUM", + "baseScore": 6, + "vectorString": "CVSS:4.0/AV:N/AC:L/AT:P/PR:L/UI:N/VC:N/VI:H/VA:N/SC:N/SI:N/SA:N" + } + } + ], + "credits": [ + { + "lang": "en", + "value": "NVIDIA Project Vanessa", + "type": "finder" + } + ], + "source": { + "discovery": "UNKNOWN" + }, + "x_generator": { + "engine": "Vulnogram 1.0.2" + } + }, + "adp": [ + { + "metrics": [ + { + "other": { + "type": "ssvc", + "content": { + "timestamp": "2026-06-26T10:30:28.816026Z", + "id": "CVE-2026-55962", + "options": [ + { + "Exploitation": "none" + }, + { + "Automatable": "no" + }, + { + "Technical Impact": "partial" + } + ], + "role": "CISA Coordinator", + "version": "2.0.3" + } + } + } + ], + "title": "CISA ADP Vulnrichment", + "providerMetadata": { + "orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0", + "shortName": "CISA-ADP", + "dateUpdated": "2026-06-26T10:31:12.017Z" + } + } + ] + } +} diff --git a/advisories/records/CVE-2026-55964.json b/advisories/records/CVE-2026-55964.json new file mode 100644 index 0000000..deef1ed --- /dev/null +++ b/advisories/records/CVE-2026-55964.json @@ -0,0 +1,157 @@ +{ + "dataType": "CVE_RECORD", + "dataVersion": "5.2", + "cveMetadata": { + "cveId": "CVE-2026-55964", + "assignerOrgId": "50d2cd11-d01a-48ed-9441-5bfce9d63b27", + "state": "PUBLISHED", + "assignerShortName": "wolfSSL", + "dateReserved": "2026-06-17T22:11:03.530Z", + "datePublished": "2026-06-25T19:30:34.789Z", + "dateUpdated": "2026-06-26T13:57:29.942Z" + }, + "containers": { + "cna": { + "providerMetadata": { + "orgId": "50d2cd11-d01a-48ed-9441-5bfce9d63b27", + "shortName": "wolfSSL", + "dateUpdated": "2026-06-25T19:30:34.789Z" + }, + "title": "Chain intermediate CA:TRUE without keyCertSign accepted as a signing CA (temporary CA exemption)", + "problemTypes": [ + { + "descriptions": [ + { + "lang": "en", + "cweId": "CWE-295", + "description": "CWE-295 Improper Certificate Validation", + "type": "CWE" + } + ] + } + ], + "affected": [ + { + "vendor": "wolfSSL", + "product": "wolfSSL", + "collectionURL": "https://github.com/wolfSSL/wolfssl", + "versions": [ + { + "status": "affected", + "version": "5.7.4", + "lessThanOrEqual": "5.9.1", + "versionType": "semver" + } + ], + "defaultStatus": "unaffected" + } + ], + "descriptions": [ + { + "lang": "en", + "value": "Chain intermediate CA:TRUE without keyCertSign accepted as a signing CA. Intermediate CA certificates are required to have the keyCertSign key usage when a Key Usage extension is present, but chain-supplied temporary CAs (WOLFSSL_TEMP_CA) added while building a certificate path were previously exempted from this check, so an intermediate asserting CA:TRUE but lacking keyCertSign was accepted as a signing CA. The check now applies to chain-supplied temporary CAs as well; only operator-loaded root certificates (WOLFSSL_USER_CA) and self-signed roots remain exempt. Per RFC 5280 an absent Key Usage extension implies all usages, so the requirement is enforced only when the extension is actually present (extKeyUsageSet). Affects the OpenSSL-compatibility certificate-path-building path (X509_verify_cert / X509_STORE, OPENSSL_EXTRA/OPENSSL_ALL), where untrusted chain intermediates are added as temporary CAs; native (non-OpenSSL-compat) certificate verification does not create temporary CAs and is unaffected. Within those builds, the check applies unless ALLOW_INVALID_CERTSIGN is defined.", + "supportingMedia": [ + { + "type": "text/html", + "base64": false, + "value": "

Chain intermediate CA:TRUE without keyCertSign accepted as a signing CA. Intermediate CA certificates are required to have the keyCertSign key usage when a Key Usage extension is present, but chain-supplied temporary CAs (WOLFSSL_TEMP_CA) added while building a certificate path were previously exempted from this check, so an intermediate asserting CA:TRUE but lacking keyCertSign was accepted as a signing CA. The check now applies to chain-supplied temporary CAs as well; only operator-loaded root certificates (WOLFSSL_USER_CA) and self-signed roots remain exempt. Per RFC 5280 an absent Key Usage extension implies all usages, so the requirement is enforced only when the extension is actually present (extKeyUsageSet). Affects the OpenSSL-compatibility certificate-path-building path (X509_verify_cert / X509_STORE, OPENSSL_EXTRA/OPENSSL_ALL), where untrusted chain intermediates are added as temporary CAs; native (non-OpenSSL-compat) certificate verification does not create temporary CAs and is unaffected. Within those builds, the check applies unless ALLOW_INVALID_CERTSIGN is defined.

" + } + ] + } + ], + "references": [ + { + "url": "https://github.com/wolfSSL/wolfssl/pull/10702", + "tags": [ + "patch" + ] + }, + { + "url": "https://www.wolfssl.com/docs/security-vulnerabilities/" + } + ], + "metrics": [ + { + "format": "CVSS", + "scenarios": [ + { + "lang": "en", + "value": "GENERAL" + } + ], + "cvssV4_0": { + "attackVector": "NETWORK", + "attackComplexity": "LOW", + "attackRequirements": "PRESENT", + "privilegesRequired": "NONE", + "userInteraction": "NONE", + "vulnConfidentialityImpact": "NONE", + "subConfidentialityImpact": "NONE", + "vulnIntegrityImpact": "LOW", + "subIntegrityImpact": "NONE", + "vulnAvailabilityImpact": "NONE", + "subAvailabilityImpact": "NONE", + "exploitMaturity": "NOT_DEFINED", + "Safety": "NOT_DEFINED", + "Automatable": "NOT_DEFINED", + "Recovery": "NOT_DEFINED", + "valueDensity": "NOT_DEFINED", + "vulnerabilityResponseEffort": "NOT_DEFINED", + "providerUrgency": "NOT_DEFINED", + "version": "4.0", + "baseSeverity": "MEDIUM", + "baseScore": 6.3, + "vectorString": "CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:L/VA:N/SC:N/SI:N/SA:N" + } + } + ], + "credits": [ + { + "lang": "en", + "value": "NVIDIA Project Vanessa", + "type": "finder" + } + ], + "source": { + "discovery": "UNKNOWN" + }, + "x_generator": { + "engine": "Vulnogram 1.0.2" + } + }, + "adp": [ + { + "metrics": [ + { + "other": { + "type": "ssvc", + "content": { + "timestamp": "2026-06-26T13:56:12.832072Z", + "id": "CVE-2026-55964", + "options": [ + { + "Exploitation": "none" + }, + { + "Automatable": "no" + }, + { + "Technical Impact": "partial" + } + ], + "role": "CISA Coordinator", + "version": "2.0.3" + } + } + } + ], + "title": "CISA ADP Vulnrichment", + "providerMetadata": { + "orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0", + "shortName": "CISA-ADP", + "dateUpdated": "2026-06-26T13:57:29.942Z" + } + } + ] + } +} diff --git a/advisories/records/CVE-2026-55967.json b/advisories/records/CVE-2026-55967.json new file mode 100644 index 0000000..4c1b23d --- /dev/null +++ b/advisories/records/CVE-2026-55967.json @@ -0,0 +1,157 @@ +{ + "dataType": "CVE_RECORD", + "dataVersion": "5.2", + "cveMetadata": { + "cveId": "CVE-2026-55967", + "assignerOrgId": "50d2cd11-d01a-48ed-9441-5bfce9d63b27", + "state": "PUBLISHED", + "assignerShortName": "wolfSSL", + "dateReserved": "2026-06-17T22:11:03.531Z", + "datePublished": "2026-06-25T16:53:14.695Z", + "dateUpdated": "2026-06-25T17:57:09.838Z" + }, + "containers": { + "cna": { + "providerMetadata": { + "orgId": "50d2cd11-d01a-48ed-9441-5bfce9d63b27", + "shortName": "wolfSSL", + "dateUpdated": "2026-06-25T16:53:14.695Z" + }, + "title": "AES-GCM streaming APIs do not reject >64 GiB cumulative single messages, enabling counter wrap and keystream reuse", + "problemTypes": [ + { + "descriptions": [ + { + "lang": "en", + "cweId": "CWE-323", + "description": "CWE-323 Reusing a Nonce, Key Pair in Encryption", + "type": "CWE" + } + ] + } + ], + "affected": [ + { + "vendor": "wolfSSL", + "product": "wolfSSL", + "collectionURL": "https://github.com/wolfSSL/wolfssl", + "versions": [ + { + "status": "affected", + "version": "4.8.0", + "lessThanOrEqual": "5.9.1", + "versionType": "semver" + } + ], + "defaultStatus": "unaffected" + } + ], + "descriptions": [ + { + "lang": "en", + "value": "AES-GCM encryption/decryption with extremely large cumulative single message sizes (>64 GiB) were not properly rejected by the streaming APIs, allowing counter wrap, keystream reuse, and consequent plaintext recovery.", + "supportingMedia": [ + { + "type": "text/html", + "base64": false, + "value": "

AES-GCM encryption/decryption with extremely large cumulative single message sizes (>64 GiB) were not properly rejected by the streaming APIs, allowing counter wrap, keystream reuse, and consequent plaintext recovery.

" + } + ] + } + ], + "references": [ + { + "url": "https://github.com/wolfSSL/wolfssl/pull/10709", + "tags": [ + "patch" + ] + }, + { + "url": "https://www.wolfssl.com/docs/security-vulnerabilities/" + } + ], + "metrics": [ + { + "format": "CVSS", + "scenarios": [ + { + "lang": "en", + "value": "GENERAL" + } + ], + "cvssV4_0": { + "attackVector": "LOCAL", + "attackComplexity": "HIGH", + "attackRequirements": "PRESENT", + "privilegesRequired": "LOW", + "userInteraction": "NONE", + "vulnConfidentialityImpact": "LOW", + "subConfidentialityImpact": "NONE", + "vulnIntegrityImpact": "NONE", + "subIntegrityImpact": "NONE", + "vulnAvailabilityImpact": "NONE", + "subAvailabilityImpact": "NONE", + "exploitMaturity": "NOT_DEFINED", + "Safety": "NOT_DEFINED", + "Automatable": "NOT_DEFINED", + "Recovery": "NOT_DEFINED", + "valueDensity": "NOT_DEFINED", + "vulnerabilityResponseEffort": "NOT_DEFINED", + "providerUrgency": "NOT_DEFINED", + "version": "4.0", + "baseSeverity": "LOW", + "baseScore": 2, + "vectorString": "CVSS:4.0/AV:L/AC:H/AT:P/PR:L/UI:N/VC:L/VI:N/VA:N/SC:N/SI:N/SA:N" + } + } + ], + "credits": [ + { + "lang": "en", + "value": "NVIDIA Project Vanessa", + "type": "finder" + } + ], + "source": { + "discovery": "UNKNOWN" + }, + "x_generator": { + "engine": "Vulnogram 1.0.2" + } + }, + "adp": [ + { + "metrics": [ + { + "other": { + "type": "ssvc", + "content": { + "timestamp": "2026-06-25T17:57:03.803039Z", + "id": "CVE-2026-55967", + "options": [ + { + "Exploitation": "none" + }, + { + "Automatable": "no" + }, + { + "Technical Impact": "partial" + } + ], + "role": "CISA Coordinator", + "version": "2.0.3" + } + } + } + ], + "title": "CISA ADP Vulnrichment", + "providerMetadata": { + "orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0", + "shortName": "CISA-ADP", + "dateUpdated": "2026-06-25T17:57:09.838Z" + } + } + ] + } +} diff --git a/advisories/records/CVE-2026-6091.json b/advisories/records/CVE-2026-6091.json new file mode 100644 index 0000000..5d98841 --- /dev/null +++ b/advisories/records/CVE-2026-6091.json @@ -0,0 +1,157 @@ +{ + "dataType": "CVE_RECORD", + "dataVersion": "5.2", + "cveMetadata": { + "cveId": "CVE-2026-6091", + "assignerOrgId": "50d2cd11-d01a-48ed-9441-5bfce9d63b27", + "state": "PUBLISHED", + "assignerShortName": "wolfSSL", + "dateReserved": "2026-04-10T16:01:23.181Z", + "datePublished": "2026-06-25T16:46:12.599Z", + "dateUpdated": "2026-06-25T17:58:31.045Z" + }, + "containers": { + "cna": { + "providerMetadata": { + "orgId": "50d2cd11-d01a-48ed-9441-5bfce9d63b27", + "shortName": "wolfSSL", + "dateUpdated": "2026-06-25T16:46:12.599Z" + }, + "title": "Partial-chain verification accepts untrusted intermediate as trust anchor", + "problemTypes": [ + { + "descriptions": [ + { + "lang": "en", + "cweId": "CWE-295", + "description": "CWE-295 Improper Certificate Validation", + "type": "CWE" + } + ] + } + ], + "affected": [ + { + "vendor": "wolfSSL", + "product": "wolfSSL", + "collectionURL": "https://github.com/wolfSSL/wolfssl", + "versions": [ + { + "status": "affected", + "version": "5.7.4", + "lessThanOrEqual": "5.9.1", + "versionType": "semver" + } + ], + "defaultStatus": "unaffected" + } + ], + "descriptions": [ + { + "lang": "en", + "value": "Partial-chain certificate verification may accept chains that terminate at a peer-supplied, untrusted intermediate certificate rather than a trusted anchor. An attacker could present a chain that ends at an intermediate they control and have it accepted as valid. This affects the OpenSSL compatibility certificate-path-building path (wolfSSL_X509_verify_cert / X509_STORE, OPENSSL_EXTRA) when the X509_V_FLAG_PARTIAL_CHAIN verify flag is enabled.", + "supportingMedia": [ + { + "type": "text/html", + "base64": false, + "value": "

Partial-chain certificate verification may accept chains that terminate at a peer-supplied, untrusted intermediate certificate rather than a trusted anchor. An attacker could present a chain that ends at an intermediate they control and have it accepted as valid. This affects the OpenSSL compatibility certificate-path-building path (wolfSSL_X509_verify_cert / X509_STORE, OPENSSL_EXTRA) when the X509_V_FLAG_PARTIAL_CHAIN verify flag is enabled.

" + } + ] + } + ], + "references": [ + { + "url": "https://github.com/wolfSSL/wolfssl/pull/10170", + "tags": [ + "patch" + ] + }, + { + "url": "https://www.wolfssl.com/docs/security-vulnerabilities/" + } + ], + "metrics": [ + { + "format": "CVSS", + "scenarios": [ + { + "lang": "en", + "value": "GENERAL" + } + ], + "cvssV4_0": { + "attackVector": "NETWORK", + "attackComplexity": "LOW", + "attackRequirements": "PRESENT", + "privilegesRequired": "LOW", + "userInteraction": "NONE", + "vulnConfidentialityImpact": "NONE", + "subConfidentialityImpact": "NONE", + "vulnIntegrityImpact": "HIGH", + "subIntegrityImpact": "NONE", + "vulnAvailabilityImpact": "NONE", + "subAvailabilityImpact": "NONE", + "exploitMaturity": "NOT_DEFINED", + "Safety": "NOT_DEFINED", + "Automatable": "NOT_DEFINED", + "Recovery": "NOT_DEFINED", + "valueDensity": "NOT_DEFINED", + "vulnerabilityResponseEffort": "NOT_DEFINED", + "providerUrgency": "NOT_DEFINED", + "version": "4.0", + "baseSeverity": "MEDIUM", + "baseScore": 6, + "vectorString": "CVSS:4.0/AV:N/AC:L/AT:P/PR:L/UI:N/VC:N/VI:H/VA:N/SC:N/SI:N/SA:N" + } + } + ], + "credits": [ + { + "lang": "en", + "value": "Dikai Zou", + "type": "finder" + } + ], + "source": { + "discovery": "UNKNOWN" + }, + "x_generator": { + "engine": "Vulnogram 1.0.2" + } + }, + "adp": [ + { + "metrics": [ + { + "other": { + "type": "ssvc", + "content": { + "timestamp": "2026-06-25T17:58:24.366839Z", + "id": "CVE-2026-6091", + "options": [ + { + "Exploitation": "none" + }, + { + "Automatable": "no" + }, + { + "Technical Impact": "partial" + } + ], + "role": "CISA Coordinator", + "version": "2.0.3" + } + } + } + ], + "title": "CISA ADP Vulnrichment", + "providerMetadata": { + "orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0", + "shortName": "CISA-ADP", + "dateUpdated": "2026-06-25T17:58:31.045Z" + } + } + ] + } +} diff --git a/advisories/records/CVE-2026-6092.json b/advisories/records/CVE-2026-6092.json new file mode 100644 index 0000000..5f240d9 --- /dev/null +++ b/advisories/records/CVE-2026-6092.json @@ -0,0 +1,157 @@ +{ + "dataType": "CVE_RECORD", + "dataVersion": "5.2", + "cveMetadata": { + "cveId": "CVE-2026-6092", + "assignerOrgId": "50d2cd11-d01a-48ed-9441-5bfce9d63b27", + "state": "PUBLISHED", + "assignerShortName": "wolfSSL", + "dateReserved": "2026-04-10T16:06:55.587Z", + "datePublished": "2026-06-25T21:06:20.494Z", + "dateUpdated": "2026-06-26T10:25:01.830Z" + }, + "containers": { + "cna": { + "providerMetadata": { + "orgId": "50d2cd11-d01a-48ed-9441-5bfce9d63b27", + "shortName": "wolfSSL", + "dateUpdated": "2026-06-25T21:06:20.494Z" + }, + "title": "Encrypt-then-MAC could fall back to MAC-then-Encrypt when HAVE_ENCRYPT_THEN_MAC is configured", + "problemTypes": [ + { + "descriptions": [ + { + "lang": "en", + "cweId": "CWE-757", + "description": "CWE-757 Selection of Less-Secure Algorithm During Negotiation ('Algorithm Downgrade')", + "type": "CWE" + } + ] + } + ], + "affected": [ + { + "vendor": "wolfSSL", + "product": "wolfSSL", + "collectionURL": "https://github.com/wolfSSL/wolfssl", + "versions": [ + { + "status": "affected", + "version": "5.2.0", + "lessThanOrEqual": "5.9.1", + "versionType": "semver" + } + ], + "defaultStatus": "unaffected" + } + ], + "descriptions": [ + { + "lang": "en", + "value": "When HAVE_ENCRYPT_THEN_MAC is configured, the implementation could fall back to MAC-then-Encrypt rather than enforcing Encrypt-then-MAC.", + "supportingMedia": [ + { + "type": "text/html", + "base64": false, + "value": "

When HAVE_ENCRYPT_THEN_MAC is configured, the implementation could fall back to MAC-then-Encrypt rather than enforcing Encrypt-then-MAC.

" + } + ] + } + ], + "references": [ + { + "url": "https://github.com/wolfSSL/wolfssl/pull/10167", + "tags": [ + "patch" + ] + }, + { + "url": "https://www.wolfssl.com/docs/security-vulnerabilities/" + } + ], + "metrics": [ + { + "format": "CVSS", + "scenarios": [ + { + "lang": "en", + "value": "GENERAL" + } + ], + "cvssV4_0": { + "attackVector": "ADJACENT", + "attackComplexity": "HIGH", + "attackRequirements": "PRESENT", + "privilegesRequired": "LOW", + "userInteraction": "NONE", + "vulnConfidentialityImpact": "LOW", + "subConfidentialityImpact": "NONE", + "vulnIntegrityImpact": "NONE", + "subIntegrityImpact": "NONE", + "vulnAvailabilityImpact": "NONE", + "subAvailabilityImpact": "NONE", + "exploitMaturity": "NOT_DEFINED", + "Safety": "NOT_DEFINED", + "Automatable": "NOT_DEFINED", + "Recovery": "NOT_DEFINED", + "valueDensity": "NOT_DEFINED", + "vulnerabilityResponseEffort": "NOT_DEFINED", + "providerUrgency": "CLEAR", + "version": "4.0", + "baseSeverity": "LOW", + "baseScore": 2.1, + "vectorString": "CVSS:4.0/AV:A/AC:H/AT:P/PR:L/UI:N/VC:L/VI:N/VA:N/SC:N/SI:N/SA:N/U:Clear" + } + } + ], + "credits": [ + { + "lang": "en", + "value": "Marcin Olejnik (Rockwell Automation)", + "type": "finder" + } + ], + "source": { + "discovery": "UNKNOWN" + }, + "x_generator": { + "engine": "Vulnogram 1.0.2" + } + }, + "adp": [ + { + "metrics": [ + { + "other": { + "type": "ssvc", + "content": { + "timestamp": "2026-06-26T10:24:15.925878Z", + "id": "CVE-2026-6092", + "options": [ + { + "Exploitation": "none" + }, + { + "Automatable": "no" + }, + { + "Technical Impact": "partial" + } + ], + "role": "CISA Coordinator", + "version": "2.0.3" + } + } + } + ], + "title": "CISA ADP Vulnrichment", + "providerMetadata": { + "orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0", + "shortName": "CISA-ADP", + "dateUpdated": "2026-06-26T10:25:01.830Z" + } + } + ] + } +} diff --git a/advisories/records/CVE-2026-6094.json b/advisories/records/CVE-2026-6094.json new file mode 100644 index 0000000..9f617cb --- /dev/null +++ b/advisories/records/CVE-2026-6094.json @@ -0,0 +1,157 @@ +{ + "dataType": "CVE_RECORD", + "dataVersion": "5.2", + "cveMetadata": { + "cveId": "CVE-2026-6094", + "assignerOrgId": "50d2cd11-d01a-48ed-9441-5bfce9d63b27", + "state": "PUBLISHED", + "assignerShortName": "wolfSSL", + "dateReserved": "2026-04-10T16:18:33.557Z", + "datePublished": "2026-06-25T16:35:48.013Z", + "dateUpdated": "2026-06-25T17:59:41.485Z" + }, + "containers": { + "cna": { + "providerMetadata": { + "orgId": "50d2cd11-d01a-48ed-9441-5bfce9d63b27", + "shortName": "wolfSSL", + "dateUpdated": "2026-06-25T16:35:48.013Z" + }, + "title": "Heap buffer overread in wc_PKCS7_DecodeEnvelopedData parsing crafted PKCS7 EnvelopedData", + "problemTypes": [ + { + "descriptions": [ + { + "lang": "en", + "cweId": "CWE-125", + "description": "CWE-125 Out-of-bounds Read", + "type": "CWE" + } + ] + } + ], + "affected": [ + { + "vendor": "wolfSSL", + "product": "wolfSSL", + "collectionURL": "https://github.com/wolfSSL/wolfssl", + "versions": [ + { + "status": "affected", + "version": "5.8.0", + "lessThanOrEqual": "5.9.1", + "versionType": "semver" + } + ], + "defaultStatus": "unaffected" + } + ], + "descriptions": [ + { + "lang": "en", + "value": "Heap buffer overread in wc_PKCS7_DecodeEnvelopedData when parsing crafted PKCS7 EnvelopedData. This could theoretically be triggered by attacker-supplied data delivered via S/MIME or CMS.", + "supportingMedia": [ + { + "type": "text/html", + "base64": false, + "value": "

Heap buffer overread in wc_PKCS7_DecodeEnvelopedData when parsing crafted PKCS7 EnvelopedData. This could theoretically be triggered by attacker-supplied data delivered via S/MIME or CMS.

" + } + ] + } + ], + "references": [ + { + "url": "https://github.com/wolfSSL/wolfssl/pull/10128", + "tags": [ + "patch" + ] + }, + { + "url": "https://www.wolfssl.com/docs/security-vulnerabilities/" + } + ], + "metrics": [ + { + "format": "CVSS", + "scenarios": [ + { + "lang": "en", + "value": "GENERAL" + } + ], + "cvssV4_0": { + "attackVector": "NETWORK", + "attackComplexity": "LOW", + "attackRequirements": "PRESENT", + "privilegesRequired": "NONE", + "userInteraction": "NONE", + "vulnConfidentialityImpact": "NONE", + "subConfidentialityImpact": "NONE", + "vulnIntegrityImpact": "NONE", + "subIntegrityImpact": "NONE", + "vulnAvailabilityImpact": "LOW", + "subAvailabilityImpact": "NONE", + "exploitMaturity": "NOT_DEFINED", + "Safety": "NOT_DEFINED", + "Automatable": "NOT_DEFINED", + "Recovery": "NOT_DEFINED", + "valueDensity": "NOT_DEFINED", + "vulnerabilityResponseEffort": "NOT_DEFINED", + "providerUrgency": "NOT_DEFINED", + "version": "4.0", + "baseSeverity": "MEDIUM", + "baseScore": 6.3, + "vectorString": "CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:N/VA:L/SC:N/SI:N/SA:N" + } + } + ], + "credits": [ + { + "lang": "en", + "value": "Dikai Zou", + "type": "finder" + } + ], + "source": { + "discovery": "UNKNOWN" + }, + "x_generator": { + "engine": "Vulnogram 1.0.2" + } + }, + "adp": [ + { + "metrics": [ + { + "other": { + "type": "ssvc", + "content": { + "timestamp": "2026-06-25T17:59:35.331027Z", + "id": "CVE-2026-6094", + "options": [ + { + "Exploitation": "none" + }, + { + "Automatable": "no" + }, + { + "Technical Impact": "partial" + } + ], + "role": "CISA Coordinator", + "version": "2.0.3" + } + } + } + ], + "title": "CISA ADP Vulnrichment", + "providerMetadata": { + "orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0", + "shortName": "CISA-ADP", + "dateUpdated": "2026-06-25T17:59:41.485Z" + } + } + ] + } +} diff --git a/advisories/records/CVE-2026-6291.json b/advisories/records/CVE-2026-6291.json new file mode 100644 index 0000000..c86e515 --- /dev/null +++ b/advisories/records/CVE-2026-6291.json @@ -0,0 +1,150 @@ +{ + "dataType": "CVE_RECORD", + "dataVersion": "5.2", + "cveMetadata": { + "cveId": "CVE-2026-6291", + "assignerOrgId": "50d2cd11-d01a-48ed-9441-5bfce9d63b27", + "state": "PUBLISHED", + "assignerShortName": "wolfSSL", + "dateReserved": "2026-04-14T17:40:51.467Z", + "datePublished": "2026-06-25T16:41:42.232Z", + "dateUpdated": "2026-06-25T17:59:08.922Z" + }, + "containers": { + "cna": { + "providerMetadata": { + "orgId": "50d2cd11-d01a-48ed-9441-5bfce9d63b27", + "shortName": "wolfSSL", + "dateUpdated": "2026-06-25T16:41:42.232Z" + }, + "title": "Bleichenbacher padding oracle in PKCS#7 KTRI RSA PKCS#1 v1.5 decryption", + "problemTypes": [ + { + "descriptions": [ + { + "lang": "en", + "cweId": "CWE-208", + "description": "CWE-208 Observable Timing Discrepancy", + "type": "CWE" + } + ] + } + ], + "affected": [ + { + "vendor": "wolfSSL", + "product": "wolfSSL", + "collectionURL": "https://github.com/wolfSSL/wolfssl", + "versions": [ + { + "status": "affected", + "version": "3.9.10", + "lessThanOrEqual": "5.9.1", + "versionType": "semver" + } + ], + "defaultStatus": "unaffected" + } + ], + "descriptions": [ + { + "lang": "en", + "value": "Bleichenbacher padding oracle in PKCS#7 KTRI decryption. When decrypting PKCS#7 EnvelopedData using RSA PKCS#1 v1.5 key transport, wolfSSL returned distinguishable error codes depending on whether RSA padding validation failed versus whether the decrypted content was malformed. An attacker able to submit crafted EnvelopedData messages and observe error responses could use this as a padding oracle to incrementally recover the encrypted Content Encryption Key (CEK). The fix generates a deterministic pseudo-random fake CEK on padding failure (via HMAC-SHA256) and proceeds with decryption identically, using constant-time operations throughout, so that all failure paths produce the same error regardless of padding validity.", + "supportingMedia": [ + { + "type": "text/html", + "base64": false, + "value": "

Bleichenbacher padding oracle in PKCS#7 KTRI decryption. When decrypting PKCS#7 EnvelopedData using RSA PKCS#1 v1.5 key transport, wolfSSL returned distinguishable error codes depending on whether RSA padding validation failed versus whether the decrypted content was malformed. An attacker able to submit crafted EnvelopedData messages and observe error responses could use this as a padding oracle to incrementally recover the encrypted Content Encryption Key (CEK). The fix generates a deterministic pseudo-random fake CEK on padding failure (via HMAC-SHA256) and proceeds with decryption identically, using constant-time operations throughout, so that all failure paths produce the same error regardless of padding validity.

" + } + ] + } + ], + "references": [ + { + "url": "https://github.com/wolfSSL/wolfssl/pull/10203", + "tags": [ + "patch" + ] + }, + { + "url": "https://www.wolfssl.com/docs/security-vulnerabilities/" + } + ], + "metrics": [ + { + "format": "CVSS", + "scenarios": [ + { + "lang": "en", + "value": "GENERAL" + } + ], + "cvssV4_0": { + "attackVector": "NETWORK", + "attackComplexity": "LOW", + "attackRequirements": "PRESENT", + "privilegesRequired": "LOW", + "userInteraction": "NONE", + "vulnConfidentialityImpact": "HIGH", + "subConfidentialityImpact": "NONE", + "vulnIntegrityImpact": "NONE", + "subIntegrityImpact": "NONE", + "vulnAvailabilityImpact": "NONE", + "subAvailabilityImpact": "NONE", + "exploitMaturity": "NOT_DEFINED", + "Safety": "NOT_DEFINED", + "Automatable": "NOT_DEFINED", + "Recovery": "NOT_DEFINED", + "valueDensity": "NOT_DEFINED", + "vulnerabilityResponseEffort": "NOT_DEFINED", + "providerUrgency": "NOT_DEFINED", + "version": "4.0", + "baseSeverity": "MEDIUM", + "baseScore": 6, + "vectorString": "CVSS:4.0/AV:N/AC:L/AT:P/PR:L/UI:N/VC:H/VI:N/VA:N/SC:N/SI:N/SA:N" + } + } + ], + "source": { + "discovery": "UNKNOWN" + }, + "x_generator": { + "engine": "Vulnogram 1.0.2" + } + }, + "adp": [ + { + "metrics": [ + { + "other": { + "type": "ssvc", + "content": { + "timestamp": "2026-06-25T17:59:02.789664Z", + "id": "CVE-2026-6291", + "options": [ + { + "Exploitation": "none" + }, + { + "Automatable": "no" + }, + { + "Technical Impact": "partial" + } + ], + "role": "CISA Coordinator", + "version": "2.0.3" + } + } + } + ], + "title": "CISA ADP Vulnrichment", + "providerMetadata": { + "orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0", + "shortName": "CISA-ADP", + "dateUpdated": "2026-06-25T17:59:08.922Z" + } + } + ] + } +} diff --git a/advisories/records/CVE-2026-6325.json b/advisories/records/CVE-2026-6325.json new file mode 100644 index 0000000..f0e09bf --- /dev/null +++ b/advisories/records/CVE-2026-6325.json @@ -0,0 +1,157 @@ +{ + "dataType": "CVE_RECORD", + "dataVersion": "5.2", + "cveMetadata": { + "cveId": "CVE-2026-6325", + "assignerOrgId": "50d2cd11-d01a-48ed-9441-5bfce9d63b27", + "state": "PUBLISHED", + "assignerShortName": "wolfSSL", + "dateReserved": "2026-04-14T20:57:15.490Z", + "datePublished": "2026-06-25T21:04:31.827Z", + "dateUpdated": "2026-06-26T10:23:33.220Z" + }, + "containers": { + "cna": { + "providerMetadata": { + "orgId": "50d2cd11-d01a-48ed-9441-5bfce9d63b27", + "shortName": "wolfSSL", + "dateUpdated": "2026-06-25T21:04:31.827Z" + }, + "title": "Out-of-bounds write in SetSuitesHashSigAlgo on oversized signature algorithms list", + "problemTypes": [ + { + "descriptions": [ + { + "lang": "en", + "cweId": "CWE-787", + "description": "CWE-787 Out-of-bounds Write", + "type": "CWE" + } + ] + } + ], + "affected": [ + { + "vendor": "wolfSSL", + "product": "wolfSSL", + "collectionURL": "https://github.com/wolfSSL/wolfssl", + "versions": [ + { + "status": "affected", + "version": "4.8.0", + "lessThanOrEqual": "5.9.1", + "versionType": "semver" + } + ], + "defaultStatus": "unaffected" + } + ], + "descriptions": [ + { + "lang": "en", + "value": "Out-of-bounds write in SetSuitesHashSigAlgo when processing an oversized signature algorithms list, allowing a write past the bounds of the destination buffer.", + "supportingMedia": [ + { + "type": "text/html", + "base64": false, + "value": "

Out-of-bounds write in SetSuitesHashSigAlgo when processing an oversized signature algorithms list, allowing a write past the bounds of the destination buffer.

" + } + ] + } + ], + "references": [ + { + "url": "https://github.com/wolfSSL/wolfssl/pull/10204", + "tags": [ + "patch" + ] + }, + { + "url": "https://www.wolfssl.com/docs/security-vulnerabilities/" + } + ], + "metrics": [ + { + "format": "CVSS", + "scenarios": [ + { + "lang": "en", + "value": "GENERAL" + } + ], + "cvssV4_0": { + "attackVector": "LOCAL", + "attackComplexity": "HIGH", + "attackRequirements": "PRESENT", + "privilegesRequired": "NONE", + "userInteraction": "PASSIVE", + "vulnConfidentialityImpact": "NONE", + "subConfidentialityImpact": "NONE", + "vulnIntegrityImpact": "LOW", + "subIntegrityImpact": "NONE", + "vulnAvailabilityImpact": "LOW", + "subAvailabilityImpact": "NONE", + "exploitMaturity": "NOT_DEFINED", + "Safety": "NOT_DEFINED", + "Automatable": "NOT_DEFINED", + "Recovery": "NOT_DEFINED", + "valueDensity": "NOT_DEFINED", + "vulnerabilityResponseEffort": "NOT_DEFINED", + "providerUrgency": "CLEAR", + "version": "4.0", + "baseSeverity": "LOW", + "baseScore": 2, + "vectorString": "CVSS:4.0/AV:L/AC:H/AT:P/PR:N/UI:P/VC:N/VI:L/VA:L/SC:N/SI:N/SA:N/U:Clear" + } + } + ], + "credits": [ + { + "lang": "en", + "value": "Muhammad Arya Arjuna Habibullah (Pelioro)", + "type": "finder" + } + ], + "source": { + "discovery": "UNKNOWN" + }, + "x_generator": { + "engine": "Vulnogram 1.0.2" + } + }, + "adp": [ + { + "metrics": [ + { + "other": { + "type": "ssvc", + "content": { + "timestamp": "2026-06-26T10:22:44.145921Z", + "id": "CVE-2026-6325", + "options": [ + { + "Exploitation": "none" + }, + { + "Automatable": "no" + }, + { + "Technical Impact": "partial" + } + ], + "role": "CISA Coordinator", + "version": "2.0.3" + } + } + } + ], + "title": "CISA ADP Vulnrichment", + "providerMetadata": { + "orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0", + "shortName": "CISA-ADP", + "dateUpdated": "2026-06-26T10:23:33.220Z" + } + } + ] + } +} diff --git a/advisories/records/CVE-2026-6329.json b/advisories/records/CVE-2026-6329.json new file mode 100644 index 0000000..68e61eb --- /dev/null +++ b/advisories/records/CVE-2026-6329.json @@ -0,0 +1,157 @@ +{ + "dataType": "CVE_RECORD", + "dataVersion": "5.2", + "cveMetadata": { + "cveId": "CVE-2026-6329", + "assignerOrgId": "50d2cd11-d01a-48ed-9441-5bfce9d63b27", + "state": "PUBLISHED", + "assignerShortName": "wolfSSL", + "dateReserved": "2026-04-15T03:08:29.037Z", + "datePublished": "2026-06-25T21:02:45.860Z", + "dateUpdated": "2026-06-26T10:22:21.379Z" + }, + "containers": { + "cna": { + "providerMetadata": { + "orgId": "50d2cd11-d01a-48ed-9441-5bfce9d63b27", + "shortName": "wolfSSL", + "dateUpdated": "2026-06-25T21:02:45.860Z" + }, + "title": "PKCS#12 MAC verification uses attacker-controlled comparison length", + "problemTypes": [ + { + "descriptions": [ + { + "lang": "en", + "cweId": "CWE-347", + "description": "CWE-347 Improper Verification of Cryptographic Signature", + "type": "CWE" + } + ] + } + ], + "affected": [ + { + "vendor": "wolfSSL", + "product": "wolfSSL", + "collectionURL": "https://github.com/wolfSSL/wolfssl", + "versions": [ + { + "status": "affected", + "version": "3.10.0", + "lessThanOrEqual": "5.9.1", + "versionType": "semver" + } + ], + "defaultStatus": "unaffected" + } + ], + "descriptions": [ + { + "lang": "en", + "value": "PKCS#12 MAC verification uses an attacker-controlled comparison length, weakening the integrity check on the MAC and allowing a mismatched MAC to be accepted. The PKCS#12 verify path compared the locally computed HMAC against the MAC parsed from the PKCS#12 structure using a length taken directly from the attacker-supplied input, without first verifying that it equals the length of the digest actually produced by the configured algorithm. A truncated or zero-length stored MAC could therefore be accepted, defeating the integrity protection of the MAC.", + "supportingMedia": [ + { + "type": "text/html", + "base64": false, + "value": "

PKCS#12 MAC verification uses an attacker-controlled comparison length, weakening the integrity check on the MAC and allowing a mismatched MAC to be accepted. The PKCS#12 verify path compared the locally computed HMAC against the MAC parsed from the PKCS#12 structure using a length taken directly from the attacker-supplied input, without first verifying that it equals the length of the digest actually produced by the configured algorithm. A truncated or zero-length stored MAC could therefore be accepted, defeating the integrity protection of the MAC.

" + } + ] + } + ], + "references": [ + { + "url": "https://github.com/wolfSSL/wolfssl/pull/10192", + "tags": [ + "patch" + ] + }, + { + "url": "https://www.wolfssl.com/docs/security-vulnerabilities/" + } + ], + "metrics": [ + { + "format": "CVSS", + "scenarios": [ + { + "lang": "en", + "value": "GENERAL" + } + ], + "cvssV4_0": { + "attackVector": "NETWORK", + "attackComplexity": "LOW", + "attackRequirements": "PRESENT", + "privilegesRequired": "LOW", + "userInteraction": "NONE", + "vulnConfidentialityImpact": "NONE", + "subConfidentialityImpact": "NONE", + "vulnIntegrityImpact": "HIGH", + "subIntegrityImpact": "NONE", + "vulnAvailabilityImpact": "NONE", + "subAvailabilityImpact": "NONE", + "exploitMaturity": "NOT_DEFINED", + "Safety": "NOT_DEFINED", + "Automatable": "NOT_DEFINED", + "Recovery": "NOT_DEFINED", + "valueDensity": "NOT_DEFINED", + "vulnerabilityResponseEffort": "NOT_DEFINED", + "providerUrgency": "NOT_DEFINED", + "version": "4.0", + "baseSeverity": "MEDIUM", + "baseScore": 6, + "vectorString": "CVSS:4.0/AV:N/AC:L/AT:P/PR:L/UI:N/VC:N/VI:H/VA:N/SC:N/SI:N/SA:N" + } + } + ], + "credits": [ + { + "lang": "en", + "value": "Nicholas Carlini from Anthropic", + "type": "finder" + } + ], + "source": { + "discovery": "UNKNOWN" + }, + "x_generator": { + "engine": "Vulnogram 1.0.2" + } + }, + "adp": [ + { + "metrics": [ + { + "other": { + "type": "ssvc", + "content": { + "timestamp": "2026-06-26T10:22:07.674452Z", + "id": "CVE-2026-6329", + "options": [ + { + "Exploitation": "none" + }, + { + "Automatable": "no" + }, + { + "Technical Impact": "partial" + } + ], + "role": "CISA Coordinator", + "version": "2.0.3" + } + } + } + ], + "title": "CISA ADP Vulnrichment", + "providerMetadata": { + "orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0", + "shortName": "CISA-ADP", + "dateUpdated": "2026-06-26T10:22:21.379Z" + } + } + ] + } +} diff --git a/advisories/records/CVE-2026-6330.json b/advisories/records/CVE-2026-6330.json new file mode 100644 index 0000000..ac1fceb --- /dev/null +++ b/advisories/records/CVE-2026-6330.json @@ -0,0 +1,157 @@ +{ + "dataType": "CVE_RECORD", + "dataVersion": "5.2", + "cveMetadata": { + "cveId": "CVE-2026-6330", + "assignerOrgId": "50d2cd11-d01a-48ed-9441-5bfce9d63b27", + "state": "PUBLISHED", + "assignerShortName": "wolfSSL", + "dateReserved": "2026-04-15T03:08:30.514Z", + "datePublished": "2026-06-25T21:01:19.563Z", + "dateUpdated": "2026-06-26T10:20:49.418Z" + }, + "containers": { + "cna": { + "providerMetadata": { + "orgId": "50d2cd11-d01a-48ed-9441-5bfce9d63b27", + "shortName": "wolfSSL", + "dateUpdated": "2026-06-25T21:01:19.563Z" + }, + "title": "ML-KEM ARM64 NEON ciphertext comparison only compares half of the input", + "problemTypes": [ + { + "descriptions": [ + { + "lang": "en", + "cweId": "CWE-327", + "description": "CWE-327 Use of a Broken or Risky Cryptographic Algorithm", + "type": "CWE" + } + ] + } + ], + "affected": [ + { + "vendor": "wolfSSL", + "product": "wolfSSL", + "collectionURL": "https://github.com/wolfSSL/wolfssl", + "versions": [ + { + "status": "affected", + "version": "5.7.4", + "lessThanOrEqual": "5.9.1", + "versionType": "semver" + } + ], + "defaultStatus": "unaffected" + } + ], + "descriptions": [ + { + "lang": "en", + "value": "The ML-KEM ARM64 NEON ciphertext comparison only compares half of the input, breaking the Fujisaki-Okamoto transform's implicit rejection and weakening IND-CCA2 security on that code path. The constant-time comparison effectively ignored part of the re-encrypted ciphertext, so a decapsulating party could fail to detect a manipulated ciphertext and proceed without the standard's required implicit rejection.", + "supportingMedia": [ + { + "type": "text/html", + "base64": false, + "value": "

The ML-KEM ARM64 NEON ciphertext comparison only compares half of the input, breaking the Fujisaki-Okamoto transform's implicit rejection and weakening IND-CCA2 security on that code path. The constant-time comparison effectively ignored part of the re-encrypted ciphertext, so a decapsulating party could fail to detect a manipulated ciphertext and proceed without the standard's required implicit rejection.

" + } + ] + } + ], + "references": [ + { + "url": "https://github.com/wolfSSL/wolfssl/pull/10192", + "tags": [ + "patch" + ] + }, + { + "url": "https://www.wolfssl.com/docs/security-vulnerabilities/" + } + ], + "metrics": [ + { + "format": "CVSS", + "scenarios": [ + { + "lang": "en", + "value": "GENERAL" + } + ], + "cvssV4_0": { + "attackVector": "NETWORK", + "attackComplexity": "HIGH", + "attackRequirements": "PRESENT", + "privilegesRequired": "NONE", + "userInteraction": "NONE", + "vulnConfidentialityImpact": "LOW", + "subConfidentialityImpact": "NONE", + "vulnIntegrityImpact": "LOW", + "subIntegrityImpact": "NONE", + "vulnAvailabilityImpact": "NONE", + "subAvailabilityImpact": "NONE", + "exploitMaturity": "NOT_DEFINED", + "Safety": "NOT_DEFINED", + "Automatable": "NOT_DEFINED", + "Recovery": "NOT_DEFINED", + "valueDensity": "NOT_DEFINED", + "vulnerabilityResponseEffort": "NOT_DEFINED", + "providerUrgency": "NOT_DEFINED", + "version": "4.0", + "baseSeverity": "MEDIUM", + "baseScore": 6.3, + "vectorString": "CVSS:4.0/AV:N/AC:H/AT:P/PR:N/UI:N/VC:L/VI:L/VA:N/SC:N/SI:N/SA:N" + } + } + ], + "credits": [ + { + "lang": "en", + "value": "Nicholas Carlini from Anthropic", + "type": "finder" + } + ], + "source": { + "discovery": "UNKNOWN" + }, + "x_generator": { + "engine": "Vulnogram 1.0.2" + } + }, + "adp": [ + { + "metrics": [ + { + "other": { + "type": "ssvc", + "content": { + "timestamp": "2026-06-26T10:20:21.938284Z", + "id": "CVE-2026-6330", + "options": [ + { + "Exploitation": "none" + }, + { + "Automatable": "no" + }, + { + "Technical Impact": "partial" + } + ], + "role": "CISA Coordinator", + "version": "2.0.3" + } + } + } + ], + "title": "CISA ADP Vulnrichment", + "providerMetadata": { + "orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0", + "shortName": "CISA-ADP", + "dateUpdated": "2026-06-26T10:20:49.418Z" + } + } + ] + } +} diff --git a/advisories/records/CVE-2026-6331.json b/advisories/records/CVE-2026-6331.json new file mode 100644 index 0000000..e6add52 --- /dev/null +++ b/advisories/records/CVE-2026-6331.json @@ -0,0 +1,157 @@ +{ + "dataType": "CVE_RECORD", + "dataVersion": "5.2", + "cveMetadata": { + "cveId": "CVE-2026-6331", + "assignerOrgId": "50d2cd11-d01a-48ed-9441-5bfce9d63b27", + "state": "PUBLISHED", + "assignerShortName": "wolfSSL", + "dateReserved": "2026-04-15T03:08:31.649Z", + "datePublished": "2026-06-25T20:56:25.876Z", + "dateUpdated": "2026-06-26T13:53:06.730Z" + }, + "containers": { + "cna": { + "providerMetadata": { + "orgId": "50d2cd11-d01a-48ed-9441-5bfce9d63b27", + "shortName": "wolfSSL", + "dateUpdated": "2026-06-25T20:56:25.876Z" + }, + "title": "HMAC zero-length tag forgery in EVP_DigestVerifyFinal", + "problemTypes": [ + { + "descriptions": [ + { + "lang": "en", + "cweId": "CWE-347", + "description": "CWE-347 Improper Verification of Cryptographic Signature", + "type": "CWE" + } + ] + } + ], + "affected": [ + { + "vendor": "wolfSSL", + "product": "wolfSSL", + "collectionURL": "https://github.com/wolfSSL/wolfssl", + "versions": [ + { + "status": "affected", + "version": "3.15.5", + "lessThanOrEqual": "5.9.1", + "versionType": "semver" + } + ], + "defaultStatus": "unaffected" + } + ], + "descriptions": [ + { + "lang": "en", + "value": "HMAC zero-length tag forgery in EVP_DigestVerifyFinal, where a zero-length tag could be accepted as valid during HMAC verification. In the OpenSSL-compatibility HMAC verify path the supplied signature length was only checked as not exceeding the MAC length, so a zero-length or otherwise truncated tag could pass verification. The fix requires the supplied tag length to exactly equal the MAC length and rejects a zero-length MAC, so a forged short or empty tag is no longer accepted.", + "supportingMedia": [ + { + "type": "text/html", + "base64": false, + "value": "

HMAC zero-length tag forgery in EVP_DigestVerifyFinal, where a zero-length tag could be accepted as valid during HMAC verification. In the OpenSSL-compatibility HMAC verify path the supplied signature length was only checked as not exceeding the MAC length, so a zero-length or otherwise truncated tag could pass verification. The fix requires the supplied tag length to exactly equal the MAC length and rejects a zero-length MAC, so a forged short or empty tag is no longer accepted.

" + } + ] + } + ], + "references": [ + { + "url": "https://github.com/wolfSSL/wolfssl/pull/10192", + "tags": [ + "patch" + ] + }, + { + "url": "https://www.wolfssl.com/docs/security-vulnerabilities/" + } + ], + "metrics": [ + { + "format": "CVSS", + "scenarios": [ + { + "lang": "en", + "value": "GENERAL" + } + ], + "cvssV4_0": { + "attackVector": "LOCAL", + "attackComplexity": "HIGH", + "attackRequirements": "PRESENT", + "privilegesRequired": "NONE", + "userInteraction": "NONE", + "vulnConfidentialityImpact": "NONE", + "subConfidentialityImpact": "NONE", + "vulnIntegrityImpact": "LOW", + "subIntegrityImpact": "NONE", + "vulnAvailabilityImpact": "NONE", + "subAvailabilityImpact": "NONE", + "exploitMaturity": "NOT_DEFINED", + "Safety": "NOT_DEFINED", + "Automatable": "NOT_DEFINED", + "Recovery": "NOT_DEFINED", + "valueDensity": "NOT_DEFINED", + "vulnerabilityResponseEffort": "NOT_DEFINED", + "providerUrgency": "NOT_DEFINED", + "version": "4.0", + "baseSeverity": "LOW", + "baseScore": 2.1, + "vectorString": "CVSS:4.0/AV:L/AC:H/AT:P/PR:N/UI:N/VC:N/VI:L/VA:N/SC:N/SI:N/SA:N" + } + } + ], + "credits": [ + { + "lang": "en", + "value": "Nicholas Carlini from Anthropic", + "type": "finder" + } + ], + "source": { + "discovery": "UNKNOWN" + }, + "x_generator": { + "engine": "Vulnogram 1.0.2" + } + }, + "adp": [ + { + "metrics": [ + { + "other": { + "type": "ssvc", + "content": { + "timestamp": "2026-06-26T13:52:52.624679Z", + "id": "CVE-2026-6331", + "options": [ + { + "Exploitation": "none" + }, + { + "Automatable": "no" + }, + { + "Technical Impact": "partial" + } + ], + "role": "CISA Coordinator", + "version": "2.0.3" + } + } + } + ], + "title": "CISA ADP Vulnrichment", + "providerMetadata": { + "orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0", + "shortName": "CISA-ADP", + "dateUpdated": "2026-06-26T13:53:06.730Z" + } + } + ] + } +} diff --git a/advisories/records/CVE-2026-6412.json b/advisories/records/CVE-2026-6412.json new file mode 100644 index 0000000..caab9a6 --- /dev/null +++ b/advisories/records/CVE-2026-6412.json @@ -0,0 +1,157 @@ +{ + "dataType": "CVE_RECORD", + "dataVersion": "5.2", + "cveMetadata": { + "cveId": "CVE-2026-6412", + "assignerOrgId": "50d2cd11-d01a-48ed-9441-5bfce9d63b27", + "state": "PUBLISHED", + "assignerShortName": "wolfSSL", + "dateReserved": "2026-04-15T23:30:42.133Z", + "datePublished": "2026-06-25T20:38:29.761Z", + "dateUpdated": "2026-06-26T13:06:26.002Z" + }, + "containers": { + "cna": { + "providerMetadata": { + "orgId": "50d2cd11-d01a-48ed-9441-5bfce9d63b27", + "shortName": "wolfSSL", + "dateUpdated": "2026-06-25T20:38:29.761Z" + }, + "title": "Continued acceptance of SHA-1/MD5 digests in certificate processing", + "problemTypes": [ + { + "descriptions": [ + { + "lang": "en", + "cweId": "CWE-327", + "description": "CWE-327 Use of a Broken or Risky Cryptographic Algorithm", + "type": "CWE" + } + ] + } + ], + "affected": [ + { + "vendor": "wolfSSL", + "product": "wolfSSL", + "collectionURL": "https://github.com/wolfSSL/wolfssl", + "versions": [ + { + "status": "affected", + "version": "3.9.10", + "lessThanOrEqual": "5.9.1", + "versionType": "semver" + } + ], + "defaultStatus": "unaffected" + } + ], + "descriptions": [ + { + "lang": "en", + "value": "Certificate policy and RFC 8446 compliance concerns regarding the continued acceptance of SHA-1/MD5 in certificate processing.", + "supportingMedia": [ + { + "type": "text/html", + "base64": false, + "value": "

Certificate policy and RFC 8446 compliance concerns regarding the continued acceptance of SHA-1/MD5 in certificate processing.

" + } + ] + } + ], + "references": [ + { + "url": "https://github.com/wolfSSL/wolfssl/pull/10222", + "tags": [ + "patch" + ] + }, + { + "url": "https://www.wolfssl.com/docs/security-vulnerabilities/" + } + ], + "metrics": [ + { + "format": "CVSS", + "scenarios": [ + { + "lang": "en", + "value": "GENERAL" + } + ], + "cvssV4_0": { + "attackVector": "NETWORK", + "attackComplexity": "HIGH", + "attackRequirements": "PRESENT", + "privilegesRequired": "LOW", + "userInteraction": "NONE", + "vulnConfidentialityImpact": "NONE", + "subConfidentialityImpact": "NONE", + "vulnIntegrityImpact": "LOW", + "subIntegrityImpact": "NONE", + "vulnAvailabilityImpact": "NONE", + "subAvailabilityImpact": "NONE", + "exploitMaturity": "NOT_DEFINED", + "Safety": "NOT_DEFINED", + "Automatable": "NOT_DEFINED", + "Recovery": "NOT_DEFINED", + "valueDensity": "NOT_DEFINED", + "vulnerabilityResponseEffort": "NOT_DEFINED", + "providerUrgency": "CLEAR", + "version": "4.0", + "baseSeverity": "LOW", + "baseScore": 2.3, + "vectorString": "CVSS:4.0/AV:N/AC:H/AT:P/PR:L/UI:N/VC:N/VI:L/VA:N/SC:N/SI:N/SA:N/U:Clear" + } + } + ], + "credits": [ + { + "lang": "en", + "value": "Xiangdong Li (Student, Beijing University of Posts and Telecommunications [BUPT])", + "type": "finder" + } + ], + "source": { + "discovery": "UNKNOWN" + }, + "x_generator": { + "engine": "Vulnogram 1.0.2" + } + }, + "adp": [ + { + "metrics": [ + { + "other": { + "type": "ssvc", + "content": { + "timestamp": "2026-06-26T13:06:13.858983Z", + "id": "CVE-2026-6412", + "options": [ + { + "Exploitation": "none" + }, + { + "Automatable": "no" + }, + { + "Technical Impact": "partial" + } + ], + "role": "CISA Coordinator", + "version": "2.0.3" + } + } + } + ], + "title": "CISA ADP Vulnrichment", + "providerMetadata": { + "orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0", + "shortName": "CISA-ADP", + "dateUpdated": "2026-06-26T13:06:26.002Z" + } + } + ] + } +} diff --git a/advisories/records/CVE-2026-6450.json b/advisories/records/CVE-2026-6450.json new file mode 100644 index 0000000..a751a8a --- /dev/null +++ b/advisories/records/CVE-2026-6450.json @@ -0,0 +1,157 @@ +{ + "dataType": "CVE_RECORD", + "dataVersion": "5.2", + "cveMetadata": { + "cveId": "CVE-2026-6450", + "assignerOrgId": "50d2cd11-d01a-48ed-9441-5bfce9d63b27", + "state": "PUBLISHED", + "assignerShortName": "wolfSSL", + "dateReserved": "2026-04-16T19:15:04.573Z", + "datePublished": "2026-06-25T20:18:53.909Z", + "dateUpdated": "2026-06-26T13:11:51.371Z" + }, + "containers": { + "cna": { + "providerMetadata": { + "orgId": "50d2cd11-d01a-48ed-9441-5bfce9d63b27", + "shortName": "wolfSSL", + "dateUpdated": "2026-06-25T20:18:53.909Z" + }, + "title": "CRL critical extension bypass in ParseCRL_Extensions", + "problemTypes": [ + { + "descriptions": [ + { + "lang": "en", + "cweId": "CWE-295", + "description": "CWE-295 Improper Certificate Validation", + "type": "CWE" + } + ] + } + ], + "affected": [ + { + "vendor": "wolfSSL", + "product": "wolfSSL", + "collectionURL": "https://github.com/wolfSSL/wolfssl", + "versions": [ + { + "status": "affected", + "version": "4.3.0", + "lessThanOrEqual": "5.9.1", + "versionType": "semver" + } + ], + "defaultStatus": "unaffected" + } + ], + "descriptions": [ + { + "lang": "en", + "value": "A CRL critical extension bypass exists in ParseCRL_Extensions where critical extensions are not properly enforced, allowing a crafted CRL with an unhandled critical extension to be accepted. This only affects builds with CRL support enabled and where a crafted CRL had a trusted signature when parsed.", + "supportingMedia": [ + { + "type": "text/html", + "base64": false, + "value": "

A CRL critical extension bypass exists in ParseCRL_Extensions where critical extensions are not properly enforced, allowing a crafted CRL with an unhandled critical extension to be accepted. This only affects builds with CRL support enabled and where a crafted CRL had a trusted signature when parsed.

" + } + ] + } + ], + "references": [ + { + "url": "https://github.com/wolfSSL/wolfssl/pull/10239", + "tags": [ + "patch" + ] + }, + { + "url": "https://www.wolfssl.com/docs/security-vulnerabilities/" + } + ], + "metrics": [ + { + "format": "CVSS", + "scenarios": [ + { + "lang": "en", + "value": "GENERAL" + } + ], + "cvssV4_0": { + "attackVector": "ADJACENT", + "attackComplexity": "HIGH", + "attackRequirements": "PRESENT", + "privilegesRequired": "HIGH", + "userInteraction": "PASSIVE", + "vulnConfidentialityImpact": "NONE", + "subConfidentialityImpact": "NONE", + "vulnIntegrityImpact": "LOW", + "subIntegrityImpact": "NONE", + "vulnAvailabilityImpact": "NONE", + "subAvailabilityImpact": "NONE", + "exploitMaturity": "NOT_DEFINED", + "Safety": "NOT_DEFINED", + "Automatable": "NOT_DEFINED", + "Recovery": "NOT_DEFINED", + "valueDensity": "NOT_DEFINED", + "vulnerabilityResponseEffort": "NOT_DEFINED", + "providerUrgency": "NOT_DEFINED", + "version": "4.0", + "baseSeverity": "LOW", + "baseScore": 1, + "vectorString": "CVSS:4.0/AV:A/AC:H/AT:P/PR:H/UI:P/VC:N/VI:L/VA:N/SC:N/SI:N/SA:N" + } + } + ], + "credits": [ + { + "lang": "en", + "value": "Oleh Konko (@1seal)", + "type": "finder" + } + ], + "source": { + "discovery": "UNKNOWN" + }, + "x_generator": { + "engine": "Vulnogram 1.0.2" + } + }, + "adp": [ + { + "metrics": [ + { + "other": { + "type": "ssvc", + "content": { + "timestamp": "2026-06-26T13:11:44.804813Z", + "id": "CVE-2026-6450", + "options": [ + { + "Exploitation": "none" + }, + { + "Automatable": "no" + }, + { + "Technical Impact": "partial" + } + ], + "role": "CISA Coordinator", + "version": "2.0.3" + } + } + } + ], + "title": "CISA ADP Vulnrichment", + "providerMetadata": { + "orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0", + "shortName": "CISA-ADP", + "dateUpdated": "2026-06-26T13:11:51.371Z" + } + } + ] + } +} diff --git a/advisories/records/CVE-2026-6678.json b/advisories/records/CVE-2026-6678.json new file mode 100644 index 0000000..baecd28 --- /dev/null +++ b/advisories/records/CVE-2026-6678.json @@ -0,0 +1,170 @@ +{ + "dataType": "CVE_RECORD", + "dataVersion": "5.2", + "cveMetadata": { + "cveId": "CVE-2026-6678", + "assignerOrgId": "50d2cd11-d01a-48ed-9441-5bfce9d63b27", + "state": "PUBLISHED", + "assignerShortName": "wolfSSL", + "dateReserved": "2026-04-20T14:57:53.610Z", + "datePublished": "2026-06-25T20:16:08.416Z", + "dateUpdated": "2026-07-01T16:47:47.199Z" + }, + "containers": { + "cna": { + "providerMetadata": { + "orgId": "50d2cd11-d01a-48ed-9441-5bfce9d63b27", + "shortName": "wolfSSL", + "dateUpdated": "2026-06-25T20:16:08.416Z" + }, + "title": "Integer underflow in wc_PKCS7_DecryptOri handling crafted Other Recipient Info", + "problemTypes": [ + { + "descriptions": [ + { + "lang": "en", + "cweId": "CWE-191", + "description": "CWE-191 Integer Underflow (Wrap or Wraparound)", + "type": "CWE" + } + ] + } + ], + "affected": [ + { + "vendor": "wolfSSL", + "product": "wolfSSL", + "collectionURL": "https://github.com/wolfSSL/wolfssl", + "versions": [ + { + "status": "affected", + "version": "3.15.5", + "lessThanOrEqual": "5.9.1", + "versionType": "semver" + } + ], + "defaultStatus": "unaffected" + } + ], + "descriptions": [ + { + "lang": "en", + "value": "Integer underflow in wc_PKCS7_DecryptOri when handling crafted Other Recipient Info, leading to incorrect length handling during decryption.", + "supportingMedia": [ + { + "type": "text/html", + "base64": false, + "value": "

Integer underflow in wc_PKCS7_DecryptOri when handling crafted Other Recipient Info, leading to incorrect length handling during decryption.

" + } + ] + } + ], + "references": [ + { + "url": "https://github.com/wolfSSL/wolfssl/pull/10203", + "tags": [ + "patch" + ] + }, + { + "url": "https://www.wolfssl.com/docs/security-vulnerabilities/" + } + ], + "metrics": [ + { + "format": "CVSS", + "scenarios": [ + { + "lang": "en", + "value": "GENERAL" + } + ], + "cvssV4_0": { + "attackVector": "LOCAL", + "attackComplexity": "HIGH", + "attackRequirements": "PRESENT", + "privilegesRequired": "LOW", + "userInteraction": "PASSIVE", + "vulnConfidentialityImpact": "NONE", + "subConfidentialityImpact": "NONE", + "vulnIntegrityImpact": "NONE", + "subIntegrityImpact": "NONE", + "vulnAvailabilityImpact": "LOW", + "subAvailabilityImpact": "NONE", + "exploitMaturity": "NOT_DEFINED", + "Safety": "NOT_DEFINED", + "Automatable": "NOT_DEFINED", + "Recovery": "NOT_DEFINED", + "valueDensity": "NOT_DEFINED", + "vulnerabilityResponseEffort": "NOT_DEFINED", + "providerUrgency": "CLEAR", + "version": "4.0", + "baseSeverity": "LOW", + "baseScore": 1, + "vectorString": "CVSS:4.0/AV:L/AC:H/AT:P/PR:L/UI:P/VC:N/VI:N/VA:L/SC:N/SI:N/SA:N/U:Clear" + } + } + ], + "credits": [ + { + "lang": "en", + "value": "Dikai Zou", + "type": "finder" + } + ], + "source": { + "discovery": "UNKNOWN" + }, + "x_generator": { + "engine": "Vulnogram 1.0.2" + } + }, + "adp": [ + { + "metrics": [ + { + "other": { + "type": "ssvc", + "content": { + "timestamp": "2026-06-26T13:12:40.962989Z", + "id": "CVE-2026-6678", + "options": [ + { + "Exploitation": "none" + }, + { + "Automatable": "no" + }, + { + "Technical Impact": "partial" + } + ], + "role": "CISA Coordinator", + "version": "2.0.3" + } + } + } + ], + "title": "CISA ADP Vulnrichment", + "providerMetadata": { + "orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0", + "shortName": "CISA-ADP", + "dateUpdated": "2026-06-26T13:12:54.073Z" + } + }, + { + "title": "CVE Program Container", + "references": [ + { + "url": "https://www.talosintelligence.com/vulnerability_reports/TALOS-2026-2408" + } + ], + "providerMetadata": { + "orgId": "af854a3a-2127-422b-91ae-364da2661108", + "shortName": "CVE", + "dateUpdated": "2026-07-01T16:47:47.199Z" + } + } + ] + } +} diff --git a/advisories/records/CVE-2026-6679.json b/advisories/records/CVE-2026-6679.json new file mode 100644 index 0000000..b7de389 --- /dev/null +++ b/advisories/records/CVE-2026-6679.json @@ -0,0 +1,169 @@ +{ + "dataType": "CVE_RECORD", + "dataVersion": "5.2", + "cveMetadata": { + "cveId": "CVE-2026-6679", + "assignerOrgId": "50d2cd11-d01a-48ed-9441-5bfce9d63b27", + "state": "PUBLISHED", + "assignerShortName": "wolfSSL", + "dateReserved": "2026-04-20T15:00:29.102Z", + "datePublished": "2026-06-25T20:13:06.190Z", + "dateUpdated": "2026-06-26T13:13:41.022Z" + }, + "containers": { + "cna": { + "providerMetadata": { + "orgId": "50d2cd11-d01a-48ed-9441-5bfce9d63b27", + "shortName": "wolfSSL", + "dateUpdated": "2026-06-25T20:13:06.190Z" + }, + "title": "DTLS 1.3 ACK serialization heap buffer overflow via integer truncation", + "problemTypes": [ + { + "descriptions": [ + { + "lang": "en", + "cweId": "CWE-787", + "description": "CWE-787 Out-of-bounds Write", + "type": "CWE" + }, + { + "lang": "en", + "cweId": "CWE-190", + "description": "CWE-190 Integer Overflow or Wraparound", + "type": "CWE" + }, + { + "lang": "en", + "cweId": "CWE-197", + "description": "CWE-197 Numeric Truncation Error", + "type": "CWE" + } + ] + } + ], + "affected": [ + { + "vendor": "wolfSSL", + "product": "wolfSSL", + "collectionURL": "https://github.com/wolfSSL/wolfssl", + "versions": [ + { + "status": "affected", + "version": "5.4.0", + "lessThanOrEqual": "5.9.0", + "versionType": "semver" + } + ], + "defaultStatus": "unaffected" + } + ], + "descriptions": [ + { + "lang": "en", + "value": "A heap buffer overflow could occur in the DTLS 1.3 ACK serialization path before the connecting peer is authenticated. The buffer overflow was due to an integer truncation when computing the length of the ACK record-number list, causing an undersized buffer to be allocated and then overrun. This affects builds using DTLS 1.3 and wolfSSL version 5.9.0 and earlier. A fix was added to the 5.9.1 release.", + "supportingMedia": [ + { + "type": "text/html", + "base64": false, + "value": "

A heap buffer overflow could occur in the DTLS 1.3 ACK serialization path before the connecting peer is authenticated. The buffer overflow was due to an integer truncation when computing the length of the ACK record-number list, causing an undersized buffer to be allocated and then overrun. This affects builds using DTLS 1.3 and wolfSSL version 5.9.0 and earlier. A fix was added to the 5.9.1 release.

" + } + ] + } + ], + "references": [ + { + "url": "https://github.com/wolfSSL/wolfssl/pull/10116", + "tags": [ + "patch" + ] + }, + { + "url": "https://www.wolfssl.com/docs/security-vulnerabilities/" + } + ], + "metrics": [ + { + "format": "CVSS", + "scenarios": [ + { + "lang": "en", + "value": "GENERAL" + } + ], + "cvssV4_0": { + "attackVector": "NETWORK", + "attackComplexity": "LOW", + "attackRequirements": "NONE", + "privilegesRequired": "NONE", + "userInteraction": "NONE", + "vulnConfidentialityImpact": "NONE", + "subConfidentialityImpact": "NONE", + "vulnIntegrityImpact": "LOW", + "subIntegrityImpact": "NONE", + "vulnAvailabilityImpact": "HIGH", + "subAvailabilityImpact": "NONE", + "exploitMaturity": "NOT_DEFINED", + "Safety": "NOT_DEFINED", + "Automatable": "NOT_DEFINED", + "Recovery": "NOT_DEFINED", + "valueDensity": "NOT_DEFINED", + "vulnerabilityResponseEffort": "NOT_DEFINED", + "providerUrgency": "NOT_DEFINED", + "version": "4.0", + "baseSeverity": "HIGH", + "baseScore": 8.8, + "vectorString": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:L/VA:H/SC:N/SI:N/SA:N" + } + } + ], + "credits": [ + { + "lang": "en", + "value": "Nicholas Carlini from Anthropic", + "type": "finder" + } + ], + "source": { + "discovery": "UNKNOWN" + }, + "x_generator": { + "engine": "Vulnogram 1.0.2" + } + }, + "adp": [ + { + "metrics": [ + { + "other": { + "type": "ssvc", + "content": { + "timestamp": "2026-06-26T13:13:34.694158Z", + "id": "CVE-2026-6679", + "options": [ + { + "Exploitation": "none" + }, + { + "Automatable": "yes" + }, + { + "Technical Impact": "partial" + } + ], + "role": "CISA Coordinator", + "version": "2.0.3" + } + } + } + ], + "title": "CISA ADP Vulnrichment", + "providerMetadata": { + "orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0", + "shortName": "CISA-ADP", + "dateUpdated": "2026-06-26T13:13:41.022Z" + } + } + ] + } +} diff --git a/advisories/records/CVE-2026-6681.json b/advisories/records/CVE-2026-6681.json new file mode 100644 index 0000000..8653221 --- /dev/null +++ b/advisories/records/CVE-2026-6681.json @@ -0,0 +1,163 @@ +{ + "dataType": "CVE_RECORD", + "dataVersion": "5.2", + "cveMetadata": { + "cveId": "CVE-2026-6681", + "assignerOrgId": "50d2cd11-d01a-48ed-9441-5bfce9d63b27", + "state": "PUBLISHED", + "assignerShortName": "wolfSSL", + "dateReserved": "2026-04-20T15:00:32.607Z", + "datePublished": "2026-06-25T20:11:39.446Z", + "dateUpdated": "2026-06-26T13:14:09.177Z" + }, + "containers": { + "cna": { + "providerMetadata": { + "orgId": "50d2cd11-d01a-48ed-9441-5bfce9d63b27", + "shortName": "wolfSSL", + "dateUpdated": "2026-06-25T20:11:39.446Z" + }, + "title": "PKCS#7 decode ignores caller output buffer size, writing past buffer bounds", + "problemTypes": [ + { + "descriptions": [ + { + "lang": "en", + "cweId": "CWE-787", + "description": "CWE-787 Out-of-bounds Write", + "type": "CWE" + }, + { + "lang": "en", + "cweId": "CWE-120", + "description": "CWE-120 Buffer Copy without Checking Size of Input", + "type": "CWE" + } + ] + } + ], + "affected": [ + { + "vendor": "wolfSSL", + "product": "wolfSSL", + "collectionURL": "https://github.com/wolfSSL/wolfssl", + "versions": [ + { + "status": "affected", + "version": "3.10.0", + "lessThanOrEqual": "5.9.0", + "versionType": "semver" + } + ], + "defaultStatus": "unaffected" + } + ], + "descriptions": [ + { + "lang": "en", + "value": "The PKCS#7 decode path ignores the caller-supplied output buffer size (outputSz), allowing decoded content to be written past the bounds of the provided buffer. This affects wolfSSL 5.9.0 and earlier and was fixed in the 5.9.1 release.", + "supportingMedia": [ + { + "type": "text/html", + "base64": false, + "value": "

The PKCS#7 decode path ignores the caller-supplied output buffer size (outputSz), allowing decoded content to be written past the bounds of the provided buffer. This affects wolfSSL 5.9.0 and earlier and was fixed in the 5.9.1 release.

" + } + ] + } + ], + "references": [ + { + "url": "https://github.com/wolfSSL/wolfssl/pull/10116", + "tags": [ + "patch" + ] + }, + { + "url": "https://www.wolfssl.com/docs/security-vulnerabilities/" + } + ], + "metrics": [ + { + "format": "CVSS", + "scenarios": [ + { + "lang": "en", + "value": "GENERAL" + } + ], + "cvssV4_0": { + "attackVector": "ADJACENT", + "attackComplexity": "LOW", + "attackRequirements": "PRESENT", + "privilegesRequired": "LOW", + "userInteraction": "PASSIVE", + "vulnConfidentialityImpact": "NONE", + "subConfidentialityImpact": "NONE", + "vulnIntegrityImpact": "LOW", + "subIntegrityImpact": "NONE", + "vulnAvailabilityImpact": "NONE", + "subAvailabilityImpact": "NONE", + "exploitMaturity": "NOT_DEFINED", + "Safety": "NOT_DEFINED", + "Automatable": "NOT_DEFINED", + "Recovery": "NOT_DEFINED", + "valueDensity": "NOT_DEFINED", + "vulnerabilityResponseEffort": "NOT_DEFINED", + "providerUrgency": "CLEAR", + "version": "4.0", + "baseSeverity": "LOW", + "baseScore": 1, + "vectorString": "CVSS:4.0/AV:A/AC:L/AT:P/PR:L/UI:P/VC:N/VI:L/VA:N/SC:N/SI:N/SA:N/U:Clear" + } + } + ], + "credits": [ + { + "lang": "en", + "value": "Nicholas Carlini from Anthropic", + "type": "finder" + } + ], + "source": { + "discovery": "UNKNOWN" + }, + "x_generator": { + "engine": "Vulnogram 1.0.2" + } + }, + "adp": [ + { + "metrics": [ + { + "other": { + "type": "ssvc", + "content": { + "timestamp": "2026-06-26T13:13:59.659791Z", + "id": "CVE-2026-6681", + "options": [ + { + "Exploitation": "none" + }, + { + "Automatable": "no" + }, + { + "Technical Impact": "partial" + } + ], + "role": "CISA Coordinator", + "version": "2.0.3" + } + } + } + ], + "title": "CISA ADP Vulnrichment", + "providerMetadata": { + "orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0", + "shortName": "CISA-ADP", + "dateUpdated": "2026-06-26T13:14:09.177Z" + } + } + ] + } +} diff --git a/advisories/records/CVE-2026-6731.json b/advisories/records/CVE-2026-6731.json new file mode 100644 index 0000000..a8f9d2b --- /dev/null +++ b/advisories/records/CVE-2026-6731.json @@ -0,0 +1,157 @@ +{ + "dataType": "CVE_RECORD", + "dataVersion": "5.2", + "cveMetadata": { + "cveId": "CVE-2026-6731", + "assignerOrgId": "50d2cd11-d01a-48ed-9441-5bfce9d63b27", + "state": "PUBLISHED", + "assignerShortName": "wolfSSL", + "dateReserved": "2026-04-20T21:59:52.635Z", + "datePublished": "2026-06-25T20:08:13.248Z", + "dateUpdated": "2026-06-26T13:16:07.279Z" + }, + "containers": { + "cna": { + "providerMetadata": { + "orgId": "50d2cd11-d01a-48ed-9441-5bfce9d63b27", + "shortName": "wolfSSL", + "dateUpdated": "2026-06-25T20:08:13.248Z" + }, + "title": "X.509 name constraint bypass via Subject CN treated as a DNS name", + "problemTypes": [ + { + "descriptions": [ + { + "lang": "en", + "cweId": "CWE-295", + "description": "CWE-295 Improper Certificate Validation", + "type": "CWE" + } + ] + } + ], + "affected": [ + { + "vendor": "wolfSSL", + "product": "wolfSSL", + "collectionURL": "https://github.com/wolfSSL/wolfssl", + "versions": [ + { + "status": "affected", + "version": "3.9.10", + "lessThanOrEqual": "5.9.1", + "versionType": "semver" + } + ], + "defaultStatus": "unaffected" + } + ], + "descriptions": [ + { + "lang": "en", + "value": "X.509 name constraint bypass via the Subject Common Name when treated as a DNS-type name. A certificate whose Subject CN violates an issuing CA's DNS name constraints could be accepted.", + "supportingMedia": [ + { + "type": "text/html", + "base64": false, + "value": "

X.509 name constraint bypass via the Subject Common Name when treated as a DNS-type name. A certificate whose Subject CN violates an issuing CA's DNS name constraints could be accepted.

" + } + ] + } + ], + "references": [ + { + "url": "https://github.com/wolfSSL/wolfssl/pull/10223", + "tags": [ + "patch" + ] + }, + { + "url": "https://www.wolfssl.com/docs/security-vulnerabilities/" + } + ], + "metrics": [ + { + "format": "CVSS", + "scenarios": [ + { + "lang": "en", + "value": "GENERAL" + } + ], + "cvssV4_0": { + "attackVector": "NETWORK", + "attackComplexity": "LOW", + "attackRequirements": "PRESENT", + "privilegesRequired": "LOW", + "userInteraction": "NONE", + "vulnConfidentialityImpact": "NONE", + "subConfidentialityImpact": "NONE", + "vulnIntegrityImpact": "HIGH", + "subIntegrityImpact": "NONE", + "vulnAvailabilityImpact": "NONE", + "subAvailabilityImpact": "NONE", + "exploitMaturity": "NOT_DEFINED", + "Safety": "NOT_DEFINED", + "Automatable": "NOT_DEFINED", + "Recovery": "NOT_DEFINED", + "valueDensity": "NOT_DEFINED", + "vulnerabilityResponseEffort": "NOT_DEFINED", + "providerUrgency": "NOT_DEFINED", + "version": "4.0", + "baseSeverity": "MEDIUM", + "baseScore": 6, + "vectorString": "CVSS:4.0/AV:N/AC:L/AT:P/PR:L/UI:N/VC:N/VI:H/VA:N/SC:N/SI:N/SA:N" + } + } + ], + "credits": [ + { + "lang": "en", + "value": "d0sf3t (Aradex)", + "type": "finder" + } + ], + "source": { + "discovery": "UNKNOWN" + }, + "x_generator": { + "engine": "Vulnogram 1.0.2" + } + }, + "adp": [ + { + "metrics": [ + { + "other": { + "type": "ssvc", + "content": { + "timestamp": "2026-06-26T13:14:35.217186Z", + "id": "CVE-2026-6731", + "options": [ + { + "Exploitation": "none" + }, + { + "Automatable": "no" + }, + { + "Technical Impact": "partial" + } + ], + "role": "CISA Coordinator", + "version": "2.0.3" + } + } + } + ], + "title": "CISA ADP Vulnrichment", + "providerMetadata": { + "orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0", + "shortName": "CISA-ADP", + "dateUpdated": "2026-06-26T13:16:07.279Z" + } + } + ] + } +} diff --git a/advisories/records/CVE-2026-7511.json b/advisories/records/CVE-2026-7511.json new file mode 100644 index 0000000..17a6d65 --- /dev/null +++ b/advisories/records/CVE-2026-7511.json @@ -0,0 +1,157 @@ +{ + "dataType": "CVE_RECORD", + "dataVersion": "5.2", + "cveMetadata": { + "cveId": "CVE-2026-7511", + "assignerOrgId": "50d2cd11-d01a-48ed-9441-5bfce9d63b27", + "state": "PUBLISHED", + "assignerShortName": "wolfSSL", + "dateReserved": "2026-04-30T15:18:06.285Z", + "datePublished": "2026-06-25T21:32:29.283Z", + "dateUpdated": "2026-06-26T10:37:09.590Z" + }, + "containers": { + "cna": { + "providerMetadata": { + "orgId": "50d2cd11-d01a-48ed-9441-5bfce9d63b27", + "shortName": "wolfSSL", + "dateUpdated": "2026-06-25T21:32:29.283Z" + }, + "title": "PKCS7_verify signer confusion allows forged signatures to be accepted", + "problemTypes": [ + { + "descriptions": [ + { + "lang": "en", + "cweId": "CWE-347", + "description": "CWE-347 Improper Verification of Cryptographic Signature", + "type": "CWE" + } + ] + } + ], + "affected": [ + { + "vendor": "wolfSSL", + "product": "wolfSSL", + "collectionURL": "https://github.com/wolfSSL/wolfssl", + "versions": [ + { + "status": "affected", + "version": "3.15.5", + "lessThanOrEqual": "5.9.1", + "versionType": "semver" + } + ], + "defaultStatus": "unaffected" + } + ], + "descriptions": [ + { + "lang": "en", + "value": "PKCS7_verify signer confusion allows forged signatures, where the signer associated with a signature is not correctly bound, permitting a forged signature to be accepted.", + "supportingMedia": [ + { + "type": "text/html", + "base64": false, + "value": "

PKCS7_verify signer confusion allows forged signatures, where the signer associated with a signature is not correctly bound, permitting a forged signature to be accepted.

" + } + ] + } + ], + "references": [ + { + "url": "https://github.com/wolfSSL/wolfssl/pull/10203", + "tags": [ + "patch" + ] + }, + { + "url": "https://www.wolfssl.com/docs/security-vulnerabilities/" + } + ], + "metrics": [ + { + "format": "CVSS", + "scenarios": [ + { + "lang": "en", + "value": "GENERAL" + } + ], + "cvssV4_0": { + "attackVector": "ADJACENT", + "attackComplexity": "HIGH", + "attackRequirements": "PRESENT", + "privilegesRequired": "NONE", + "userInteraction": "PASSIVE", + "vulnConfidentialityImpact": "NONE", + "subConfidentialityImpact": "NONE", + "vulnIntegrityImpact": "HIGH", + "subIntegrityImpact": "NONE", + "vulnAvailabilityImpact": "NONE", + "subAvailabilityImpact": "NONE", + "exploitMaturity": "NOT_DEFINED", + "Safety": "NOT_DEFINED", + "Automatable": "NOT_DEFINED", + "Recovery": "NOT_DEFINED", + "valueDensity": "NOT_DEFINED", + "vulnerabilityResponseEffort": "NOT_DEFINED", + "providerUrgency": "NOT_DEFINED", + "version": "4.0", + "baseSeverity": "MEDIUM", + "baseScore": 5.9, + "vectorString": "CVSS:4.0/AV:A/AC:H/AT:P/PR:N/UI:P/VC:N/VI:H/VA:N/SC:N/SI:N/SA:N" + } + } + ], + "credits": [ + { + "lang": "en", + "value": "Nicholas Carlini from Anthropic", + "type": "finder" + } + ], + "source": { + "discovery": "UNKNOWN" + }, + "x_generator": { + "engine": "Vulnogram 1.0.2" + } + }, + "adp": [ + { + "metrics": [ + { + "other": { + "type": "ssvc", + "content": { + "timestamp": "2026-06-26T10:36:56.224019Z", + "id": "CVE-2026-7511", + "options": [ + { + "Exploitation": "none" + }, + { + "Automatable": "no" + }, + { + "Technical Impact": "partial" + } + ], + "role": "CISA Coordinator", + "version": "2.0.3" + } + } + } + ], + "title": "CISA ADP Vulnrichment", + "providerMetadata": { + "orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0", + "shortName": "CISA-ADP", + "dateUpdated": "2026-06-26T10:37:09.590Z" + } + } + ] + } +} diff --git a/advisories/records/CVE-2026-7531.json b/advisories/records/CVE-2026-7531.json new file mode 100644 index 0000000..8c1da09 --- /dev/null +++ b/advisories/records/CVE-2026-7531.json @@ -0,0 +1,157 @@ +{ + "dataType": "CVE_RECORD", + "dataVersion": "5.2", + "cveMetadata": { + "cveId": "CVE-2026-7531", + "assignerOrgId": "50d2cd11-d01a-48ed-9441-5bfce9d63b27", + "state": "PUBLISHED", + "assignerShortName": "wolfSSL", + "dateReserved": "2026-04-30T17:58:26.743Z", + "datePublished": "2026-06-25T20:01:16.991Z", + "dateUpdated": "2026-06-26T13:17:13.271Z" + }, + "containers": { + "cna": { + "providerMetadata": { + "orgId": "50d2cd11-d01a-48ed-9441-5bfce9d63b27", + "shortName": "wolfSSL", + "dateUpdated": "2026-06-25T20:01:16.991Z" + }, + "title": "Use-after-free in PQC hybrid key-share handling", + "problemTypes": [ + { + "descriptions": [ + { + "lang": "en", + "cweId": "CWE-416", + "description": "CWE-416 Use After Free", + "type": "CWE" + } + ] + } + ], + "affected": [ + { + "vendor": "wolfSSL", + "product": "wolfSSL", + "collectionURL": "https://github.com/wolfSSL/wolfssl", + "versions": [ + { + "status": "affected", + "version": "5.8.0", + "lessThanOrEqual": "5.9.1", + "versionType": "semver" + } + ], + "defaultStatus": "unaffected" + } + ], + "descriptions": [ + { + "lang": "en", + "value": "Use-after-free in PQC hybrid key-share handling. This is an incomplete-fix follow-up to CVE-2026-5460 (released in 5.9.1): a malicious TLS 1.3 server sending a truncated PQC hybrid KeyShare can still trigger the error cleanup path to operate on freed memory.", + "supportingMedia": [ + { + "type": "text/html", + "base64": false, + "value": "

Use-after-free in PQC hybrid key-share handling. This is an incomplete-fix follow-up to CVE-2026-5460 (released in 5.9.1): a malicious TLS 1.3 server sending a truncated PQC hybrid KeyShare can still trigger the error cleanup path to operate on freed memory.

" + } + ] + } + ], + "references": [ + { + "url": "https://github.com/wolfSSL/wolfssl/pull/10327", + "tags": [ + "patch" + ] + }, + { + "url": "https://www.wolfssl.com/docs/security-vulnerabilities/" + } + ], + "metrics": [ + { + "format": "CVSS", + "scenarios": [ + { + "lang": "en", + "value": "GENERAL" + } + ], + "cvssV4_0": { + "attackVector": "NETWORK", + "attackComplexity": "HIGH", + "attackRequirements": "PRESENT", + "privilegesRequired": "NONE", + "userInteraction": "PASSIVE", + "vulnConfidentialityImpact": "NONE", + "subConfidentialityImpact": "NONE", + "vulnIntegrityImpact": "NONE", + "subIntegrityImpact": "NONE", + "vulnAvailabilityImpact": "LOW", + "subAvailabilityImpact": "NONE", + "exploitMaturity": "NOT_DEFINED", + "Safety": "NOT_DEFINED", + "Automatable": "NOT_DEFINED", + "Recovery": "NOT_DEFINED", + "valueDensity": "NOT_DEFINED", + "vulnerabilityResponseEffort": "NOT_DEFINED", + "providerUrgency": "NOT_DEFINED", + "version": "4.0", + "baseSeverity": "LOW", + "baseScore": 2.3, + "vectorString": "CVSS:4.0/AV:N/AC:H/AT:P/PR:N/UI:P/VC:N/VI:N/VA:L/SC:N/SI:N/SA:N" + } + } + ], + "credits": [ + { + "lang": "en", + "value": "Thai Duong (Calif.io / Anthropic)", + "type": "finder" + } + ], + "source": { + "discovery": "UNKNOWN" + }, + "x_generator": { + "engine": "Vulnogram 1.0.2" + } + }, + "adp": [ + { + "metrics": [ + { + "other": { + "type": "ssvc", + "content": { + "timestamp": "2026-06-26T13:17:06.406308Z", + "id": "CVE-2026-7531", + "options": [ + { + "Exploitation": "none" + }, + { + "Automatable": "no" + }, + { + "Technical Impact": "partial" + } + ], + "role": "CISA Coordinator", + "version": "2.0.3" + } + } + } + ], + "title": "CISA ADP Vulnrichment", + "providerMetadata": { + "orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0", + "shortName": "CISA-ADP", + "dateUpdated": "2026-06-26T13:17:13.271Z" + } + } + ] + } +} diff --git a/advisories/records/CVE-2026-7532.json b/advisories/records/CVE-2026-7532.json new file mode 100644 index 0000000..28540f0 --- /dev/null +++ b/advisories/records/CVE-2026-7532.json @@ -0,0 +1,170 @@ +{ + "dataType": "CVE_RECORD", + "dataVersion": "5.2", + "cveMetadata": { + "cveId": "CVE-2026-7532", + "assignerOrgId": "50d2cd11-d01a-48ed-9441-5bfce9d63b27", + "state": "PUBLISHED", + "assignerShortName": "wolfSSL", + "dateReserved": "2026-04-30T17:58:46.527Z", + "datePublished": "2026-06-25T21:31:11.577Z", + "dateUpdated": "2026-07-01T16:47:48.539Z" + }, + "containers": { + "cna": { + "providerMetadata": { + "orgId": "50d2cd11-d01a-48ed-9441-5bfce9d63b27", + "shortName": "wolfSSL", + "dateUpdated": "2026-06-25T21:31:11.577Z" + }, + "title": "iPAddress name constraints not enforced when WOLFSSL_IP_ALT_NAME is undefined", + "problemTypes": [ + { + "descriptions": [ + { + "lang": "en", + "cweId": "CWE-295", + "description": "CWE-295 Improper Certificate Validation", + "type": "CWE" + } + ] + } + ], + "affected": [ + { + "vendor": "wolfSSL", + "product": "wolfSSL", + "collectionURL": "https://github.com/wolfSSL/wolfssl", + "versions": [ + { + "status": "affected", + "version": "0", + "lessThanOrEqual": "5.9.1", + "versionType": "semver" + } + ], + "defaultStatus": "unaffected" + } + ], + "descriptions": [ + { + "lang": "en", + "value": "iPAddress name constraints bypass when WOLFSSL_IP_ALT_NAME is not defined. IP address name constraints are not enforced in that configuration, allowing a certificate to bypass an issuing CA's IP address constraints.", + "supportingMedia": [ + { + "type": "text/html", + "base64": false, + "value": "

iPAddress name constraints bypass when WOLFSSL_IP_ALT_NAME is not defined. IP address name constraints are not enforced in that configuration, allowing a certificate to bypass an issuing CA's IP address constraints.

" + } + ] + } + ], + "references": [ + { + "url": "https://github.com/wolfSSL/wolfssl/pull/10354", + "tags": [ + "patch" + ] + }, + { + "url": "https://www.wolfssl.com/docs/security-vulnerabilities/" + } + ], + "metrics": [ + { + "format": "CVSS", + "scenarios": [ + { + "lang": "en", + "value": "GENERAL" + } + ], + "cvssV4_0": { + "attackVector": "ADJACENT", + "attackComplexity": "LOW", + "attackRequirements": "PRESENT", + "privilegesRequired": "HIGH", + "userInteraction": "NONE", + "vulnConfidentialityImpact": "NONE", + "subConfidentialityImpact": "NONE", + "vulnIntegrityImpact": "HIGH", + "subIntegrityImpact": "NONE", + "vulnAvailabilityImpact": "NONE", + "subAvailabilityImpact": "NONE", + "exploitMaturity": "NOT_DEFINED", + "Safety": "NOT_DEFINED", + "Automatable": "NOT_DEFINED", + "Recovery": "NOT_DEFINED", + "valueDensity": "NOT_DEFINED", + "vulnerabilityResponseEffort": "NOT_DEFINED", + "providerUrgency": "NOT_DEFINED", + "version": "4.0", + "baseSeverity": "MEDIUM", + "baseScore": 5.7, + "vectorString": "CVSS:4.0/AV:A/AC:L/AT:P/PR:H/UI:N/VC:N/VI:H/VA:N/SC:N/SI:N/SA:N" + } + } + ], + "credits": [ + { + "lang": "en", + "value": "Ankur Tyagi of Cisco Talos (TALOS-2026-2409)", + "type": "finder" + } + ], + "source": { + "discovery": "UNKNOWN" + }, + "x_generator": { + "engine": "Vulnogram 1.0.2" + } + }, + "adp": [ + { + "metrics": [ + { + "other": { + "type": "ssvc", + "content": { + "timestamp": "2026-06-26T10:36:20.315869Z", + "id": "CVE-2026-7532", + "options": [ + { + "Exploitation": "none" + }, + { + "Automatable": "no" + }, + { + "Technical Impact": "partial" + } + ], + "role": "CISA Coordinator", + "version": "2.0.3" + } + } + } + ], + "title": "CISA ADP Vulnrichment", + "providerMetadata": { + "orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0", + "shortName": "CISA-ADP", + "dateUpdated": "2026-06-26T10:36:33.703Z" + } + }, + { + "title": "CVE Program Container", + "references": [ + { + "url": "https://www.talosintelligence.com/vulnerability_reports/TALOS-2026-2409" + } + ], + "providerMetadata": { + "orgId": "af854a3a-2127-422b-91ae-364da2661108", + "shortName": "CVE", + "dateUpdated": "2026-07-01T16:47:48.539Z" + } + } + ] + } +} diff --git a/advisories/records/CVE-2026-8720.json b/advisories/records/CVE-2026-8720.json new file mode 100644 index 0000000..f7de54a --- /dev/null +++ b/advisories/records/CVE-2026-8720.json @@ -0,0 +1,150 @@ +{ + "dataType": "CVE_RECORD", + "dataVersion": "5.2", + "cveMetadata": { + "cveId": "CVE-2026-8720", + "assignerOrgId": "50d2cd11-d01a-48ed-9441-5bfce9d63b27", + "state": "PUBLISHED", + "assignerShortName": "wolfSSL", + "dateReserved": "2026-05-15T22:33:26.158Z", + "datePublished": "2026-06-25T21:18:29.260Z", + "dateUpdated": "2026-06-26T10:35:31.343Z" + }, + "containers": { + "cna": { + "providerMetadata": { + "orgId": "50d2cd11-d01a-48ed-9441-5bfce9d63b27", + "shortName": "wolfSSL", + "dateUpdated": "2026-06-25T21:18:29.260Z" + }, + "title": "HMAC-BLAKE2 final discards message when key length exceeds block size", + "problemTypes": [ + { + "descriptions": [ + { + "lang": "en", + "cweId": "CWE-354", + "description": "CWE-354 Improper Validation of Integrity Check Value", + "type": "CWE" + } + ] + } + ], + "affected": [ + { + "vendor": "wolfSSL", + "product": "wolfSSL", + "collectionURL": "https://github.com/wolfSSL/wolfssl", + "versions": [ + { + "status": "affected", + "version": "5.9.0", + "lessThanOrEqual": "5.9.1", + "versionType": "semver" + } + ], + "defaultStatus": "unaffected" + } + ], + "descriptions": [ + { + "lang": "en", + "value": "wc_Blake2bHmacFinal and wc_Blake2sHmacFinal discard the message when the key length exceeds the block size, producing a MAC that is independent of the input. When the supplied key is longer than the BLAKE2 block size the key-hashing branch reinitialized the running hash state, discarding the accumulated message data, so the resulting MAC depended only on the key and not on the message being authenticated. This bug is specific to the HMAC-BLAKE2 APIs that were added in wolfSSL version 5.9.0.", + "supportingMedia": [ + { + "type": "text/html", + "base64": false, + "value": "

wc_Blake2bHmacFinal and wc_Blake2sHmacFinal discard the message when the key length exceeds the block size, producing a MAC that is independent of the input. When the supplied key is longer than the BLAKE2 block size the key-hashing branch reinitialized the running hash state, discarding the accumulated message data, so the resulting MAC depended only on the key and not on the message being authenticated. This bug is specific to the HMAC-BLAKE2 APIs that were added in wolfSSL version 5.9.0.

" + } + ] + } + ], + "references": [ + { + "url": "https://github.com/wolfSSL/wolfssl/pull/10447", + "tags": [ + "patch" + ] + }, + { + "url": "https://www.wolfssl.com/docs/security-vulnerabilities/" + } + ], + "metrics": [ + { + "format": "CVSS", + "scenarios": [ + { + "lang": "en", + "value": "GENERAL" + } + ], + "cvssV4_0": { + "attackVector": "LOCAL", + "attackComplexity": "LOW", + "attackRequirements": "PRESENT", + "privilegesRequired": "NONE", + "userInteraction": "NONE", + "vulnConfidentialityImpact": "NONE", + "subConfidentialityImpact": "NONE", + "vulnIntegrityImpact": "HIGH", + "subIntegrityImpact": "NONE", + "vulnAvailabilityImpact": "NONE", + "subAvailabilityImpact": "NONE", + "exploitMaturity": "NOT_DEFINED", + "Safety": "NOT_DEFINED", + "Automatable": "NOT_DEFINED", + "Recovery": "NOT_DEFINED", + "valueDensity": "NOT_DEFINED", + "vulnerabilityResponseEffort": "NOT_DEFINED", + "providerUrgency": "NOT_DEFINED", + "version": "4.0", + "baseSeverity": "MEDIUM", + "baseScore": 5.9, + "vectorString": "CVSS:4.0/AV:L/AC:L/AT:P/PR:N/UI:N/VC:N/VI:H/VA:N/SC:N/SI:N/SA:N" + } + } + ], + "source": { + "discovery": "UNKNOWN" + }, + "x_generator": { + "engine": "Vulnogram 1.0.2" + } + }, + "adp": [ + { + "metrics": [ + { + "other": { + "type": "ssvc", + "content": { + "timestamp": "2026-06-26T10:35:07.726935Z", + "id": "CVE-2026-8720", + "options": [ + { + "Exploitation": "none" + }, + { + "Automatable": "no" + }, + { + "Technical Impact": "partial" + } + ], + "role": "CISA Coordinator", + "version": "2.0.3" + } + } + } + ], + "title": "CISA ADP Vulnrichment", + "providerMetadata": { + "orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0", + "shortName": "CISA-ADP", + "dateUpdated": "2026-06-26T10:35:31.343Z" + } + } + ] + } +} diff --git a/advisories/releases/5.9.2.cves b/advisories/releases/5.9.2.cves new file mode 100644 index 0000000..72db6a9 --- /dev/null +++ b/advisories/releases/5.9.2.cves @@ -0,0 +1,37 @@ +# Pinned CVE membership for wolfSSL 5.9.2 +# +# Bullet subjects from ChangeLog.md Vulnerabilities for +# wolfSSL Release 5.9.2. Predecessor ids named only in a +# bullet body are not listed. +CVE-2026-11310 +CVE-2026-11999 +CVE-2026-6679 +CVE-2026-55958 +CVE-2026-55960 +CVE-2026-55961 +CVE-2026-10097 +CVE-2026-6731 +CVE-2026-6091 +CVE-2026-6094 +CVE-2026-6329 +CVE-2026-6330 +CVE-2026-8720 +CVE-2026-10098 +CVE-2026-10592 +CVE-2026-7532 +CVE-2026-6291 +CVE-2026-7511 +CVE-2026-11703 +CVE-2026-55962 +CVE-2026-55964 +CVE-2026-6092 +CVE-2026-6331 +CVE-2026-6681 +CVE-2026-10512 +CVE-2026-6678 +CVE-2026-7531 +CVE-2026-6325 +CVE-2026-6412 +CVE-2026-6450 +CVE-2026-12340 +CVE-2026-55967 diff --git a/advisories/vex-overlay.json b/advisories/vex-overlay.json index c04c11d..73b43d5 100644 --- a/advisories/vex-overlay.json +++ b/advisories/vex-overlay.json @@ -1,21 +1,424 @@ { "_comment": "Canonical wolfSSL VEX overlay consumed by `make advisory` / `scripts/gen-advisory`. Keyed by CVE id; carries the determinations the CVE Program record cannot express (analysis state, justification, fixed versions, remediation, optional FIPS product, optional build-reachability hedge). Constrained by scripts/advisory-vex-overlay.schema.json. To model a wolfCrypt FIPS module as a separate product, add a \"fips\" block per the format in scripts/advisory-vex-overlay.example.json using the real validated module version and CMVP certificate number (do NOT copy the illustrative placeholder values from the example).", - "CVE-2026-5501": { "state": "exploitable", - "response": ["update"], + "response": [ + "update" + ], "detail": "Limited to applications using the OpenSSL compatibility API directly (wolfSSL_X509_verify_cert), such as nginx and haproxy integrations. The native wolfSSL TLS handshake path (ProcessPeerCerts) is not susceptible.", - "fixed_versions": ["5.9.1"], + "fixed_versions": [ + "5.9.1" + ], "remediation": "Update to wolfSSL 5.9.1 or later, or avoid relying on wolfSSL_X509_verify_cert in the OpenSSL compatibility layer for chain validation." }, - "CVE-2026-5778": { "state": "exploitable", - "response": ["update"], + "response": [ + "update" + ], "detail": "Integer underflow in the ChaCha20-Poly1305 decryption path of the packet sniffer.", - "requires_defines": ["WOLFSSL_SNIFFER", "HAVE_CHACHA", "HAVE_POLY1305"], + "requires_defines": [ + "WOLFSSL_SNIFFER", + "HAVE_CHACHA", + "HAVE_POLY1305" + ], "default_status": "off", - "fixed_versions": ["5.9.1"], + "fixed_versions": [ + "5.9.1" + ], "remediation": "Update to wolfSSL 5.9.1 or later. Builds without --enable-sniffer are not affected." + }, + "CVE-2026-11310": { + "state": "exploitable", + "response": [ + "update" + ], + "detail": "X.509 trust-chain bypass in the OpenSSL compatibility certificate verifier (wolfSSL_X509_verify_cert()). This affects only builds with --enable-opensslextra (OPENSSL_EXTRA) and whose application validates certificates by calling X509_verify_cert() (OpenSSL compatibility layer function) with caller-supplied untrusted intermediate certificates; for those users it is critical, otherwise the library is unaffected.", + "fixed_versions": [ + "5.9.2" + ], + "remediation": "Update to wolfSSL 5.9.2 or later.", + "requires_defines": [ + "OPENSSL_EXTRA" + ] + }, + "CVE-2026-11999": { + "state": "exploitable", + "response": [ + "update" + ], + "detail": "X.509 trust-chain bypass (path-depth exhaustion) in the OpenSSL compatibility certificate verifier (wolfSSL_X509_verify_cert()). This affects only builds with --enable-opensslextra whose application calls X509_verify_cert() with caller-supplied untrusted intermediates; for those users it is critical, otherwise the library is unaffected.", + "fixed_versions": [ + "5.9.2" + ], + "remediation": "Update to wolfSSL 5.9.2 or later.", + "requires_defines": [ + "OPENSSL_EXTRA" + ] + }, + "CVE-2026-6679": { + "state": "exploitable", + "response": [ + "update" + ], + "detail": "A heap buffer overflow could occur in the DTLS 1.3 ACK serialization path before the connecting peer is authenticated. The buffer overflow was due to an integer truncation when computing the length of the ACK record-number list, causing an undersized buffer to be allocated and then overrun. This affects builds using DTLS 1.3 and wolfSSL version 5.9.0 and earlier. A fix was added to the 5.9.1 release. Thanks to Nicholas Carlini from Anthropic for the report. Fixed in PR 10116.", + "fixed_versions": [ + "5.9.1" + ], + "remediation": "Update to wolfSSL 5.9.1 or later.", + "requires_defines": [ + "WOLFSSL_DTLS13" + ] + }, + "CVE-2026-55958": { + "state": "exploitable", + "response": [ + "update" + ], + "detail": "Out-of-bounds write in the Renesas TSIP TLS 1.3 transcript buffer. In tsip_StoreMessage() the capacity check guarding the fixed message bag (MSGBAG_SIZE) sets an error code but fails to return, so execution falls through to an XMEMCPY that writes past the end of the buffer once the accumulated TLS 1.3 handshake transcript exceeds MSGBAG_SIZE (8 KB), corrupting adjacent heap state and potentially causing a remote denial of service crash.", + "fixed_versions": [ + "5.9.2" + ], + "remediation": "Update to wolfSSL 5.9.2 or later. Builds without the gating feature are not affected.", + "requires_defines": [ + "WOLFSSL_RENESAS_TSIP_TLS" + ], + "default_status": "off" + }, + "CVE-2026-55960": { + "state": "exploitable", + "response": [ + "update" + ], + "detail": "Un-negotiated Raw Public Key (RFC 7250) accepted in place of an X.509 certificate, bypassing chain validation. A raw public key has no chain, so ParseCertRelative() accepts it without performing any trust verification; it must therefore only be accepted when RPK was actually negotiated for that peer.", + "fixed_versions": [ + "5.9.2" + ], + "remediation": "Update to wolfSSL 5.9.2 or later. Builds without the gating feature are not affected.", + "requires_defines": [ + "HAVE_RPK" + ], + "default_status": "off" + }, + "CVE-2026-55961": { + "state": "exploitable", + "response": [ + "update" + ], + "detail": "wolfSSL_PKCS7_verify() returning success for a degenerate (certs-only) PKCS#7 object that contains no signer. Such an object has empty signerInfos, so the underlying signed-data verification succeeds without authenticating any content.", + "fixed_versions": [ + "5.9.2" + ], + "remediation": "Update to wolfSSL 5.9.2 or later.", + "requires_defines": [ + "OPENSSL_EXTRA" + ] + }, + "CVE-2026-10097": { + "state": "exploitable", + "response": [ + "update" + ], + "detail": "wolfSSL's AVX2-optimized ML-KEM implementation (mlkem_cmp_avx2) compares only 1536 of the 1568 ciphertext bytes during the Fujisaki-Okamoto re-encryption check in ML-KEM-1024 decapsulation. Ciphertexts that differ from the expected re-encryption solely in bytes 1536-1567 bypass implicit rejection and are accepted as valid, breaking IND-CCA2 security.", + "fixed_versions": [ + "5.9.2" + ], + "remediation": "Update to wolfSSL 5.9.2 or later." + }, + "CVE-2026-6731": { + "state": "exploitable", + "response": [ + "update" + ], + "detail": "X.509 name constraint bypass via the Subject Common Name when treated as a DNS-type name. A certificate whose Subject CN violates an issuing CA's DNS name constraints could be accepted. Thanks to d0sf3t (Aradex) for the report. Fixed in PR 10223.", + "fixed_versions": [ + "5.9.2" + ], + "remediation": "Update to wolfSSL 5.9.2 or later." + }, + "CVE-2026-6091": { + "state": "exploitable", + "response": [ + "update" + ], + "detail": "Partial-chain certificate verification may accept chains that terminate at a peer-supplied, untrusted intermediate certificate rather than a trusted anchor. An attacker could present a chain that ends at an intermediate they control and have it accepted as valid. Thanks to Dikai Zou for the report. Fixed in PR 10170.", + "fixed_versions": [ + "5.9.2" + ], + "remediation": "Update to wolfSSL 5.9.2 or later." + }, + "CVE-2026-6094": { + "state": "exploitable", + "response": [ + "update" + ], + "detail": "Heap buffer overread in wc_PKCS7_DecodeEnvelopedData when parsing crafted PKCS7 EnvelopedData. This could theoretically be triggered by attacker-supplied data delivered via S/MIME or CMS. Thanks to Dikai Zou for the report. Fixed in PR 10128.", + "fixed_versions": [ + "5.9.2" + ], + "remediation": "Update to wolfSSL 5.9.2 or later." + }, + "CVE-2026-6329": { + "state": "exploitable", + "response": [ + "update" + ], + "detail": "PKCS#12 MAC verification uses an attacker-controlled comparison length, weakening the integrity check on the MAC and allowing a mismatched MAC to be accepted. Thanks to Nicholas Carlini from Anthropic for the report. Fixed in PR 10192.", + "fixed_versions": [ + "5.9.2" + ], + "remediation": "Update to wolfSSL 5.9.2 or later." + }, + "CVE-2026-6330": { + "state": "exploitable", + "response": [ + "update" + ], + "detail": "The ML-KEM ARM64 NEON ciphertext comparison only compares half of the input, breaking the Fujisaki-Okamoto transform's implicit rejection and weakening IND-CCA2 security on that code path. Thanks to Nicholas Carlini from Anthropic for the report. Fixed in PR 10192.", + "fixed_versions": [ + "5.9.2" + ], + "remediation": "Update to wolfSSL 5.9.2 or later." + }, + "CVE-2026-8720": { + "state": "exploitable", + "response": [ + "update" + ], + "detail": "wc_Blake2bHmacFinal and wc_Blake2sHmacFinal discard the message when the key length exceeds the block size, producing a MAC that is independent of the input. This bug is specific to the HMAC-BLAKE2 API\u2019s that were added in wolfSSL version 5.9.0. Fixed in PR 10447.", + "fixed_versions": [ + "5.9.2" + ], + "remediation": "Update to wolfSSL 5.9.2 or later." + }, + "CVE-2026-10098": { + "state": "exploitable", + "response": [ + "update" + ], + "detail": "OCSP CertID serial-number length-confusion in wolfSSL_OCSP_resp_find_status allows a same-issuer SingleResponse whose serial is a prefix of the target serial to be reported as the revocation status of a different certificate. Thanks to Kim Youngjoon (Team-Atlanta and Georgia Institute of Technology) for the report. Fixed in PR 10554.", + "fixed_versions": [ + "5.9.2" + ], + "remediation": "Update to wolfSSL 5.9.2 or later." + }, + "CVE-2026-10592": { + "state": "exploitable", + "response": [ + "update" + ], + "detail": "Certificates with wildcard DNS SANs (e.g. *.example.com) bypassed CA name-constraint checks. Thanks to tonghuaroot for the report. Fixed in PR 10549.", + "fixed_versions": [ + "5.9.2" + ], + "remediation": "Update to wolfSSL 5.9.2 or later." + }, + "CVE-2026-7532": { + "state": "exploitable", + "response": [ + "update" + ], + "detail": "iPAddress name constraints bypass when WOLFSSL_IP_ALT_NAME is not defined. IP address name constraints are not enforced in that configuration, allowing a certificate to bypass an issuing CA's IP address constraints. Thanks to Ankur Tyagi of Cisco Talos (TALOS-2026-2409) for the report. Fixed in PR 10354.", + "fixed_versions": [ + "5.9.2" + ], + "remediation": "Update to wolfSSL 5.9.2 or later. Builds that define WOLFSSL_IP_ALT_NAME already enforced IP constraints." + }, + "CVE-2026-6291": { + "state": "exploitable", + "response": [ + "update" + ], + "detail": "Bleichenbacher padding oracle in PKCS#7 KTRI decryption. When decrypting PKCS#7 EnvelopedData using RSA PKCS#1 v1.5 key transport, wolfSSL returned distinguishable error codes depending on whether RSA padding validation failed versus whether the decrypted content was malformed.", + "fixed_versions": [ + "5.9.2" + ], + "remediation": "Update to wolfSSL 5.9.2 or later." + }, + "CVE-2026-7511": { + "state": "exploitable", + "response": [ + "update" + ], + "detail": "PKCS7_verify signer confusion allows forged signatures, where the signer associated with a signature is not correctly bound, permitting a forged signature to be accepted. Thanks to Nicholas Carlini from Anthropic for the report. Fixed in PR 10203.", + "fixed_versions": [ + "5.9.2" + ], + "remediation": "Update to wolfSSL 5.9.2 or later." + }, + "CVE-2026-11703": { + "state": "exploitable", + "response": [ + "update" + ], + "detail": "Fixed missing SNI/ALPN binding on stateful (session-ID) resumption, which previously skipped the binding check performed for ticket-based resumption. A cached session could be resumed under a different SNI/ALPN than originally negotiated and, where client-authentication policy differs across virtual hosts, carry the cached peer-authentication state into a context it was not established for. Resumption now verifies the SNI/ALPN binding for all paths and declines (falling back to a full handshake) on mismatch. Thanks to Dikai Zou for the report. Fixed in PR 10489.", + "fixed_versions": [ + "5.9.2" + ], + "remediation": "Update to wolfSSL 5.9.2 or later." + }, + "CVE-2026-55962": { + "state": "exploitable", + "response": [ + "update" + ], + "detail": "TLS 1.3 post-handshake authentication (PHA) issue where a server could accept a client's Finished message without the client having sent a Certificate and CertificateVerify. The post-handshake-auth exemption that allows an empty/absent peer certificate was only intended for the initial handshake, but it was also being applied while a post-handshake CertificateRequest was still outstanding.", + "fixed_versions": [ + "5.9.2" + ], + "remediation": "Update to wolfSSL 5.9.2 or later. Builds without the gating feature are not affected.", + "requires_defines": [ + "WOLFSSL_POST_HANDSHAKE_AUTH" + ], + "default_status": "off" + }, + "CVE-2026-55964": { + "state": "exploitable", + "response": [ + "update" + ], + "detail": "Chain intermediate CA:TRUE without keyCertSign accepted as a signing CA. Intermediate CA certificates are required to have the keyCertSign key usage when a Key Usage extension is present, but chain-supplied temporary CAs (WOLFSSL_TEMP_CA) added while building a certificate path were previously exempted from this check, so an intermediate asserting CA:TRUE but lacking keyCertSign was accepted as a signing CA.", + "fixed_versions": [ + "5.9.2" + ], + "remediation": "Update to wolfSSL 5.9.2 or later.", + "requires_defines": [ + "OPENSSL_EXTRA" + ] + }, + "CVE-2026-6092": { + "state": "exploitable", + "response": [ + "update" + ], + "detail": "When HAVE_ENCRYPT_THEN_MAC is configured, the implementation could fall back to MAC-then-Encrypt rather than enforcing Encrypt-then-MAC. Thanks to Marcin Olejnik (Rockwell Automation) for the report. Fixed in PR 10167.", + "fixed_versions": [ + "5.9.2" + ], + "remediation": "Update to wolfSSL 5.9.2 or later.", + "requires_defines": [ + "HAVE_ENCRYPT_THEN_MAC" + ] + }, + "CVE-2026-6331": { + "state": "exploitable", + "response": [ + "update" + ], + "detail": "HMAC zero-length tag forgery in EVP_DigestVerifyFinal, where a zero-length tag could be accepted as valid during HMAC verification. Thanks to Nicholas Carlini from Anthropic for the report. Fixed in PR 10192.", + "fixed_versions": [ + "5.9.2" + ], + "remediation": "Update to wolfSSL 5.9.2 or later.", + "requires_defines": [ + "OPENSSL_EXTRA" + ] + }, + "CVE-2026-6681": { + "state": "exploitable", + "response": [ + "update" + ], + "detail": "The PKCS#7 decode path ignores the caller-supplied output buffer size (outputSz), allowing decoded content to be written past the bounds of the provided buffer. This affects wolfSSL 5.9.0 and earlier and was fixed in the 5.9.1 release. Thanks to Nicholas Carlini from Anthropic for the report. Fixed in PR 10116.", + "fixed_versions": [ + "5.9.1" + ], + "remediation": "Update to wolfSSL 5.9.1 or later." + }, + "CVE-2026-10512": { + "state": "exploitable", + "response": [ + "update" + ], + "detail": "The X25519 x86_64 assembly implementation fails to clear the most significant bit during the final modular reduction, so the computed result may not be fully reduced modulo the field prime 2^255 - 19. This can leave the field element in a non-canonical form, producing an incorrect result from the scalar multiplication and potentially a wrong shared secret. Thanks to Haruki Oyama for the report. Fixed in PR 10536.", + "fixed_versions": [ + "5.9.2" + ], + "remediation": "Update to wolfSSL 5.9.2 or later." + }, + "CVE-2026-6678": { + "state": "exploitable", + "response": [ + "update" + ], + "detail": "Integer underflow in wc_PKCS7_DecryptOri when handling crafted Other Recipient Info, leading to incorrect length handling during decryption. Thanks to Dikai Zou for the report. Fixed in PR 10203.", + "fixed_versions": [ + "5.9.2" + ], + "remediation": "Update to wolfSSL 5.9.2 or later." + }, + "CVE-2026-7531": { + "state": "exploitable", + "response": [ + "update" + ], + "detail": "Use-after-free in PQC hybrid key-share handling. This is an incomplete-fix follow-up to CVE-2026-5460 (released in 5.9.1): a malicious TLS 1.3 server sending a truncated PQC hybrid KeyShare can still trigger the error cleanup path to operate on freed memory. Thanks to Thai Duong (Calif.io / Anthropic) for the report. Fixed in PR 10327.", + "fixed_versions": [ + "5.9.2" + ], + "remediation": "Update to wolfSSL 5.9.2 or later." + }, + "CVE-2026-6325": { + "state": "exploitable", + "response": [ + "update" + ], + "detail": "Out-of-bounds write in SetSuitesHashSigAlgo when processing an oversized signature algorithms list, allowing a write past the bounds of the destination buffer. Thanks to Muhammad Arya Arjuna Habibullah (Pelioro) for the report. Fixed in PR 10204.", + "fixed_versions": [ + "5.9.2" + ], + "remediation": "Update to wolfSSL 5.9.2 or later." + }, + "CVE-2026-6412": { + "state": "exploitable", + "response": [ + "update" + ], + "detail": "Certificate policy and RFC 8446 compliance concerns regarding the continued acceptance of SHA-1/MD5 in certificate processing. Thanks to Xiangdong Li (Student, Beijing University of Posts and Telecommunications [BUPT]) for the report. Fixed in PR 10222.", + "fixed_versions": [ + "5.9.2" + ], + "remediation": "Update to wolfSSL 5.9.2 or later." + }, + "CVE-2026-6450": { + "state": "exploitable", + "response": [ + "update" + ], + "detail": "A CRL critical extension bypass exists in ParseCRL_Extensions where critical extensions are not properly enforced, allowing a crafted CRL with an unhandled critical extension to be accepted. This only affects builds with CRL support enabled and where a crafted CRL had a trusted signature when parsed. Thanks to Oleh Konko (@1seal) for the report. Fixed in PR 10239.", + "fixed_versions": [ + "5.9.2" + ], + "remediation": "Update to wolfSSL 5.9.2 or later. Builds without the gating feature are not affected.", + "requires_defines": [ + "HAVE_CRL" + ], + "default_status": "off" + }, + "CVE-2026-12340": { + "state": "exploitable", + "response": [ + "update" + ], + "detail": "Out-of-bounds heap read during SM2/SM3 certificate signature verification. When parsing a certificate with an SM3wSM2 signature, the Subject Key Identifier computation reads the trailing 65 bytes of the public key without checking that the key is at least that long. A public key shorter than 65 bytes results in an out-of-bounds heap read, leading to a potential crash (denial of service); there is no out-of-bounds write. Note this only affects builds with SM2 support (--enable-sm2 or --enable-all). Thanks to David Pokora, Trail of Bits (in collaboration with Anthropic). Fixed in PR 10641.", + "fixed_versions": [ + "5.9.2" + ], + "remediation": "Update to wolfSSL 5.9.2 or later. Builds without the gating feature are not affected.", + "requires_defines": [ + "WOLFSSL_SM2" + ], + "default_status": "off" + }, + "CVE-2026-55967": { + "state": "exploitable", + "response": [ + "update" + ], + "detail": "AES-GCM encryption/decryption with extremely large cumulative single message sizes (>64 GiB) were not properly rejected by the streaming APIs, allowing counter wrap, keystream reuse, and consequent plaintext recovery. Thanks to NVIDIA Project Vanessa for the report. Fixed in PR 10709.", + "fixed_versions": [ + "5.9.2" + ], + "remediation": "Update to wolfSSL 5.9.2 or later." } } diff --git a/central/README.md b/central/README.md index ad00ddb..708b359 100644 --- a/central/README.md +++ b/central/README.md @@ -2,9 +2,23 @@ These tools run for wolfSSL only. Do not vendor them into a product. -Planned contents (see `docs/PLAN.md`): - - `gen-advisory` — the CSAF 2.0 and CycloneDX VEX generator. +- `advisory-completeness` — the release gate. It reconciles the CVEs a + release is supposed to cover against the CVE records and VEX overlay + entries present, and fails if any are missing: + + python3 central/advisory-completeness --cve-list advisories/releases/5.9.2.cves + + python3 central/advisory-completeness --release 5.9.2 \ + --changelog ../wolfssl/ChangeLog.md + + It checks completeness only; it cannot judge whether a determination is + correct — that is human analysis. `--cve-list` is the CI path (this repo + does not contain the product ChangeLog). Count only ChangeLog bullets of + the form `* [High] CVE-…`; ids named in the paragraph are ignored. +- `csaf-publish` — assemble the `.well-known/csaf` directory (hashes, index, + provider-metadata, optional OpenPGP signatures). Sign at deploy, not in git. +- `csaf-verify` — consumer-side check of hashes and signatures. - `advisory-vex-overlay.schema.json` — the per-CVE overlay schema. - `advisory-vex-overlay.example.json` — an overlay example. diff --git a/central/advisory-completeness b/central/advisory-completeness new file mode 100755 index 0000000..4574da7 --- /dev/null +++ b/central/advisory-completeness @@ -0,0 +1,252 @@ +#!/usr/bin/env python3 +"""Completeness gate for wolfSSL release advisories. + +`gen-advisory` faithfully turns whatever CVE records it is given into CSAF/VEX. +It has no notion of *which* CVEs a given product release actually fixed, so a +bundle built from an incomplete `advisories/records/` directory is emitted +without complaint. A `wolfssl-5.9.1` advisory that lists 2 CVEs when the +release fixed 22 is standards-conformant but materially wrong: a consumer reads +it as "5.9.1 fixed 2 issues". + +This tool closes that hole. It is the CI gate that reconciles three sources of +truth for one release: + + 1. the CVE ids named in the product ChangeLog's Vulnerabilit* section(s) + (what the release actually fixed -- the authoritative membership list), + 2. the CVE Program records present in --records-dir + (what `gen-advisory` can turn into an advisory body), + 3. the entries present in the VEX overlay + (the human determination `gen-advisory` cannot invent). + +It fails (exit 1) if any release CVE is missing a record or an overlay entry, +and it flags overlay entries that point at a CVE with no record. It does NOT +judge whether a determination is *correct* -- that is human analysis no tool +can validate; it only proves nothing was silently dropped. + +Pure stdlib, mirroring the other central/ tools. +""" + +import argparse +import json +import pathlib +import re +import sys + +_SCRIPTS_DIR = pathlib.Path(__file__).resolve().parent +_REPO_ROOT = _SCRIPTS_DIR.parent + +# Mirror gen-advisory's canonical locations so the gate and the generator see +# the same inputs. +DEFAULT_RECORDS_DIR = _REPO_ROOT / 'advisories' / 'records' +DEFAULT_OVERLAY = _REPO_ROOT / 'advisories' / 'vex-overlay.json' + +# The product ChangeLog is the release membership authority. wolfSSL lives in a +# sibling checkout next to wolfglass; override with --changelog for any product. +DEFAULT_CHANGELOG = _REPO_ROOT.parent / 'wolfssl' / 'ChangeLog.md' + +_CVE_ID_RE = re.compile(r'CVE-[0-9]{4}-[0-9]{4,}') +_VERSION_RE = re.compile(r'^[0-9]+\.[0-9]+(?:\.[0-9]+)?$') + + +def _release_header_re(product): + """Match e.g. '# wolfSSL Release 5.9.1 (Apr. 8, 2026)'.""" + return re.compile(rf'^#\s+{re.escape(product)}\s+Release\s+' + r'([0-9]+\.[0-9]+(?:\.[0-9]+)?)\b') + + +def release_block(changelog_text, product, release): + """Return the lines of the ChangeLog belonging to one release. + + The block runs from that release's header up to (not including) the next + release header of the same product. + """ + header = _release_header_re(product) + lines = changelog_text.splitlines() + start = end = None + for i, line in enumerate(lines): + m = header.match(line) + if not m: + continue + if m.group(1) == release: + start = i + elif start is not None: + end = i + break + if start is None: + sys.exit(f"ERROR: release {product} {release} not found in ChangeLog. " + "Check --product/--release/--changelog.") + return lines[start:end] + + +# Bullet subject only: `* [High] CVE-2026-7531`. Ids named in the paragraph +# (e.g. "follow-up to CVE-2026-5460") are context, not this release's membership. +_BULLET_CVE_RE = re.compile( + r'^\*\s*\[(?:Critical|High|Med|Medium|Low)\]\s*' + r'(CVE-[0-9]{4}-[0-9]{4,})\b' +) + + +def cves_fixed_in_release(block_lines): + """CVE ids that head a Vulnerabilit* bullet in one release. + + A release block has one or more `## ...Vulnerabilit...` sections (wolfSSL + 5.9.1 has both `## Vulnerabilities` and `## Experimental Build + Vulnerability`). CVE ids mentioned in *other* sections (e.g. a Bug Fixes + note referencing a prior CVE) are excluded. CVE ids named only in a + bullet's body are also excluded: they were not the subject of that entry. + Order of first appearance is preserved. + """ + found = [] + in_vuln = False + for line in block_lines: + if re.match(r'^##\s', line): + in_vuln = 'vulnerab' in line.lower() + continue + if not in_vuln: + continue + m = _BULLET_CVE_RE.match(line) + if m and m.group(1) not in found: + found.append(m.group(1)) + return found + + +def load_cve_list(path): + """Pinned membership file: one CVE id per line, `#` comments allowed.""" + found = [] + for raw in pathlib.Path(path).read_text().splitlines(): + line = raw.split('#', 1)[0].strip() + if not line: + continue + if not _CVE_ID_RE.fullmatch(line): + sys.exit(f"ERROR: not a CVE id in {path}: {line!r}") + if line not in found: + found.append(line) + return found + + +def load_overlay(path): + with open(path) as fh: + data = json.load(fh) + # Keys are CVE ids; keys starting with '_' are documentation/comments. + return {k for k in data if _CVE_ID_RE.fullmatch(k)} + + +def records_present(records_dir): + d = pathlib.Path(records_dir) + return {p.stem for p in d.glob('*.json') if _CVE_ID_RE.fullmatch(p.stem)} + + +def build_report(release_cves, have_records, have_overlay): + rows = [] + for cve in release_cves: + rows.append({ + 'cve': cve, + 'record': cve in have_records, + 'overlay': cve in have_overlay, + }) + missing_record = [r['cve'] for r in rows if not r['record']] + missing_overlay = [r['cve'] for r in rows if not r['overlay']] + # Overlay entries that reference a CVE with no record are broken input. + orphan_overlay = sorted(c for c in have_overlay if c not in have_records) + return { + 'rows': rows, + 'missing_record': missing_record, + 'missing_overlay': missing_overlay, + 'orphan_overlay': orphan_overlay, + } + + +def print_human(product, release, report): + rows = report['rows'] + total = len(rows) + covered = sum(1 for r in rows if r['record'] and r['overlay']) + print(f"Advisory completeness: {product} {release}") + print(f" release CVEs: {total}") + print(f" fully covered (record + overlay): {covered}/{total}") + print() + print(f" {'CVE':<18} {'record':<8} {'overlay':<8}") + print(f" {'-'*18} {'-'*8} {'-'*8}") + for r in rows: + rec = 'yes' if r['record'] else 'MISSING' + ov = 'yes' if r['overlay'] else 'MISSING' + print(f" {r['cve']:<18} {rec:<8} {ov:<8}") + if report['missing_record']: + print(f"\n missing CVE records ({len(report['missing_record'])}): " + + ', '.join(report['missing_record'])) + if report['missing_overlay']: + print(f" missing overlay entries ({len(report['missing_overlay'])}): " + + ', '.join(report['missing_overlay'])) + if report['orphan_overlay']: + print(f" overlay entries with no record ({len(report['orphan_overlay'])}): " + + ', '.join(report['orphan_overlay'])) + + +def main(): + p = argparse.ArgumentParser( + description='Fail a release if any of its ChangeLog CVEs lacks a CVE ' + 'record or a VEX overlay entry (the completeness gate for ' + 'gen-advisory bundles).') + p.add_argument('--release', default=None, + help='Product release version, e.g. 5.9.1. Required unless ' + '--cve-list is given.') + p.add_argument('--cve-list', default=None, + help='Pinned CVE id list (one per line). Use this in CI ' + 'when the product ChangeLog is not in this repo.') + p.add_argument('--product', default='wolfSSL', + help='Product name as it appears in the ChangeLog release ' + 'header (default: wolfSSL).') + p.add_argument('--changelog', default=str(DEFAULT_CHANGELOG), + help='Path to the product ChangeLog (default: sibling ' + 'wolfssl/ChangeLog.md).') + p.add_argument('--records-dir', default=str(DEFAULT_RECORDS_DIR), + help='Directory of CVE JSON 5.x records.') + p.add_argument('--overlay', default=str(DEFAULT_OVERLAY), + help='VEX overlay JSON.') + p.add_argument('--json', action='store_true', + help='Emit the reconciliation as JSON instead of a table.') + args = p.parse_args() + + if args.cve_list: + list_path = pathlib.Path(args.cve_list) + if not list_path.is_file(): + sys.exit(f"ERROR: CVE list not found: {list_path}") + release_cves = load_cve_list(list_path) + if args.release is None: + args.release = list_path.stem + elif args.release: + if not _VERSION_RE.match(args.release): + sys.exit(f"ERROR: --release {args.release!r} is not a version like 5.9.1") + changelog = pathlib.Path(args.changelog) + if not changelog.is_file(): + sys.exit(f"ERROR: ChangeLog not found: {changelog}") + block = release_block(changelog.read_text(), args.product, args.release) + release_cves = cves_fixed_in_release(block) + else: + sys.exit("ERROR: pass --release (with a ChangeLog) or --cve-list.") + + if not release_cves: + sys.exit(f"ERROR: no CVEs found for {args.product} {args.release}.") + + have_records = records_present(args.records_dir) + have_overlay = load_overlay(args.overlay) + report = build_report(release_cves, have_records, have_overlay) + + if args.json: + print(json.dumps({ + 'product': args.product, + 'release': args.release, + **report, + }, indent=2)) + else: + print_human(args.product, args.release, report) + + ok = (not report['missing_record'] + and not report['missing_overlay'] + and not report['orphan_overlay']) + if not ok: + sys.exit(1) + print("\nOK: every release CVE has a record and an overlay entry.") + + +if __name__ == '__main__': + main() diff --git a/central/csaf-keygen b/central/csaf-keygen new file mode 100755 index 0000000..52a19d3 --- /dev/null +++ b/central/csaf-keygen @@ -0,0 +1,58 @@ +#!/usr/bin/env python3 +"""Generate a throwaway OpenPGP signing key for the CSAF PoC (pure Python, pgpy). + +This is NOT a production key. Real publishing must use a wolfSSL-controlled key +whose master part stays offline and whose signing subkey lives in CI (see the +scoping doc, W2 "key custody"). This tool exists so the PoC can produce real +detached OpenPGP signatures without host GnuPG. + +Writes: + * .sec.asc -- the secret key (keep out of git), + * .pub.asc -- the public key (published as openpgp-key.asc), +and prints the primary key fingerprint. +""" + +import argparse +import pathlib +import sys + +import pgpy +from pgpy.constants import (PubKeyAlgorithm, KeyFlags, HashAlgorithm, + SymmetricKeyAlgorithm, CompressionAlgorithm) + + +def main(): + p = argparse.ArgumentParser(description=__doc__, + formatter_class=argparse.RawDescriptionHelpFormatter) + p.add_argument('--uid', default='wolfSSL CSAF Signing (PoC - DO NOT TRUST)', + help='User id name for the key.') + p.add_argument('--email', default='security@wolfssl.com', + help='User id email.') + p.add_argument('--out', default='advisories/.poc-key/csaf-poc', + help='Output path prefix for the key files.') + args = p.parse_args() + + # RSA-3072 primary + signing capability. RSA keeps the PoC portable across + # OpenPGP implementations; production may prefer Ed25519. + key = pgpy.PGPKey.new(PubKeyAlgorithm.RSAEncryptOrSign, 3072) + uid = pgpy.PGPUID.new(args.uid, email=args.email) + key.add_uid( + uid, + usage={KeyFlags.Sign}, + hashes=[HashAlgorithm.SHA512, HashAlgorithm.SHA256], + ciphers=[SymmetricKeyAlgorithm.AES256], + compression=[CompressionAlgorithm.Uncompressed], + ) + + out = pathlib.Path(args.out) + out.parent.mkdir(parents=True, exist_ok=True) + (out.with_suffix('.sec.asc')).write_text(str(key)) + (out.with_suffix('.pub.asc')).write_text(str(key.pubkey)) + + print(key.fingerprint.replace(' ', '')) + print(f'secret: {out.with_suffix(".sec.asc")}', file=sys.stderr) + print(f'public: {out.with_suffix(".pub.asc")}', file=sys.stderr) + + +if __name__ == '__main__': + main() diff --git a/central/csaf-publish b/central/csaf-publish new file mode 100755 index 0000000..f52632b --- /dev/null +++ b/central/csaf-publish @@ -0,0 +1,208 @@ +#!/usr/bin/env python3 +"""Assemble a CSAF 2.0 *directory-based* distribution from generated CSAF docs. + +`gen-advisory` emits the advisory *bodies* (`.csaf.json`). To become a CSAF +Trusted Provider you must also publish, for every document: + + * a SHA-256 and a SHA-512 hash file, + * a detached OpenPGP signature (`.asc`), + +and, at the distribution root: + + * `provider-metadata.json` (the discovery file + signing-key fingerprint), + * `index.txt` (every document path, one per line), + * `changes.csv` ("path",iso-timestamp, newest first), + * `openpgp-key.asc` (the public signing key). + +This tool takes the `advisories/out/` directory and lays out a ready-to-host +`.well-known/csaf///` tree. Signing is delegated to `gpg`; if no key +is given the tree is built unsigned (hashes + metadata only) so the layout can +still be inspected. + +Pure stdlib. The CSAF filename convention is applied: the tracking id, +lowercased, with every char outside [+\\-a-z0-9] replaced by '_', plus '.json'. +""" + +import argparse +import csv +import datetime as _dt +import hashlib +import json +import pathlib +import re +import shutil +import sys + +_CANON_STRIP = re.compile(r'[^+\-a-z0-9]') + + +def canonical_filename(tracking_id): + """CSAF recommended filename for a document tracking id.""" + return _CANON_STRIP.sub('_', tracking_id.lower()) + '.json' + + +def _year_of(doc): + """Distribution sub-folder: year of the initial release date.""" + tr = doc.get('document', {}).get('tracking', {}) + date = tr.get('initial_release_date') or tr.get('current_release_date') or '' + m = re.match(r'(\d{4})', date) + return m.group(1) if m else str(_dt.datetime.now(_dt.timezone.utc).year) + + +def _sha_files(path): + """Write .sha256 and .sha512 in `shasum`-style format.""" + data = path.read_bytes() + for algo in ('sha256', 'sha512'): + digest = hashlib.new(algo, data).hexdigest() + sidecar = path.with_name(path.name + '.' + algo) + sidecar.write_text(f'{digest} {path.name}\n') + + +def _load_key(key_file): + """Load an OpenPGP secret key (ASCII-armored) with pgpy.""" + import pgpy # imported lazily so unsigned runs need no dependency + key, _ = pgpy.PGPKey.from_file(key_file) + return key + + +def _sign(path, key): + """Detached, ASCII-armored OpenPGP signature over the raw file bytes. + + Signs the document bytes directly (an OpenPGP binary-document signature), + which is what a detached `.asc` must verify against.""" + data = path.read_bytes() + sig = key.sign(data) + asc = path.with_name(path.name + '.asc') + asc.write_text(str(sig)) + return asc + + +def _key_fingerprint(key): + return str(key.fingerprint).replace(' ', '') + + +def _export_pubkey(key, dest): + dest.write_text(str(key.pubkey)) + + +def build_provider_metadata(base_url, publisher, fingerprint, timestamp): + md = { + 'canonical_url': f'{base_url}/provider-metadata.json', + 'last_updated': timestamp, + 'list_on_CSAF_aggregators': True, + 'metadata_version': '2.0', + 'mirror_on_CSAF_aggregators': True, + 'publisher': publisher, + 'role': 'csaf_trusted_provider' if fingerprint else 'csaf_provider', + 'distributions': [{'directory_url': f'{base_url}/'}], + } + if fingerprint: + md['public_openpgp_keys'] = [{ + 'fingerprint': fingerprint, + 'url': f'{base_url}/openpgp-key.asc', + }] + return md + + +def _reset_tree(csaf_root): + """Drop a previous publish so a re-run cannot leave stale documents.""" + for name in ('index.txt', 'changes.csv', 'provider-metadata.json', + 'openpgp-key.asc'): + p = csaf_root / name + if p.is_file(): + p.unlink() + for tlp in ('white', 'green', 'amber', 'red'): + d = csaf_root / tlp + if d.is_dir(): + shutil.rmtree(d) + + +def main(): + p = argparse.ArgumentParser(description=__doc__, + formatter_class=argparse.RawDescriptionHelpFormatter) + p.add_argument('--docs-dir', default='advisories/out', + help='Directory holding generated *.csaf.json documents.') + p.add_argument('--out-root', default='advisories/publish', + help='Distribution root; the .well-known/csaf tree is built here.') + p.add_argument('--base-url', + default='https://www.wolfssl.com/.well-known/csaf', + help='Public base URL the tree will be served from.') + p.add_argument('--tlp', default='white', + choices=['white', 'green', 'amber', 'red'], + help='TLP label folder for the documents.') + p.add_argument('--key-file', default=None, + help='ASCII-armored OpenPGP secret key (pgpy). Omit to skip signing.') + args = p.parse_args() + + docs_dir = pathlib.Path(args.docs_dir) + csaf_root = pathlib.Path(args.out_root) / '.well-known' / 'csaf' + csaf_root.mkdir(parents=True, exist_ok=True) + _reset_tree(csaf_root) + + timestamp = _dt.datetime.now(_dt.timezone.utc).strftime('%Y-%m-%dT%H:%M:%SZ') + + key = None + fingerprint = None + if args.key_file: + key = _load_key(args.key_file) + fingerprint = _key_fingerprint(key) + _export_pubkey(key, csaf_root / 'openpgp-key.asc') + + index_lines = [] + changes_rows = [] + publisher = None + + csaf_docs = sorted(docs_dir.glob('*.csaf.json')) + if not csaf_docs: + sys.exit(f'ERROR: no *.csaf.json in {docs_dir}') + + for src in csaf_docs: + doc = json.loads(src.read_text()) + publisher = publisher or doc['document']['publisher'] + tracking_id = doc['document']['tracking']['id'] + year = _year_of(doc) + rel_dir = pathlib.Path(args.tlp) / year + dest_dir = csaf_root / rel_dir + dest_dir.mkdir(parents=True, exist_ok=True) + + dest = dest_dir / canonical_filename(tracking_id) + rel = (rel_dir / dest.name).as_posix() + # Point the in-document `self` URL at the hosted path *before* hashing + # and signing, so the published bytes match the canonical location. + public_url = args.base_url.rstrip('/') + '/' + rel + for ref in doc.get('document', {}).get('references', []): + if ref.get('category') == 'self': + ref['url'] = public_url + dest.write_text(json.dumps(doc, indent=2) + '\n') + + _sha_files(dest) + if key is not None: + _sign(dest, key) + + index_lines.append(rel) + released = doc['document']['tracking'].get('current_release_date', timestamp) + changes_rows.append((rel, released)) + + # index.txt + (csaf_root / 'index.txt').write_text('\n'.join(index_lines) + '\n') + + # changes.csv (newest first) + changes_rows.sort(key=lambda r: r[1], reverse=True) + with (csaf_root / 'changes.csv').open('w', newline='') as fh: + w = csv.writer(fh) + for rel, ts in changes_rows: + w.writerow([rel, ts]) + + # provider-metadata.json + md = build_provider_metadata(args.base_url, publisher, fingerprint, timestamp) + (csaf_root / 'provider-metadata.json').write_text( + json.dumps(md, indent=2) + '\n') + + signed = 'signed' if key is not None else 'UNSIGNED' + print(f'Published {len(csaf_docs)} CSAF document(s) [{signed}] to {csaf_root}') + if fingerprint: + print(f'Signing key fingerprint: {fingerprint}') + + +if __name__ == '__main__': + main() diff --git a/central/csaf-verify b/central/csaf-verify new file mode 100755 index 0000000..f1ff8d8 --- /dev/null +++ b/central/csaf-verify @@ -0,0 +1,76 @@ +#!/usr/bin/env python3 +"""Verify a published CSAF directory: hashes + OpenPGP signatures. + +Consumer-side check. For every CSAF document under the distribution root it +confirms: + + * the `.sha256` and `.sha512` sidecars match the file bytes, and + * the detached `.asc` signature verifies against the published + `openpgp-key.asc`. + +Exit 0 only if every document passes. Uses pgpy for signature checking. +""" + +import argparse +import hashlib +import pathlib +import sys + +import pgpy + + +def _check_hash(path, algo): + sidecar = path.with_name(path.name + '.' + algo) + if not sidecar.exists(): + return f'missing {sidecar.name}' + want = sidecar.read_text().split()[0].strip() + got = hashlib.new(algo, path.read_bytes()).hexdigest() + return None if want == got else f'{algo} mismatch' + + +def main(): + p = argparse.ArgumentParser(description=__doc__, + formatter_class=argparse.RawDescriptionHelpFormatter) + p.add_argument('--root', default='advisories/publish/.well-known/csaf', + help='Distribution root containing openpgp-key.asc and TLP folders.') + args = p.parse_args() + + root = pathlib.Path(args.root) + pubkey, _ = pgpy.PGPKey.from_file(str(root / 'openpgp-key.asc')) + + docs = sorted(root.glob('*/*/*.json')) + if not docs: + sys.exit(f'ERROR: no CSAF documents under {root}') + + failures = 0 + for doc in docs: + problems = [] + for algo in ('sha256', 'sha512'): + err = _check_hash(doc, algo) + if err: + problems.append(err) + + asc = doc.with_name(doc.name + '.asc') + if not asc.exists(): + problems.append('missing .asc') + else: + try: + sig = pgpy.PGPSignature.from_file(str(asc)) + if not pubkey.verify(doc.read_bytes(), sig): + problems.append('signature INVALID') + except Exception as e: # noqa: BLE001 + problems.append(f'signature error: {e}') + + rel = doc.relative_to(root) + if problems: + failures += 1 + print(f'FAIL {rel}: {"; ".join(problems)}') + else: + print(f'OK {rel} (sha256+sha512+OpenPGP)') + + print(f'\n{len(docs) - failures}/{len(docs)} documents verified') + sys.exit(1 if failures else 0) + + +if __name__ == '__main__': + main() diff --git a/central/test_advisory_completeness.py b/central/test_advisory_completeness.py new file mode 100644 index 0000000..1150e11 --- /dev/null +++ b/central/test_advisory_completeness.py @@ -0,0 +1,140 @@ +#!/usr/bin/env python3 +"""Unit tests for central/advisory-completeness (the release advisory gate). + +Run: + python3 -m unittest central/test_advisory_completeness.py +""" + +import importlib.util +import json +import pathlib +import tempfile +import unittest +from importlib.machinery import SourceFileLoader + +HERE = pathlib.Path(__file__).resolve().parent +SCRIPT = HERE / 'advisory-completeness' + + +def _load(): + loader = SourceFileLoader('ac', str(SCRIPT)) + spec = importlib.util.spec_from_loader('ac', loader) + module = importlib.util.module_from_spec(spec) + loader.exec_module(module) + return module + + +ac = _load() + +# A minimal ChangeLog with two releases. 5.9.1 has a normal Vulnerabilities +# section plus a second vuln-titled section, and a Bug Fixes section that +# mentions an *unrelated* CVE which must NOT be counted as fixed here. +CHANGELOG = """\ +# wolfSSL Release 5.9.2 (Jun 23, 2026) +## Vulnerabilities +* [High] CVE-2026-9001 + Incomplete-fix follow-up to CVE-2026-5460 (released in 5.9.1). + +# wolfSSL Release 5.9.1 (Apr. 8, 2026) +## Vulnerabilities +* [Critical] CVE-2026-5194 + A. +* [High] CVE-2026-5778 + B. +## Experimental Build Vulnerability +* [Low] CVE-2026-5507 + C. +## Bug Fixes +* Regression from the CVE-2020-0001 fix; not a new advisory. + +# wolfSSL Release 5.9.0 (Mar. 18, 2026) +## Vulnerabilities +* [Low] CVE-2026-1000 + Old. +""" + + +class ExtractionTests(unittest.TestCase): + def setUp(self): + self.block = ac.release_block(CHANGELOG, 'wolfSSL', '5.9.1') + + def test_block_is_scoped_to_the_release(self): + text = '\n'.join(self.block) + self.assertIn('CVE-2026-5194', text) + self.assertNotIn('CVE-2026-9001', text) # belongs to 5.9.2 + self.assertNotIn('CVE-2026-1000', text) # belongs to 5.9.0 + + def test_counts_both_vuln_sections(self): + cves = ac.cves_fixed_in_release(self.block) + self.assertEqual(set(cves), + {'CVE-2026-5194', 'CVE-2026-5778', 'CVE-2026-5507'}) + + def test_excludes_non_vuln_sections(self): + # The CVE named only under Bug Fixes must not be counted. + self.assertNotIn('CVE-2020-0001', ac.cves_fixed_in_release(self.block)) + + def test_missing_release_exits(self): + with self.assertRaises(SystemExit): + ac.release_block(CHANGELOG, 'wolfSSL', '9.9.9') + + + def test_excludes_cve_named_only_in_bullet_body(self): + block = ac.release_block(CHANGELOG, 'wolfSSL', '5.9.2') + self.assertEqual(ac.cves_fixed_in_release(block), ['CVE-2026-9001']) + self.assertNotIn('CVE-2026-5460', ac.cves_fixed_in_release(block)) + + +class ReconcileTests(unittest.TestCase): + def test_gap_is_reported(self): + release = ['CVE-2026-5194', 'CVE-2026-5778', 'CVE-2026-5507'] + records = {'CVE-2026-5778'} + overlay = {'CVE-2026-5778'} + r = ac.build_report(release, records, overlay) + self.assertEqual(r['missing_record'], ['CVE-2026-5194', 'CVE-2026-5507']) + self.assertEqual(r['missing_overlay'], ['CVE-2026-5194', 'CVE-2026-5507']) + + def test_full_coverage_has_no_gap(self): + release = ['CVE-2026-5778'] + r = ac.build_report(release, {'CVE-2026-5778'}, {'CVE-2026-5778'}) + self.assertFalse(r['missing_record']) + self.assertFalse(r['missing_overlay']) + self.assertFalse(r['orphan_overlay']) + + def test_orphan_overlay_detected(self): + # An overlay entry pointing at a CVE with no record is broken input. + release = ['CVE-2026-5778'] + r = ac.build_report(release, {'CVE-2026-5778'}, + {'CVE-2026-5778', 'CVE-2026-0000'}) + self.assertEqual(r['orphan_overlay'], ['CVE-2026-0000']) + + +class OverlayLoadTests(unittest.TestCase): + def test_comment_keys_ignored(self): + with tempfile.TemporaryDirectory() as d: + p = pathlib.Path(d) / 'overlay.json' + p.write_text(json.dumps({ + '_comment': 'docs', + 'CVE-2026-5778': {'state': 'exploitable'}, + })) + self.assertEqual(ac.load_overlay(str(p)), {'CVE-2026-5778'}) + + +class Release592CatalogueTests(unittest.TestCase): + """The committed 5.9.2 pin list must be fully covered by records+overlay.""" + + def test_pinned_list_is_fully_covered(self): + root = HERE.parent + pin = root / 'advisories' / 'releases' / '5.9.2.cves' + cves = ac.load_cve_list(pin) + self.assertEqual(len(cves), 32) + self.assertNotIn('CVE-2026-5460', cves) + records = ac.records_present(root / 'advisories' / 'records') + overlay = ac.load_overlay(str(root / 'advisories' / 'vex-overlay.json')) + report = ac.build_report(cves, records, overlay) + self.assertFalse(report['missing_record'], report['missing_record']) + self.assertFalse(report['missing_overlay'], report['missing_overlay']) + self.assertFalse(report['orphan_overlay'], report['orphan_overlay']) + + +if __name__ == '__main__': + unittest.main() diff --git a/central/test_csaf_publish.py b/central/test_csaf_publish.py new file mode 100644 index 0000000..4c70394 --- /dev/null +++ b/central/test_csaf_publish.py @@ -0,0 +1,114 @@ +#!/usr/bin/env python3 +"""Unit tests for central/csaf-publish (unsigned directory layout). + +Run: + python3 -m unittest central/test_csaf_publish.py +""" + +import hashlib +import importlib.util +import json +import pathlib +import tempfile +import unittest +from importlib.machinery import SourceFileLoader + +HERE = pathlib.Path(__file__).resolve().parent +PUBLISH = HERE / 'csaf-publish' +GEN = HERE / 'gen-advisory' +TESTDATA = HERE / 'testdata' +EXAMPLE_OVERLAY = HERE / 'advisory-vex-overlay.example.json' + + +def _load(path, name): + loader = SourceFileLoader(name, str(path)) + spec = importlib.util.spec_from_loader(name, loader) + module = importlib.util.module_from_spec(spec) + loader.exec_module(module) + return module + + +pub = _load(PUBLISH, 'csaf_publish') +ga = _load(GEN, 'ga') + + +def _sha(path, algo): + return hashlib.new(algo, path.read_bytes()).hexdigest() + + +class CanonicalNameTests(unittest.TestCase): + def test_cve_id(self): + self.assertEqual(pub.canonical_filename('CVE-2026-5501'), + 'cve-2026-5501.json') + + def test_bundle_id(self): + self.assertEqual(pub.canonical_filename('wolfssl-5.9.2'), + 'wolfssl-5_9_2.json') + + +class UnsignedPublishTests(unittest.TestCase): + def setUp(self): + self.tmp = tempfile.TemporaryDirectory() + self.root = pathlib.Path(self.tmp.name) + self.docs = self.root / 'docs' + self.out = self.root / 'publish' + self.docs.mkdir() + adv = ga.parse_record(json.loads( + (TESTDATA / 'CVE-2026-5501.json').read_text())) + ov = json.loads(EXAMPLE_OVERLAY.read_text()) + csaf = ga.generate_csaf([adv], ov, adv['cve'], '2026-01-02T00:00:00Z') + (self.docs / 'CVE-2026-5501.csaf.json').write_text( + json.dumps(csaf, indent=2) + '\n') + + def tearDown(self): + self.tmp.cleanup() + + def _publish(self): + # Drive the CLI through the same argv path CI will use. + import sys + argv = sys.argv + try: + sys.argv = [ + 'csaf-publish', + '--docs-dir', str(self.docs), + '--out-root', str(self.out), + '--base-url', 'https://www.wolfssl.com/.well-known/csaf', + ] + pub.main() + finally: + sys.argv = argv + return self.out / '.well-known' / 'csaf' + + def test_layout_hashes_and_self_url(self): + csaf_root = self._publish() + dest = csaf_root / 'white' / '2026' / 'cve-2026-5501.json' + self.assertTrue(dest.is_file()) + doc = json.loads(dest.read_text()) + selfs = [r['url'] for r in doc['document']['references'] + if r.get('category') == 'self'] + self.assertEqual( + selfs, + ['https://www.wolfssl.com/.well-known/csaf/white/2026/cve-2026-5501.json']) + for algo in ('sha256', 'sha512'): + side = dest.with_name(dest.name + '.' + algo) + want = side.read_text().split()[0] + self.assertEqual(want, _sha(dest, algo)) + index = csaf_root.joinpath('index.txt').read_text().splitlines() + self.assertEqual(index, ['white/2026/cve-2026-5501.json']) + md = json.loads((csaf_root / 'provider-metadata.json').read_text()) + self.assertEqual(md['role'], 'csaf_provider') + self.assertNotIn('public_openpgp_keys', md) + + def test_rerun_drops_stale_files(self): + csaf_root = self._publish() + stale = csaf_root / 'white' / '2026' / 'cve-1999-0001.json' + stale.parent.mkdir(parents=True, exist_ok=True) + stale.write_text('{}\n') + self._publish() + self.assertFalse(stale.exists()) + json_docs = sorted(p.name for p in (csaf_root / 'white' / '2026').glob('*.json')) + self.assertEqual(json_docs, ['cve-2026-5501.json']) + + +if __name__ == '__main__': + unittest.main() diff --git a/tools/csaf-validate/csaf_validate.mjs b/tools/csaf-validate/csaf_validate.mjs new file mode 100644 index 0000000..8775be7 --- /dev/null +++ b/tools/csaf-validate/csaf_validate.mjs @@ -0,0 +1,79 @@ +// CSAF 2.0 conformance gate for documents emitted by central/gen-advisory. +// +// JSON-schema validity is necessary but NOT sufficient for CSAF: the standard +// defines a battery of *mandatory tests* (section 6.1.*) -- CVSS/vector +// consistency, contradicting product status, product_id defined/used, +// tracking.version vs revision_history, and so on -- that a bare schema pass +// happily accepts. This runner uses the Secvisogram reference implementation +// (@secvisogram/csaf-validator-lib) which bundles every schema (incl. the +// first.org CVSS schemas) and implements those mandatory tests, so the check +// is fully offline and reproducible once the pinned dependency is installed. +// +// Gate = the strict CSAF 2.0 schema test + all mandatory tests. Optional and +// informative tests are reported as warnings only (they encode house-style +// preferences, not conformance). +// +// Usage: node tools/csaf-validate/csaf_validate.mjs [...] +// Exit 0 if every document passes the gate, 1 otherwise. + +import { readFileSync } from 'node:fs' +import validate from '@secvisogram/csaf-validator-lib/validate.js' +import * as schemaTests from '@secvisogram/csaf-validator-lib/schemaTests.js' +import * as mandatoryTests from '@secvisogram/csaf-validator-lib/mandatoryTests.js' +import * as optionalTests from '@secvisogram/csaf-validator-lib/optionalTests.js' + +const files = process.argv.slice(2) +if (files.length === 0) { + console.error('usage: node tools/csaf-validate/csaf_validate.mjs ...') + process.exit(2) +} + +const gateTests = [schemaTests.csaf_2_0_strict, ...Object.values(mandatoryTests)] +const advisoryTests = [...Object.values(optionalTests)] + +function summarize(testResults) { + const failed = [] + for (const t of testResults) { + if (t.isValid === false || (t.errors && t.errors.length > 0)) { + failed.push(t) + } + } + return failed +} + +let anyInvalid = false + +for (const file of files) { + let doc + try { + doc = JSON.parse(readFileSync(file, 'utf8')) + } catch (e) { + console.error(`ERROR: cannot read/parse ${file}: ${e.message}`) + anyInvalid = true + continue + } + + const gate = await validate(gateTests, doc) + const advisory = await validate(advisoryTests, doc) + + if (gate.isValid) { + console.log(`OK ${file} (strict schema + ${Object.keys(mandatoryTests).length} mandatory tests)`) + } else { + anyInvalid = true + console.error(`FAIL ${file}`) + for (const t of summarize(gate.tests)) { + for (const err of t.errors || []) { + console.error(` [${t.name}] ${err.instancePath || '/'}: ${err.message}`) + } + } + } + + const optWarn = summarize(advisory.tests) + for (const t of optWarn) { + for (const err of t.errors || []) { + console.warn(` warn ${file} [${t.name}] ${err.instancePath || '/'}: ${err.message}`) + } + } +} + +process.exit(anyInvalid ? 1 : 0) diff --git a/tools/csaf-validate/package.json b/tools/csaf-validate/package.json new file mode 100644 index 0000000..4d3455e --- /dev/null +++ b/tools/csaf-validate/package.json @@ -0,0 +1,9 @@ +{ + "name": "wolfglass-csaf-validate", + "private": true, + "type": "module", + "description": "Pinned Secvisogram CSAF 2.0 gate used by .github/workflows/advisory.yml", + "dependencies": { + "@secvisogram/csaf-validator-lib": "2.0.25" + } +} diff --git a/tools/csaf-validate/test_csaf_validate.mjs b/tools/csaf-validate/test_csaf_validate.mjs new file mode 100644 index 0000000..ca2ef35 --- /dev/null +++ b/tools/csaf-validate/test_csaf_validate.mjs @@ -0,0 +1,56 @@ +// Runner self-test for tools/csaf-validate/csaf_validate.mjs. +// +// Usage: node tools/csaf-validate/test_csaf_validate.mjs [] +// +// Requires @secvisogram/csaf-validator-lib to be installed (CI installs the +// pin in tools/csaf-validate/package.json). + +import { spawnSync } from 'node:child_process' +import { mkdtempSync, writeFileSync, rmSync } from 'node:fs' +import { tmpdir } from 'node:os' +import { join, dirname } from 'node:path' +import { fileURLToPath } from 'node:url' + +const HERE = dirname(fileURLToPath(import.meta.url)) +const RUNNER = join(HERE, 'csaf_validate.mjs') + +function run(args) { + return spawnSync(process.execPath, [RUNNER, ...args], { encoding: 'utf8' }) +} + +let failures = 0 +function check(name, ok) { + if (ok) { + console.log(`ok - ${name}`) + } else { + failures++ + console.error(`FAIL - ${name}`) + } +} + +check('no args exits 2 (usage)', run([]).status === 2) + +const tmp = mkdtempSync(join(tmpdir(), 'csaf-selftest-')) +try { + const badDoc = join(tmp, 'bad.csaf.json') + writeFileSync(badDoc, JSON.stringify({ + document: { category: 'csaf_security_advisory', csaf_version: '2.0' }, + })) + check('non-conformant document exits 1', run([badDoc]).status === 1) + + const junk = join(tmp, 'junk.csaf.json') + writeFileSync(junk, '{ not valid json') + check('unparsable document exits non-zero', run([junk]).status !== 0) + + const validDoc = process.argv[2] + if (validDoc) { + check(`valid document exits 0 (${validDoc})`, run([validDoc]).status === 0) + } else { + console.log('skip - valid-document exit-0 check (no valid doc path given)') + } +} finally { + rmSync(tmp, { recursive: true, force: true }) +} + +console.log(failures === 0 ? 'PASS' : `FAILED (${failures})`) +process.exit(failures === 0 ? 0 : 1) From 38b8363f2c0ae3b60815f4b84ca6468685887f94 Mon Sep 17 00:00:00 2001 From: Sameeh Jubran Date: Wed, 16 Sep 2026 21:42:06 +0300 Subject: [PATCH 2/3] fix(csaf): keep 5.9.1 fixes out of the 5.9.2 pin CVE-2026-6679 and CVE-2026-6681 shipped in 5.9.1. Completeness now fails on ids the strict bullet rule drops, and publish/verify/CI close the rest of the review on #28. --- .github/workflows/advisory.yml | 46 +++- .github/workflows/selftest.yml | 3 + .gitignore | 1 - advisories/records/CVE-2026-6681.json | 2 +- advisories/releases/5.9.2.cves | 10 +- advisories/releases/5.9.2.mentions.cves | 4 + advisories/releases/5.9.2.prior-release.cves | 5 + central/README.md | 20 +- central/advisory-completeness | 190 ++++++++++++++--- central/csaf-keygen | 30 ++- central/csaf-publish | 43 +++- central/csaf-verify | 160 +++++++++++--- central/test_advisory_completeness.py | 134 +++++++++++- central/test_csaf_publish.py | 72 +++++++ central/testdata/ChangeLog-5.9.2.md | 119 +++++++++++ central/testdata/README.md | 1 + .../schema-ok-mandatory-fail.csaf.json | 195 +++++++++++++++++ tools/csaf-validate/package-lock.json | 197 ++++++++++++++++++ tools/csaf-validate/requirements.txt | 5 + tools/csaf-validate/test_csaf_validate.mjs | 9 + 20 files changed, 1146 insertions(+), 100 deletions(-) create mode 100644 advisories/releases/5.9.2.mentions.cves create mode 100644 advisories/releases/5.9.2.prior-release.cves create mode 100644 central/testdata/ChangeLog-5.9.2.md create mode 100644 tools/csaf-validate/fixtures/schema-ok-mandatory-fail.csaf.json create mode 100644 tools/csaf-validate/package-lock.json create mode 100644 tools/csaf-validate/requirements.txt diff --git a/.github/workflows/advisory.yml b/.github/workflows/advisory.yml index 354d298..6a29605 100644 --- a/.github/workflows/advisory.yml +++ b/.github/workflows/advisory.yml @@ -8,6 +8,9 @@ on: branches: [master] pull_request: +permissions: + contents: read + jobs: unit: name: advisory unit tests @@ -39,8 +42,15 @@ jobs: central/test_advisory_completeness.py \ central/test_csaf_publish.py - - name: Completeness gate against the pinned 5.9.2 list - run: python3 central/advisory-completeness --cve-list advisories/releases/5.9.2.cves + - name: Completeness gate against ChangeLog + 5.9.2 pin + run: | + python3 central/advisory-completeness \ + --cve-list advisories/releases/5.9.2.cves \ + --release 5.9.2 \ + --changelog central/testdata/ChangeLog-5.9.2.md \ + --prior-release advisories/releases/5.9.2.prior-release.cves \ + --mentions advisories/releases/5.9.2.mentions.cves \ + --require-fixed-version 5.9.2 catalogue: name: generate and validate 5.9.2 @@ -60,9 +70,9 @@ jobs: - name: Install validators run: | - python3 -m pip install --user 'cyclonedx-bom==7.*' 'jsonschema==4.*' + python3 -m pip install --user -r tools/csaf-validate/requirements.txt echo "$HOME/.local/bin" >> "$GITHUB_PATH" - npm install --no-save --prefix tools/csaf-validate + npm ci --ignore-scripts --prefix tools/csaf-validate - name: Real overlay matches its JSON Schema run: | @@ -102,7 +112,6 @@ jobs: python3 - <<'PY' import pathlib, os, sys sys.path.insert(0, 'central') - # Load advisory-completeness as a module (no .py suffix). import importlib.util from importlib.machinery import SourceFileLoader loader = SourceFileLoader('ac', 'central/advisory-completeness') @@ -126,28 +135,41 @@ jobs: - name: csaf_validate runner contract run: node tools/csaf-validate/test_csaf_validate.mjs "${ADV}/CVE-2026-11310.csaf.json" - - name: CycloneDX 1.6 strict schema + - name: CycloneDX 1.6 strict schema and CVSS v4 ratings run: | python3 - <<'PY' - import glob, os, sys + import glob, json, os, sys from cyclonedx.validation.json import JsonStrictValidator from cyclonedx.schema import SchemaVersion v = JsonStrictValidator(SchemaVersion.V1_6) paths = sorted(glob.glob(os.environ['ADV'] + '/*.cdx.json')) assert paths, 'no CycloneDX VEX documents were generated' + missing = [] for p in paths: - errs = v.validate_str(open(p).read()) + text = open(p).read() + errs = v.validate_str(text) if errs: print(f'INVALID: {p}: {errs}', file=sys.stderr) sys.exit(1) + bom = json.loads(text) + for vuln in bom.get('vulnerabilities') or []: + ratings = vuln.get('ratings') or [] + if not any(r.get('method') == 'CVSSv4' and r.get('score') is not None + for r in ratings): + missing.append(f"{p}:{vuln.get('id')}") print(f'OK: {p}') + if missing: + print('missing CVSSv4 ratings:', missing, file=sys.stderr) + sys.exit(1) PY - - name: Unsigned publish tree (hashes + self URL) + - name: Unsigned publish tree (hashes + self URL + verify) run: | python3 central/csaf-publish \ --docs-dir "${ADV}" \ --out-root "${RUNNER_TEMP}/publish592" + python3 central/csaf-verify \ + --root "${RUNNER_TEMP}/publish592/.well-known/csaf" python3 - <<'PY' import hashlib, json, os, pathlib, sys root = pathlib.Path(os.environ['RUNNER_TEMP']) / 'publish592' / '.well-known' / 'csaf' @@ -170,5 +192,11 @@ jobs: got = hashlib.new(algo, dest.read_bytes()).hexdigest() if side.read_text().split()[0] != got: sys.exit(f'ERROR: {algo} mismatch for {rel}') + md = root / 'provider-metadata.json' + for algo in ('sha256', 'sha512'): + side = md.with_name(md.name + '.' + algo) + got = hashlib.new(algo, md.read_bytes()).hexdigest() + if side.read_text().split()[0] != got: + sys.exit(f'ERROR: {algo} mismatch for provider-metadata.json') print(f'OK: published {len(docs)} unsigned documents') PY diff --git a/.github/workflows/selftest.yml b/.github/workflows/selftest.yml index ba229dc..8d50f62 100644 --- a/.github/workflows/selftest.yml +++ b/.github/workflows/selftest.yml @@ -8,6 +8,9 @@ on: branches: [master] pull_request: +permissions: + contents: read + jobs: selftest: runs-on: ubuntu-latest diff --git a/.gitignore b/.gitignore index dd1b4d1..52bd650 100644 --- a/.gitignore +++ b/.gitignore @@ -22,7 +22,6 @@ venv/ # CSAF PoC: throwaway signing key (never commit a secret key) + node deps advisories/.poc-key/ tools/csaf-validate/node_modules/ -tools/csaf-validate/package-lock.json # Editor / OS .DS_Store diff --git a/advisories/records/CVE-2026-6681.json b/advisories/records/CVE-2026-6681.json index 8653221..a926207 100644 --- a/advisories/records/CVE-2026-6681.json +++ b/advisories/records/CVE-2026-6681.json @@ -30,7 +30,7 @@ { "lang": "en", "cweId": "CWE-120", - "description": "CWE-120 Buffer Copy without Checking Size of Input", + "description": "CWE-120 Buffer Copy without Checking Size of Input ('Classic Buffer Overflow')", "type": "CWE" } ] diff --git a/advisories/releases/5.9.2.cves b/advisories/releases/5.9.2.cves index 72db6a9..01e3f97 100644 --- a/advisories/releases/5.9.2.cves +++ b/advisories/releases/5.9.2.cves @@ -1,11 +1,12 @@ # Pinned CVE membership for wolfSSL 5.9.2 # -# Bullet subjects from ChangeLog.md Vulnerabilities for -# wolfSSL Release 5.9.2. Predecessor ids named only in a -# bullet body are not listed. +# ChangeLog Vulnerabilities bullets whose overlay fixed_versions +# contains 5.9.2. Two 5.9.2 bullets (CVE-2026-6679, CVE-2026-6681) +# shipped in 5.9.1; they live in 5.9.2.prior-release.cves. +# CVE-2026-5460 is named only in a bullet body; see +# 5.9.2.mentions.cves. CVE-2026-11310 CVE-2026-11999 -CVE-2026-6679 CVE-2026-55958 CVE-2026-55960 CVE-2026-55961 @@ -26,7 +27,6 @@ CVE-2026-55962 CVE-2026-55964 CVE-2026-6092 CVE-2026-6331 -CVE-2026-6681 CVE-2026-10512 CVE-2026-6678 CVE-2026-7531 diff --git a/advisories/releases/5.9.2.mentions.cves b/advisories/releases/5.9.2.mentions.cves new file mode 100644 index 0000000..81d22b7 --- /dev/null +++ b/advisories/releases/5.9.2.mentions.cves @@ -0,0 +1,4 @@ +# CVE ids that appear in the 5.9.2 Vulnerabilities section but do not +# head a bullet. The strict parser drops these; the completeness gate +# must name them rather than treat a partial miss as success. +CVE-2026-5460 diff --git a/advisories/releases/5.9.2.prior-release.cves b/advisories/releases/5.9.2.prior-release.cves new file mode 100644 index 0000000..28a8b6e --- /dev/null +++ b/advisories/releases/5.9.2.prior-release.cves @@ -0,0 +1,5 @@ +# ChangeLog 5.9.2 Vulnerabilities bullets that were fixed in 5.9.1. +# Records and overlay stay in the catalogue; they are not members of +# the 5.9.2 pin list or the wolfssl-5.9.2 bundle. +CVE-2026-6679 +CVE-2026-6681 diff --git a/central/README.md b/central/README.md index 708b359..f5104f1 100644 --- a/central/README.md +++ b/central/README.md @@ -7,18 +7,28 @@ These tools run for wolfSSL only. Do not vendor them into a product. release is supposed to cover against the CVE records and VEX overlay entries present, and fails if any are missing: - python3 central/advisory-completeness --cve-list advisories/releases/5.9.2.cves + python3 central/advisory-completeness --cve-list advisories/releases/5.9.2.cves \ + --release 5.9.2 \ + --changelog central/testdata/ChangeLog-5.9.2.md \ + --prior-release advisories/releases/5.9.2.prior-release.cves \ + --mentions advisories/releases/5.9.2.mentions.cves \ + --require-fixed-version 5.9.2 python3 central/advisory-completeness --release 5.9.2 \ --changelog ../wolfssl/ChangeLog.md It checks completeness only; it cannot judge whether a determination is correct — that is human analysis. `--cve-list` is the CI path (this repo - does not contain the product ChangeLog). Count only ChangeLog bullets of - the form `* [High] CVE-…`; ids named in the paragraph are ignored. + does not contain the product ChangeLog). Count ChangeLog bullets of the + form `* [High] CVE-…` as members. The tool also computes a loose set of + every CVE id in the Vulnerabilities section and fails if the strict rule + dropped an id that is not listed in `--mentions`. `--release` must match + the CVE-list filename stem when both flags are set. - `csaf-publish` — assemble the `.well-known/csaf` directory (hashes, index, - provider-metadata, optional OpenPGP signatures). Sign at deploy, not in git. -- `csaf-verify` — consumer-side check of hashes and signatures. + provider-metadata, optional OpenPGP signatures via pgpy). Sign at deploy, + not in git. Honors `SOURCE_DATE_EPOCH`. +- `csaf-verify` — consumer-side check. Walks `index.txt` and hash sidecars. + Signature checks require `--fingerprint` matching provider-metadata.json. - `advisory-vex-overlay.schema.json` — the per-CVE overlay schema. - `advisory-vex-overlay.example.json` — an overlay example. diff --git a/central/advisory-completeness b/central/advisory-completeness index 4574da7..3ddeece 100755 --- a/central/advisory-completeness +++ b/central/advisory-completeness @@ -23,6 +23,16 @@ and it flags overlay entries that point at a CVE with no record. It does NOT judge whether a determination is *correct* -- that is human analysis no tool can validate; it only proves nothing was silently dropped. +When a ChangeLog is supplied together with a pin list, it also checks: + + * strict bullets minus --prior-release equals the pin list + * loose CVE ids minus strict bullets equals --mentions + * optional --require-fixed-version is present on every pin overlay entry + +A partial miss used to look like a complete release: the strict bullet regex +captures one id per line, so a second id on the same bullet was silent. The +loose set makes that fail loudly. + Pure stdlib, mirroring the other central/ tools. """ @@ -86,17 +96,16 @@ _BULLET_CVE_RE = re.compile( ) -def cves_fixed_in_release(block_lines): - """CVE ids that head a Vulnerabilit* bullet in one release. - - A release block has one or more `## ...Vulnerabilit...` sections (wolfSSL - 5.9.1 has both `## Vulnerabilities` and `## Experimental Build - Vulnerability`). CVE ids mentioned in *other* sections (e.g. a Bug Fixes - note referencing a prior CVE) are excluded. CVE ids named only in a - bullet's body are also excluded: they were not the subject of that entry. - Order of first appearance is preserved. +def cves_in_vuln_sections(block_lines): + """Return (strict, loose) CVE ids from Vulnerabilit* sections. + + strict: one id per `* [Sev] CVE-…` bullet head, order of first appearance. + loose: every CVE id in those sections, including body mentions and extra + ids on the same bullet. A non-empty (loose - strict) is a silent drop by + the strict rule and must be classified (pin, prior-release, or mentions). """ - found = [] + strict = [] + loose = [] in_vuln = False for line in block_lines: if re.match(r'^##\s', line): @@ -104,10 +113,19 @@ def cves_fixed_in_release(block_lines): continue if not in_vuln: continue + for cid in _CVE_ID_RE.findall(line): + if cid not in loose: + loose.append(cid) m = _BULLET_CVE_RE.match(line) - if m and m.group(1) not in found: - found.append(m.group(1)) - return found + if m and m.group(1) not in strict: + strict.append(m.group(1)) + return strict, loose + + +def cves_fixed_in_release(block_lines): + """CVE ids that head a Vulnerabilit* bullet in one release.""" + strict, _loose = cves_in_vuln_sections(block_lines) + return strict def load_cve_list(path): @@ -124,11 +142,15 @@ def load_cve_list(path): return found -def load_overlay(path): +def load_overlay_map(path): with open(path) as fh: data = json.load(fh) + return {k: v for k, v in data.items() if _CVE_ID_RE.fullmatch(k)} + + +def load_overlay(path): # Keys are CVE ids; keys starting with '_' are documentation/comments. - return {k for k in data if _CVE_ID_RE.fullmatch(k)} + return set(load_overlay_map(path)) def records_present(records_dir): @@ -136,6 +158,44 @@ def records_present(records_dir): return {p.stem for p in d.glob('*.json') if _CVE_ID_RE.fullmatch(p.stem)} +def reconcile_changelog(strict, loose, pin, prior, mentions): + """Compare pin/prior/mentions lists to ChangeLog strict and loose sets. + + expected pin = strict bullets minus prior-release bullets + expected mentions = loose ids the strict rule dropped + """ + strict_set = set(strict) + pin_set = set(pin) + prior_set = set(prior) + mentions_set = set(mentions) + + dropped = [c for c in loose if c not in strict_set] + expected_pin = [c for c in strict if c not in prior_set] + + return { + 'strict': strict, + 'loose': loose, + 'dropped_by_strict': dropped, + 'expected_pin': expected_pin, + 'pin_missing': [c for c in expected_pin if c not in pin_set], + 'pin_extra': [c for c in pin if c not in set(expected_pin)], + 'mentions_missing': [c for c in dropped if c not in mentions_set], + 'mentions_extra': [c for c in mentions if c not in set(dropped)], + 'prior_not_in_strict': [c for c in prior if c not in strict_set], + } + + +def overlay_missing_fixed_version(pin, overlay_map, release): + """Pin members whose overlay does not list `release` in fixed_versions.""" + bad = [] + for cve in pin: + entry = overlay_map.get(cve) or {} + versions = entry.get('fixed_versions') or [] + if release not in versions: + bad.append(cve) + return bad + + def build_report(release_cves, have_records, have_overlay): rows = [] for cve in release_cves: @@ -179,6 +239,29 @@ def print_human(product, release, report): if report['orphan_overlay']: print(f" overlay entries with no record ({len(report['orphan_overlay'])}): " + ', '.join(report['orphan_overlay'])) + ch = report.get('changelog') + if ch: + print() + print(f" ChangeLog strict bullets: {len(ch['strict'])}") + print(f" ChangeLog loose ids: {len(ch['loose'])}") + if ch['dropped_by_strict']: + print(f" ids the strict rule dropped: " + + ', '.join(ch['dropped_by_strict'])) + if ch['pin_missing']: + print(f" pin missing vs ChangeLog: " + ', '.join(ch['pin_missing'])) + if ch['pin_extra']: + print(f" pin extra vs ChangeLog: " + ', '.join(ch['pin_extra'])) + if ch['mentions_missing']: + print(f" mentions file missing: " + + ', '.join(ch['mentions_missing'])) + if ch['mentions_extra']: + print(f" mentions file extra: " + ', '.join(ch['mentions_extra'])) + if ch['prior_not_in_strict']: + print(f" prior-release not a ChangeLog bullet: " + + ', '.join(ch['prior_not_in_strict'])) + if report.get('wrong_fixed_version'): + print(f" overlay fixed_versions missing {release}: " + + ', '.join(report['wrong_fixed_version'])) def main(): @@ -188,16 +271,27 @@ def main(): 'gen-advisory bundles).') p.add_argument('--release', default=None, help='Product release version, e.g. 5.9.1. Required unless ' - '--cve-list is given.') + '--cve-list is given. Must match the CVE-list filename ' + 'stem when both are set.') p.add_argument('--cve-list', default=None, help='Pinned CVE id list (one per line). Use this in CI ' 'when the product ChangeLog is not in this repo.') p.add_argument('--product', default='wolfSSL', help='Product name as it appears in the ChangeLog release ' 'header (default: wolfSSL).') - p.add_argument('--changelog', default=str(DEFAULT_CHANGELOG), - help='Path to the product ChangeLog (default: sibling ' - 'wolfssl/ChangeLog.md).') + p.add_argument('--changelog', default=None, + help='Path to the product ChangeLog. Required with ' + '--release when --cve-list is omitted. With --cve-list, ' + 'pass this to reconcile the pin against bullets.') + p.add_argument('--prior-release', default=None, + help='CVE ids that head a ChangeLog bullet but shipped in ' + 'an earlier release (not pin members).') + p.add_argument('--mentions', default=None, + help='CVE ids the strict bullet rule drops (body mentions ' + 'or extra ids on the same bullet).') + p.add_argument('--require-fixed-version', default=None, + help='Every pin overlay entry must list this version in ' + 'fixed_versions (catches a 5.9.1 fix pinned as 5.9.2).') p.add_argument('--records-dir', default=str(DEFAULT_RECORDS_DIR), help='Directory of CVE JSON 5.x records.') p.add_argument('--overlay', default=str(DEFAULT_OVERLAY), @@ -206,21 +300,33 @@ def main(): help='Emit the reconciliation as JSON instead of a table.') args = p.parse_args() + changelog_path = None + reconcile_pin_vs_changelog = False if args.cve_list: list_path = pathlib.Path(args.cve_list) if not list_path.is_file(): sys.exit(f"ERROR: CVE list not found: {list_path}") release_cves = load_cve_list(list_path) + list_stem = list_path.stem if args.release is None: - args.release = list_path.stem + args.release = list_stem + elif args.release != list_stem: + sys.exit(f"ERROR: --release {args.release} does not match " + f"--cve-list stem {list_stem} ({list_path.name}).") + if args.changelog: + changelog_path = pathlib.Path(args.changelog) + reconcile_pin_vs_changelog = True elif args.release: if not _VERSION_RE.match(args.release): sys.exit(f"ERROR: --release {args.release!r} is not a version like 5.9.1") - changelog = pathlib.Path(args.changelog) - if not changelog.is_file(): - sys.exit(f"ERROR: ChangeLog not found: {changelog}") - block = release_block(changelog.read_text(), args.product, args.release) + changelog_path = pathlib.Path(args.changelog or DEFAULT_CHANGELOG) + if not changelog_path.is_file(): + sys.exit(f"ERROR: ChangeLog not found: {changelog_path}") + block = release_block(changelog_path.read_text(), args.product, + args.release) release_cves = cves_fixed_in_release(block) + # Pin came from the ChangeLog. Still reconcile if prior/mentions given. + reconcile_pin_vs_changelog = bool(args.prior_release or args.mentions) else: sys.exit("ERROR: pass --release (with a ChangeLog) or --cve-list.") @@ -228,8 +334,28 @@ def main(): sys.exit(f"ERROR: no CVEs found for {args.product} {args.release}.") have_records = records_present(args.records_dir) - have_overlay = load_overlay(args.overlay) + overlay_map = load_overlay_map(args.overlay) + have_overlay = set(overlay_map) report = build_report(release_cves, have_records, have_overlay) + report['wrong_fixed_version'] = [] + report['changelog'] = None + + if args.require_fixed_version: + report['wrong_fixed_version'] = overlay_missing_fixed_version( + release_cves, overlay_map, args.require_fixed_version) + + if reconcile_pin_vs_changelog: + if changelog_path is None: + changelog_path = pathlib.Path(args.changelog or DEFAULT_CHANGELOG) + if not changelog_path.is_file(): + sys.exit(f"ERROR: ChangeLog not found: {changelog_path}") + prior = load_cve_list(args.prior_release) if args.prior_release else [] + mentions = load_cve_list(args.mentions) if args.mentions else [] + block = release_block(changelog_path.read_text(), args.product, + args.release) + strict, loose = cves_in_vuln_sections(block) + report['changelog'] = reconcile_changelog( + strict, loose, release_cves, prior, mentions) if args.json: print(json.dumps({ @@ -240,9 +366,21 @@ def main(): else: print_human(args.product, args.release, report) + ch = report.get('changelog') or {} + # dropped_by_strict is OK iff it equals the mentions list. + changelog_ok = not ch or ( + not ch['pin_missing'] + and not ch['pin_extra'] + and not ch['mentions_missing'] + and not ch['mentions_extra'] + and not ch['prior_not_in_strict'] + ) + ok = (not report['missing_record'] and not report['missing_overlay'] - and not report['orphan_overlay']) + and not report['orphan_overlay'] + and not report['wrong_fixed_version'] + and changelog_ok) if not ok: sys.exit(1) print("\nOK: every release CVE has a record and an overlay entry.") diff --git a/central/csaf-keygen b/central/csaf-keygen index 52a19d3..528dcd1 100755 --- a/central/csaf-keygen +++ b/central/csaf-keygen @@ -7,18 +7,35 @@ scoping doc, W2 "key custody"). This tool exists so the PoC can produce real detached OpenPGP signatures without host GnuPG. Writes: - * .sec.asc -- the secret key (keep out of git), + * .sec.asc -- the secret key (mode 0600, keep out of git), * .pub.asc -- the public key (published as openpgp-key.asc), and prints the primary key fingerprint. + +Requires the optional `pgpy` package. Unsigned publish/verify does not. """ import argparse +import os import pathlib import sys -import pgpy -from pgpy.constants import (PubKeyAlgorithm, KeyFlags, HashAlgorithm, - SymmetricKeyAlgorithm, CompressionAlgorithm) + +def _require_pgpy(): + try: + import pgpy + from pgpy.constants import (PubKeyAlgorithm, KeyFlags, HashAlgorithm, + SymmetricKeyAlgorithm, CompressionAlgorithm) + except ImportError: + sys.exit('ERROR: pgpy is required for csaf-keygen (PoC keys only)') + return (pgpy, PubKeyAlgorithm, KeyFlags, HashAlgorithm, + SymmetricKeyAlgorithm, CompressionAlgorithm) + + +def write_secret(path, text): + """Write the secret key with mode 0600 before any bytes land.""" + fd = os.open(path, os.O_WRONLY | os.O_CREAT | os.O_TRUNC, 0o600) + with os.fdopen(fd, 'w') as fh: + fh.write(text) def main(): @@ -32,6 +49,9 @@ def main(): help='Output path prefix for the key files.') args = p.parse_args() + (pgpy, PubKeyAlgorithm, KeyFlags, HashAlgorithm, + SymmetricKeyAlgorithm, CompressionAlgorithm) = _require_pgpy() + # RSA-3072 primary + signing capability. RSA keeps the PoC portable across # OpenPGP implementations; production may prefer Ed25519. key = pgpy.PGPKey.new(PubKeyAlgorithm.RSAEncryptOrSign, 3072) @@ -46,7 +66,7 @@ def main(): out = pathlib.Path(args.out) out.parent.mkdir(parents=True, exist_ok=True) - (out.with_suffix('.sec.asc')).write_text(str(key)) + write_secret(str(out.with_suffix('.sec.asc')), str(key)) (out.with_suffix('.pub.asc')).write_text(str(key.pubkey)) print(key.fingerprint.replace(' ', '')) diff --git a/central/csaf-publish b/central/csaf-publish index f52632b..9b84f57 100755 --- a/central/csaf-publish +++ b/central/csaf-publish @@ -15,9 +15,9 @@ and, at the distribution root: * `openpgp-key.asc` (the public signing key). This tool takes the `advisories/out/` directory and lays out a ready-to-host -`.well-known/csaf///` tree. Signing is delegated to `gpg`; if no key -is given the tree is built unsigned (hashes + metadata only) so the layout can -still be inspected. +`.well-known/csaf///` tree. Signing uses `pgpy` when `--key-file` is +given; if no key is given the tree is built unsigned (hashes + metadata only) +so the layout can still be inspected. `SOURCE_DATE_EPOCH` pins timestamps. Pure stdlib. The CSAF filename convention is applied: the tracking id, lowercased, with every char outside [+\\-a-z0-9] replaced by '_', plus '.json'. @@ -28,6 +28,7 @@ import csv import datetime as _dt import hashlib import json +import os import pathlib import re import shutil @@ -41,12 +42,25 @@ def canonical_filename(tracking_id): return _CANON_STRIP.sub('_', tracking_id.lower()) + '.json' -def _year_of(doc): +def build_timestamp(): + """ISO-8601-Z timestamp; honors SOURCE_DATE_EPOCH for reproducibility.""" + sde = os.environ.get('SOURCE_DATE_EPOCH', '').strip() + if sde: + try: + dt = _dt.datetime.fromtimestamp(int(sde), tz=_dt.timezone.utc) + return dt.strftime('%Y-%m-%dT%H:%M:%SZ') + except (ValueError, OverflowError, OSError) as e: + print(f"WARNING: ignoring invalid SOURCE_DATE_EPOCH={sde!r}: {e}", + file=sys.stderr) + return _dt.datetime.now(_dt.timezone.utc).strftime('%Y-%m-%dT%H:%M:%SZ') + + +def _year_of(doc, timestamp): """Distribution sub-folder: year of the initial release date.""" tr = doc.get('document', {}).get('tracking', {}) date = tr.get('initial_release_date') or tr.get('current_release_date') or '' m = re.match(r'(\d{4})', date) - return m.group(1) if m else str(_dt.datetime.now(_dt.timezone.utc).year) + return m.group(1) if m else timestamp[:4] def _sha_files(path): @@ -139,7 +153,7 @@ def main(): csaf_root.mkdir(parents=True, exist_ok=True) _reset_tree(csaf_root) - timestamp = _dt.datetime.now(_dt.timezone.utc).strftime('%Y-%m-%dT%H:%M:%SZ') + timestamp = build_timestamp() key = None fingerprint = None @@ -151,6 +165,7 @@ def main(): index_lines = [] changes_rows = [] publisher = None + used_names = {} csaf_docs = sorted(docs_dir.glob('*.csaf.json')) if not csaf_docs: @@ -160,12 +175,17 @@ def main(): doc = json.loads(src.read_text()) publisher = publisher or doc['document']['publisher'] tracking_id = doc['document']['tracking']['id'] - year = _year_of(doc) + year = _year_of(doc, timestamp) rel_dir = pathlib.Path(args.tlp) / year dest_dir = csaf_root / rel_dir dest_dir.mkdir(parents=True, exist_ok=True) dest = dest_dir / canonical_filename(tracking_id) + if dest.name in used_names: + sys.exit( + f'ERROR: tracking ids {used_names[dest.name]!r} and ' + f'{tracking_id!r} both canonicalize to {dest.name}') + used_names[dest.name] = tracking_id rel = (rel_dir / dest.name).as_posix() # Point the in-document `self` URL at the hosted path *before* hashing # and signing, so the published bytes match the canonical location. @@ -193,10 +213,13 @@ def main(): for rel, ts in changes_rows: w.writerow([rel, ts]) - # provider-metadata.json + # provider-metadata.json is hashed (and signed when a key is given). md = build_provider_metadata(args.base_url, publisher, fingerprint, timestamp) - (csaf_root / 'provider-metadata.json').write_text( - json.dumps(md, indent=2) + '\n') + md_path = csaf_root / 'provider-metadata.json' + md_path.write_text(json.dumps(md, indent=2) + '\n') + _sha_files(md_path) + if key is not None: + _sign(md_path, key) signed = 'signed' if key is not None else 'UNSIGNED' print(f'Published {len(csaf_docs)} CSAF document(s) [{signed}] to {csaf_root}') diff --git a/central/csaf-verify b/central/csaf-verify index f1ff8d8..7d5a8fe 100755 --- a/central/csaf-verify +++ b/central/csaf-verify @@ -1,22 +1,34 @@ #!/usr/bin/env python3 -"""Verify a published CSAF directory: hashes + OpenPGP signatures. +"""Verify a published CSAF directory: index, hashes, optional OpenPGP. -Consumer-side check. For every CSAF document under the distribution root it -confirms: +Consumer-side check. Walks `index.txt` (not a glob of whatever is on disk): - * the `.sha256` and `.sha512` sidecars match the file bytes, and - * the detached `.asc` signature verifies against the published - `openpgp-key.asc`. + * every path in the index exists and every on-disk TLP document is indexed + * `.sha256` and `.sha512` sidecars match the file bytes + * `provider-metadata.json` hashes match when sidecars are present -Exit 0 only if every document passes. Uses pgpy for signature checking. +Unsigned trees (role `csaf_provider`) are the default: hashes + index only. +Signature mode requires `--fingerprint`, which must match +`provider-metadata.json` `public_openpgp_keys`. The key is loaded from that +metadata URL mapped onto the tree, not from a loose file that an attacker with +web-root write could swap. + +Exit 0 only if every check passes. `pgpy` is imported only for signature mode. """ import argparse import hashlib +import json import pathlib import sys -import pgpy + +def _require_pgpy(): + try: + import pgpy + except ImportError: + sys.exit('ERROR: pgpy is required for signature verification') + return pgpy def _check_hash(path, algo): @@ -28,47 +40,133 @@ def _check_hash(path, algo): return None if want == got else f'{algo} mismatch' +def _index_paths(root): + index = root / 'index.txt' + if not index.is_file(): + sys.exit(f'ERROR: missing index.txt under {root}') + rels = [] + for ln in index.read_text().splitlines(): + line = ln.strip() + if line and not line.startswith('#'): + rels.append(line) + if not rels: + sys.exit(f'ERROR: index.txt is empty under {root}') + return rels + + +def _disk_docs(root): + """CSAF documents on disk: TLP/year/*.json, excluding hash sidecars.""" + found = [] + for tlp in ('white', 'green', 'amber', 'red'): + tlp_dir = root / tlp + if not tlp_dir.is_dir(): + continue + for p in tlp_dir.glob('*/*.json'): + if p.suffix == '.json': + found.append(p.relative_to(root).as_posix()) + return found + + +def _local_key_path(root, url): + """Map a metadata key URL onto this tree (last path component).""" + name = url.rstrip('/').rsplit('/', 1)[-1] + candidate = root / name + if candidate.is_file(): + return candidate + sys.exit(f'ERROR: OpenPGP key {url} not found at {candidate}') + + def main(): p = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter) p.add_argument('--root', default='advisories/publish/.well-known/csaf', - help='Distribution root containing openpgp-key.asc and TLP folders.') + help='Distribution root containing provider-metadata.json.') + p.add_argument('--fingerprint', default=None, + help='Signing-key fingerprint. Required to check .asc ' + 'signatures. Must match provider-metadata.json.') args = p.parse_args() root = pathlib.Path(args.root) - pubkey, _ = pgpy.PGPKey.from_file(str(root / 'openpgp-key.asc')) - - docs = sorted(root.glob('*/*/*.json')) - if not docs: - sys.exit(f'ERROR: no CSAF documents under {root}') - + if not root.is_dir(): + sys.exit(f'ERROR: distribution root not found: {root}') + + md_path = root / 'provider-metadata.json' + if not md_path.is_file(): + sys.exit(f'ERROR: missing provider-metadata.json under {root}') + try: + metadata = json.loads(md_path.read_text()) + except json.JSONDecodeError as e: + sys.exit(f'ERROR: provider-metadata.json: {e}') + + index_rels = _index_paths(root) + disk_rels = _disk_docs(root) + index_set = set(index_rels) + disk_set = set(disk_rels) failures = 0 - for doc in docs: + + for rel in sorted(index_set - disk_set): + print(f'FAIL index lists missing file: {rel}') + failures += 1 + for rel in sorted(disk_set - index_set): + print(f'FAIL on-disk document not in index.txt: {rel}') + failures += 1 + + # provider-metadata is not in index.txt; still check its sidecars. + to_hash_paths = [(rel, root / rel) for rel in index_rels] + to_hash_paths.append(('provider-metadata.json', md_path)) + + pubkey = None + pgpy = None + if args.fingerprint: + want_fp = args.fingerprint.replace(' ', '').upper() + keys = metadata.get('public_openpgp_keys') or [] + match = None + for k in keys: + fp = str(k.get('fingerprint') or '').replace(' ', '').upper() + if fp == want_fp: + match = k + break + if match is None: + sys.exit('ERROR: --fingerprint does not match provider-metadata.json') + key_url = match.get('url') + if not key_url: + sys.exit('ERROR: matching public_openpgp_keys entry has no url') + pgpy = _require_pgpy() + pubkey, _ = pgpy.PGPKey.from_file(str(_local_key_path(root, key_url))) + + for rel, path in to_hash_paths: + if rel != 'provider-metadata.json' and rel not in disk_set: + continue + if not path.is_file(): + continue problems = [] for algo in ('sha256', 'sha512'): - err = _check_hash(doc, algo) + err = _check_hash(path, algo) if err: problems.append(err) - asc = doc.with_name(doc.name + '.asc') - if not asc.exists(): - problems.append('missing .asc') - else: - try: - sig = pgpy.PGPSignature.from_file(str(asc)) - if not pubkey.verify(doc.read_bytes(), sig): - problems.append('signature INVALID') - except Exception as e: # noqa: BLE001 - problems.append(f'signature error: {e}') - - rel = doc.relative_to(root) + if pubkey is not None: + asc = path.with_name(path.name + '.asc') + if not asc.exists(): + problems.append('missing .asc') + else: + try: + sig = pgpy.PGPSignature.from_file(str(asc)) + if not pubkey.verify(path.read_bytes(), sig): + problems.append('signature INVALID') + except Exception as e: # noqa: BLE001 + problems.append(f'signature error: {e}') + if problems: failures += 1 print(f'FAIL {rel}: {"; ".join(problems)}') else: - print(f'OK {rel} (sha256+sha512+OpenPGP)') + extra = '+OpenPGP' if pubkey is not None else '' + print(f'OK {rel} (sha256+sha512{extra})') - print(f'\n{len(docs) - failures}/{len(docs)} documents verified') + n = len(index_rels) + print(f'\n{n} indexed document(s); ' + f'{"FAIL" if failures else "OK"} ({failures} failure(s))') sys.exit(1 if failures else 0) diff --git a/central/test_advisory_completeness.py b/central/test_advisory_completeness.py index 1150e11..982a367 100644 --- a/central/test_advisory_completeness.py +++ b/central/test_advisory_completeness.py @@ -8,12 +8,15 @@ import importlib.util import json import pathlib +import subprocess +import sys import tempfile import unittest from importlib.machinery import SourceFileLoader HERE = pathlib.Path(__file__).resolve().parent SCRIPT = HERE / 'advisory-completeness' +ROOT = HERE.parent def _load(): @@ -29,11 +32,14 @@ def _load(): # A minimal ChangeLog with two releases. 5.9.1 has a normal Vulnerabilities # section plus a second vuln-titled section, and a Bug Fixes section that # mentions an *unrelated* CVE which must NOT be counted as fixed here. +# 5.9.2 has a body mention and a two-id bullet (strict drops the second id). CHANGELOG = """\ # wolfSSL Release 5.9.2 (Jun 23, 2026) ## Vulnerabilities * [High] CVE-2026-9001 Incomplete-fix follow-up to CVE-2026-5460 (released in 5.9.1). +* [Med] CVE-2026-1111, CVE-2026-2222 + Two ids on one bullet. # wolfSSL Release 5.9.1 (Apr. 8, 2026) ## Vulnerabilities @@ -77,12 +83,22 @@ def test_missing_release_exits(self): with self.assertRaises(SystemExit): ac.release_block(CHANGELOG, 'wolfSSL', '9.9.9') - def test_excludes_cve_named_only_in_bullet_body(self): block = ac.release_block(CHANGELOG, 'wolfSSL', '5.9.2') - self.assertEqual(ac.cves_fixed_in_release(block), ['CVE-2026-9001']) + self.assertEqual(ac.cves_fixed_in_release(block), + ['CVE-2026-9001', 'CVE-2026-1111']) self.assertNotIn('CVE-2026-5460', ac.cves_fixed_in_release(block)) + def test_loose_set_names_ids_the_strict_rule_drops(self): + block = ac.release_block(CHANGELOG, 'wolfSSL', '5.9.2') + strict, loose = ac.cves_in_vuln_sections(block) + self.assertEqual(strict, ['CVE-2026-9001', 'CVE-2026-1111']) + self.assertEqual(loose, [ + 'CVE-2026-9001', 'CVE-2026-5460', 'CVE-2026-1111', 'CVE-2026-2222', + ]) + dropped = [c for c in loose if c not in set(strict)] + self.assertEqual(dropped, ['CVE-2026-5460', 'CVE-2026-2222']) + class ReconcileTests(unittest.TestCase): def test_gap_is_reported(self): @@ -107,6 +123,25 @@ def test_orphan_overlay_detected(self): {'CVE-2026-5778', 'CVE-2026-0000'}) self.assertEqual(r['orphan_overlay'], ['CVE-2026-0000']) + def test_changelog_reconcile_names_strict_drops(self): + strict = ['CVE-2026-9001', 'CVE-2026-1111'] + loose = ['CVE-2026-9001', 'CVE-2026-5460', 'CVE-2026-1111', + 'CVE-2026-2222'] + pin = ['CVE-2026-9001'] + prior = ['CVE-2026-1111'] + mentions = ['CVE-2026-5460', 'CVE-2026-2222'] + r = ac.reconcile_changelog(strict, loose, pin, prior, mentions) + self.assertFalse(r['pin_missing']) + self.assertFalse(r['pin_extra']) + self.assertFalse(r['mentions_missing']) + self.assertFalse(r['mentions_extra']) + + def test_changelog_reconcile_fails_unclassified_drop(self): + strict = ['CVE-2026-9001', 'CVE-2026-1111'] + loose = ['CVE-2026-9001', 'CVE-2026-5460', 'CVE-2026-1111'] + r = ac.reconcile_changelog(strict, loose, strict, [], []) + self.assertEqual(r['mentions_missing'], ['CVE-2026-5460']) + class OverlayLoadTests(unittest.TestCase): def test_comment_keys_ignored(self): @@ -118,23 +153,108 @@ def test_comment_keys_ignored(self): })) self.assertEqual(ac.load_overlay(str(p)), {'CVE-2026-5778'}) + def test_missing_fixed_version(self): + overlay = { + 'CVE-2026-9001': {'fixed_versions': ['5.9.1']}, + 'CVE-2026-9002': {'fixed_versions': ['5.9.2']}, + } + bad = ac.overlay_missing_fixed_version( + ['CVE-2026-9001', 'CVE-2026-9002'], overlay, '5.9.2') + self.assertEqual(bad, ['CVE-2026-9001']) + + +class CliTests(unittest.TestCase): + def _run(self, args): + return subprocess.run( + [sys.executable, str(SCRIPT)] + args, + capture_output=True, text=True) + + def test_release_must_match_cve_list_stem(self): + pin = ROOT / 'advisories' / 'releases' / '5.9.2.cves' + r = self._run(['--cve-list', str(pin), '--release', '9.9.9']) + self.assertNotEqual(r.returncode, 0) + self.assertIn('--release 9.9.9', r.stderr) + class Release592CatalogueTests(unittest.TestCase): """The committed 5.9.2 pin list must be fully covered by records+overlay.""" def test_pinned_list_is_fully_covered(self): - root = HERE.parent - pin = root / 'advisories' / 'releases' / '5.9.2.cves' + pin = ROOT / 'advisories' / 'releases' / '5.9.2.cves' cves = ac.load_cve_list(pin) - self.assertEqual(len(cves), 32) + self.assertEqual(len(cves), 30) self.assertNotIn('CVE-2026-5460', cves) - records = ac.records_present(root / 'advisories' / 'records') - overlay = ac.load_overlay(str(root / 'advisories' / 'vex-overlay.json')) + self.assertNotIn('CVE-2026-6679', cves) + self.assertNotIn('CVE-2026-6681', cves) + records = ac.records_present(ROOT / 'advisories' / 'records') + overlay = ac.load_overlay(str(ROOT / 'advisories' / 'vex-overlay.json')) report = ac.build_report(cves, records, overlay) self.assertFalse(report['missing_record'], report['missing_record']) self.assertFalse(report['missing_overlay'], report['missing_overlay']) self.assertFalse(report['orphan_overlay'], report['orphan_overlay']) + def test_overlay_fixed_versions_are_5_9_2(self): + pin = ac.load_cve_list(ROOT / 'advisories' / 'releases' / '5.9.2.cves') + overlay = ac.load_overlay_map( + str(ROOT / 'advisories' / 'vex-overlay.json')) + bad = ac.overlay_missing_fixed_version(pin, overlay, '5.9.2') + self.assertFalse(bad, bad) + + def test_prior_release_ids_are_5_9_1_fixes(self): + prior = ac.load_cve_list( + ROOT / 'advisories' / 'releases' / '5.9.2.prior-release.cves') + self.assertEqual(prior, ['CVE-2026-6679', 'CVE-2026-6681']) + overlay = ac.load_overlay_map( + str(ROOT / 'advisories' / 'vex-overlay.json')) + for cve in prior: + self.assertIn('5.9.1', overlay[cve]['fixed_versions'], cve) + self.assertNotIn('5.9.2', overlay[cve]['fixed_versions'], cve) + + def test_pin_matches_frozen_changelog(self): + pin = ac.load_cve_list(ROOT / 'advisories' / 'releases' / '5.9.2.cves') + prior = ac.load_cve_list( + ROOT / 'advisories' / 'releases' / '5.9.2.prior-release.cves') + mentions = ac.load_cve_list( + ROOT / 'advisories' / 'releases' / '5.9.2.mentions.cves') + text = (HERE / 'testdata' / 'ChangeLog-5.9.2.md').read_text() + block = ac.release_block(text, 'wolfSSL', '5.9.2') + strict, loose = ac.cves_in_vuln_sections(block) + r = ac.reconcile_changelog(strict, loose, pin, prior, mentions) + self.assertFalse(r['pin_missing'], r) + self.assertFalse(r['pin_extra'], r) + self.assertFalse(r['mentions_missing'], r) + self.assertFalse(r['mentions_extra'], r) + self.assertFalse(r['prior_not_in_strict'], r) + self.assertEqual(mentions, ['CVE-2026-5460']) + + +class Release592CdxRatingsTests(unittest.TestCase): + """CycloneDX is the machine-readable CVSS v4 path (CSAF 2.0 has no v4).""" + + def test_every_pinned_cve_has_cvss_v4_rating(self): + ga_loader = SourceFileLoader('ga', str(HERE / 'gen-advisory')) + spec = importlib.util.spec_from_loader('ga', ga_loader) + ga = importlib.util.module_from_spec(spec) + ga_loader.exec_module(ga) + pin = ac.load_cve_list(ROOT / 'advisories' / 'releases' / '5.9.2.cves') + overlay = json.loads( + (ROOT / 'advisories' / 'vex-overlay.json').read_text()) + rec_dir = ROOT / 'advisories' / 'records' + advs = [] + for cve in pin: + rec = json.loads((rec_dir / f'{cve}.json').read_text()) + advs.append(ga.parse_record(rec)) + bom = ga.generate_cdx_vex(advs, overlay, 'wolfssl-5.9.2', + '2026-01-02T00:00:00Z') + self.assertEqual(len(bom['vulnerabilities']), 30) + missing = [] + for v in bom['vulnerabilities']: + ratings = v.get('ratings') or [] + if not any(r.get('method') == 'CVSSv4' and r.get('score') is not None + for r in ratings): + missing.append(v['id']) + self.assertFalse(missing, missing) + if __name__ == '__main__': unittest.main() diff --git a/central/test_csaf_publish.py b/central/test_csaf_publish.py index 4c70394..9c45b8b 100644 --- a/central/test_csaf_publish.py +++ b/central/test_csaf_publish.py @@ -8,6 +8,7 @@ import hashlib import importlib.util import json +import os import pathlib import tempfile import unittest @@ -15,6 +16,8 @@ HERE = pathlib.Path(__file__).resolve().parent PUBLISH = HERE / 'csaf-publish' +VERIFY = HERE / 'csaf-verify' +KEYGEN = HERE / 'csaf-keygen' GEN = HERE / 'gen-advisory' TESTDATA = HERE / 'testdata' EXAMPLE_OVERLAY = HERE / 'advisory-vex-overlay.example.json' @@ -29,6 +32,8 @@ def _load(path, name): pub = _load(PUBLISH, 'csaf_publish') +ver = _load(VERIFY, 'csaf_verify') +keygen = _load(KEYGEN, 'csaf_keygen') ga = _load(GEN, 'ga') @@ -98,6 +103,10 @@ def test_layout_hashes_and_self_url(self): md = json.loads((csaf_root / 'provider-metadata.json').read_text()) self.assertEqual(md['role'], 'csaf_provider') self.assertNotIn('public_openpgp_keys', md) + md_path = csaf_root / 'provider-metadata.json' + for algo in ('sha256', 'sha512'): + side = md_path.with_name(md_path.name + '.' + algo) + self.assertEqual(side.read_text().split()[0], _sha(md_path, algo)) def test_rerun_drops_stale_files(self): csaf_root = self._publish() @@ -109,6 +118,69 @@ def test_rerun_drops_stale_files(self): json_docs = sorted(p.name for p in (csaf_root / 'white' / '2026').glob('*.json')) self.assertEqual(json_docs, ['cve-2026-5501.json']) + def test_source_date_epoch_pins_metadata_timestamp(self): + saved = os.environ.get('SOURCE_DATE_EPOCH') + os.environ['SOURCE_DATE_EPOCH'] = '1700000000' + try: + csaf_root = self._publish() + finally: + if saved is None: + os.environ.pop('SOURCE_DATE_EPOCH', None) + else: + os.environ['SOURCE_DATE_EPOCH'] = saved + md = json.loads((csaf_root / 'provider-metadata.json').read_text()) + self.assertEqual(md['last_updated'], '2023-11-14T22:13:20Z') + + def test_case_colliding_tracking_ids_fail(self): + # A second document whose tracking id differs only in case must not + # silently overwrite the first canonical filename. + first = json.loads((self.docs / 'CVE-2026-5501.csaf.json').read_text()) + (self.docs / 'CVE-2026-5501.csaf.json').unlink() + one = json.loads(json.dumps(first)) + one['document']['tracking']['id'] = 'WolfSSL-SA-1' + two = json.loads(json.dumps(first)) + two['document']['tracking']['id'] = 'wolfssl-sa-1' + (self.docs / 'one.csaf.json').write_text(json.dumps(one, indent=2) + '\n') + (self.docs / 'two.csaf.json').write_text(json.dumps(two, indent=2) + '\n') + with self.assertRaises(SystemExit) as cm: + self._publish() + self.assertIn('canonicalize', str(cm.exception)) + + def test_unsigned_verify_walks_index(self): + csaf_root = self._publish() + import sys + argv = sys.argv + try: + sys.argv = ['csaf-verify', '--root', str(csaf_root)] + with self.assertRaises(SystemExit) as cm: + ver.main() + self.assertEqual(cm.exception.code, 0) + finally: + sys.argv = argv + + def test_verify_detects_index_without_file(self): + csaf_root = self._publish() + index = csaf_root / 'index.txt' + index.write_text(index.read_text() + 'white/2026/cve-1999-0001.json\n') + import sys + argv = sys.argv + try: + sys.argv = ['csaf-verify', '--root', str(csaf_root)] + with self.assertRaises(SystemExit) as cm: + ver.main() + self.assertEqual(cm.exception.code, 1) + finally: + sys.argv = argv + + +class KeygenPermTests(unittest.TestCase): + def test_secret_written_mode_0600(self): + with tempfile.TemporaryDirectory() as d: + path = pathlib.Path(d) / 'secret.asc' + keygen.write_secret(str(path), 'SECRET\n') + mode = path.stat().st_mode & 0o777 + self.assertEqual(mode, 0o600) + if __name__ == '__main__': unittest.main() diff --git a/central/testdata/ChangeLog-5.9.2.md b/central/testdata/ChangeLog-5.9.2.md new file mode 100644 index 0000000..d3535af --- /dev/null +++ b/central/testdata/ChangeLog-5.9.2.md @@ -0,0 +1,119 @@ +# wolfSSL Release 5.9.2 (Jun 23, 2026) + +Release 5.9.2 has been developed according to wolfSSL's development and QA +process (see link below) and successfully passed the quality criteria. +https://www.wolfssl.com/about/wolfssl-software-development-process-quality-assurance + +NOTE: +* The pre-standardization Dilithium API has been renamed to its FIPS 204 ML-DSA name; the legacy `dilithium.h` header and `wc_dilithium_*` names remain available through a temporary compatibility shim. +* The SLH-DSA Hash sign/verify APIs now require a caller-supplied pre-hashed digest rather than the raw message (see Enhancements below). +* liboqs integrations for ML-KEM, ML-DSA, and SLH-DSA (SPHINCS+) have been removed in favor of the native implementations; the deprecated liblms and libxmss integrations have also been removed. +* **BREAKING (RFC 6960 4.2.2.2)**: OCSP responder authorization is now strictly enforced. Removes the non-compliant `CheckOcspResponderChain()` fallback, which authorized any OCSP responder cert issued by an ancestor of the target's issuer; RFC 6960 4.2.2.2 requires direct issuance by the CA identified in the request. Also removes the now-unused `WOLFSSL_NO_OCSP_ISSUER_CHAIN_CHECK` macro and the `vp` parameter from `CheckOcspResponder()`. + +PR stands for Pull Request, and PR references a GitHub pull request number where the code change was added. + +## Vulnerabilities + +* [High] CVE-2026-11310 + X.509 trust-chain bypass in the OpenSSL compatibility certificate verifier (wolfSSL_X509_verify_cert()). + + This affects only builds with --enable-opensslextra (OPENSSL_EXTRA) and whose application validates certificates by calling X509_verify_cert() (OpenSSL compatibility layer function) with caller-supplied untrusted intermediate certificates; for those users it is critical, otherwise the library is unaffected. In particular, native wolfSSL TLS/DTLS usage is not impacted. + + wolfSSL’s X509_verify_cert() temporarily loads each caller-supplied untrusted intermediate into the certificate manager but failed to drop them before the trusted-store check, so an untrusted intermediate could anchor the path itself. An attacker can present a chain that never reaches a configured trust anchor and have it accepted, resulting in acceptance of an attacker-controlled certificate. + + This is certificate verification independent of TLS (e.g. S/MIME/CMS, code/firmware signing, JWT/JWS x5c), is not specific to any key type or algorithm, and a single untrusted intermediate suffices. The default wolfSSL TLS handshake (WOLFSSL_VERIFY_PEER) is not affected; only TLS applications doing manual or deferred peer verification through this API are, which also requires --enable-sessioncerts. Affected: v5.8.4, v5.9.0 and v5.9.1 (introduced by commit 025dbc34); v5.8.2 and earlier are not. Thanks to Corban Villa, Sohee Kim and Austin Chu (UC Berkeley, Sky Lab). Fixed in PR 10674. + +* [High] CVE-2026-11999 + X.509 trust-chain bypass (path-depth exhaustion) in the OpenSSL compatibility certificate verifier (wolfSSL_X509_verify_cert()). This affects only builds with --enable-opensslextra whose application calls X509_verify_cert() with caller-supplied untrusted intermediates; for those users it is critical, otherwise the library is unaffected. Native wolfSSL TLS/DTLS usage is not impacted. + + X509_verify_cert() returned success based only on the last verified link rather than on reaching a trust anchor: when the supplied chain is deeper than the verifier's maximum path depth (default 100), path building runs out of depth while still walking untrusted intermediates and the chain is accepted even though it never reaches a configured trust anchor, allowing acceptance of an attacker-controlled certificate. The default TLS handshake (WOLFSSL_VERIFY_PEER) is not affected; only applications doing manual or deferred verification through this API are. Affected versions: v5.7.4 through v5.9.1, introduced in commit 17c9e92b7 (first released in v5.7.4); v5.7.2 and earlier are not affected. Thanks to Corban Villa, Sohee Kim and Austin Chu (UC Berkeley, Sky Lab). Fixed in PR 10674. + +* [High] CVE-2026-6679 + A heap buffer overflow could occur in the DTLS 1.3 ACK serialization path before the connecting peer is authenticated. The buffer overflow was due to an integer truncation when computing the length of the ACK record-number list, causing an undersized buffer to be allocated and then overrun. This affects builds using DTLS 1.3 and wolfSSL version 5.9.0 and earlier. A fix was added to the 5.9.1 release. Thanks to Nicholas Carlini from Anthropic for the report. Fixed in PR 10116. + +* [High] CVE-2026-55958 + Out-of-bounds write in the Renesas TSIP TLS 1.3 transcript buffer. In tsip_StoreMessage() the capacity check guarding the fixed message bag (MSGBAG_SIZE) sets an error code but fails to return, so execution falls through to an XMEMCPY that writes past the end of the buffer once the accumulated TLS 1.3 handshake transcript exceeds MSGBAG_SIZE (8 KB), corrupting adjacent heap state and potentially causing a remote denial of service crash. The bag is sized to hold a normal handshake, so this is reached only by an unusually large but valid certificate chain, or by a malicious or man-in-the-middle server sending an oversized handshake message to a client that does not strictly verify the chain. This only affects builds using the Renesas TSIP TLS port (WOLFSSL_RENESAS_TSIP_TLS) as a TLS 1.3 client on Renesas MCUs with TSIP hardware enabled, and is rated High within those builds. All other configurations are unaffected. Thanks to NVIDIA Project Vanessa for the report. Fixed in PR 10705. + +* [High] CVE-2026-55960 + Un-negotiated Raw Public Key (RFC 7250) accepted in place of an X.509 certificate, bypassing chain validation. A raw public key has no chain, so ParseCertRelative() accepts it without performing any trust verification; it must therefore only be accepted when RPK was actually negotiated for that peer. The check now defaults the expected type to X.509 (per RFC 7250/8446) when no type was negotiated, comparing against the received server certificate type on the client and the selected client certificate type on the server, and rejects any mismatch, including an un-negotiated raw public key, with UNSUPPORTED_CERTIFICATE. Only affects builds with Raw Public Key support (HAVE_RPK) enabled - disabled by default in a standalone build, but included in --enable-all. Thanks to NVIDIA Project Vanessa for the report. Fixed in PR 10702. + +* [High] CVE-2026-55961 + wolfSSL_PKCS7_verify() returning success for a degenerate (certs-only) PKCS#7 object that contains no signer. Such an object has empty signerInfos, so the underlying signed-data verification succeeds without authenticating any content. The compatibility-layer verify path now rejects the object when no signer signature has actually been verified, so a PKCS#7 carrying no valid signature is no longer reported as verified. This is enforced regardless of the PKCS7_NOVERIFY flag, which only suppresses signer certificate chain validation and was never intended to waive the requirement that a signature exist. Only affects OpenSSL compatibility builds that call the PKCS7_verify() compatibility API on potentially degenerate PKCS#7 bundles. Thanks to NVIDIA Project Vanessa for the report. Fixed in PR 10702. + +* [High] CVE-2026-10097 + wolfSSL's AVX2-optimized ML-KEM implementation (mlkem_cmp_avx2) compares only 1536 of the 1568 ciphertext bytes during the Fujisaki-Okamoto re-encryption check in ML-KEM-1024 decapsulation. Ciphertexts that differ from the expected re-encryption solely in bytes 1536-1567 bypass implicit rejection and are accepted as valid, breaking IND-CCA2 security. An attacker able to submit chosen ciphertexts to a decapsulation oracle that uses a static ML-KEM-1024 key, and to observe whether the genuine shared secret or the implicit-rejection secret was produced, can use this as a plaintext-checking oracle to recover the private key. A proof of concept recovered a full ML-KEM-1024 private key with approximately 98% success using roughly 350 chosen ciphertexts. The flaw is a deterministic logic error and does not rely on timing measurements. Thanks to 007bsd @007bsd for the report. Fixed in PR 10430. + +* [Med] CVE-2026-6731 + X.509 name constraint bypass via the Subject Common Name when treated as a DNS-type name. A certificate whose Subject CN violates an issuing CA's DNS name constraints could be accepted. Thanks to d0sf3t (Aradex) for the report. Fixed in PR 10223. + +* [Med] CVE-2026-6091 + Partial-chain certificate verification may accept chains that terminate at a peer-supplied, untrusted intermediate certificate rather than a trusted anchor. An attacker could present a chain that ends at an intermediate they control and have it accepted as valid. Thanks to Dikai Zou for the report. Fixed in PR 10170. + +* [Med] CVE-2026-6094 + Heap buffer overread in wc_PKCS7_DecodeEnvelopedData when parsing crafted PKCS7 EnvelopedData. This could theoretically be triggered by attacker-supplied data delivered via S/MIME or CMS. Thanks to Dikai Zou for the report. Fixed in PR 10128. + +* [Med] CVE-2026-6329 + PKCS#12 MAC verification uses an attacker-controlled comparison length, weakening the integrity check on the MAC and allowing a mismatched MAC to be accepted. Thanks to Nicholas Carlini from Anthropic for the report. Fixed in PR 10192. + +* [Med] CVE-2026-6330 + The ML-KEM ARM64 NEON ciphertext comparison only compares half of the input, breaking the Fujisaki-Okamoto transform's implicit rejection and weakening IND-CCA2 security on that code path. Thanks to Nicholas Carlini from Anthropic for the report. Fixed in PR 10192. + +* [Med] CVE-2026-8720 + wc_Blake2bHmacFinal and wc_Blake2sHmacFinal discard the message when the key length exceeds the block size, producing a MAC that is independent of the input. This bug is specific to the HMAC-BLAKE2 API’s that were added in wolfSSL version 5.9.0. Fixed in PR 10447. + +* [Med] CVE-2026-10098 + OCSP CertID serial-number length-confusion in wolfSSL_OCSP_resp_find_status allows a same-issuer SingleResponse whose serial is a prefix of the target serial to be reported as the revocation status of a different certificate. Thanks to Kim Youngjoon (Team-Atlanta and Georgia Institute of Technology) for the report. Fixed in PR 10554. + +* [Med] CVE-2026-10592 + Certificates with wildcard DNS SANs (e.g. *.example.com) bypassed CA name-constraint checks. Thanks to tonghuaroot for the report. Fixed in PR 10549. + +* [Med] CVE-2026-7532 + iPAddress name constraints bypass when WOLFSSL_IP_ALT_NAME is not defined. IP address name constraints are not enforced in that configuration, allowing a certificate to bypass an issuing CA's IP address constraints. Thanks to Ankur Tyagi of Cisco Talos (TALOS-2026-2409) for the report. Fixed in PR 10354. + +* [Med] CVE-2026-6291 + Bleichenbacher padding oracle in PKCS#7 KTRI decryption. When decrypting PKCS#7 EnvelopedData using RSA PKCS#1 v1.5 key transport, wolfSSL returned distinguishable error codes depending on whether RSA padding validation failed versus whether the decrypted content was malformed. An attacker able to submit crafted EnvelopedData messages and observe error responses could use this as a padding oracle to incrementally recover the encrypted Content Encryption Key (CEK). The fix generates a deterministic pseudo-random fake CEK on padding failure (via HMAC-SHA256) and proceeds with decryption identically, using constant-time operations throughout, so that all failure paths produce the same error regardless of padding validity. Found with internal wolfSSL review. Fixed in PR 10203. + +* [Med] CVE-2026-7511 + PKCS7_verify signer confusion allows forged signatures, where the signer associated with a signature is not correctly bound, permitting a forged signature to be accepted. Thanks to Nicholas Carlini from Anthropic for the report. Fixed in PR 10203. + +* [Med] CVE-2026-11703 + Fixed missing SNI/ALPN binding on stateful (session-ID) resumption, which previously skipped the binding check performed for ticket-based resumption. A cached session could be resumed under a different SNI/ALPN than originally negotiated and, where client-authentication policy differs across virtual hosts, carry the cached peer-authentication state into a context it was not established for. Resumption now verifies the SNI/ALPN binding for all paths and declines (falling back to a full handshake) on mismatch. Thanks to Dikai Zou for the report. Fixed in PR 10489. + +* [Med] CVE-2026-55962 + TLS 1.3 post-handshake authentication (PHA) issue where a server could accept a client's Finished message without the client having sent a Certificate and CertificateVerify. The post-handshake-auth exemption that allows an empty/absent peer certificate was only intended for the initial handshake, but it was also being applied while a post-handshake CertificateRequest was still outstanding. The check is now scoped to the initial handshake only: on the server, once a post-handshake CertificateRequest has been sent (certReqCtx is set), a peer certificate and a valid CertificateVerify are required again before the Finished is accepted, with empty-certificate handling following the configured verify mode (FAIL_IF_NO_PEER_CERT) just as during first-handshake client authentication. Only affects TLS 1.3 servers built with post-handshake authentication support (WOLFSSL_POST_HANDSHAKE_AUTH / --enable-postauth, included in --enable-all) that enable WOLFSSL_VERIFY_POST_HANDSHAKE and request a client certificate after the handshake via wolfSSL_request_certificate(). Clients, and servers that do not use post-handshake authentication, are unaffected. Thanks to NVIDIA Project Vanessa for the report. Fixed in PR 10702. + +* [Med] CVE-2026-55964 + Chain intermediate CA:TRUE without keyCertSign accepted as a signing CA. Intermediate CA certificates are required to have the keyCertSign key usage when a Key Usage extension is present, but chain-supplied temporary CAs (WOLFSSL_TEMP_CA) added while building a certificate path were previously exempted from this check, so an intermediate asserting CA:TRUE but lacking keyCertSign was accepted as a signing CA. The check now applies to chain-supplied temporary CAs as well; only operator-loaded root certificates (WOLFSSL_USER_CA) and self-signed roots remain exempt. Per RFC 5280 an absent Key Usage extension implies all usages, so the requirement is enforced only when the extension is actually present (extKeyUsageSet). Affects the OpenSSL-compatibility certificate-path-building path (X509_verify_cert / X509_STORE, OPENSSL_EXTRA/OPENSSL_ALL), where untrusted chain intermediates are added as temporary CAs; native (non-OpenSSL-compat) certificate verification does not create temporary CAs and is unaffected. Within those builds, the check applies unless ALLOW_INVALID_CERTSIGN is defined. Thanks to NVIDIA Project Vanessa for the report. Fixed in PR 10702. + +* [Low] CVE-2026-6092 + When HAVE_ENCRYPT_THEN_MAC is configured, the implementation could fall back to MAC-then-Encrypt rather than enforcing Encrypt-then-MAC. Thanks to Marcin Olejnik (Rockwell Automation) for the report. Fixed in PR 10167. + +* [Low] CVE-2026-6331 + HMAC zero-length tag forgery in EVP_DigestVerifyFinal, where a zero-length tag could be accepted as valid during HMAC verification. Thanks to Nicholas Carlini from Anthropic for the report. Fixed in PR 10192. + +* [Low] CVE-2026-6681 + The PKCS#7 decode path ignores the caller-supplied output buffer size (outputSz), allowing decoded content to be written past the bounds of the provided buffer. This affects wolfSSL 5.9.0 and earlier and was fixed in the 5.9.1 release. Thanks to Nicholas Carlini from Anthropic for the report. Fixed in PR 10116. + +* [Low] CVE-2026-10512 + The X25519 x86_64 assembly implementation fails to clear the most significant bit during the final modular reduction, so the computed result may not be fully reduced modulo the field prime 2^255 - 19. This can leave the field element in a non-canonical form, producing an incorrect result from the scalar multiplication and potentially a wrong shared secret. Thanks to Haruki Oyama for the report. Fixed in PR 10536. + +* [Low] CVE-2026-6678 + Integer underflow in wc_PKCS7_DecryptOri when handling crafted Other Recipient Info, leading to incorrect length handling during decryption. Thanks to Dikai Zou for the report. Fixed in PR 10203. + +* [Low] CVE-2026-7531 + Use-after-free in PQC hybrid key-share handling. This is an incomplete-fix follow-up to CVE-2026-5460 (released in 5.9.1): a malicious TLS 1.3 server sending a truncated PQC hybrid KeyShare can still trigger the error cleanup path to operate on freed memory. Thanks to Thai Duong (Calif.io / Anthropic) for the report. Fixed in PR 10327. + +* [Low] CVE-2026-6325 + Out-of-bounds write in SetSuitesHashSigAlgo when processing an oversized signature algorithms list, allowing a write past the bounds of the destination buffer. Thanks to Muhammad Arya Arjuna Habibullah (Pelioro) for the report. Fixed in PR 10204. + +* [Low] CVE-2026-6412 + Certificate policy and RFC 8446 compliance concerns regarding the continued acceptance of SHA-1/MD5 in certificate processing. Thanks to Xiangdong Li (Student, Beijing University of Posts and Telecommunications [BUPT]) for the report. Fixed in PR 10222. + +* [Low] CVE-2026-6450 + A CRL critical extension bypass exists in ParseCRL_Extensions where critical extensions are not properly enforced, allowing a crafted CRL with an unhandled critical extension to be accepted. This only affects builds with CRL support enabled and where a crafted CRL had a trusted signature when parsed. Thanks to Oleh Konko (@1seal) for the report. Fixed in PR 10239. + +* [Low] CVE-2026-12340 + Out-of-bounds heap read during SM2/SM3 certificate signature verification. When parsing a certificate with an SM3wSM2 signature, the Subject Key Identifier computation reads the trailing 65 bytes of the public key without checking that the key is at least that long. A public key shorter than 65 bytes results in an out-of-bounds heap read, leading to a potential crash (denial of service); there is no out-of-bounds write. Note this only affects builds with SM2 support (--enable-sm2 or --enable-all). Thanks to David Pokora, Trail of Bits (in collaboration with Anthropic). Fixed in PR 10641. + +* [Low] CVE-2026-55967 + AES-GCM encryption/decryption with extremely large cumulative single message sizes (>64 GiB) were not properly rejected by the streaming APIs, allowing counter wrap, keystream reuse, and consequent plaintext recovery. Thanks to NVIDIA Project Vanessa for the report. Fixed in PR 10709. diff --git a/central/testdata/README.md b/central/testdata/README.md index 180bc51..0585751 100644 --- a/central/testdata/README.md +++ b/central/testdata/README.md @@ -9,3 +9,4 @@ the `.github/workflows/advisory.yml` jobs. Committed so the tests are hermetic | `CVE-2026-5501.json` | Real published wolfSSL CNA record (CVSS v4 only). | | `CVE-2026-5778.json` | Real published wolfSSL CNA record (CVSS v4 only). | | `CVE-2026-5999.json` | **Synthetic fixture, not a real CVE.** Carries a CVSS v3.1 block so the CSAF `scores[]` emission path (and the CVSS-consistency mandatory tests 6.1.8/6.1.9) is exercised; the v4-only records above never populate `scores[]` in CSAF 2.0. | +| `ChangeLog-5.9.2.md` | Frozen wolfSSL 5.9.2 release header and Vulnerabilities section. Completeness CI reconciles the pin list against this file so the gate does not need a sibling wolfssl checkout. | diff --git a/tools/csaf-validate/fixtures/schema-ok-mandatory-fail.csaf.json b/tools/csaf-validate/fixtures/schema-ok-mandatory-fail.csaf.json new file mode 100644 index 0000000..6fe67b1 --- /dev/null +++ b/tools/csaf-validate/fixtures/schema-ok-mandatory-fail.csaf.json @@ -0,0 +1,195 @@ +{ + "document": { + "category": "csaf_security_advisory", + "csaf_version": "2.0", + "title": "wolfSSL: Improper Certificate Signature Verification in X.509 Chain Validation Allows Forged Leaf Certificates", + "publisher": { + "category": "vendor", + "name": "wolfSSL Inc.", + "namespace": "https://www.wolfssl.com" + }, + "tracking": { + "id": "CVE-2026-5501", + "status": "final", + "version": "1", + "initial_release_date": "2026-04-10T03:07:39.604Z", + "current_release_date": "2026-04-22T13:59:28.514Z", + "revision_history": [ + { + "number": "1", + "date": "2026-04-10T03:07:39.604Z", + "summary": "Initial release" + } + ], + "generator": { + "engine": { + "name": "wolfssl-advisory-gen", + "version": "0.3" + } + } + }, + "distribution": { + "tlp": { + "label": "WHITE" + } + }, + "references": [ + { + "summary": "Canonical CSAF document for CVE-2026-5501", + "url": "https://www.wolfssl.com/docs/security-vulnerabilities/csaf/CVE-2026-5501.csaf.json", + "category": "self" + }, + { + "summary": "wolfSSL published security vulnerabilities", + "url": "https://www.wolfssl.com/docs/security-vulnerabilities/", + "category": "external" + } + ], + "notes": [ + { + "category": "summary", + "title": "Summary", + "text": "wolfSSL_X509_verify_cert in the OpenSSL compatibility layer accepts a certificate chain in which the leaf's signature is not checked, if the attacker supplies an untrusted intermediate with Basic Constraints `CA:FALSE` that is legitimately signed by a trusted root. An attacker who obtains any leaf certificate from a trusted CA (e.g. a free DV cert from Let's Encrypt) can forge a certificate for any subject name with any public key and arbitrary signature bytes, and the function returns `WOLFSSL_SUCCESS` / `X509_V_OK`. The native wolfSSL TLS handshake path (`ProcessPeerCerts`) is not susceptible and the issue is limited to applications using the OpenSSL compatibility API directly, which would include integrations of wolfSSL into nginx and haproxy." + } + ], + "aggregate_severity": { + "text": "CRITICAL" + } + }, + "product_tree": { + "branches": [ + { + "category": "vendor", + "name": "wolfSSL", + "branches": [ + { + "category": "product_name", + "name": "wolfSSL", + "branches": [ + { + "category": "product_version_range", + "name": "<= 5.9.0", + "product": { + "product_id": "f338f179-6564-510a-a371-4f9d5ae7cfd8", + "name": "wolfSSL <= 5.9.0", + "product_identification_helper": { + "cpe": "cpe:2.3:a:wolfssl:wolfssl:*:*:*:*:*:*:*:*" + } + } + }, + { + "category": "product_version", + "name": "5.9.1", + "product": { + "product_id": "cdbca113-e651-55c5-8648-814580b5cfe8", + "name": "wolfSSL 5.9.1", + "product_identification_helper": { + "cpe": "cpe:2.3:a:wolfssl:wolfssl:5.9.1:*:*:*:*:*:*:*", + "purl": "pkg:github/wolfssl/wolfssl@v5.9.1-stable" + } + } + } + ] + } + ] + }, + { + "category": "vendor", + "name": "wolfSSL", + "branches": [ + { + "category": "product_name", + "name": "wolfCrypt FIPS 140-3 Module", + "branches": [ + { + "category": "product_version_range", + "name": "5.2.1", + "product": { + "product_id": "358e11f7-fbf4-5f8c-9d7d-4b129fb9874f", + "name": "wolfCrypt FIPS 140-3 Module 5.2.1", + "product_identification_helper": { + "cpe": "cpe:2.3:a:wolfssl:wolfcrypt:5.2.1:*:*:*:*:*:*:*", + "model_numbers": [ + "CMVP Certificate #4718" + ] + } + } + } + ] + } + ] + } + ] + }, + "vulnerabilities": [ + { + "cve": "CVE-2026-5501", + "notes": [ + { + "category": "description", + "text": "wolfSSL_X509_verify_cert in the OpenSSL compatibility layer accepts a certificate chain in which the leaf's signature is not checked, if the attacker supplies an untrusted intermediate with Basic Constraints `CA:FALSE` that is legitimately signed by a trusted root. An attacker who obtains any leaf certificate from a trusted CA (e.g. a free DV cert from Let's Encrypt) can forge a certificate for any subject name with any public key and arbitrary signature bytes, and the function returns `WOLFSSL_SUCCESS` / `X509_V_OK`. The native wolfSSL TLS handshake path (`ProcessPeerCerts`) is not susceptible and the issue is limited to applications using the OpenSSL compatibility API directly, which would include integrations of wolfSSL into nginx and haproxy.", + "title": "Vulnerability description" + }, + { + "category": "other", + "title": "CVSS v4.0", + "text": "CVSS v4.0 base score 9.3 (CRITICAL); vector CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:N/SC:N/SI:N/SA:N. CSAF 2.0 scores[] cannot encode CVSS v4; the machine-readable v4 rating is provided in the CycloneDX VEX output." + } + ], + "product_status": { + "known_affected": [ + "f338f179-6564-510a-a371-4f9d5ae7cfd8" + ], + "fixed": [ + "cdbca113-e651-55c5-8648-814580b5cfe8" + ], + "known_not_affected": [ + "358e11f7-fbf4-5f8c-9d7d-4b129fb9874f", + "f338f179-6564-510a-a371-4f9d5ae7cfd8" + ] + }, + "cwe": { + "id": "CWE-295", + "name": "Improper Certificate Validation" + }, + "references": [ + { + "summary": "https://github.com/wolfSSL/wolfssl/pull/10102", + "url": "https://github.com/wolfSSL/wolfssl/pull/10102", + "category": "external" + } + ], + "flags": [ + { + "label": "vulnerable_code_not_present", + "product_ids": [ + "358e11f7-fbf4-5f8c-9d7d-4b129fb9874f" + ] + } + ], + "remediations": [ + { + "category": "vendor_fix", + "details": "Update to wolfSSL 5.9.1 or later, or avoid relying on wolfSSL_X509_verify_cert in the OpenSSL compatibility layer for chain validation.", + "product_ids": [ + "f338f179-6564-510a-a371-4f9d5ae7cfd8" + ], + "url": "https://github.com/wolfSSL/wolfssl/pull/10102" + }, + { + "category": "no_fix_planned", + "details": "No action required for the FIPS-validated module: the affected OpenSSL compatibility layer (wolfSSL_X509_verify_cert) is outside the wolfCrypt FIPS module boundary.", + "product_ids": [ + "358e11f7-fbf4-5f8c-9d7d-4b129fb9874f" + ], + "url": "https://github.com/wolfSSL/wolfssl/pull/10102" + } + ], + "acknowledgments": [ + { + "summary": "Calif.io in collaboration with Claude and Anthropic Research" + } + ] + } + ] +} diff --git a/tools/csaf-validate/package-lock.json b/tools/csaf-validate/package-lock.json new file mode 100644 index 0000000..64f51ef --- /dev/null +++ b/tools/csaf-validate/package-lock.json @@ -0,0 +1,197 @@ +{ + "name": "wolfglass-csaf-validate", + "version": "0.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "wolfglass-csaf-validate", + "dependencies": { + "@secvisogram/csaf-validator-lib": "2.0.25" + } + }, + "node_modules/@js-joda/core": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@js-joda/core/-/core-5.7.0.tgz", + "integrity": "sha512-WBu4ULVVxySLLzK1Ppq+OdfP+adRS4ntmDQT915rzDJ++i95gc2jZkM5B6LWEAwN3lGXpfie3yPABozdD3K3Vg==", + "license": "BSD-3-Clause" + }, + "node_modules/@js-joda/timezone": { + "version": "2.25.2", + "resolved": "https://registry.npmjs.org/@js-joda/timezone/-/timezone-2.25.2.tgz", + "integrity": "sha512-TEjy13bQrJyIkoWZ4EqiZ+Vz66y3sYhEdibySZpfLgPij6mhh8ncGb0NGkSROOg2PwSmZLu1+0f3o4esSv2Yaw==", + "license": "BSD-3-Clause", + "peerDependencies": { + "@js-joda/core": ">=5.7.0" + } + }, + "node_modules/@secvisogram/csaf-validator-lib": { + "version": "2.0.25", + "resolved": "https://registry.npmjs.org/@secvisogram/csaf-validator-lib/-/csaf-validator-lib-2.0.25.tgz", + "integrity": "sha512-MzlyAruLqQwoBuL22jyZ3pCO2pkWCCpaz9StRJlC4CEjpd85/G0vCy2gPo+CvQaAykvmfJhm6zyPyz+Pmuv6hg==", + "license": "MIT", + "dependencies": { + "@js-joda/core": "^5.6.1", + "@js-joda/timezone": "^2.18.2", + "ajv": "^8.11.2", + "ajv-formats": "^3.0.1", + "bcp47": "^1.1.2", + "cvss2js": "^1.1.0", + "json-pointer": "^0.6.1", + "lodash": "^4.17.21", + "packageurl-js": "^2.0.1", + "semver": "^7.5.4", + "temporal-polyfill": "^0.3.0", + "undici": "^6.23.0" + } + }, + "node_modules/ajv": { + "version": "8.20.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.20.0.tgz", + "integrity": "sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", + "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", + "license": "MIT", + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/bcp47": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/bcp47/-/bcp47-1.1.2.tgz", + "integrity": "sha512-JnkkL4GUpOvvanH9AZPX38CxhiLsXMBicBY2IAtqiVN8YulGDQybUydWA4W6yAMtw6iShtw+8HEF6cfrTHU+UQ==", + "license": "MIT", + "engines": { + "node": ">=0.10" + } + }, + "node_modules/cvss2js": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/cvss2js/-/cvss2js-1.1.0.tgz", + "integrity": "sha512-ssH3uw7jcxZgp1rbsUoYUbVlvQghAgPKDUQafapMhNvr4N/MvrXr217KOTHJZHDjT6hxOlOqvCLbC/JxL1T8Tg==", + "license": "MIT" + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "license": "MIT" + }, + "node_modules/fast-uri": { + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.8.tgz", + "integrity": "sha512-GZMtZUTNRpOVIECoXwLNZS5xUGE+mVNbTB8h/7Rwh2TFWcBQiPzTgyZi05BF9UMZKkLJv8XBRJTlU7zg8+ZfMg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/foreach": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.6.tgz", + "integrity": "sha512-k6GAGDyqLe9JaebCsFCoudPPWfihKu8pylYXRlqP1J7ms39iPoTtk2fviNglIeQEwdh0bQeKJ01ZPyuyQvKzwg==", + "license": "MIT" + }, + "node_modules/json-pointer": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/json-pointer/-/json-pointer-0.6.2.tgz", + "integrity": "sha512-vLWcKbOaXlO+jvRy4qNd+TI1QUPZzfJj1tpJ3vAXDych5XJf93ftpUKe5pKCrzyIIwgBJcOcCVRUfqQP25afBw==", + "license": "MIT", + "dependencies": { + "foreach": "^2.0.4" + } + }, + "node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "license": "MIT" + }, + "node_modules/lodash": { + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.18.1.tgz", + "integrity": "sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==", + "license": "MIT" + }, + "node_modules/packageurl-js": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/packageurl-js/-/packageurl-js-2.0.1.tgz", + "integrity": "sha512-N5ixXjzTy4QDQH0Q9YFjqIWd6zH6936Djpl2m9QNFmDv5Fum8q8BjkpAcHNMzOFE0IwQrFhJWex3AN6kS0OSwg==", + "license": "MIT" + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/semver": { + "version": "7.8.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", + "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/temporal-polyfill": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/temporal-polyfill/-/temporal-polyfill-0.3.2.tgz", + "integrity": "sha512-TzHthD/heRK947GNiSu3Y5gSPpeUDH34+LESnfsq8bqpFhsB79HFBX8+Z834IVX68P3EUyRPZK5bL/1fh437Eg==", + "license": "MIT", + "dependencies": { + "temporal-spec": "0.3.1" + } + }, + "node_modules/temporal-spec": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/temporal-spec/-/temporal-spec-0.3.1.tgz", + "integrity": "sha512-B4TUhezh9knfSIMwt7RVggApDRJZo73uZdj8AacL2mZ8RP5KtLianh2MXxL06GN9ESYiIsiuoLQhgVfwe55Yhw==", + "license": "ISC" + }, + "node_modules/undici": { + "version": "6.28.1", + "resolved": "https://registry.npmjs.org/undici/-/undici-6.28.1.tgz", + "integrity": "sha512-zWpdTVD54H48CIybL0rWQ3ukpb9d23wM7eH5RtfdmeP70cWHNjtfo7P4vZX+5CoDcO53J4Pu5uXp7lNfjc6DRA==", + "license": "MIT", + "engines": { + "node": ">=18.17" + } + } + } +} diff --git a/tools/csaf-validate/requirements.txt b/tools/csaf-validate/requirements.txt new file mode 100644 index 0000000..710f2e5 --- /dev/null +++ b/tools/csaf-validate/requirements.txt @@ -0,0 +1,5 @@ +# Pinned Python validator deps for .github/workflows/advisory.yml. +# The CycloneDX 1.6 schema is loaded from cyclonedx-python-lib; there is no +# cyclonedx-bom CLI in this path. +jsonschema==4.23.0 +cyclonedx-python-lib==11.12.0 diff --git a/tools/csaf-validate/test_csaf_validate.mjs b/tools/csaf-validate/test_csaf_validate.mjs index ca2ef35..fe3bad3 100644 --- a/tools/csaf-validate/test_csaf_validate.mjs +++ b/tools/csaf-validate/test_csaf_validate.mjs @@ -42,6 +42,15 @@ try { writeFileSync(junk, '{ not valid json') check('unparsable document exits non-zero', run([junk]).status !== 0) + // Schema-valid but mandatory-test-violating: the same product_id is both + // known_affected and known_not_affected (CSAF 6.1.6). A stub that only + // ran the schema test would exit 0; the gate must still fail. + const mandatoryFail = join(HERE, 'fixtures', 'schema-ok-mandatory-fail.csaf.json') + const mf = run([mandatoryFail]) + check('schema-valid mandatory-fail fixture exits 1', mf.status === 1) + const mfOut = `${mf.stdout}\n${mf.stderr}` + check('mandatory-fail names a 6.1.* test', /6[._]1[._]/.test(mfOut)) + const validDoc = process.argv[2] if (validDoc) { check(`valid document exits 0 (${validDoc})`, run([validDoc]).status === 0) From 09c8c67b6b0d46c0589831c86319cb5ac74e09a1 Mon Sep 17 00:00:00 2001 From: Sameeh Jubran Date: Thu, 17 Sep 2026 12:31:31 +0300 Subject: [PATCH 3/3] feat(csaf): make the catalogue version-agnostic and add 5.9.1 CI loops advisories/releases// instead of naming 5.9.2. 5.9.1 is a full pin (ChangeLog bullets plus late disclosures 6679/6681) so a second release proves the same path works for any version. --- .github/workflows/advisory.yml | 133 +++++--- advisories/records/CVE-2026-5187.json | 206 ++++++++++++ advisories/records/CVE-2026-5188.json | 165 ++++++++++ advisories/records/CVE-2026-5194.json | 174 +++++++++++ advisories/records/CVE-2026-5263.json | 167 ++++++++++ advisories/records/CVE-2026-5264.json | 159 ++++++++++ advisories/records/CVE-2026-5295.json | 164 ++++++++++ advisories/records/CVE-2026-5392.json | 154 +++++++++ advisories/records/CVE-2026-5393.json | 164 ++++++++++ advisories/records/CVE-2026-5446.json | 155 +++++++++ advisories/records/CVE-2026-5447.json | 154 +++++++++ advisories/records/CVE-2026-5448.json | 156 ++++++++++ advisories/records/CVE-2026-5460.json | 159 ++++++++++ advisories/records/CVE-2026-5466.json | 151 +++++++++ advisories/records/CVE-2026-5477.json | 157 ++++++++++ advisories/records/CVE-2026-5479.json | 154 +++++++++ advisories/records/CVE-2026-5500.json | 156 ++++++++++ advisories/records/CVE-2026-5503.json | 150 +++++++++ advisories/records/CVE-2026-5504.json | 177 +++++++++++ advisories/records/CVE-2026-5507.json | 166 ++++++++++ advisories/records/CVE-2026-5772.json | 156 ++++++++++ advisories/releases/5.9.1/ChangeLog.md | 81 +++++ advisories/releases/5.9.1/cves | 27 ++ advisories/releases/5.9.1/supplemental.cves | 3 + .../releases/5.9.2/ChangeLog.md | 0 .../releases/{5.9.2.cves => 5.9.2/cves} | 4 +- .../mentions.cves} | 0 .../prior-release.cves} | 0 advisories/vex-overlay.json | 293 ++++++++++++++++-- central/README.md | 26 +- central/advisory-completeness | 107 ++++++- central/test_advisory_completeness.py | 156 ++++++---- central/testdata/README.md | 1 - 33 files changed, 3903 insertions(+), 172 deletions(-) create mode 100644 advisories/records/CVE-2026-5187.json create mode 100644 advisories/records/CVE-2026-5188.json create mode 100644 advisories/records/CVE-2026-5194.json create mode 100644 advisories/records/CVE-2026-5263.json create mode 100644 advisories/records/CVE-2026-5264.json create mode 100644 advisories/records/CVE-2026-5295.json create mode 100644 advisories/records/CVE-2026-5392.json create mode 100644 advisories/records/CVE-2026-5393.json create mode 100644 advisories/records/CVE-2026-5446.json create mode 100644 advisories/records/CVE-2026-5447.json create mode 100644 advisories/records/CVE-2026-5448.json create mode 100644 advisories/records/CVE-2026-5460.json create mode 100644 advisories/records/CVE-2026-5466.json create mode 100644 advisories/records/CVE-2026-5477.json create mode 100644 advisories/records/CVE-2026-5479.json create mode 100644 advisories/records/CVE-2026-5500.json create mode 100644 advisories/records/CVE-2026-5503.json create mode 100644 advisories/records/CVE-2026-5504.json create mode 100644 advisories/records/CVE-2026-5507.json create mode 100644 advisories/records/CVE-2026-5772.json create mode 100644 advisories/releases/5.9.1/ChangeLog.md create mode 100644 advisories/releases/5.9.1/cves create mode 100644 advisories/releases/5.9.1/supplemental.cves rename central/testdata/ChangeLog-5.9.2.md => advisories/releases/5.9.2/ChangeLog.md (100%) rename advisories/releases/{5.9.2.cves => 5.9.2/cves} (88%) rename advisories/releases/{5.9.2.mentions.cves => 5.9.2/mentions.cves} (100%) rename advisories/releases/{5.9.2.prior-release.cves => 5.9.2/prior-release.cves} (100%) diff --git a/.github/workflows/advisory.yml b/.github/workflows/advisory.yml index 6a29605..846c7d5 100644 --- a/.github/workflows/advisory.yml +++ b/.github/workflows/advisory.yml @@ -2,6 +2,8 @@ name: Advisory catalogue # Validates the committed CSAF/VEX catalogue (records + overlay) and the # publish layout. Generated documents are built in CI, not committed. +# Every advisories/releases// directory is a release; the workflow +# does not name 5.9.1 or 5.9.2. on: push: @@ -42,21 +44,33 @@ jobs: central/test_advisory_completeness.py \ central/test_csaf_publish.py - - name: Completeness gate against ChangeLog + 5.9.2 pin + - name: Completeness gate for every release directory run: | - python3 central/advisory-completeness \ - --cve-list advisories/releases/5.9.2.cves \ - --release 5.9.2 \ - --changelog central/testdata/ChangeLog-5.9.2.md \ - --prior-release advisories/releases/5.9.2.prior-release.cves \ - --mentions advisories/releases/5.9.2.mentions.cves \ - --require-fixed-version 5.9.2 + python3 - <<'PY' + import subprocess, sys + import importlib.util + from importlib.machinery import SourceFileLoader + loader = SourceFileLoader('ac', 'central/advisory-completeness') + spec = importlib.util.spec_from_loader('ac', loader) + ac = importlib.util.module_from_spec(spec) + loader.exec_module(ac) + dirs = ac.list_release_dirs('advisories/releases') + if not dirs: + sys.exit('ERROR: no advisories/releases// directories') + rc = 0 + for d in dirs: + print(f'--- {d} ---') + r = subprocess.run([sys.executable, 'central/advisory-completeness', + '--release-dir', str(d)]) + rc |= r.returncode + sys.exit(rc) + PY catalogue: - name: generate and validate 5.9.2 + name: generate and validate all releases runs-on: ubuntu-24.04 needs: unit - timeout-minutes: 15 + timeout-minutes: 25 steps: - uses: actions/checkout@v4 @@ -85,55 +99,80 @@ jobs: print('OK: advisories/vex-overlay.json matches schema') PY - - name: Generate 5.9.2 CSAF + CycloneDX VEX + - name: Generate CSAF + CycloneDX VEX for every release run: | - set -e - REC="${RUNNER_TEMP}/rec592" - ADV="${RUNNER_TEMP}/adv592" - mkdir -p "$REC" "$ADV" - while read -r id; do - [ -n "$id" ] || continue - cp "advisories/records/${id}.json" "$REC/" - done < <(grep -E '^CVE-[0-9]{4}-[0-9]{4,}$' advisories/releases/5.9.2.cves) - python3 central/gen-advisory \ - --records-dir "$REC" \ - --vex-overlay advisories/vex-overlay.json \ - --out-dir "$ADV" - python3 central/gen-advisory \ - --records-dir "$REC" \ - --vex-overlay advisories/vex-overlay.json \ - --advisory-id wolfssl-5.9.2 \ - --csaf-out "$ADV/wolfssl-5.9.2.csaf.json" \ - --cdx-vex-out "$ADV/wolfssl-5.9.2.cdx.json" - echo "ADV=$ADV" >> "$GITHUB_ENV" - - - name: Bundle membership matches 5.9.2.cves + python3 - <<'PY' + import os, pathlib, shutil, subprocess, sys + import importlib.util + from importlib.machinery import SourceFileLoader + loader = SourceFileLoader('ac', 'central/advisory-completeness') + spec = importlib.util.spec_from_loader('ac', loader) + ac = importlib.util.module_from_spec(spec) + loader.exec_module(ac) + adv = pathlib.Path(os.environ['RUNNER_TEMP']) / 'adv' + rec_root = pathlib.Path(os.environ['RUNNER_TEMP']) / 'rec' + adv.mkdir(parents=True) + records = pathlib.Path('advisories/records') + dirs = ac.list_release_dirs('advisories/releases') + if not dirs: + sys.exit('ERROR: no release directories') + for d in dirs: + pin = ac.load_cve_list(d / 'cves') + rec = rec_root / d.name + rec.mkdir(parents=True) + for cve in pin: + src = records / f'{cve}.json' + if not src.is_file(): + sys.exit(f'ERROR: missing record {src}') + shutil.copy(src, rec / src.name) + subprocess.check_call([ + sys.executable, 'central/gen-advisory', + '--records-dir', str(rec), + '--vex-overlay', 'advisories/vex-overlay.json', + '--out-dir', str(adv), + ]) + subprocess.check_call([ + sys.executable, 'central/gen-advisory', + '--records-dir', str(rec), + '--vex-overlay', 'advisories/vex-overlay.json', + '--advisory-id', f'wolfssl-{d.name}', + '--csaf-out', str(adv / f'wolfssl-{d.name}.csaf.json'), + '--cdx-vex-out', str(adv / f'wolfssl-{d.name}.cdx.json'), + ]) + print(f'OK: generated {d.name} ({len(pin)} CVEs)') + with open(os.environ['GITHUB_ENV'], 'a', encoding='utf-8') as fh: + fh.write(f'ADV={adv}\n') + PY + + - name: Bundle membership matches each pin list run: | python3 - <<'PY' - import pathlib, os, sys - sys.path.insert(0, 'central') + import json, os, pathlib, sys import importlib.util from importlib.machinery import SourceFileLoader loader = SourceFileLoader('ac', 'central/advisory-completeness') spec = importlib.util.spec_from_loader('ac', loader) ac = importlib.util.module_from_spec(spec) loader.exec_module(ac) - pin = ac.load_cve_list('advisories/releases/5.9.2.cves') - doc = __import__('json').loads( - pathlib.Path(os.environ['ADV'], 'wolfssl-5.9.2.csaf.json').read_text()) - got = [v['cve'] for v in doc['vulnerabilities']] - if set(got) != set(pin) or len(got) != len(pin): - print('pin', pin, file=sys.stderr) - print('got', got, file=sys.stderr) - sys.exit('ERROR: bundle CVE set does not match 5.9.2.cves') - print(f'OK: bundle has {len(got)} CVEs matching 5.9.2.cves') + adv = pathlib.Path(os.environ['ADV']) + for d in ac.list_release_dirs('advisories/releases'): + pin = ac.load_cve_list(d / 'cves') + doc = json.loads((adv / f'wolfssl-{d.name}.csaf.json').read_text()) + got = [v['cve'] for v in doc['vulnerabilities']] + if set(got) != set(pin) or len(got) != len(pin): + print('pin', pin, file=sys.stderr) + print('got', got, file=sys.stderr) + sys.exit(f'ERROR: bundle CVE set does not match {d.name}') + print(f'OK: wolfssl-{d.name} has {len(got)} CVEs') PY - name: CSAF 2.0 strict schema + mandatory tests run: node tools/csaf-validate/csaf_validate.mjs "${ADV}"/*.csaf.json - name: csaf_validate runner contract - run: node tools/csaf-validate/test_csaf_validate.mjs "${ADV}/CVE-2026-11310.csaf.json" + run: | + VALID=$(ls "${ADV}"/CVE-*.csaf.json | head -n 1) + node tools/csaf-validate/test_csaf_validate.mjs "${VALID}" - name: CycloneDX 1.6 strict schema and CVSS v4 ratings run: | @@ -167,12 +206,12 @@ jobs: run: | python3 central/csaf-publish \ --docs-dir "${ADV}" \ - --out-root "${RUNNER_TEMP}/publish592" + --out-root "${RUNNER_TEMP}/publish" python3 central/csaf-verify \ - --root "${RUNNER_TEMP}/publish592/.well-known/csaf" + --root "${RUNNER_TEMP}/publish/.well-known/csaf" python3 - <<'PY' import hashlib, json, os, pathlib, sys - root = pathlib.Path(os.environ['RUNNER_TEMP']) / 'publish592' / '.well-known' / 'csaf' + root = pathlib.Path(os.environ['RUNNER_TEMP']) / 'publish' / '.well-known' / 'csaf' index = [ln for ln in (root / 'index.txt').read_text().splitlines() if ln] docs = sorted(p for p in root.glob('*/*/*.json')) if len(index) != len(docs): diff --git a/advisories/records/CVE-2026-5187.json b/advisories/records/CVE-2026-5187.json new file mode 100644 index 0000000..ff5a20a --- /dev/null +++ b/advisories/records/CVE-2026-5187.json @@ -0,0 +1,206 @@ +{ + "dataType": "CVE_RECORD", + "dataVersion": "5.2", + "cveMetadata": { + "cveId": "CVE-2026-5187", + "assignerOrgId": "50d2cd11-d01a-48ed-9441-5bfce9d63b27", + "state": "PUBLISHED", + "assignerShortName": "wolfSSL", + "dateReserved": "2026-03-30T19:57:33.843Z", + "datePublished": "2026-04-09T19:45:39.937Z", + "dateUpdated": "2026-04-14T14:04:53.585Z" + }, + "containers": { + "cna": { + "providerMetadata": { + "orgId": "50d2cd11-d01a-48ed-9441-5bfce9d63b27", + "shortName": "wolfSSL", + "dateUpdated": "2026-04-09T19:45:39.937Z" + }, + "title": "Heap Out-of-Bounds Write in DecodeObjectId() in wolfSSL", + "problemTypes": [ + { + "descriptions": [ + { + "lang": "en", + "cweId": "CWE-122", + "description": "CWE-122: Heap-based Buffer Overflow", + "type": "CWE" + } + ] + }, + { + "descriptions": [ + { + "lang": "en", + "cweId": "CWE-787", + "description": "CWE-787: Out-of-bounds Write", + "type": "CWE" + } + ] + } + ], + "affected": [ + { + "vendor": "wolfSSL", + "product": "wolfSSL", + "modules": [ + "wolfcrypt/src/asn.c" + ], + "programFiles": [ + "wolfcrypt/src/asn.c" + ], + "versions": [ + { + "status": "affected", + "version": "0", + "lessThanOrEqual": "5.9.0", + "versionType": "semver" + } + ], + "defaultStatus": "unaffected" + } + ], + "descriptions": [ + { + "lang": "en", + "value": "Two potential heap out-of-bounds write locations existed in DecodeObjectId() in wolfcrypt/src/asn.c. First, a bounds check only validates one available slot before writing two OID arc values (out[0] and out[1]), enabling a 2-byte out-of-bounds write when outSz equals 1. Second, multiple callers pass sizeof(decOid) (64 bytes on 64-bit platforms) instead of the element count MAX_OID_SZ (32), causing the function to accept crafted OIDs with 33 or more arcs that write past the end of the allocated buffer.", + "supportingMedia": [ + { + "type": "text/html", + "base64": false, + "value": "

Two potential heap out-of-bounds write locations existed in DecodeObjectId() in wolfcrypt/src/asn.c. First, a bounds check only validates one available slot before writing two OID arc values (out[0] and out[1]), enabling a 2-byte out-of-bounds write when outSz equals 1. Second, multiple callers pass sizeof(decOid) (64 bytes on 64-bit platforms) instead of the element count MAX_OID_SZ (32), causing the function to accept crafted OIDs with 33 or more arcs that write past the end of the allocated buffer.

" + } + ] + } + ], + "references": [ + { + "url": "https://github.com/wolfSSL/wolfssl", + "name": "wolfSSL GitHub Repository" + } + ], + "metrics": [ + { + "format": "CVSS", + "scenarios": [ + { + "lang": "en", + "value": "GENERAL" + } + ], + "cvssV4_0": { + "attackVector": "NETWORK", + "attackComplexity": "LOW", + "attackRequirements": "PRESENT", + "privilegesRequired": "LOW", + "userInteraction": "NONE", + "vulnConfidentialityImpact": "NONE", + "subConfidentialityImpact": "NONE", + "vulnIntegrityImpact": "LOW", + "subIntegrityImpact": "NONE", + "vulnAvailabilityImpact": "LOW", + "subAvailabilityImpact": "NONE", + "exploitMaturity": "NOT_DEFINED", + "Safety": "NOT_DEFINED", + "Automatable": "NOT_DEFINED", + "Recovery": "NOT_DEFINED", + "valueDensity": "NOT_DEFINED", + "vulnerabilityResponseEffort": "NOT_DEFINED", + "providerUrgency": "NOT_DEFINED", + "version": "4.0", + "baseSeverity": "LOW", + "baseScore": 2.3, + "vectorString": "CVSS:4.0/AV:N/AC:L/AT:P/PR:L/UI:N/VC:N/VI:L/VA:L/SC:N/SI:N/SA:N" + } + } + ], + "configurations": [ + { + "lang": "en", + "value": "Bug 1 (off-by-one) affects any code calling DecodeObjectId() with an output buffer of size 1. Bug 2 (sizeof mismatch) is reachable via network when wolfSSL is compiled with HAVE_OID_DECODING or WOLFSSL_ASN_PRINT, and WC_ASN_UNKNOWN_EXT_CB is enabled with a registered unknown extension callback.", + "supportingMedia": [ + { + "type": "text/html", + "base64": false, + "value": "

Bug 1 (off-by-one) affects any code calling DecodeObjectId() with an output buffer of size 1. Bug 2 (sizeof mismatch) is reachable via network when wolfSSL is compiled with HAVE_OID_DECODING or WOLFSSL_ASN_PRINT, and WC_ASN_UNKNOWN_EXT_CB is enabled with a registered unknown extension callback.

" + } + ] + } + ], + "workarounds": [ + { + "lang": "en", + "value": "Do not enable WC_ASN_UNKNOWN_EXT_CB or do not register an unknown extension callback if not required. This mitigates the network-reachable variant (Bug 2) but does not address Bug 1.", + "supportingMedia": [ + { + "type": "text/html", + "base64": false, + "value": "

Do not enable WC_ASN_UNKNOWN_EXT_CB or do not register an unknown extension callback if not required. This mitigates the network-reachable variant (Bug 2) but does not address Bug 1.

" + } + ] + } + ], + "solutions": [ + { + "lang": "en", + "value": "Fix Bug 1: Add a bounds check requiring at least 2 output slots before writing the first OID arc split (y == 0 case). Fix Bug 2: Change callers to pass the element count (MAX_OID_SZ) instead of sizeof(decOid) as the output buffer size parameter.", + "supportingMedia": [ + { + "type": "text/html", + "base64": false, + "value": "

Fix Bug 1: Add a bounds check requiring at least 2 output slots before writing the first OID arc split (y == 0 case). Fix Bug 2: Change callers to pass the element count (MAX_OID_SZ) instead of sizeof(decOid) as the output buffer size parameter.

" + } + ] + } + ], + "credits": [ + { + "lang": "en", + "value": "ytsun, Independent Security Researcher", + "type": "finder" + } + ], + "source": { + "discovery": "UNKNOWN" + }, + "x_generator": { + "engine": "Vulnogram 1.0.1" + } + }, + "adp": [ + { + "metrics": [ + { + "other": { + "type": "ssvc", + "content": { + "id": "CVE-2026-5187", + "role": "CISA Coordinator", + "options": [ + { + "Exploitation": "none" + }, + { + "Automatable": "no" + }, + { + "Technical Impact": "partial" + } + ], + "version": "2.0.3", + "timestamp": "2026-04-14T14:03:11.195034Z" + } + } + } + ], + "title": "CISA ADP Vulnrichment", + "providerMetadata": { + "orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0", + "shortName": "CISA-ADP", + "dateUpdated": "2026-04-14T14:04:53.585Z" + } + } + ] + } +} diff --git a/advisories/records/CVE-2026-5188.json b/advisories/records/CVE-2026-5188.json new file mode 100644 index 0000000..71b417d --- /dev/null +++ b/advisories/records/CVE-2026-5188.json @@ -0,0 +1,165 @@ +{ + "dataType": "CVE_RECORD", + "dataVersion": "5.2", + "cveMetadata": { + "cveId": "CVE-2026-5188", + "assignerOrgId": "50d2cd11-d01a-48ed-9441-5bfce9d63b27", + "state": "PUBLISHED", + "assignerShortName": "wolfSSL", + "dateReserved": "2026-03-30T19:57:35.065Z", + "datePublished": "2026-04-10T03:24:21.126Z", + "dateUpdated": "2026-04-10T13:41:51.326Z" + }, + "containers": { + "cna": { + "providerMetadata": { + "orgId": "50d2cd11-d01a-48ed-9441-5bfce9d63b27", + "shortName": "wolfSSL", + "dateUpdated": "2026-04-10T03:24:21.126Z" + }, + "title": "Integer underflow in X.509 SAN parsing in wolfSSL", + "datePublic": "2026-03-31T00:02:00.000Z", + "problemTypes": [ + { + "descriptions": [ + { + "lang": "en", + "cweId": "CWE-191", + "description": "CWE-191 Integer underflow", + "type": "CWE" + } + ] + } + ], + "impacts": [ + { + "descriptions": [ + { + "lang": "en", + "value": "Incorrect handling of certificate data during parsing" + } + ] + } + ], + "affected": [ + { + "vendor": "wolfSSL", + "product": "wolfSSL", + "repo": "https://github.com/wolfSSL/wolfssl", + "programFiles": [ + "wolfcrypt/src/asn.c" + ], + "versions": [ + { + "status": "affected", + "version": "0", + "lessThanOrEqual": "5.9.0", + "versionType": "semver" + } + ], + "defaultStatus": "unaffected" + } + ], + "descriptions": [ + { + "lang": "en", + "value": "An integer underflow issue exists in wolfSSL when parsing the Subject Alternative Name (SAN) extension of X.509 certificates. A malformed certificate can specify an entry length larger than the enclosing sequence, causing the internal length counter to wrap during parsing. This results in incorrect handling of certificate data. The issue is limited to configurations using the original ASN.1 parsing implementation which is off by default.", + "supportingMedia": [ + { + "type": "text/html", + "base64": false, + "value": "

An integer underflow issue exists in wolfSSL when parsing the Subject Alternative Name (SAN) extension of X.509 certificates. A malformed certificate can specify an entry length larger than the enclosing sequence, causing the internal length counter to wrap during parsing. This results in incorrect handling of certificate data. The issue is limited to configurations using the original ASN.1 parsing implementation which is off by default.

" + } + ] + } + ], + "references": [ + { + "url": "https://github.com/wolfSSL/wolfssl/pull/10024" + } + ], + "metrics": [ + { + "format": "CVSS", + "scenarios": [ + { + "lang": "en", + "value": "GENERAL" + } + ], + "cvssV4_0": { + "attackVector": "NETWORK", + "attackComplexity": "HIGH", + "attackRequirements": "PRESENT", + "privilegesRequired": "NONE", + "userInteraction": "PASSIVE", + "vulnConfidentialityImpact": "LOW", + "subConfidentialityImpact": "NONE", + "vulnIntegrityImpact": "NONE", + "subIntegrityImpact": "NONE", + "vulnAvailabilityImpact": "LOW", + "subAvailabilityImpact": "NONE", + "exploitMaturity": "NOT_DEFINED", + "Safety": "NOT_DEFINED", + "Automatable": "NOT_DEFINED", + "Recovery": "NOT_DEFINED", + "valueDensity": "NOT_DEFINED", + "vulnerabilityResponseEffort": "NOT_DEFINED", + "providerUrgency": "NOT_DEFINED", + "version": "4.0", + "baseSeverity": "LOW", + "baseScore": 2.3, + "vectorString": "CVSS:4.0/AV:N/AC:H/AT:P/PR:N/UI:P/VC:L/VI:N/VA:L/SC:N/SI:N/SA:N" + } + } + ], + "credits": [ + { + "lang": "en", + "value": "Discovered by Muhammad Arya Arjuna Habibullah", + "type": "finder" + } + ], + "source": { + "discovery": "EXTERNAL" + }, + "x_generator": { + "engine": "Vulnogram 1.0.1" + } + }, + "adp": [ + { + "metrics": [ + { + "other": { + "type": "ssvc", + "content": { + "timestamp": "2026-04-10T13:41:44.654454Z", + "id": "CVE-2026-5188", + "options": [ + { + "Exploitation": "none" + }, + { + "Automatable": "no" + }, + { + "Technical Impact": "partial" + } + ], + "role": "CISA Coordinator", + "version": "2.0.3" + } + } + } + ], + "title": "CISA ADP Vulnrichment", + "providerMetadata": { + "orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0", + "shortName": "CISA-ADP", + "dateUpdated": "2026-04-10T13:41:51.326Z" + } + } + ] + } +} diff --git a/advisories/records/CVE-2026-5194.json b/advisories/records/CVE-2026-5194.json new file mode 100644 index 0000000..49842cc --- /dev/null +++ b/advisories/records/CVE-2026-5194.json @@ -0,0 +1,174 @@ +{ + "dataType": "CVE_RECORD", + "dataVersion": "5.2", + "cveMetadata": { + "cveId": "CVE-2026-5194", + "assignerOrgId": "50d2cd11-d01a-48ed-9441-5bfce9d63b27", + "state": "PUBLISHED", + "assignerShortName": "wolfSSL", + "dateReserved": "2026-03-30T22:13:40.162Z", + "datePublished": "2026-04-09T19:30:24.095Z", + "dateUpdated": "2026-05-23T22:06:54.008Z" + }, + "containers": { + "cna": { + "providerMetadata": { + "orgId": "50d2cd11-d01a-48ed-9441-5bfce9d63b27", + "shortName": "wolfSSL", + "dateUpdated": "2026-04-09T19:30:24.095Z" + }, + "title": "wolfSSL ECDSA Certificate Verification", + "problemTypes": [ + { + "descriptions": [ + { + "lang": "en", + "cweId": "CWE-295", + "description": "CWE-295 Improper Certificate Validation", + "type": "CWE" + } + ] + } + ], + "affected": [ + { + "vendor": "wolfSSL", + "product": "wolfSSL", + "repo": "https://github.com/wolfSSL/wolfssl", + "programFiles": [ + "wolfcrypt/src/asn.c", + "wolfcrypt/src/ecc.c" + ], + "versions": [ + { + "status": "affected", + "version": "3.12.0", + "lessThan": "5.9.1", + "versionType": "semver" + } + ], + "defaultStatus": "unaffected" + } + ], + "descriptions": [ + { + "lang": "en", + "value": "Missing hash/digest size and OID checks allow digests smaller than allowed when verifying ECDSA certificates, or smaller than is appropriate for the relevant key type, to be accepted by signature verification functions. This could lead to reduced security of ECDSA certificate-based authentication if the public CA key used is also known. This affects ECDSA/ECC verification when EdDSA or ML-DSA is also enabled.", + "supportingMedia": [ + { + "type": "text/html", + "base64": false, + "value": "

Missing hash/digest size and OID checks allow digests smaller than allowed when verifying ECDSA certificates, or smaller than is appropriate for the relevant key type, to be accepted by signature verification functions. This could lead to reduced security of ECDSA certificate-based authentication if the public CA key used is also known. This affects ECDSA/ECC verification when EdDSA or ML-DSA is also enabled.

" + } + ] + } + ], + "references": [ + { + "url": "https://github.com/wolfSSL/wolfssl/pull/10131", + "tags": [ + "patch" + ] + } + ], + "metrics": [ + { + "format": "CVSS", + "scenarios": [ + { + "lang": "en", + "value": "GENERAL" + } + ], + "cvssV4_0": { + "attackVector": "NETWORK", + "attackComplexity": "LOW", + "attackRequirements": "NONE", + "privilegesRequired": "LOW", + "userInteraction": "NONE", + "vulnConfidentialityImpact": "HIGH", + "subConfidentialityImpact": "HIGH", + "vulnIntegrityImpact": "HIGH", + "subIntegrityImpact": "LOW", + "vulnAvailabilityImpact": "LOW", + "subAvailabilityImpact": "LOW", + "exploitMaturity": "NOT_DEFINED", + "Safety": "NOT_DEFINED", + "Automatable": "NOT_DEFINED", + "Recovery": "NOT_DEFINED", + "valueDensity": "NOT_DEFINED", + "vulnerabilityResponseEffort": "NOT_DEFINED", + "providerUrgency": "RED", + "version": "4.0", + "baseSeverity": "CRITICAL", + "baseScore": 9.3, + "vectorString": "CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:H/VA:L/SC:H/SI:L/SA:L/U:Red" + } + } + ], + "credits": [ + { + "lang": "en", + "value": "Nicholas Carlini from Anthropic", + "type": "finder" + } + ], + "source": { + "discovery": "EXTERNAL" + }, + "x_generator": { + "engine": "Vulnogram 1.0.1" + } + }, + "adp": [ + { + "metrics": [ + { + "other": { + "type": "ssvc", + "content": { + "timestamp": "2026-04-21T00:00:00+00:00", + "options": [ + { + "Exploitation": "none" + }, + { + "Automatable": "no" + }, + { + "Technical Impact": "total" + } + ], + "role": "CISA Coordinator", + "version": "2.0.3", + "id": "CVE-2026-5194" + } + } + } + ], + "title": "CISA ADP Vulnrichment", + "providerMetadata": { + "orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0", + "shortName": "CISA-ADP", + "dateUpdated": "2026-04-22T03:55:45.778Z" + } + }, + { + "providerMetadata": { + "orgId": "af854a3a-2127-422b-91ae-364da2661108", + "shortName": "CVE", + "dateUpdated": "2026-05-23T22:06:54.008Z" + }, + "references": [ + { + "url": "https://www.anthropic.com/research/glasswing-initial-update" + } + ], + "title": "CVE Program Container", + "x_generator": { + "engine": "ADPogram 0.0.1" + } + } + ] + } +} diff --git a/advisories/records/CVE-2026-5263.json b/advisories/records/CVE-2026-5263.json new file mode 100644 index 0000000..29e3b13 --- /dev/null +++ b/advisories/records/CVE-2026-5263.json @@ -0,0 +1,167 @@ +{ + "dataType": "CVE_RECORD", + "dataVersion": "5.2", + "cveMetadata": { + "cveId": "CVE-2026-5263", + "assignerOrgId": "50d2cd11-d01a-48ed-9441-5bfce9d63b27", + "state": "PUBLISHED", + "assignerShortName": "wolfSSL", + "dateReserved": "2026-03-31T16:56:07.521Z", + "datePublished": "2026-04-09T21:15:48.148Z", + "dateUpdated": "2026-07-02T14:45:49.247Z" + }, + "containers": { + "cna": { + "providerMetadata": { + "orgId": "50d2cd11-d01a-48ed-9441-5bfce9d63b27", + "shortName": "wolfSSL", + "dateUpdated": "2026-04-09T21:15:48.148Z" + }, + "title": "URI nameConstraints not enforced in ConfirmNameConstraints()", + "problemTypes": [ + { + "descriptions": [ + { + "lang": "en", + "cweId": "CWE-295", + "description": "CWE-295 Improper Certificate Validation", + "type": "CWE" + } + ] + } + ], + "affected": [ + { + "vendor": "wolfSSL", + "product": "wolfSSL", + "repo": "https://github.com/wolfSSL/wolfssl", + "programFiles": [ + "wolfcrypt/src/asn.c" + ], + "versions": [ + { + "status": "affected", + "version": "0", + "lessThan": "5.9.1", + "versionType": "semver" + } + ], + "defaultStatus": "unaffected" + } + ], + "descriptions": [ + { + "lang": "en", + "value": "URI nameConstraints from constrained intermediate CAs are parsed but not enforced during certificate chain verification in wolfcrypt/src/asn.c. A compromised or malicious sub-CA could issue leaf certificates with URI SAN entries that violate the nameConstraints of the issuing CA, and wolfSSL would accept them as valid.", + "supportingMedia": [ + { + "type": "text/html", + "base64": false, + "value": "

URI nameConstraints from constrained intermediate CAs are parsed but not enforced during certificate chain verification in wolfcrypt/src/asn.c. A compromised or malicious sub-CA could issue leaf certificates with URI SAN entries that violate the nameConstraints of the issuing CA, and wolfSSL would accept them as valid.

" + } + ] + } + ], + "references": [ + { + "url": "https://github.com/wolfSSL/wolfssl/pull/10048" + } + ], + "metrics": [ + { + "format": "CVSS", + "scenarios": [ + { + "lang": "en", + "value": "GENERAL" + } + ], + "cvssV4_0": { + "attackVector": "NETWORK", + "attackComplexity": "LOW", + "attackRequirements": "PRESENT", + "privilegesRequired": "HIGH", + "userInteraction": "NONE", + "vulnConfidentialityImpact": "HIGH", + "subConfidentialityImpact": "HIGH", + "vulnIntegrityImpact": "LOW", + "subIntegrityImpact": "NONE", + "vulnAvailabilityImpact": "NONE", + "subAvailabilityImpact": "NONE", + "exploitMaturity": "NOT_DEFINED", + "Safety": "NOT_DEFINED", + "Automatable": "NOT_DEFINED", + "Recovery": "NOT_DEFINED", + "valueDensity": "NOT_DEFINED", + "vulnerabilityResponseEffort": "NOT_DEFINED", + "providerUrgency": "NOT_DEFINED", + "version": "4.0", + "baseSeverity": "HIGH", + "baseScore": 7, + "vectorString": "CVSS:4.0/AV:N/AC:L/AT:P/PR:H/UI:N/VC:H/VI:L/VA:N/SC:H/SI:N/SA:N" + } + } + ], + "credits": [ + { + "lang": "en", + "value": "Oleh Konko @1seal", + "type": "finder" + } + ], + "source": { + "discovery": "EXTERNAL" + }, + "x_generator": { + "engine": "Vulnogram 1.0.1" + } + }, + "adp": [ + { + "metrics": [ + { + "other": { + "type": "ssvc", + "content": { + "timestamp": "2026-04-10T18:08:58.932126Z", + "id": "CVE-2026-5263", + "options": [ + { + "Exploitation": "none" + }, + { + "Automatable": "no" + }, + { + "Technical Impact": "partial" + } + ], + "role": "CISA Coordinator", + "version": "2.0.3" + } + } + } + ], + "title": "CISA ADP Vulnrichment", + "providerMetadata": { + "orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0", + "shortName": "CISA-ADP", + "dateUpdated": "2026-04-10T18:09:12.862Z" + } + }, + { + "title": "CVE Program Container", + "references": [ + { + "url": "https://www.talosintelligence.com/vulnerability_reports/TALOS-2026-2410" + } + ], + "providerMetadata": { + "orgId": "af854a3a-2127-422b-91ae-364da2661108", + "shortName": "CVE", + "dateUpdated": "2026-07-02T14:45:49.247Z" + } + } + ] + } +} diff --git a/advisories/records/CVE-2026-5264.json b/advisories/records/CVE-2026-5264.json new file mode 100644 index 0000000..8df6ed3 --- /dev/null +++ b/advisories/records/CVE-2026-5264.json @@ -0,0 +1,159 @@ +{ + "dataType": "CVE_RECORD", + "dataVersion": "5.2", + "cveMetadata": { + "cveId": "CVE-2026-5264", + "assignerOrgId": "50d2cd11-d01a-48ed-9441-5bfce9d63b27", + "state": "PUBLISHED", + "assignerShortName": "wolfSSL", + "dateReserved": "2026-03-31T16:56:10.370Z", + "datePublished": "2026-04-09T21:43:12.479Z", + "dateUpdated": "2026-04-10T13:55:41.431Z" + }, + "containers": { + "cna": { + "providerMetadata": { + "orgId": "50d2cd11-d01a-48ed-9441-5bfce9d63b27", + "shortName": "wolfSSL", + "dateUpdated": "2026-04-09T21:43:12.479Z" + }, + "title": "DTLS 1.3 ACK heap buffer overflow", + "problemTypes": [ + { + "descriptions": [ + { + "lang": "en", + "cweId": "CWE-122", + "description": "CWE-122 Heap-based Buffer Overflow", + "type": "CWE" + } + ] + } + ], + "affected": [ + { + "vendor": "wolfSSL", + "product": "wolfSSL", + "repo": "https://github.com/wolfSSL/wolfssl", + "programFiles": [ + "src/dtls13.c" + ], + "versions": [ + { + "status": "affected", + "version": "0", + "lessThan": "5.9.1", + "versionType": "semver" + } + ], + "defaultStatus": "unaffected" + } + ], + "descriptions": [ + { + "lang": "en", + "value": "Heap buffer overflow in DTLS 1.3 ACK message processing. A remote attacker can send a crafted DTLS 1.3 ACK message that triggers a heap buffer overflow.", + "supportingMedia": [ + { + "type": "text/html", + "base64": false, + "value": "

Heap buffer overflow in DTLS 1.3 ACK message processing. A remote attacker can send a crafted DTLS 1.3 ACK message that triggers a heap buffer overflow.

" + } + ] + } + ], + "references": [ + { + "url": "https://github.com/wolfssl/wolfssl/pull/10076" + } + ], + "metrics": [ + { + "format": "CVSS", + "scenarios": [ + { + "lang": "en", + "value": "GENERAL" + } + ], + "cvssV4_0": { + "attackVector": "NETWORK", + "attackComplexity": "LOW", + "attackRequirements": "PRESENT", + "privilegesRequired": "NONE", + "userInteraction": "NONE", + "vulnConfidentialityImpact": "NONE", + "subConfidentialityImpact": "NONE", + "vulnIntegrityImpact": "HIGH", + "subIntegrityImpact": "NONE", + "vulnAvailabilityImpact": "HIGH", + "subAvailabilityImpact": "NONE", + "exploitMaturity": "NOT_DEFINED", + "Safety": "NOT_DEFINED", + "Automatable": "NOT_DEFINED", + "Recovery": "NOT_DEFINED", + "valueDensity": "NOT_DEFINED", + "vulnerabilityResponseEffort": "NOT_DEFINED", + "providerUrgency": "NOT_DEFINED", + "version": "4.0", + "baseSeverity": "HIGH", + "baseScore": 8.3, + "vectorString": "CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:H/VA:H/SC:N/SI:N/SA:N" + } + } + ], + "credits": [ + { + "lang": "en", + "value": "Sunwoo Lee, Korea Institute of Energy Technology (KENTECH)", + "type": "finder" + }, + { + "lang": "en", + "value": "Seunghyun Yoon, Korea Institute of Energy Technology (KENTECH)", + "type": "finder" + } + ], + "source": { + "discovery": "EXTERNAL" + }, + "x_generator": { + "engine": "Vulnogram 1.0.1" + } + }, + "adp": [ + { + "metrics": [ + { + "other": { + "type": "ssvc", + "content": { + "timestamp": "2026-04-10T13:55:34.953997Z", + "id": "CVE-2026-5264", + "options": [ + { + "Exploitation": "none" + }, + { + "Automatable": "yes" + }, + { + "Technical Impact": "total" + } + ], + "role": "CISA Coordinator", + "version": "2.0.3" + } + } + } + ], + "title": "CISA ADP Vulnrichment", + "providerMetadata": { + "orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0", + "shortName": "CISA-ADP", + "dateUpdated": "2026-04-10T13:55:41.431Z" + } + } + ] + } +} diff --git a/advisories/records/CVE-2026-5295.json b/advisories/records/CVE-2026-5295.json new file mode 100644 index 0000000..103dc67 --- /dev/null +++ b/advisories/records/CVE-2026-5295.json @@ -0,0 +1,164 @@ +{ + "dataType": "CVE_RECORD", + "dataVersion": "5.2", + "cveMetadata": { + "cveId": "CVE-2026-5295", + "assignerOrgId": "50d2cd11-d01a-48ed-9441-5bfce9d63b27", + "state": "PUBLISHED", + "assignerShortName": "wolfSSL", + "dateReserved": "2026-03-31T23:22:25.201Z", + "datePublished": "2026-04-09T22:53:10.635Z", + "dateUpdated": "2026-04-14T14:32:57.454Z" + }, + "containers": { + "cna": { + "providerMetadata": { + "orgId": "50d2cd11-d01a-48ed-9441-5bfce9d63b27", + "shortName": "wolfSSL", + "dateUpdated": "2026-04-09T22:53:10.635Z" + }, + "title": "Stack Buffer Overflow in wolfSSL PKCS7 wc_PKCS7_DecryptOri() via Oversized OID", + "problemTypes": [ + { + "descriptions": [ + { + "lang": "en", + "cweId": "CWE-121", + "description": "CWE-121 Stack-based Buffer Overflow", + "type": "CWE" + } + ] + } + ], + "affected": [ + { + "vendor": "wolfSSL", + "product": "wolfSSL", + "repo": "https://github.com/wolfSSL/wolfssl", + "programFiles": [ + "wolfcrypt/src/pkcs7.c" + ], + "versions": [ + { + "status": "affected", + "version": "0", + "lessThan": "5.9.1", + "versionType": "semver" + } + ], + "defaultStatus": "unaffected" + } + ], + "descriptions": [ + { + "lang": "en", + "value": "A stack buffer overflow exists in wolfSSL's PKCS7 implementation in the wc_PKCS7_DecryptOri() function in wolfcrypt/src/pkcs7.c. When processing a CMS EnvelopedData message containing an OtherRecipientInfo (ORI) recipient, the function copies an ASN.1-parsed OID into a fixed 32-byte stack buffer (oriOID[MAX_OID_SZ]) via XMEMCPY without first validating that the parsed OID length does not exceed MAX_OID_SZ. A crafted CMS EnvelopedData message with an ORI recipient containing an OID longer than 32 bytes triggers a stack buffer overflow. Exploitation requires the library to be built with --enable-pkcs7 (disabled by default) and the application to have registered an ORI decrypt callback via wc_PKCS7_SetOriDecryptCb().", + "supportingMedia": [ + { + "type": "text/html", + "base64": false, + "value": "

A stack buffer overflow exists in wolfSSL's PKCS7 implementation in the wc_PKCS7_DecryptOri() function in wolfcrypt/src/pkcs7.c. When processing a CMS EnvelopedData message containing an OtherRecipientInfo (ORI) recipient, the function copies an ASN.1-parsed OID into a fixed 32-byte stack buffer (oriOID[MAX_OID_SZ]) via XMEMCPY without first validating that the parsed OID length does not exceed MAX_OID_SZ. A crafted CMS EnvelopedData message with an ORI recipient containing an OID longer than 32 bytes triggers a stack buffer overflow. Exploitation requires the library to be built with --enable-pkcs7 (disabled by default) and the application to have registered an ORI decrypt callback via wc_PKCS7_SetOriDecryptCb().

" + } + ] + } + ], + "references": [ + { + "url": "https://github.com/wolfSSL/wolfssl/pull/10116" + } + ], + "metrics": [ + { + "format": "CVSS", + "scenarios": [ + { + "lang": "en", + "value": "GENERAL" + } + ], + "cvssV4_0": { + "attackVector": "ADJACENT", + "attackComplexity": "LOW", + "attackRequirements": "PRESENT", + "privilegesRequired": "NONE", + "userInteraction": "PASSIVE", + "vulnConfidentialityImpact": "LOW", + "subConfidentialityImpact": "NONE", + "vulnIntegrityImpact": "LOW", + "subIntegrityImpact": "NONE", + "vulnAvailabilityImpact": "HIGH", + "subAvailabilityImpact": "NONE", + "exploitMaturity": "NOT_DEFINED", + "Safety": "NOT_DEFINED", + "Automatable": "NOT_DEFINED", + "Recovery": "NOT_DEFINED", + "valueDensity": "NOT_DEFINED", + "vulnerabilityResponseEffort": "NOT_DEFINED", + "providerUrgency": "NOT_DEFINED", + "version": "4.0", + "baseSeverity": "MEDIUM", + "baseScore": 5.9, + "vectorString": "CVSS:4.0/AV:A/AC:L/AT:P/PR:N/UI:P/VC:L/VI:L/VA:H/SC:N/SI:N/SA:N" + } + } + ], + "credits": [ + { + "lang": "en", + "value": "Sunwoo Lee, (Korea Institute of Energy Technology, KENTECH)", + "type": "finder" + }, + { + "lang": "en", + "value": "Woohyun Choi, (Korea Institute of Energy Technology, KENTECH)", + "type": "finder" + }, + { + "lang": "en", + "value": "Seunghyun Yoon, (Korea Institute of Energy Technology, KENTECH)", + "type": "finder" + } + ], + "source": { + "discovery": "EXTERNAL" + }, + "x_generator": { + "engine": "Vulnogram 1.0.1" + } + }, + "adp": [ + { + "metrics": [ + { + "other": { + "type": "ssvc", + "content": { + "timestamp": "2026-04-14T14:32:50.288335Z", + "id": "CVE-2026-5295", + "options": [ + { + "Exploitation": "none" + }, + { + "Automatable": "no" + }, + { + "Technical Impact": "partial" + } + ], + "role": "CISA Coordinator", + "version": "2.0.3" + } + } + } + ], + "title": "CISA ADP Vulnrichment", + "providerMetadata": { + "orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0", + "shortName": "CISA-ADP", + "dateUpdated": "2026-04-14T14:32:57.454Z" + } + } + ] + } +} diff --git a/advisories/records/CVE-2026-5392.json b/advisories/records/CVE-2026-5392.json new file mode 100644 index 0000000..327b217 --- /dev/null +++ b/advisories/records/CVE-2026-5392.json @@ -0,0 +1,154 @@ +{ + "dataType": "CVE_RECORD", + "dataVersion": "5.2", + "cveMetadata": { + "cveId": "CVE-2026-5392", + "assignerOrgId": "50d2cd11-d01a-48ed-9441-5bfce9d63b27", + "state": "PUBLISHED", + "assignerShortName": "wolfSSL", + "dateReserved": "2026-04-01T23:11:07.366Z", + "datePublished": "2026-04-09T23:10:55.739Z", + "dateUpdated": "2026-04-10T14:08:48.204Z" + }, + "containers": { + "cna": { + "providerMetadata": { + "orgId": "50d2cd11-d01a-48ed-9441-5bfce9d63b27", + "shortName": "wolfSSL", + "dateUpdated": "2026-04-09T23:10:55.739Z" + }, + "title": "wolfSSL heap OOB read in PKCS7 SignedData streaming", + "problemTypes": [ + { + "descriptions": [ + { + "lang": "en", + "cweId": "CWE-125", + "description": "CWE-125 Out-of-bounds Read", + "type": "CWE" + } + ] + } + ], + "affected": [ + { + "vendor": "wolfSSL", + "product": "wolfSSL", + "repo": "https://github.com/wolfSSL/wolfssl", + "programFiles": [ + "wolfcrypt/src/pkcs7.c" + ], + "versions": [ + { + "status": "affected", + "version": "0", + "lessThan": "5.9.1", + "versionType": "semver" + } + ], + "defaultStatus": "unaffected" + } + ], + "descriptions": [ + { + "lang": "en", + "value": "Heap out-of-bounds read in PKCS7 parsing. A crafted PKCS7 message can trigger an OOB read on the heap. The missing bounds check is in the indefinite-length end-of-content verification loop in PKCS7_VerifySignedData().", + "supportingMedia": [ + { + "type": "text/html", + "base64": false, + "value": "

Heap out-of-bounds read in PKCS7 parsing. A crafted PKCS7 message can trigger an OOB read on the heap. The missing bounds check is in the indefinite-length end-of-content verification loop in PKCS7_VerifySignedData().

" + } + ] + } + ], + "references": [ + { + "url": "https://github.com/wolfssl/wolfssl/pull/10039" + } + ], + "metrics": [ + { + "format": "CVSS", + "scenarios": [ + { + "lang": "en", + "value": "GENERAL" + } + ], + "cvssV4_0": { + "attackVector": "ADJACENT", + "attackComplexity": "LOW", + "attackRequirements": "PRESENT", + "privilegesRequired": "NONE", + "userInteraction": "NONE", + "vulnConfidentialityImpact": "NONE", + "subConfidentialityImpact": "NONE", + "vulnIntegrityImpact": "LOW", + "subIntegrityImpact": "NONE", + "vulnAvailabilityImpact": "LOW", + "subAvailabilityImpact": "NONE", + "exploitMaturity": "NOT_DEFINED", + "Safety": "NOT_DEFINED", + "Automatable": "NOT_DEFINED", + "Recovery": "NOT_DEFINED", + "valueDensity": "NOT_DEFINED", + "vulnerabilityResponseEffort": "NOT_DEFINED", + "providerUrgency": "NOT_DEFINED", + "version": "4.0", + "baseSeverity": "LOW", + "baseScore": 2.3, + "vectorString": "CVSS:4.0/AV:A/AC:L/AT:P/PR:N/UI:N/VC:N/VI:L/VA:L/SC:N/SI:N/SA:N" + } + } + ], + "credits": [ + { + "lang": "en", + "value": "J Laratro (d0sf3t)", + "type": "finder" + } + ], + "source": { + "discovery": "EXTERNAL" + }, + "x_generator": { + "engine": "Vulnogram 1.0.1" + } + }, + "adp": [ + { + "metrics": [ + { + "other": { + "type": "ssvc", + "content": { + "timestamp": "2026-04-10T14:08:38.837104Z", + "id": "CVE-2026-5392", + "options": [ + { + "Exploitation": "none" + }, + { + "Automatable": "no" + }, + { + "Technical Impact": "partial" + } + ], + "role": "CISA Coordinator", + "version": "2.0.3" + } + } + } + ], + "title": "CISA ADP Vulnrichment", + "providerMetadata": { + "orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0", + "shortName": "CISA-ADP", + "dateUpdated": "2026-04-10T14:08:48.204Z" + } + } + ] + } +} diff --git a/advisories/records/CVE-2026-5393.json b/advisories/records/CVE-2026-5393.json new file mode 100644 index 0000000..c46e70f --- /dev/null +++ b/advisories/records/CVE-2026-5393.json @@ -0,0 +1,164 @@ +{ + "dataType": "CVE_RECORD", + "dataVersion": "5.2", + "cveMetadata": { + "cveId": "CVE-2026-5393", + "assignerOrgId": "50d2cd11-d01a-48ed-9441-5bfce9d63b27", + "state": "PUBLISHED", + "assignerShortName": "wolfSSL", + "dateReserved": "2026-04-01T23:11:41.235Z", + "datePublished": "2026-04-09T23:02:28.747Z", + "dateUpdated": "2026-04-10T15:02:58.096Z" + }, + "containers": { + "cna": { + "providerMetadata": { + "orgId": "50d2cd11-d01a-48ed-9441-5bfce9d63b27", + "shortName": "wolfSSL", + "dateUpdated": "2026-04-09T23:02:28.747Z" + }, + "title": "OOB Read in DoTls13CertificateVerify with WOLFSSL_DUAL_ALG_CERTS", + "problemTypes": [ + { + "descriptions": [ + { + "lang": "en", + "cweId": "CWE-125", + "description": "CWE-125 Out-of-bounds Read", + "type": "CWE" + } + ] + } + ], + "affected": [ + { + "vendor": "wolfSSL", + "product": "wolfSSL", + "repo": "https://github.com/wolfSSL/wolfssl", + "programFiles": [ + "src/tls13.c" + ], + "versions": [ + { + "status": "affected", + "version": "0", + "lessThan": "5.9.1", + "versionType": "semver" + } + ], + "defaultStatus": "unaffected" + } + ], + "descriptions": [ + { + "lang": "en", + "value": "Dual-Algorithm CertificateVerify out-of-bounds read. When processing a dual-algorithm CertificateVerify message, an out-of-bounds read can occur on crafted input. This can only occur when --enable-experimental and --enable-dual-alg-certs is used when building wolfSSL.", + "supportingMedia": [ + { + "type": "text/html", + "base64": false, + "value": "

Dual-Algorithm CertificateVerify out-of-bounds read. When processing a dual-algorithm CertificateVerify message, an out-of-bounds read can occur on crafted input. This can only occur when --enable-experimental and --enable-dual-alg-certs is used when building wolfSSL.

" + } + ] + } + ], + "references": [ + { + "url": "https://github.com/wolfSSL/wolfssl/pull/10079" + } + ], + "metrics": [ + { + "format": "CVSS", + "scenarios": [ + { + "lang": "en", + "value": "GENERAL" + } + ], + "cvssV4_0": { + "attackVector": "NETWORK", + "attackComplexity": "LOW", + "attackRequirements": "PRESENT", + "privilegesRequired": "NONE", + "userInteraction": "NONE", + "vulnConfidentialityImpact": "NONE", + "subConfidentialityImpact": "NONE", + "vulnIntegrityImpact": "LOW", + "subIntegrityImpact": "NONE", + "vulnAvailabilityImpact": "LOW", + "subAvailabilityImpact": "NONE", + "exploitMaturity": "NOT_DEFINED", + "Safety": "NOT_DEFINED", + "Automatable": "NOT_DEFINED", + "Recovery": "NOT_DEFINED", + "valueDensity": "NOT_DEFINED", + "vulnerabilityResponseEffort": "NOT_DEFINED", + "providerUrgency": "NOT_DEFINED", + "version": "4.0", + "baseSeverity": "MEDIUM", + "baseScore": 6.3, + "vectorString": "CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:L/VA:L/SC:N/SI:N/SA:N" + } + } + ], + "credits": [ + { + "lang": "en", + "value": "Sunwoo Lee, (Korea Institute of Energy Technology, KENTECH) for testing", + "type": "other" + }, + { + "lang": "en", + "value": "Woohyun Choi, (Korea Institute of Energy Technology, KENTECH) for testing", + "type": "other" + }, + { + "lang": "en", + "value": "Seunghyun Yoon, (Korea Institute of Energy Technology, KENTECH) for testing", + "type": "other" + } + ], + "source": { + "discovery": "EXTERNAL" + }, + "x_generator": { + "engine": "Vulnogram 1.0.1" + } + }, + "adp": [ + { + "metrics": [ + { + "other": { + "type": "ssvc", + "content": { + "timestamp": "2026-04-10T15:02:50.587191Z", + "id": "CVE-2026-5393", + "options": [ + { + "Exploitation": "none" + }, + { + "Automatable": "yes" + }, + { + "Technical Impact": "partial" + } + ], + "role": "CISA Coordinator", + "version": "2.0.3" + } + } + } + ], + "title": "CISA ADP Vulnrichment", + "providerMetadata": { + "orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0", + "shortName": "CISA-ADP", + "dateUpdated": "2026-04-10T15:02:58.096Z" + } + } + ] + } +} diff --git a/advisories/records/CVE-2026-5446.json b/advisories/records/CVE-2026-5446.json new file mode 100644 index 0000000..3f9be22 --- /dev/null +++ b/advisories/records/CVE-2026-5446.json @@ -0,0 +1,155 @@ +{ + "dataType": "CVE_RECORD", + "dataVersion": "5.2", + "cveMetadata": { + "cveId": "CVE-2026-5446", + "assignerOrgId": "50d2cd11-d01a-48ed-9441-5bfce9d63b27", + "state": "PUBLISHED", + "assignerShortName": "wolfSSL", + "dateReserved": "2026-04-02T19:37:56.049Z", + "datePublished": "2026-04-09T21:02:27.201Z", + "dateUpdated": "2026-04-10T18:11:52.759Z" + }, + "containers": { + "cna": { + "providerMetadata": { + "orgId": "50d2cd11-d01a-48ed-9441-5bfce9d63b27", + "shortName": "wolfSSL", + "dateUpdated": "2026-04-09T21:02:27.201Z" + }, + "title": "wolfSSL ARIA-GCM TLS 1.2/DTLS 1.2 GCM nonce reuse", + "problemTypes": [ + { + "descriptions": [ + { + "lang": "en", + "cweId": "CWE-323", + "description": "CWE-323 Reusing a Nonce, Key Pair in Encryption", + "type": "CWE" + } + ] + } + ], + "affected": [ + { + "vendor": "wolfSSL", + "product": "wolfSSL", + "repo": "https://github.com/wolfSSL/wolfssl", + "programFiles": [ + "src/internal.c", + "wolfcrypt/src/aria-crypt.c" + ], + "versions": [ + { + "status": "affected", + "version": "5.2.1", + "lessThan": "5.9.1", + "versionType": "semver" + } + ], + "defaultStatus": "unaffected" + } + ], + "descriptions": [ + { + "lang": "en", + "value": "In wolfSSL, ARIA-GCM cipher suites used in TLS 1.2 and DTLS 1.2 reuse an identical 12-byte GCM nonce for every application-data record. Because wc_AriaEncrypt is stateless and passes the caller-supplied IV verbatim to the MagicCrypto SDK with no internal counter, and because the explicit IV is zero-initialized at session setup and never incremented in non-FIPS builds. This vulnerability affects wolfSSL builds configured with --enable-aria and the proprietary MagicCrypto SDK (a non-default, opt-in configuration required for Korean regulatory deployments). AES-GCM is not affected because wc_AesGcmEncrypt_ex maintains an internal invocation counter independently of the call-site guard.", + "supportingMedia": [ + { + "type": "text/html", + "base64": false, + "value": "

In wolfSSL, ARIA-GCM cipher suites used in TLS 1.2 and DTLS 1.2 reuse an identical 12-byte GCM nonce for every application-data record. Because wc_AriaEncrypt is stateless and passes the caller-supplied IV verbatim to the MagicCrypto SDK with no internal counter, and because the explicit IV is zero-initialized at session setup and never incremented in non-FIPS builds. This vulnerability affects wolfSSL builds configured with --enable-aria and the proprietary MagicCrypto SDK (a non-default, opt-in configuration required for Korean regulatory deployments). AES-GCM is not affected because wc_AesGcmEncrypt_ex maintains an internal invocation counter independently of the call-site guard.

" + } + ] + } + ], + "references": [ + { + "url": "https://github.com/wolfSSL/wolfssl/pull/10111" + } + ], + "metrics": [ + { + "format": "CVSS", + "scenarios": [ + { + "lang": "en", + "value": "GENERAL" + } + ], + "cvssV4_0": { + "attackVector": "NETWORK", + "attackComplexity": "LOW", + "attackRequirements": "PRESENT", + "privilegesRequired": "LOW", + "userInteraction": "NONE", + "vulnConfidentialityImpact": "HIGH", + "subConfidentialityImpact": "NONE", + "vulnIntegrityImpact": "LOW", + "subIntegrityImpact": "NONE", + "vulnAvailabilityImpact": "NONE", + "subAvailabilityImpact": "NONE", + "exploitMaturity": "NOT_DEFINED", + "Safety": "NOT_DEFINED", + "Automatable": "NOT_DEFINED", + "Recovery": "NOT_DEFINED", + "valueDensity": "NOT_DEFINED", + "vulnerabilityResponseEffort": "NOT_DEFINED", + "providerUrgency": "NOT_DEFINED", + "version": "4.0", + "baseSeverity": "MEDIUM", + "baseScore": 6, + "vectorString": "CVSS:4.0/AV:N/AC:L/AT:P/PR:L/UI:N/VC:H/VI:L/VA:N/SC:N/SI:N/SA:N" + } + } + ], + "credits": [ + { + "lang": "en", + "value": "Calif.io in collaboration with Claude and Anthropic Research", + "type": "finder" + } + ], + "source": { + "discovery": "EXTERNAL" + }, + "x_generator": { + "engine": "Vulnogram 1.0.1" + } + }, + "adp": [ + { + "metrics": [ + { + "other": { + "type": "ssvc", + "content": { + "timestamp": "2026-04-10T18:11:44.381864Z", + "id": "CVE-2026-5446", + "options": [ + { + "Exploitation": "none" + }, + { + "Automatable": "no" + }, + { + "Technical Impact": "partial" + } + ], + "role": "CISA Coordinator", + "version": "2.0.3" + } + } + } + ], + "title": "CISA ADP Vulnrichment", + "providerMetadata": { + "orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0", + "shortName": "CISA-ADP", + "dateUpdated": "2026-04-10T18:11:52.759Z" + } + } + ] + } +} diff --git a/advisories/records/CVE-2026-5447.json b/advisories/records/CVE-2026-5447.json new file mode 100644 index 0000000..4ff6468 --- /dev/null +++ b/advisories/records/CVE-2026-5447.json @@ -0,0 +1,154 @@ +{ + "dataType": "CVE_RECORD", + "dataVersion": "5.2", + "cveMetadata": { + "cveId": "CVE-2026-5447", + "assignerOrgId": "50d2cd11-d01a-48ed-9441-5bfce9d63b27", + "state": "PUBLISHED", + "assignerShortName": "wolfSSL", + "dateReserved": "2026-04-02T19:39:14.309Z", + "datePublished": "2026-04-09T20:13:34.398Z", + "dateUpdated": "2026-04-10T18:07:28.848Z" + }, + "containers": { + "cna": { + "providerMetadata": { + "orgId": "50d2cd11-d01a-48ed-9441-5bfce9d63b27", + "shortName": "wolfSSL", + "dateUpdated": "2026-04-09T20:13:34.398Z" + }, + "title": "Heap buffer overflow in CertFromX509() via AuthorityKeyIdentifier", + "problemTypes": [ + { + "descriptions": [ + { + "lang": "en", + "cweId": "CWE-122", + "description": "CWE-122 Heap-based Buffer Overflow", + "type": "CWE" + } + ] + } + ], + "affected": [ + { + "vendor": "wolfSSL", + "product": "wolfSSL", + "repo": "https://github.com/wolfSSL/wolfssl", + "programFiles": [ + "src/x509.c" + ], + "versions": [ + { + "status": "affected", + "version": "0", + "lessThan": "5.9.1", + "versionType": "semver" + } + ], + "defaultStatus": "unaffected" + } + ], + "descriptions": [ + { + "lang": "en", + "value": "Heap buffer overflow in CertFromX509 via AuthorityKeyIdentifier size confusion. A heap buffer overflow occurs when converting an X.509 certificate internally due to incorrect size handling of the AuthorityKeyIdentifier extension.", + "supportingMedia": [ + { + "type": "text/html", + "base64": false, + "value": "

Heap buffer overflow in CertFromX509 via AuthorityKeyIdentifier size confusion. A heap buffer overflow occurs when converting an X.509 certificate internally due to incorrect size handling of the AuthorityKeyIdentifier extension.

" + } + ] + } + ], + "references": [ + { + "url": "https://github.com/wolfSSL/wolfssl/pull/10112" + } + ], + "metrics": [ + { + "format": "CVSS", + "scenarios": [ + { + "lang": "en", + "value": "GENERAL" + } + ], + "cvssV4_0": { + "attackVector": "NETWORK", + "attackComplexity": "LOW", + "attackRequirements": "PRESENT", + "privilegesRequired": "NONE", + "userInteraction": "NONE", + "vulnConfidentialityImpact": "NONE", + "subConfidentialityImpact": "NONE", + "vulnIntegrityImpact": "LOW", + "subIntegrityImpact": "NONE", + "vulnAvailabilityImpact": "NONE", + "subAvailabilityImpact": "NONE", + "exploitMaturity": "NOT_DEFINED", + "Safety": "NOT_DEFINED", + "Automatable": "NOT_DEFINED", + "Recovery": "NOT_DEFINED", + "valueDensity": "NOT_DEFINED", + "vulnerabilityResponseEffort": "NOT_DEFINED", + "providerUrgency": "NOT_DEFINED", + "version": "4.0", + "baseSeverity": "MEDIUM", + "baseScore": 6.3, + "vectorString": "CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:L/VA:N/SC:N/SI:N/SA:N" + } + } + ], + "credits": [ + { + "lang": "en", + "value": "Calif.io in collaboration with Claude and Anthropic Research", + "type": "finder" + } + ], + "source": { + "discovery": "EXTERNAL" + }, + "x_generator": { + "engine": "Vulnogram 1.0.1" + } + }, + "adp": [ + { + "metrics": [ + { + "other": { + "type": "ssvc", + "content": { + "timestamp": "2026-04-10T18:07:18.012291Z", + "id": "CVE-2026-5447", + "options": [ + { + "Exploitation": "none" + }, + { + "Automatable": "no" + }, + { + "Technical Impact": "partial" + } + ], + "role": "CISA Coordinator", + "version": "2.0.3" + } + } + } + ], + "title": "CISA ADP Vulnrichment", + "providerMetadata": { + "orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0", + "shortName": "CISA-ADP", + "dateUpdated": "2026-04-10T18:07:28.848Z" + } + } + ] + } +} diff --git a/advisories/records/CVE-2026-5448.json b/advisories/records/CVE-2026-5448.json new file mode 100644 index 0000000..17d564e --- /dev/null +++ b/advisories/records/CVE-2026-5448.json @@ -0,0 +1,156 @@ +{ + "dataType": "CVE_RECORD", + "dataVersion": "5.2", + "cveMetadata": { + "cveId": "CVE-2026-5448", + "assignerOrgId": "50d2cd11-d01a-48ed-9441-5bfce9d63b27", + "state": "PUBLISHED", + "assignerShortName": "wolfSSL", + "dateReserved": "2026-04-02T20:24:47.039Z", + "datePublished": "2026-04-09T23:18:15.780Z", + "dateUpdated": "2026-04-10T13:51:56.742Z" + }, + "containers": { + "cna": { + "providerMetadata": { + "orgId": "50d2cd11-d01a-48ed-9441-5bfce9d63b27", + "shortName": "wolfSSL", + "dateUpdated": "2026-04-09T23:18:15.780Z" + }, + "title": "1-2 Byte Buffer Overflow in wolfSSL_X509_notAfter/notBefore", + "problemTypes": [ + { + "descriptions": [ + { + "lang": "en", + "cweId": "CWE-122", + "description": "CWE-122 Heap-based Buffer Overflow", + "type": "CWE" + } + ] + } + ], + "affected": [ + { + "vendor": "wolfSSL", + "product": "wolfSSL", + "repo": "https://github.com/wolfSSL/wolfssl", + "versions": [ + { + "status": "affected", + "version": "0", + "lessThan": "5.9.1", + "versionType": "server" + } + ], + "defaultStatus": "unaffected" + } + ], + "descriptions": [ + { + "lang": "en", + "value": "X.509 date buffer overflow in wolfSSL_X509_notAfter / wolfSSL_X509_notBefore. A buffer overflow may occur when parsing date fields from a crafted X.509 certificate via the compatibility layer API. This is only triggered when calling these two APIs directly from an application, and does not affect TLS or certificate verify operations in wolfSSL.", + "supportingMedia": [ + { + "type": "text/html", + "base64": false, + "value": "

X.509 date buffer overflow in wolfSSL_X509_notAfter / wolfSSL_X509_notBefore. A buffer overflow may occur when parsing date fields from a crafted X.509 certificate via the compatibility layer API. This is only triggered when calling these two APIs directly from an application, and does not affect TLS or certificate verify operations in wolfSSL.

" + } + ] + } + ], + "references": [ + { + "url": "https://github.com/wolfSSL/wolfssl/pull/10071" + } + ], + "metrics": [ + { + "format": "CVSS", + "scenarios": [ + { + "lang": "en", + "value": "GENERAL" + } + ], + "cvssV4_0": { + "attackVector": "ADJACENT", + "attackComplexity": "LOW", + "attackRequirements": "PRESENT", + "privilegesRequired": "NONE", + "userInteraction": "NONE", + "vulnConfidentialityImpact": "NONE", + "subConfidentialityImpact": "NONE", + "vulnIntegrityImpact": "NONE", + "subIntegrityImpact": "NONE", + "vulnAvailabilityImpact": "LOW", + "subAvailabilityImpact": "NONE", + "exploitMaturity": "NOT_DEFINED", + "Safety": "NOT_DEFINED", + "Automatable": "NOT_DEFINED", + "Recovery": "NOT_DEFINED", + "valueDensity": "NOT_DEFINED", + "vulnerabilityResponseEffort": "NOT_DEFINED", + "providerUrgency": "GREEN", + "version": "4.0", + "baseSeverity": "LOW", + "baseScore": 2.3, + "vectorString": "CVSS:4.0/AV:A/AC:L/AT:P/PR:N/UI:N/VC:N/VI:N/VA:L/SC:N/SI:N/SA:N/U:Green" + } + } + ], + "credits": [ + { + "lang": "en", + "value": "Sunwoo Lee, Korea Institute of Energy Technology (KENTECH)", + "type": "finder" + }, + { + "lang": "en", + "value": "Seunghyun Yoon, Korea Institute of Energy Technology (KENTECH)", + "type": "finder" + } + ], + "source": { + "discovery": "EXTERNAL" + }, + "x_generator": { + "engine": "Vulnogram 1.0.1" + } + }, + "adp": [ + { + "metrics": [ + { + "other": { + "type": "ssvc", + "content": { + "timestamp": "2026-04-10T13:51:49.237675Z", + "id": "CVE-2026-5448", + "options": [ + { + "Exploitation": "none" + }, + { + "Automatable": "no" + }, + { + "Technical Impact": "partial" + } + ], + "role": "CISA Coordinator", + "version": "2.0.3" + } + } + } + ], + "title": "CISA ADP Vulnrichment", + "providerMetadata": { + "orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0", + "shortName": "CISA-ADP", + "dateUpdated": "2026-04-10T13:51:56.742Z" + } + } + ] + } +} diff --git a/advisories/records/CVE-2026-5460.json b/advisories/records/CVE-2026-5460.json new file mode 100644 index 0000000..0910dd8 --- /dev/null +++ b/advisories/records/CVE-2026-5460.json @@ -0,0 +1,159 @@ +{ + "dataType": "CVE_RECORD", + "dataVersion": "5.2", + "cveMetadata": { + "cveId": "CVE-2026-5460", + "assignerOrgId": "50d2cd11-d01a-48ed-9441-5bfce9d63b27", + "state": "PUBLISHED", + "assignerShortName": "wolfSSL", + "dateReserved": "2026-04-02T22:57:35.093Z", + "datePublished": "2026-04-09T23:29:27.577Z", + "dateUpdated": "2026-04-10T13:51:18.283Z" + }, + "containers": { + "cna": { + "providerMetadata": { + "orgId": "50d2cd11-d01a-48ed-9441-5bfce9d63b27", + "shortName": "wolfSSL", + "dateUpdated": "2026-04-09T23:29:27.577Z" + }, + "title": "Heap Use-After-Free in PQC Hybrid KeyShare Error Cleanup in wolfSSL TLS 1.3", + "problemTypes": [ + { + "descriptions": [ + { + "lang": "en", + "cweId": "CWE-416", + "description": "CWE-416 Use After Free", + "type": "CWE" + } + ] + } + ], + "affected": [ + { + "vendor": "wolfSSL", + "product": "wolfSSL", + "repo": "https://github.com/wolfSSL/wolfssl", + "programFiles": [ + "src/tls.c" + ], + "versions": [ + { + "status": "affected", + "version": "0", + "lessThan": "5.9.1", + "versionType": "semver" + } + ], + "defaultStatus": "unaffected" + } + ], + "descriptions": [ + { + "lang": "en", + "value": "A heap use-after-free exists in wolfSSL's TLS 1.3 post-quantum cryptography (PQC) hybrid KeyShare processing. In the error handling path of TLSX_KeyShare_ProcessPqcHybridClient() in src/tls.c, the inner function TLSX_KeyShare_ProcessPqcClient_ex() frees a KyberKey object upon encountering an error. The caller then invokes TLSX_KeyShare_FreeAll(), which attempts to call ForceZero() on the already-freed KyberKey, resulting in writes of zero bytes over freed heap memory.", + "supportingMedia": [ + { + "type": "text/html", + "base64": false, + "value": "

A heap use-after-free exists in wolfSSL's TLS 1.3 post-quantum cryptography (PQC) hybrid KeyShare processing. In the error handling path of TLSX_KeyShare_ProcessPqcHybridClient() in src/tls.c, the inner function TLSX_KeyShare_ProcessPqcClient_ex() frees a KyberKey object upon encountering an error. The caller then invokes TLSX_KeyShare_FreeAll(), which attempts to call ForceZero() on the already-freed KyberKey, resulting in writes of zero bytes over freed heap memory.

" + } + ] + } + ], + "references": [ + { + "url": "https://github.com/wolfssl/wolfssl/pull/10092" + } + ], + "metrics": [ + { + "format": "CVSS", + "scenarios": [ + { + "lang": "en", + "value": "GENERAL" + } + ], + "cvssV4_0": { + "attackVector": "NETWORK", + "attackComplexity": "LOW", + "attackRequirements": "PRESENT", + "privilegesRequired": "NONE", + "userInteraction": "NONE", + "vulnConfidentialityImpact": "NONE", + "subConfidentialityImpact": "NONE", + "vulnIntegrityImpact": "LOW", + "subIntegrityImpact": "NONE", + "vulnAvailabilityImpact": "LOW", + "subAvailabilityImpact": "NONE", + "exploitMaturity": "NOT_DEFINED", + "Safety": "NOT_DEFINED", + "Automatable": "NOT_DEFINED", + "Recovery": "NOT_DEFINED", + "valueDensity": "NOT_DEFINED", + "vulnerabilityResponseEffort": "NOT_DEFINED", + "providerUrgency": "NOT_DEFINED", + "version": "4.0", + "baseSeverity": "MEDIUM", + "baseScore": 6.3, + "vectorString": "CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:L/VA:L/SC:N/SI:N/SA:N" + } + } + ], + "credits": [ + { + "lang": "en", + "value": "Calvin Young (eWalker Consulting Inc.)", + "type": "finder" + }, + { + "lang": "en", + "value": "Enoch Chow (Isomorph Cyber)", + "type": "finder" + } + ], + "source": { + "discovery": "EXTERNAL" + }, + "x_generator": { + "engine": "Vulnogram 1.0.1" + } + }, + "adp": [ + { + "metrics": [ + { + "other": { + "type": "ssvc", + "content": { + "timestamp": "2026-04-10T13:51:11.637858Z", + "id": "CVE-2026-5460", + "options": [ + { + "Exploitation": "none" + }, + { + "Automatable": "yes" + }, + { + "Technical Impact": "partial" + } + ], + "role": "CISA Coordinator", + "version": "2.0.3" + } + } + } + ], + "title": "CISA ADP Vulnrichment", + "providerMetadata": { + "orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0", + "shortName": "CISA-ADP", + "dateUpdated": "2026-04-10T13:51:18.283Z" + } + } + ] + } +} diff --git a/advisories/records/CVE-2026-5466.json b/advisories/records/CVE-2026-5466.json new file mode 100644 index 0000000..ac4c14a --- /dev/null +++ b/advisories/records/CVE-2026-5466.json @@ -0,0 +1,151 @@ +{ + "dataType": "CVE_RECORD", + "dataVersion": "5.2", + "cveMetadata": { + "cveId": "CVE-2026-5466", + "assignerOrgId": "50d2cd11-d01a-48ed-9441-5bfce9d63b27", + "state": "PUBLISHED", + "assignerShortName": "wolfSSL", + "dateReserved": "2026-04-03T07:07:31.067Z", + "datePublished": "2026-04-10T03:00:42.976Z", + "dateUpdated": "2026-04-22T03:55:48.877Z" + }, + "containers": { + "cna": { + "providerMetadata": { + "orgId": "50d2cd11-d01a-48ed-9441-5bfce9d63b27", + "shortName": "wolfSSL", + "dateUpdated": "2026-04-10T03:00:42.976Z" + }, + "title": "wc_VerifyEccsiHash missing sanity check", + "datePublic": "2026-04-10T03:00:00.000Z", + "problemTypes": [ + { + "descriptions": [ + { + "lang": "en", + "cweId": "CWE-347", + "description": "CWE-347 Improper verification of cryptographic signature", + "type": "CWE" + } + ] + } + ], + "affected": [ + { + "vendor": "wolfSSL", + "product": "wolfSSL", + "versions": [ + { + "status": "affected", + "version": "0", + "lessThan": "5.9.1", + "versionType": "semver" + } + ], + "defaultStatus": "unaffected" + } + ], + "descriptions": [ + { + "lang": "en", + "value": "wolfSSL's ECCSI signature verifier `wc_VerifyEccsiHash` decodes the `r` and `s` scalars from the signature blob via `mp_read_unsigned_bin` with no check that they lie in `[1, q-1]`. A crafted forged signature could verify against any message for any identity, using only publicly-known constants.", + "supportingMedia": [ + { + "type": "text/html", + "base64": false, + "value": "

wolfSSL's ECCSI signature verifier `wc_VerifyEccsiHash` decodes the `r` and `s` scalars from the signature blob via `mp_read_unsigned_bin` with no check that they lie in `[1, q-1]`. A crafted forged signature could verify against any message for any identity, using only publicly-known constants.

" + } + ] + } + ], + "references": [ + { + "url": "https://github.com/wolfssl/wolfssl/pull/10102" + } + ], + "metrics": [ + { + "format": "CVSS", + "scenarios": [ + { + "lang": "en", + "value": "GENERAL" + } + ], + "cvssV4_0": { + "attackVector": "ADJACENT", + "attackComplexity": "LOW", + "attackRequirements": "PRESENT", + "privilegesRequired": "NONE", + "userInteraction": "NONE", + "vulnConfidentialityImpact": "HIGH", + "subConfidentialityImpact": "NONE", + "vulnIntegrityImpact": "HIGH", + "subIntegrityImpact": "NONE", + "vulnAvailabilityImpact": "NONE", + "subAvailabilityImpact": "NONE", + "exploitMaturity": "NOT_DEFINED", + "Safety": "NOT_DEFINED", + "Automatable": "NOT_DEFINED", + "Recovery": "NOT_DEFINED", + "valueDensity": "NOT_DEFINED", + "vulnerabilityResponseEffort": "NOT_DEFINED", + "providerUrgency": "NOT_DEFINED", + "version": "4.0", + "baseSeverity": "HIGH", + "baseScore": 7.6, + "vectorString": "CVSS:4.0/AV:A/AC:L/AT:P/PR:N/UI:N/VC:H/VI:H/VA:N/SC:N/SI:N/SA:N" + } + } + ], + "credits": [ + { + "lang": "en", + "value": "Calif.io in collaboration with Claude and Anthropic Research", + "type": "finder" + } + ], + "source": { + "discovery": "UNKNOWN" + }, + "x_generator": { + "engine": "Vulnogram 1.0.1" + } + }, + "adp": [ + { + "metrics": [ + { + "other": { + "type": "ssvc", + "content": { + "timestamp": "2026-04-21T00:00:00+00:00", + "options": [ + { + "Exploitation": "none" + }, + { + "Automatable": "no" + }, + { + "Technical Impact": "total" + } + ], + "role": "CISA Coordinator", + "version": "2.0.3", + "id": "CVE-2026-5466" + } + } + } + ], + "title": "CISA ADP Vulnrichment", + "providerMetadata": { + "orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0", + "shortName": "CISA-ADP", + "dateUpdated": "2026-04-22T03:55:48.877Z" + } + } + ] + } +} diff --git a/advisories/records/CVE-2026-5477.json b/advisories/records/CVE-2026-5477.json new file mode 100644 index 0000000..38bc48e --- /dev/null +++ b/advisories/records/CVE-2026-5477.json @@ -0,0 +1,157 @@ +{ + "dataType": "CVE_RECORD", + "dataVersion": "5.2", + "cveMetadata": { + "cveId": "CVE-2026-5477", + "assignerOrgId": "50d2cd11-d01a-48ed-9441-5bfce9d63b27", + "state": "PUBLISHED", + "assignerShortName": "wolfSSL", + "dateReserved": "2026-04-03T07:59:59.388Z", + "datePublished": "2026-04-10T05:06:22.884Z", + "dateUpdated": "2026-04-10T14:04:00.411Z" + }, + "containers": { + "cna": { + "providerMetadata": { + "orgId": "50d2cd11-d01a-48ed-9441-5bfce9d63b27", + "shortName": "wolfSSL", + "dateUpdated": "2026-04-10T05:06:22.884Z" + }, + "title": "Prefix-substitution forgery via integer overflow in wolfCrypt CMAC", + "problemTypes": [ + { + "descriptions": [ + { + "lang": "en", + "cweId": "CWE-190", + "description": "CWE-190 Integer overflow or wraparound", + "type": "CWE" + } + ] + } + ], + "affected": [ + { + "vendor": "wolfSSL", + "product": "wolfSSL", + "modules": [ + "wc_CmacUpdate" + ], + "programFiles": [ + "wolfcrypt/src/cmac.c", + "wolfcrypt/src/aes.c" + ], + "versions": [ + { + "status": "affected", + "version": "0", + "lessThanOrEqual": "5.9.0", + "versionType": "semver" + } + ], + "defaultStatus": "unaffected" + } + ], + "descriptions": [ + { + "lang": "en", + "value": "An integer overflow existed in the wolfCrypt CMAC implementation, that could be exploited to forge CMAC tags. The function wc_CmacUpdate used the\u00a0guard `if (cmac->totalSz != 0)` to skip XOR-chaining on the first block (where digest is all-zeros and the XOR is a no-op).\u00a0However, totalSz is word32 and wraps to zero after 2^28 block flushes (4 GiB), causing the guard to erroneously discard the live CBC-MAC chain state. Any two messages sharing a common suffix\u00a0beyond the 4 GiB mark then produce identical CMAC tags, enabling a zero-work prefix-substitution forgery. The fix removes the guard,\u00a0making the XOR unconditional; the no-op property on the first block is preserved because digest is zero-initialized by wc_InitCmac_ex.", + "supportingMedia": [ + { + "type": "text/html", + "base64": false, + "value": "An integer overflow existed in the wolfCrypt CMAC implementation, that could be exploited to forge CMAC tags. The function wc_CmacUpdate used the guard `if (cmac->totalSz != 0)` to skip XOR-chaining on the first block (where digest is all-zeros and the XOR is a no-op). However, totalSz is word32 and wraps to zero after 2^28 block flushes (4 GiB), causing the guard to erroneously discard the live CBC-MAC chain state. Any two messages sharing a common suffix beyond the 4 GiB mark then produce identical CMAC tags, enabling a zero-work prefix-substitution forgery. The fix removes the guard, making the XOR unconditional; the no-op property on the first block is preserved because digest is zero-initialized by wc_InitCmac_ex." + } + ] + } + ], + "references": [ + { + "url": "https://github.com/wolfSSL/wolfssl/pull/10102" + } + ], + "metrics": [ + { + "format": "CVSS", + "scenarios": [ + { + "lang": "en", + "value": "GENERAL" + } + ], + "cvssV4_0": { + "attackVector": "NETWORK", + "attackComplexity": "LOW", + "attackRequirements": "PRESENT", + "privilegesRequired": "NONE", + "userInteraction": "NONE", + "vulnConfidentialityImpact": "NONE", + "subConfidentialityImpact": "NONE", + "vulnIntegrityImpact": "HIGH", + "subIntegrityImpact": "NONE", + "vulnAvailabilityImpact": "NONE", + "subAvailabilityImpact": "NONE", + "exploitMaturity": "NOT_DEFINED", + "Safety": "NOT_DEFINED", + "Automatable": "NOT_DEFINED", + "Recovery": "NOT_DEFINED", + "valueDensity": "NOT_DEFINED", + "vulnerabilityResponseEffort": "NOT_DEFINED", + "providerUrgency": "NOT_DEFINED", + "version": "4.0", + "baseSeverity": "HIGH", + "baseScore": 8.2, + "vectorString": "CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:H/VA:N/SC:N/SI:N/SA:N" + } + } + ], + "credits": [ + { + "lang": "en", + "value": "Calif.io in collaboration with Claude and Anthropic Research", + "type": "finder" + } + ], + "source": { + "discovery": "EXTERNAL" + }, + "x_generator": { + "engine": "Vulnogram 1.0.1" + } + }, + "adp": [ + { + "metrics": [ + { + "other": { + "type": "ssvc", + "content": { + "timestamp": "2026-04-10T14:03:53.265423Z", + "id": "CVE-2026-5477", + "options": [ + { + "Exploitation": "none" + }, + { + "Automatable": "yes" + }, + { + "Technical Impact": "partial" + } + ], + "role": "CISA Coordinator", + "version": "2.0.3" + } + } + } + ], + "title": "CISA ADP Vulnrichment", + "providerMetadata": { + "orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0", + "shortName": "CISA-ADP", + "dateUpdated": "2026-04-10T14:04:00.411Z" + } + } + ] + } +} diff --git a/advisories/records/CVE-2026-5479.json b/advisories/records/CVE-2026-5479.json new file mode 100644 index 0000000..7fae5b9 --- /dev/null +++ b/advisories/records/CVE-2026-5479.json @@ -0,0 +1,154 @@ +{ + "dataType": "CVE_RECORD", + "dataVersion": "5.2", + "cveMetadata": { + "cveId": "CVE-2026-5479", + "assignerOrgId": "50d2cd11-d01a-48ed-9441-5bfce9d63b27", + "state": "PUBLISHED", + "assignerShortName": "wolfSSL", + "dateReserved": "2026-04-03T08:22:18.791Z", + "datePublished": "2026-04-10T02:38:39.918Z", + "dateUpdated": "2026-04-22T03:55:50.004Z" + }, + "containers": { + "cna": { + "providerMetadata": { + "orgId": "50d2cd11-d01a-48ed-9441-5bfce9d63b27", + "shortName": "wolfSSL", + "dateUpdated": "2026-04-10T02:38:39.918Z" + }, + "title": "wolfSSL EVP ChaCha20-Poly1305 AEAD authentication tag", + "problemTypes": [ + { + "descriptions": [ + { + "lang": "en", + "cweId": "CWE-354", + "description": "CWE-354 Improper Validation of Integrity Check Value", + "type": "CWE" + } + ] + } + ], + "affected": [ + { + "vendor": "wolfSSL", + "product": "wolfSSL", + "repo": "https://github.com/wolfSSL/wolfssl", + "programFiles": [ + "wolfcrypt/src/evp.c" + ], + "versions": [ + { + "status": "affected", + "version": "0", + "lessThan": "5.9.1", + "versionType": "semver" + } + ], + "defaultStatus": "unaffected" + } + ], + "descriptions": [ + { + "lang": "en", + "value": "In wolfSSL's EVP layer, the ChaCha20-Poly1305 AEAD decryption path in wolfSSL_EVP_CipherFinal (and related EVP cipher finalization functions) fails to verify the authentication tag before returning plaintext to the caller. When an application uses the EVP API to perform ChaCha20-Poly1305 decryption, the implementation computes or accepts the tag but does not compare it against the expected value.", + "supportingMedia": [ + { + "type": "text/html", + "base64": false, + "value": "

In wolfSSL's EVP layer, the ChaCha20-Poly1305 AEAD decryption path in wolfSSL_EVP_CipherFinal (and related EVP cipher finalization functions) fails to verify the authentication tag before returning plaintext to the caller. When an application uses the EVP API to perform ChaCha20-Poly1305 decryption, the implementation computes or accepts the tag but does not compare it against the expected value.

" + } + ] + } + ], + "references": [ + { + "url": "https://github.com/wolfSSL/wolfssl/pull/10102" + } + ], + "metrics": [ + { + "format": "CVSS", + "scenarios": [ + { + "lang": "en", + "value": "GENERAL" + } + ], + "cvssV4_0": { + "attackVector": "ADJACENT", + "attackComplexity": "LOW", + "attackRequirements": "PRESENT", + "privilegesRequired": "NONE", + "userInteraction": "NONE", + "vulnConfidentialityImpact": "HIGH", + "subConfidentialityImpact": "NONE", + "vulnIntegrityImpact": "HIGH", + "subIntegrityImpact": "NONE", + "vulnAvailabilityImpact": "NONE", + "subAvailabilityImpact": "NONE", + "exploitMaturity": "NOT_DEFINED", + "Safety": "NOT_DEFINED", + "Automatable": "NOT_DEFINED", + "Recovery": "NOT_DEFINED", + "valueDensity": "NOT_DEFINED", + "vulnerabilityResponseEffort": "NOT_DEFINED", + "providerUrgency": "NOT_DEFINED", + "version": "4.0", + "baseSeverity": "HIGH", + "baseScore": 7.6, + "vectorString": "CVSS:4.0/AV:A/AC:L/AT:P/PR:N/UI:N/VC:H/VI:H/VA:N/SC:N/SI:N/SA:N" + } + } + ], + "credits": [ + { + "lang": "en", + "value": "Calif.io in collaboration with Claude and Anthropic Research", + "type": "finder" + } + ], + "source": { + "discovery": "EXTERNAL" + }, + "x_generator": { + "engine": "Vulnogram 1.0.1" + } + }, + "adp": [ + { + "metrics": [ + { + "other": { + "type": "ssvc", + "content": { + "timestamp": "2026-04-21T00:00:00+00:00", + "options": [ + { + "Exploitation": "none" + }, + { + "Automatable": "no" + }, + { + "Technical Impact": "total" + } + ], + "role": "CISA Coordinator", + "version": "2.0.3", + "id": "CVE-2026-5479" + } + } + } + ], + "title": "CISA ADP Vulnrichment", + "providerMetadata": { + "orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0", + "shortName": "CISA-ADP", + "dateUpdated": "2026-04-22T03:55:50.004Z" + } + } + ] + } +} diff --git a/advisories/records/CVE-2026-5500.json b/advisories/records/CVE-2026-5500.json new file mode 100644 index 0000000..fe35fbd --- /dev/null +++ b/advisories/records/CVE-2026-5500.json @@ -0,0 +1,156 @@ +{ + "dataType": "CVE_RECORD", + "dataVersion": "5.2", + "cveMetadata": { + "cveId": "CVE-2026-5500", + "assignerOrgId": "50d2cd11-d01a-48ed-9441-5bfce9d63b27", + "state": "PUBLISHED", + "assignerShortName": "wolfSSL", + "dateReserved": "2026-04-03T15:33:05.734Z", + "datePublished": "2026-04-10T03:10:25.671Z", + "dateUpdated": "2026-04-10T13:42:28.091Z" + }, + "containers": { + "cna": { + "providerMetadata": { + "orgId": "50d2cd11-d01a-48ed-9441-5bfce9d63b27", + "shortName": "wolfSSL", + "dateUpdated": "2026-04-10T03:10:25.671Z" + }, + "title": "Improper Validation of AES-GCM Authentication Tag Length in PKCS#7 Envelope Allows Authentication Bypass", + "problemTypes": [ + { + "descriptions": [ + { + "lang": "en", + "cweId": "CWE-20", + "description": "CWE-20 Improper input validation", + "type": "CWE" + } + ] + } + ], + "affected": [ + { + "vendor": "wolfSSL", + "product": "wolfSSL", + "modules": [ + "wc_PKCS7_DecodeAuthEnvelopedData" + ], + "programFiles": [ + "wolfcrypt/src/pkcs7.c" + ], + "versions": [ + { + "status": "affected", + "version": "0", + "lessThanOrEqual": "5.9.0", + "versionType": "semver" + } + ], + "defaultStatus": "unaffected" + } + ], + "descriptions": [ + { + "lang": "en", + "value": "wolfSSL's wc_PKCS7_DecodeAuthEnvelopedData() does not properly sanitize the AES-GCM authentication tag length received and has no lower bounds check. A man-in-the-middle can therefore truncate the mac field from 16 bytes to 1 byte, reducing the tag check from 2\u207b\u00b9\u00b2\u2078 to 2\u207b\u2078.", + "supportingMedia": [ + { + "type": "text/html", + "base64": false, + "value": "wolfSSL's wc_PKCS7_DecodeAuthEnvelopedData() does not properly sanitize the AES-GCM authentication tag length received and has no lower bounds check. A man-in-the-middle can therefore truncate the mac field from 16 bytes to 1 byte, reducing the tag check from 2\u207b\u00b9\u00b2\u2078 to 2\u207b\u2078." + } + ] + } + ], + "references": [ + { + "url": "https://github.com/wolfSSL/wolfssl/pull/10102" + } + ], + "metrics": [ + { + "format": "CVSS", + "scenarios": [ + { + "lang": "en", + "value": "GENERAL" + } + ], + "cvssV4_0": { + "attackVector": "NETWORK", + "attackComplexity": "LOW", + "attackRequirements": "NONE", + "privilegesRequired": "NONE", + "userInteraction": "NONE", + "vulnConfidentialityImpact": "NONE", + "subConfidentialityImpact": "NONE", + "vulnIntegrityImpact": "HIGH", + "subIntegrityImpact": "NONE", + "vulnAvailabilityImpact": "NONE", + "subAvailabilityImpact": "NONE", + "exploitMaturity": "NOT_DEFINED", + "Safety": "NOT_DEFINED", + "Automatable": "NOT_DEFINED", + "Recovery": "NOT_DEFINED", + "valueDensity": "NOT_DEFINED", + "vulnerabilityResponseEffort": "NOT_DEFINED", + "providerUrgency": "NOT_DEFINED", + "version": "4.0", + "baseSeverity": "HIGH", + "baseScore": 8.7, + "vectorString": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:H/VA:N/SC:N/SI:N/SA:N" + } + } + ], + "credits": [ + { + "lang": "en", + "value": "Calif.io in collaboration with Claude and Anthropic Research", + "type": "finder" + } + ], + "source": { + "discovery": "EXTERNAL" + }, + "x_generator": { + "engine": "Vulnogram 1.0.1" + } + }, + "adp": [ + { + "metrics": [ + { + "other": { + "type": "ssvc", + "content": { + "timestamp": "2026-04-10T13:42:21.317016Z", + "id": "CVE-2026-5500", + "options": [ + { + "Exploitation": "none" + }, + { + "Automatable": "yes" + }, + { + "Technical Impact": "partial" + } + ], + "role": "CISA Coordinator", + "version": "2.0.3" + } + } + } + ], + "title": "CISA ADP Vulnrichment", + "providerMetadata": { + "orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0", + "shortName": "CISA-ADP", + "dateUpdated": "2026-04-10T13:42:28.091Z" + } + } + ] + } +} diff --git a/advisories/records/CVE-2026-5503.json b/advisories/records/CVE-2026-5503.json new file mode 100644 index 0000000..b6ee4c8 --- /dev/null +++ b/advisories/records/CVE-2026-5503.json @@ -0,0 +1,150 @@ +{ + "dataType": "CVE_RECORD", + "dataVersion": "5.2", + "cveMetadata": { + "cveId": "CVE-2026-5503", + "assignerOrgId": "50d2cd11-d01a-48ed-9441-5bfce9d63b27", + "state": "PUBLISHED", + "assignerShortName": "wolfSSL", + "dateReserved": "2026-04-03T15:55:20.740Z", + "datePublished": "2026-04-09T22:35:39.437Z", + "dateUpdated": "2026-04-10T17:58:51.312Z" + }, + "containers": { + "cna": { + "providerMetadata": { + "orgId": "50d2cd11-d01a-48ed-9441-5bfce9d63b27", + "shortName": "wolfSSL", + "dateUpdated": "2026-04-09T22:35:39.437Z" + }, + "title": "out-of-bounds write in TLSX_EchChangeSNI via attacker-controlled publicName", + "problemTypes": [ + { + "descriptions": [ + { + "lang": "en", + "cweId": "CWE-787", + "description": "CWE-787 Out-of-bounds write", + "type": "CWE" + } + ] + } + ], + "affected": [ + { + "vendor": "wolfSSL", + "product": "wolfSSL", + "versions": [ + { + "status": "affected", + "version": "0", + "lessThanOrEqual": "5.9.0", + "versionType": "semver" + } + ], + "defaultStatus": "unaffected" + } + ], + "descriptions": [ + { + "lang": "en", + "value": "In TLSX_EchChangeSNI, the ctx->extensions branch set extensions unconditionally even when TLSX_Find returned NULL. This caused TLSX_UseSNI to attach the attacker-controlled publicName to the shared WOLFSSL_CTX when no inner SNI was configured. TLSX_EchRestoreSNI then failed to clean it up because its removal was gated on serverNameX != NULL. The inner ClientHello was sized before the pollution but written after it, causing TLSX_SNI_Write to memcpy 255 bytes past the allocation boundary.", + "supportingMedia": [ + { + "type": "text/html", + "base64": false, + "value": "In TLSX_EchChangeSNI, the ctx->extensions branch set extensions unconditionally even when TLSX_Find returned NULL. This caused TLSX_UseSNI to attach the attacker-controlled publicName to the shared WOLFSSL_CTX when no inner SNI was configured. TLSX_EchRestoreSNI then failed to clean it up because its removal was gated on serverNameX != NULL. The inner ClientHello was sized before the pollution but written after it, causing TLSX_SNI_Write to memcpy 255 bytes past the allocation boundary." + } + ] + } + ], + "references": [ + { + "url": "https://github.com/wolfSSL/wolfssl/pull/10102" + } + ], + "metrics": [ + { + "format": "CVSS", + "scenarios": [ + { + "lang": "en", + "value": "GENERAL" + } + ], + "cvssV4_0": { + "attackVector": "NETWORK", + "attackComplexity": "LOW", + "attackRequirements": "NONE", + "privilegesRequired": "NONE", + "userInteraction": "NONE", + "vulnConfidentialityImpact": "NONE", + "subConfidentialityImpact": "NONE", + "vulnIntegrityImpact": "LOW", + "subIntegrityImpact": "NONE", + "vulnAvailabilityImpact": "LOW", + "subAvailabilityImpact": "NONE", + "exploitMaturity": "NOT_DEFINED", + "Safety": "NOT_DEFINED", + "Automatable": "NOT_DEFINED", + "Recovery": "NOT_DEFINED", + "valueDensity": "NOT_DEFINED", + "vulnerabilityResponseEffort": "NOT_DEFINED", + "providerUrgency": "NOT_DEFINED", + "version": "4.0", + "baseSeverity": "MEDIUM", + "baseScore": 6.9, + "vectorString": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:L/VA:L/SC:N/SI:N/SA:N" + } + } + ], + "credits": [ + { + "lang": "en", + "value": "Calif.io in collaboration with Claude and Anthropic Research", + "type": "finder" + } + ], + "source": { + "discovery": "EXTERNAL" + }, + "x_generator": { + "engine": "Vulnogram 1.0.1" + } + }, + "adp": [ + { + "metrics": [ + { + "other": { + "type": "ssvc", + "content": { + "timestamp": "2026-04-10T17:58:43.475862Z", + "id": "CVE-2026-5503", + "options": [ + { + "Exploitation": "none" + }, + { + "Automatable": "yes" + }, + { + "Technical Impact": "partial" + } + ], + "role": "CISA Coordinator", + "version": "2.0.3" + } + } + } + ], + "title": "CISA ADP Vulnrichment", + "providerMetadata": { + "orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0", + "shortName": "CISA-ADP", + "dateUpdated": "2026-04-10T17:58:51.312Z" + } + } + ] + } +} diff --git a/advisories/records/CVE-2026-5504.json b/advisories/records/CVE-2026-5504.json new file mode 100644 index 0000000..1497aba --- /dev/null +++ b/advisories/records/CVE-2026-5504.json @@ -0,0 +1,177 @@ +{ + "dataType": "CVE_RECORD", + "dataVersion": "5.2", + "cveMetadata": { + "cveId": "CVE-2026-5504", + "assignerOrgId": "50d2cd11-d01a-48ed-9441-5bfce9d63b27", + "state": "PUBLISHED", + "assignerShortName": "wolfSSL", + "dateReserved": "2026-04-03T16:06:24.620Z", + "datePublished": "2026-04-09T22:33:42.179Z", + "dateUpdated": "2026-04-14T14:34:40.546Z" + }, + "containers": { + "cna": { + "providerMetadata": { + "orgId": "50d2cd11-d01a-48ed-9441-5bfce9d63b27", + "shortName": "wolfSSL", + "dateUpdated": "2026-04-09T22:33:42.179Z" + }, + "title": "PKCS7 CBC Padding Oracle \u2014 Plaintext Recovery", + "problemTypes": [ + { + "descriptions": [ + { + "lang": "en", + "cweId": "CWE-354", + "description": "CWE-354 Improper validation of integrity check value", + "type": "CWE" + } + ] + } + ], + "impacts": [ + { + "capecId": "CAPEC-463", + "descriptions": [ + { + "lang": "en", + "value": "CAPEC-463 Padding Oracle Crypto Attack" + } + ] + } + ], + "affected": [ + { + "vendor": "wolfSSL", + "product": "wolfSSL", + "modules": [ + "PKCS7" + ], + "programFiles": [ + "wolfcrypt/src/pkcs7.c" + ], + "versions": [ + { + "status": "affected", + "version": "0", + "lessThanOrEqual": "5.9.0", + "versionType": "semver" + } + ], + "defaultStatus": "unaffected" + } + ], + "descriptions": [ + { + "lang": "en", + "value": "A padding oracle exists in wolfSSL's PKCS7 CBC decryption that could allow an attacker to recover plaintext through repeated decryption queries with modified ciphertext. In previous versions of wolfSSL the interior padding bytes are not validated.", + "supportingMedia": [ + { + "type": "text/html", + "base64": false, + "value": "A padding oracle exists in wolfSSL's PKCS7 CBC decryption that could allow an attacker to recover plaintext through repeated decryption queries with modified ciphertext. In previous versions of wolfSSL the interior padding bytes are not validated." + } + ] + } + ], + "references": [ + { + "url": "https://github.com/wolfSSL/wolfssl/pull/10088" + } + ], + "metrics": [ + { + "format": "CVSS", + "scenarios": [ + { + "lang": "en", + "value": "GENERAL" + } + ], + "cvssV4_0": { + "attackVector": "NETWORK", + "attackComplexity": "HIGH", + "attackRequirements": "PRESENT", + "privilegesRequired": "NONE", + "userInteraction": "NONE", + "vulnConfidentialityImpact": "LOW", + "subConfidentialityImpact": "NONE", + "vulnIntegrityImpact": "NONE", + "subIntegrityImpact": "NONE", + "vulnAvailabilityImpact": "NONE", + "subAvailabilityImpact": "NONE", + "exploitMaturity": "NOT_DEFINED", + "Safety": "NOT_DEFINED", + "Automatable": "NOT_DEFINED", + "Recovery": "NOT_DEFINED", + "valueDensity": "NOT_DEFINED", + "vulnerabilityResponseEffort": "NOT_DEFINED", + "providerUrgency": "NOT_DEFINED", + "version": "4.0", + "baseSeverity": "MEDIUM", + "baseScore": 6.3, + "vectorString": "CVSS:4.0/AV:N/AC:H/AT:P/PR:N/UI:N/VC:L/VI:N/VA:N/SC:N/SI:N/SA:N" + } + } + ], + "credits": [ + { + "lang": "en", + "value": "Sunwoo Lee of Korea Institute of Energy Technology (KENTECH) for the report.", + "type": "finder" + }, + { + "lang": "en", + "value": "Woohyun Choi of Korea Institute of Energy Technology (KENTECH) for the report.", + "type": "finder" + }, + { + "lang": "en", + "value": "Seunghyun Yoon of Korea Institute of Energy Technology (KENTECH) for the report.", + "type": "finder" + } + ], + "source": { + "discovery": "EXTERNAL" + }, + "x_generator": { + "engine": "Vulnogram 1.0.1" + } + }, + "adp": [ + { + "metrics": [ + { + "other": { + "type": "ssvc", + "content": { + "timestamp": "2026-04-14T14:33:56.621704Z", + "id": "CVE-2026-5504", + "options": [ + { + "Exploitation": "none" + }, + { + "Automatable": "no" + }, + { + "Technical Impact": "partial" + } + ], + "role": "CISA Coordinator", + "version": "2.0.3" + } + } + } + ], + "title": "CISA ADP Vulnrichment", + "providerMetadata": { + "orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0", + "shortName": "CISA-ADP", + "dateUpdated": "2026-04-14T14:34:40.546Z" + } + } + ] + } +} diff --git a/advisories/records/CVE-2026-5507.json b/advisories/records/CVE-2026-5507.json new file mode 100644 index 0000000..bd967f0 --- /dev/null +++ b/advisories/records/CVE-2026-5507.json @@ -0,0 +1,166 @@ +{ + "dataType": "CVE_RECORD", + "dataVersion": "5.2", + "cveMetadata": { + "cveId": "CVE-2026-5507", + "assignerOrgId": "50d2cd11-d01a-48ed-9441-5bfce9d63b27", + "state": "PUBLISHED", + "assignerShortName": "wolfSSL", + "dateReserved": "2026-04-03T16:40:00.883Z", + "datePublished": "2026-04-09T22:18:44.067Z", + "dateUpdated": "2026-04-14T14:38:40.362Z" + }, + "containers": { + "cna": { + "providerMetadata": { + "orgId": "50d2cd11-d01a-48ed-9441-5bfce9d63b27", + "shortName": "wolfSSL", + "dateUpdated": "2026-04-09T22:18:44.067Z" + }, + "title": "Session Cache Restore \u2014 Arbitrary Free via Deserialized Pointer", + "problemTypes": [ + { + "descriptions": [ + { + "lang": "en", + "cweId": "CWE-502", + "description": "CWE-502 Deserialization of untrusted data", + "type": "CWE" + } + ] + } + ], + "affected": [ + { + "vendor": "wolfSSL", + "product": "wolfSSL", + "modules": [ + "wolfSSL_memrestore_session_cache" + ], + "programFiles": [ + "src/ssl_sess.c" + ], + "versions": [ + { + "status": "affected", + "version": "0", + "lessThanOrEqual": "5.9.0", + "versionType": "semver" + } + ], + "defaultStatus": "unaffected" + } + ], + "descriptions": [ + { + "lang": "en", + "value": "When restoring a session from cache, a pointer from the serialized session data is used in a free operation without validation. An attacker who can poison the session cache could trigger an arbitrary free. Exploitation requires the ability to inject a crafted session into the cache and for the application to call specific session restore APIs.", + "supportingMedia": [ + { + "type": "text/html", + "base64": false, + "value": "When restoring a session from cache, a pointer from the serialized session data is used in a free operation without validation. An attacker who can poison the session cache could trigger an arbitrary free. Exploitation requires the ability to inject a crafted session into the cache and for the application to call specific session restore APIs." + } + ] + } + ], + "references": [ + { + "url": "https://github.com/wolfSSL/wolfssl/pull/10088" + } + ], + "metrics": [ + { + "format": "CVSS", + "scenarios": [ + { + "lang": "en", + "value": "GENERAL" + } + ], + "cvssV4_0": { + "attackVector": "LOCAL", + "attackComplexity": "HIGH", + "attackRequirements": "PRESENT", + "privilegesRequired": "HIGH", + "userInteraction": "PASSIVE", + "vulnConfidentialityImpact": "NONE", + "subConfidentialityImpact": "NONE", + "vulnIntegrityImpact": "NONE", + "subIntegrityImpact": "NONE", + "vulnAvailabilityImpact": "HIGH", + "subAvailabilityImpact": "NONE", + "exploitMaturity": "NOT_DEFINED", + "Safety": "NOT_DEFINED", + "Automatable": "NOT_DEFINED", + "Recovery": "NOT_DEFINED", + "valueDensity": "NOT_DEFINED", + "vulnerabilityResponseEffort": "NOT_DEFINED", + "providerUrgency": "NOT_DEFINED", + "version": "4.0", + "baseSeverity": "MEDIUM", + "baseScore": 4.1, + "vectorString": "CVSS:4.0/AV:L/AC:H/AT:P/PR:H/UI:P/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N" + } + } + ], + "credits": [ + { + "lang": "en", + "value": "Sunwoo Lee (Korea Institute of Energy Technology, KENTECH)", + "type": "finder" + }, + { + "lang": "en", + "value": "Woohyun Choi (Korea Institute of Energy Technology, KENTECH)", + "type": "finder" + }, + { + "lang": "en", + "value": "Seunghyun Yoon (Korea Institute of Energy Technology, KENTECH)", + "type": "finder" + } + ], + "source": { + "discovery": "UNKNOWN" + }, + "x_generator": { + "engine": "Vulnogram 1.0.1" + } + }, + "adp": [ + { + "metrics": [ + { + "other": { + "type": "ssvc", + "content": { + "timestamp": "2026-04-14T14:38:30.441473Z", + "id": "CVE-2026-5507", + "options": [ + { + "Exploitation": "none" + }, + { + "Automatable": "no" + }, + { + "Technical Impact": "partial" + } + ], + "role": "CISA Coordinator", + "version": "2.0.3" + } + } + } + ], + "title": "CISA ADP Vulnrichment", + "providerMetadata": { + "orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0", + "shortName": "CISA-ADP", + "dateUpdated": "2026-04-14T14:38:40.362Z" + } + } + ] + } +} diff --git a/advisories/records/CVE-2026-5772.json b/advisories/records/CVE-2026-5772.json new file mode 100644 index 0000000..2a56a3b --- /dev/null +++ b/advisories/records/CVE-2026-5772.json @@ -0,0 +1,156 @@ +{ + "dataType": "CVE_RECORD", + "dataVersion": "5.2", + "cveMetadata": { + "cveId": "CVE-2026-5772", + "assignerOrgId": "50d2cd11-d01a-48ed-9441-5bfce9d63b27", + "state": "PUBLISHED", + "assignerShortName": "wolfSSL", + "dateReserved": "2026-04-08T06:47:03.016Z", + "datePublished": "2026-04-09T21:50:04.038Z", + "dateUpdated": "2026-04-10T13:52:58.722Z" + }, + "containers": { + "cna": { + "providerMetadata": { + "orgId": "50d2cd11-d01a-48ed-9441-5bfce9d63b27", + "shortName": "wolfSSL", + "dateUpdated": "2026-04-09T21:50:04.038Z" + }, + "title": "MatchDomainName 1-Byte Stack Buffer Over-Read in Hostname Validation", + "problemTypes": [ + { + "descriptions": [ + { + "lang": "en", + "cweId": "CWE-126", + "description": "CWE-126 Buffer over-read", + "type": "CWE" + } + ] + } + ], + "affected": [ + { + "vendor": "wolfSSL", + "product": "wolfSSL", + "modules": [ + "MatchDomainName" + ], + "programFiles": [ + "src/internal.c" + ], + "versions": [ + { + "status": "affected", + "version": "0", + "lessThanOrEqual": "5.9.0", + "versionType": "semver" + } + ], + "defaultStatus": "unaffected" + } + ], + "descriptions": [ + { + "lang": "en", + "value": "A 1-byte stack buffer over-read was identified in the MatchDomainName function (src/internal.c) during wildcard hostname validation when the LEFT_MOST_WILDCARD_ONLY flag is active. If a wildcard * exhausts the entire hostname string, the function reads one byte past the buffer without a bounds check, which could cause a crash.", + "supportingMedia": [ + { + "type": "text/html", + "base64": false, + "value": "A 1-byte stack buffer over-read was identified in the MatchDomainName function (src/internal.c) during wildcard hostname validation when the LEFT_MOST_WILDCARD_ONLY flag is active. If a wildcard * exhausts the entire hostname string, the function reads one byte past the buffer without a bounds check, which could cause a crash." + } + ] + } + ], + "references": [ + { + "url": "https://github.com/wolfSSL/wolfssl/pull/10119" + } + ], + "metrics": [ + { + "format": "CVSS", + "scenarios": [ + { + "lang": "en", + "value": "GENERAL" + } + ], + "cvssV4_0": { + "attackVector": "NETWORK", + "attackComplexity": "LOW", + "attackRequirements": "PRESENT", + "privilegesRequired": "LOW", + "userInteraction": "PASSIVE", + "vulnConfidentialityImpact": "NONE", + "subConfidentialityImpact": "NONE", + "vulnIntegrityImpact": "NONE", + "subIntegrityImpact": "NONE", + "vulnAvailabilityImpact": "LOW", + "subAvailabilityImpact": "NONE", + "exploitMaturity": "NOT_DEFINED", + "Safety": "NOT_DEFINED", + "Automatable": "NOT_DEFINED", + "Recovery": "NOT_DEFINED", + "valueDensity": "NOT_DEFINED", + "vulnerabilityResponseEffort": "NOT_DEFINED", + "providerUrgency": "NOT_DEFINED", + "version": "4.0", + "baseSeverity": "LOW", + "baseScore": 2.1, + "vectorString": "CVSS:4.0/AV:N/AC:L/AT:P/PR:L/UI:P/VC:N/VI:N/VA:L/SC:N/SI:N/SA:N" + } + } + ], + "credits": [ + { + "lang": "en", + "value": "Zou Dikai", + "type": "finder" + } + ], + "source": { + "discovery": "UNKNOWN" + }, + "x_generator": { + "engine": "Vulnogram 1.0.1" + } + }, + "adp": [ + { + "metrics": [ + { + "other": { + "type": "ssvc", + "content": { + "timestamp": "2026-04-10T13:52:51.829903Z", + "id": "CVE-2026-5772", + "options": [ + { + "Exploitation": "none" + }, + { + "Automatable": "no" + }, + { + "Technical Impact": "partial" + } + ], + "role": "CISA Coordinator", + "version": "2.0.3" + } + } + } + ], + "title": "CISA ADP Vulnrichment", + "providerMetadata": { + "orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0", + "shortName": "CISA-ADP", + "dateUpdated": "2026-04-10T13:52:58.722Z" + } + } + ] + } +} diff --git a/advisories/releases/5.9.1/ChangeLog.md b/advisories/releases/5.9.1/ChangeLog.md new file mode 100644 index 0000000..ac79522 --- /dev/null +++ b/advisories/releases/5.9.1/ChangeLog.md @@ -0,0 +1,81 @@ +# wolfSSL Release 5.9.1 (Apr. 8, 2026) + +Release 5.9.1 has been developed according to wolfSSL's development and QA +process (see link below) and successfully passed the quality criteria. +https://www.wolfssl.com/about/wolfssl-software-development-process-quality-assurance + +NOTE: +* --enable-heapmath is deprecated +* MD5 is now disabled by default + +PR stands for Pull Request, and PR references a GitHub pull request number where the code change was added. + +## Vulnerabilities + +* [Critical] CVE-2026-5194 +Missing hash/digest size and OID checks allow digests smaller than allowed by FIPS 186-4 or 186-5 (as appropriate), or smaller than is appropriate for the relevant key type, to be accepted by signature verification functions, reducing the security of certificate-based authentication. Affects multiple signature algorithms, including ECDSA/ECC, DSA, ML-DSA, ED25519, and ED448. Builds that have both ECC and EdDSA or ML-DSA enabled that are doing certificate verification are recommended to update to the latest wolfSSL release. Thanks to Nicholas Carlini from Anthropic for the report. Fixed in PR 10131. + +* [High] CVE-2026-5264 +Heap buffer overflow in DTLS 1.3 ACK message processing. A remote attacker can send a crafted DTLS 1.3 ACK message that triggers a heap buffer overflow. Thanks to Sunwoo Lee and Seunghyun Yoon, Korea Institute of Energy Technology (KENTECH). Fixed in PR 10076. + +* [High] CVE-2026-5263 +URI nameConstraints from constrained intermediate CAs are parsed but not enforced during certificate chain verification in wolfcrypt/src/asn.c. A compromised or malicious sub-CA could issue leaf certificates with URI SAN entries that violate the nameConstraints of the issuing CA, and wolfSSL would accept them as valid. Thanks to Oleh Konko @1seal for the report. Fixed in PR 10048. + +* [High] CVE-2026-5295 +Stack buffer overflow in PKCS7 ORI (Other Recipient Info) OID processing. When parsing a PKCS7 envelope with a crafted ORI OID value, a stack-based buffer overflow can be triggered. Thanks to Sunwoo Lee, Woohyun Choi, and Seunghyun Yoon (Korea Institute of Energy Technology, KENTECH). Fixed in PR 10116. + +* [High] CVE-2026-5466 +wolfSSL's ECCSI signature verifier `wc_VerifyEccsiHash` decodes the `r` and `s` scalars from the signature blob via `mp_read_unsigned_bin` with no check that they lie in `[1, q-1]`. A crafted forged signature could verify against any message for any identity, using only publicly-known constants. Thanks to Calif.io in collaboration with Claude and Anthropic Research for the report. Fixed in PR 10102. + +* [High] CVE-2026-5477 +Potential for AES-EAX AEAD and CMAC authentication bypass on messages larger than 4 GiB. An attacker who observes one valid (ciphertext, tag) pair for a >4 GiB EAX message can replace the first 4 GiB of ciphertext arbitrarily while the tag still verifies. Thanks to Calif.io in collaboration with Claude and Anthropic Research for the report. Fixed in PR 10102. + +* [High] CVE-2026-5447 +Heap buffer overflow in CertFromX509 via AuthorityKeyIdentifier size confusion. A heap buffer overflow occurs when converting an X.509 certificate internally due to incorrect size handling of the AuthorityKeyIdentifier extension. Thanks to Calif.io in collaboration with Claude and Anthropic Research for the report. Fixed in PR 10112. + +* [High] CVE-2026-5500 +wolfSSL's `wc_PKCS7_DecodeAuthEnvelopedData()` does not properly sanitize the AES-GCM authentication tag length received and has no lower bounds check. A man-in-the-middle can therefore truncate the `mac` field from 16 bytes to 1 byte, reducing the tag check from 2⁻¹²⁸ to 2⁻⁸. Thanks to Calif.io in collaboration with Claude and Anthropic Research for the report. Fixed in PR 10102. + +* [High] CVE-2026-5501 +`wolfSSL_X509_verify_cert()` in the OpenSSL compatibility layer accepts a certificate chain in which the leaf's signature is not checked, if the attacker supplies an untrusted intermediate with Basic Constraints `CA:FALSE` that is legitimately signed by a trusted root. An attacker who obtains any leaf certificate from a trusted CA (e.g. a free DV cert from Let's Encrypt) can forge a certificate for any subject name with any public key and arbitrary signature bytes, and the function returns `WOLFSSL_SUCCESS` / `X509_V_OK`. The native wolfSSL TLS handshake path (`ProcessPeerCerts`) is not susceptible and the issue is limited to applications using the OpenSSL compatibility API directly. Thanks to Calif.io in collaboration with Claude and Anthropic Research for the report. Fixed in PR 10102. + +* [High] CVE-2026-5503 +In TLSX_EchChangeSNI, the ctx->extensions branch set extensions unconditionally even when TLSX_Find returned NULL. This caused TLSX_UseSNI to attach the attacker-controlled publicName to the shared WOLFSSL_CTX when no inner SNI was configured. TLSX_EchRestoreSNI then failed to clean it up because its removal was gated on serverNameX != NULL. The inner ClientHello was sized before the pollution but written after it, causing TLSX_SNI_Write to memcpy 255 bytes past the allocation boundary. Thanks to Calif.io in collaboration with Claude and Anthropic Research for the report. Fixed in PR 10102. + +* [High] CVE-2026-5479 +In wolfSSL's EVP layer, the ChaCha20-Poly1305 AEAD decryption path in wolfSSL_EVP_CipherFinal (and related EVP cipher finalization functions) fails to verify the authentication tag before returning plaintext to the caller. When an application uses the EVP API to perform ChaCha20-Poly1305 decryption, the implementation computes or accepts the tag but does not compare it against the expected value. Thanks to Calif.io in collaboration with Claude and Anthropic Research for the report. Fixed in PR 10102. + +* [Med] CVE-2026-5392 +Heap out-of-bounds read in PKCS7 parsing. A crafted PKCS7 message can trigger an OOB read on the heap. The missing bounds check is in the indefinite-length end-of-content verification loop in PKCS7_VerifySignedData(). This only affects builds with PKCS7 support enabled. Thanks to J Laratro (d0sf3t) for the report. Fixed in PR 10039. + +* [Med] CVE-2026-5446 +ARIA-GCM nonce reuse in TLS 1.2 record encryption. ARIA cipher support requires a proprietary Korean library (MagicCrypto) and --enable-aria, limiting real-world exposure. Thanks to Calif.io in collaboration with Claude and Anthropic Research for the report. Fixed in PR 10111. + +* [Med] CVE-2026-5460 +When a malicious TLS 1.3 server sends a ServerHello with a truncated PQC hybrid KeyShare (e.g., P256_ML_KEM_512 with 10 bytes instead of the required 768+), the error cleanup path double-frees the KyberKey. Thanks to Calvin Young (eWalker Consulting Inc.) and Enoch Chow (Isomorph Cyber). Fixed in PR 10092. + +* [Med] CVE-2026-5504 +A padding oracle exists in wolfSSL's PKCS7 CBC decryption that could allow an attacker to recover plaintext through repeated decryption queries with modified ciphertext. In previous versions of wolfSSL the interior padding bytes are not validated. Thanks to Sunwoo Lee, Woohyun Choi, and Seunghyun Yoon of Korea Institute of Energy Technology (KENTECH) for the report. Fixed in PR 10088. + +* [Med] CVE-2026-5507 +When restoring a session from cache, a pointer from the serialized session data is used in a free operation without validation. An attacker who can poison the session cache could trigger an arbitrary free. Exploitation requires the ability to inject a crafted session into the cache and for the application to call specific session restore APIs. Thanks to Sunwoo Lee, Woohyun Choi, and Seunghyun Yoon of Korea Institute of Energy Technology (KENTECH) for the report. Fixed in PR 10088. + +* [Low] CVE-2026-5187 +Heap out-of-bounds write in DecodeObjectId() caused by an off-by-one bounds check combined with a sizeof mismatch. A crafted ASN.1 object identifier can trigger a small heap OOB write. Thanks to Yuteng for the report. Fixed in PR 10025. + +* [Low] CVE-2026-5188 +An integer underflow issue exists in wolfSSL when parsing the Subject Alternative Name (SAN) extension of X.509 certificates. A malformed certificate can specify an entry length larger than the enclosing sequence, causing the internal length counter to wrap during parsing. This results in incorrect handling of certificate data. The issue is limited to configurations using the original ASN.1 parsing implementation. The original ASN.1 parsing implementation is off by default. Thanks to Muhammad Arya Arjuna Habibullah for the report. Fixed in PR 10024. + +* [Low] CVE-2026-5448 +X.509 date buffer overflow in wolfSSL_X509_notAfter / wolfSSL_X509_notBefore. A buffer overflow may occur when parsing date fields from a crafted X.509 certificate via the compatibility layer API. This is only triggered when calling these two APIs directly from an application, and does not affect TLS or certificate verify operations in wolfSSL. Thanks to Sunwoo Lee and Seunghyun Yoon, Korea Institute of Energy Technology (KENTECH) for the report. Fixed in PR 10071. + +* [Low] CVE-2026-5772 +A 1-byte stack buffer over-read exists in the MatchDomainName function in src/internal.c when processing wildcard patterns with the LEFT_MOST_WILDCARD_ONLY flag active. When a wildcard '*' exhausts the entire hostname string (strLen reaches 0), the function proceeds to compare remaining pattern characters against the now-exhausted buffer without a bounds check, causing an out-of-bounds read. Thanks to Zou Dikai for the report. Fixed in PR 10119. + +* [Low] CVE-2026-5778 +An integer underflow exists in the ChaCha20-Poly1305 decryption path where a malformed TLS 1.2 record with a payload shorter than the AEAD MAC size causes the message length calculation to underflow, resulting in an out-of-bounds read. This only affects sniffer builds. Thanks to Zou Dikai for the report. Fixed in PR 10125. + +## Experimental Build Vulnerability + +* [Med] CVE-2026-5393 +Dual-Algorithm CertificateVerify out-of-bounds read. When processing a dual-algorithm CertificateVerify message, an out-of-bounds read can occur on crafted input. This can only occur when --enable-experimental and --enable-dual-alg-certs is used when building wolfSSL. Thanks to Sunwoo Lee, Woohyun Choi, and Seunghyun Yoon (Korea Institute of Energy Technology, KENTECH) for testing the fix. Fixed in PR 10079. diff --git a/advisories/releases/5.9.1/cves b/advisories/releases/5.9.1/cves new file mode 100644 index 0000000..a565628 --- /dev/null +++ b/advisories/releases/5.9.1/cves @@ -0,0 +1,27 @@ +# Pinned CVE membership for wolfSSL 5.9.1 +# ChangeLog Vulnerabilities bullets plus supplemental late +# disclosures listed in supplemental.cves. +CVE-2026-5194 +CVE-2026-5264 +CVE-2026-5263 +CVE-2026-5295 +CVE-2026-5466 +CVE-2026-5477 +CVE-2026-5447 +CVE-2026-5500 +CVE-2026-5501 +CVE-2026-5503 +CVE-2026-5479 +CVE-2026-5392 +CVE-2026-5446 +CVE-2026-5460 +CVE-2026-5504 +CVE-2026-5507 +CVE-2026-5187 +CVE-2026-5188 +CVE-2026-5448 +CVE-2026-5772 +CVE-2026-5778 +CVE-2026-5393 +CVE-2026-6679 +CVE-2026-6681 diff --git a/advisories/releases/5.9.1/supplemental.cves b/advisories/releases/5.9.1/supplemental.cves new file mode 100644 index 0000000..8eba685 --- /dev/null +++ b/advisories/releases/5.9.1/supplemental.cves @@ -0,0 +1,3 @@ +# Fixed in 5.9.1; disclosed as 5.9.2 ChangeLog bullets. +CVE-2026-6679 +CVE-2026-6681 diff --git a/central/testdata/ChangeLog-5.9.2.md b/advisories/releases/5.9.2/ChangeLog.md similarity index 100% rename from central/testdata/ChangeLog-5.9.2.md rename to advisories/releases/5.9.2/ChangeLog.md diff --git a/advisories/releases/5.9.2.cves b/advisories/releases/5.9.2/cves similarity index 88% rename from advisories/releases/5.9.2.cves rename to advisories/releases/5.9.2/cves index 01e3f97..2899c92 100644 --- a/advisories/releases/5.9.2.cves +++ b/advisories/releases/5.9.2/cves @@ -2,9 +2,9 @@ # # ChangeLog Vulnerabilities bullets whose overlay fixed_versions # contains 5.9.2. Two 5.9.2 bullets (CVE-2026-6679, CVE-2026-6681) -# shipped in 5.9.1; they live in 5.9.2.prior-release.cves. +# shipped in 5.9.1; they live in prior-release.cves. # CVE-2026-5460 is named only in a bullet body; see -# 5.9.2.mentions.cves. +# mentions.cves. CVE-2026-11310 CVE-2026-11999 CVE-2026-55958 diff --git a/advisories/releases/5.9.2.mentions.cves b/advisories/releases/5.9.2/mentions.cves similarity index 100% rename from advisories/releases/5.9.2.mentions.cves rename to advisories/releases/5.9.2/mentions.cves diff --git a/advisories/releases/5.9.2.prior-release.cves b/advisories/releases/5.9.2/prior-release.cves similarity index 100% rename from advisories/releases/5.9.2.prior-release.cves rename to advisories/releases/5.9.2/prior-release.cves diff --git a/advisories/vex-overlay.json b/advisories/vex-overlay.json index 73b43d5..cc93643 100644 --- a/advisories/vex-overlay.json +++ b/advisories/vex-overlay.json @@ -1,5 +1,102 @@ { "_comment": "Canonical wolfSSL VEX overlay consumed by `make advisory` / `scripts/gen-advisory`. Keyed by CVE id; carries the determinations the CVE Program record cannot express (analysis state, justification, fixed versions, remediation, optional FIPS product, optional build-reachability hedge). Constrained by scripts/advisory-vex-overlay.schema.json. To model a wolfCrypt FIPS module as a separate product, add a \"fips\" block per the format in scripts/advisory-vex-overlay.example.json using the real validated module version and CMVP certificate number (do NOT copy the illustrative placeholder values from the example).", + "CVE-2026-5194": { + "state": "exploitable", + "response": [ + "update" + ], + "detail": "Missing hash/digest size and OID checks allow digests smaller than allowed by FIPS 186-4 or 186-5 (as appropriate), or smaller than is appropriate for the relevant key type, to be accepted by signature verification functions, reducing the security of certificate-based authentication. Affects multiple signature algorithms, including ECDSA/ECC, DSA, ML-DSA, ED25519, and ED448. Builds that have both ECC and EdDSA or ML-DSA enabled that are doing certificate verification are recommended to update to the latest wolfSSL release.", + "fixed_versions": [ + "5.9.1" + ], + "remediation": "Update to wolfSSL 5.9.1 or later." + }, + "CVE-2026-5264": { + "state": "exploitable", + "response": [ + "update" + ], + "detail": "Heap buffer overflow in DTLS 1.3 ACK message processing. A remote attacker can send a crafted DTLS 1.3 ACK message that triggers a heap buffer overflow.", + "fixed_versions": [ + "5.9.1" + ], + "remediation": "Update to wolfSSL 5.9.1 or later.", + "requires_defines": [ + "WOLFSSL_DTLS13" + ] + }, + "CVE-2026-5263": { + "state": "exploitable", + "response": [ + "update" + ], + "detail": "URI nameConstraints from constrained intermediate CAs are parsed but not enforced during certificate chain verification in wolfcrypt/src/asn.c. A compromised or malicious sub-CA could issue leaf certificates with URI SAN entries that violate the nameConstraints of the issuing CA, and wolfSSL would accept them as valid.", + "fixed_versions": [ + "5.9.1" + ], + "remediation": "Update to wolfSSL 5.9.1 or later." + }, + "CVE-2026-5295": { + "state": "exploitable", + "response": [ + "update" + ], + "detail": "Stack buffer overflow in PKCS7 ORI (Other Recipient Info) OID processing. When parsing a PKCS7 envelope with a crafted ORI OID value, a stack-based buffer overflow can be triggered.", + "fixed_versions": [ + "5.9.1" + ], + "remediation": "Update to wolfSSL 5.9.1 or later.", + "requires_defines": [ + "HAVE_PKCS7" + ] + }, + "CVE-2026-5466": { + "state": "exploitable", + "response": [ + "update" + ], + "detail": "wolfSSL's ECCSI signature verifier `wc_VerifyEccsiHash` decodes the `r` and `s` scalars from the signature blob via `mp_read_unsigned_bin` with no check that they lie in `[1, q-1]`. A crafted forged signature could verify against any message for any identity, using only publicly-known constants.", + "fixed_versions": [ + "5.9.1" + ], + "remediation": "Update to wolfSSL 5.9.1 or later." + }, + "CVE-2026-5477": { + "state": "exploitable", + "response": [ + "update" + ], + "detail": "Potential for AES-EAX AEAD and CMAC authentication bypass on messages larger than 4 GiB. An attacker who observes one valid (ciphertext, tag) pair for a >4 GiB EAX message can replace the first 4 GiB of ciphertext arbitrarily while the tag still verifies.", + "fixed_versions": [ + "5.9.1" + ], + "remediation": "Update to wolfSSL 5.9.1 or later." + }, + "CVE-2026-5447": { + "state": "exploitable", + "response": [ + "update" + ], + "detail": "Heap buffer overflow in CertFromX509 via AuthorityKeyIdentifier size confusion. A heap buffer overflow occurs when converting an X.509 certificate internally due to incorrect size handling of the AuthorityKeyIdentifier extension.", + "fixed_versions": [ + "5.9.1" + ], + "remediation": "Update to wolfSSL 5.9.1 or later." + }, + "CVE-2026-5500": { + "state": "exploitable", + "response": [ + "update" + ], + "detail": "wolfSSL's `wc_PKCS7_DecodeAuthEnvelopedData()` does not properly sanitize the AES-GCM authentication tag length received and has no lower bounds check. A man-in-the-middle can therefore truncate the `mac` field from 16 bytes to 1 byte, reducing the tag check from 2\u207b\u00b9\u00b2\u2078 to 2\u207b\u2078.", + "fixed_versions": [ + "5.9.1" + ], + "remediation": "Update to wolfSSL 5.9.1 or later.", + "requires_defines": [ + "HAVE_PKCS7" + ] + }, "CVE-2026-5501": { "state": "exploitable", "response": [ @@ -11,6 +108,140 @@ ], "remediation": "Update to wolfSSL 5.9.1 or later, or avoid relying on wolfSSL_X509_verify_cert in the OpenSSL compatibility layer for chain validation." }, + "CVE-2026-5503": { + "state": "exploitable", + "response": [ + "update" + ], + "detail": "In TLSX_EchChangeSNI, the ctx->extensions branch set extensions unconditionally even when TLSX_Find returned NULL. This caused TLSX_UseSNI to attach the attacker-controlled publicName to the shared WOLFSSL_CTX when no inner SNI was configured. TLSX_EchRestoreSNI then failed to clean it up because its removal was gated on serverNameX != NULL. The inner ClientHello was sized before the pollution but written after it, causing TLSX_SNI_Write to memcpy 255 bytes past the allocation boundary.", + "fixed_versions": [ + "5.9.1" + ], + "remediation": "Update to wolfSSL 5.9.1 or later." + }, + "CVE-2026-5479": { + "state": "exploitable", + "response": [ + "update" + ], + "detail": "In wolfSSL's EVP layer, the ChaCha20-Poly1305 AEAD decryption path in wolfSSL_EVP_CipherFinal (and related EVP cipher finalization functions) fails to verify the authentication tag before returning plaintext to the caller. When an application uses the EVP API to perform ChaCha20-Poly1305 decryption, the implementation computes or accepts the tag but does not compare it against the expected value.", + "fixed_versions": [ + "5.9.1" + ], + "remediation": "Update to wolfSSL 5.9.1 or later.", + "requires_defines": [ + "OPENSSL_EXTRA" + ] + }, + "CVE-2026-5392": { + "state": "exploitable", + "response": [ + "update" + ], + "detail": "Heap out-of-bounds read in PKCS7 parsing. A crafted PKCS7 message can trigger an OOB read on the heap. The missing bounds check is in the indefinite-length end-of-content verification loop in PKCS7_VerifySignedData(). This only affects builds with PKCS7 support enabled.", + "fixed_versions": [ + "5.9.1" + ], + "remediation": "Update to wolfSSL 5.9.1 or later.", + "requires_defines": [ + "HAVE_PKCS7" + ] + }, + "CVE-2026-5446": { + "state": "exploitable", + "response": [ + "update" + ], + "detail": "ARIA-GCM nonce reuse in TLS 1.2 record encryption. ARIA cipher support requires a proprietary Korean library (MagicCrypto) and --enable-aria, limiting real-world exposure.", + "fixed_versions": [ + "5.9.1" + ], + "remediation": "Update to wolfSSL 5.9.1 or later.", + "requires_defines": [ + "WOLFSSL_ARIA" + ], + "default_status": "off" + }, + "CVE-2026-5460": { + "state": "exploitable", + "response": [ + "update" + ], + "detail": "When a malicious TLS 1.3 server sends a ServerHello with a truncated PQC hybrid KeyShare (e.g., P256_ML_KEM_512 with 10 bytes instead of the required 768+), the error cleanup path double-frees the KyberKey.", + "fixed_versions": [ + "5.9.1" + ], + "remediation": "Update to wolfSSL 5.9.1 or later." + }, + "CVE-2026-5504": { + "state": "exploitable", + "response": [ + "update" + ], + "detail": "A padding oracle exists in wolfSSL's PKCS7 CBC decryption that could allow an attacker to recover plaintext through repeated decryption queries with modified ciphertext. In previous versions of wolfSSL the interior padding bytes are not validated.", + "fixed_versions": [ + "5.9.1" + ], + "remediation": "Update to wolfSSL 5.9.1 or later.", + "requires_defines": [ + "HAVE_PKCS7" + ] + }, + "CVE-2026-5507": { + "state": "exploitable", + "response": [ + "update" + ], + "detail": "When restoring a session from cache, a pointer from the serialized session data is used in a free operation without validation. An attacker who can poison the session cache could trigger an arbitrary free. Exploitation requires the ability to inject a crafted session into the cache and for the application to call specific session restore APIs.", + "fixed_versions": [ + "5.9.1" + ], + "remediation": "Update to wolfSSL 5.9.1 or later." + }, + "CVE-2026-5187": { + "state": "exploitable", + "response": [ + "update" + ], + "detail": "Heap out-of-bounds write in DecodeObjectId() caused by an off-by-one bounds check combined with a sizeof mismatch. A crafted ASN.1 object identifier can trigger a small heap OOB write.", + "fixed_versions": [ + "5.9.1" + ], + "remediation": "Update to wolfSSL 5.9.1 or later." + }, + "CVE-2026-5188": { + "state": "exploitable", + "response": [ + "update" + ], + "detail": "An integer underflow issue exists in wolfSSL when parsing the Subject Alternative Name (SAN) extension of X.509 certificates. A malformed certificate can specify an entry length larger than the enclosing sequence, causing the internal length counter to wrap during parsing. This results in incorrect handling of certificate data. The issue is limited to configurations using the original ASN.1 parsing implementation. The original ASN.1 parsing implementation is off by default.", + "fixed_versions": [ + "5.9.1" + ], + "remediation": "Update to wolfSSL 5.9.1 or later." + }, + "CVE-2026-5448": { + "state": "exploitable", + "response": [ + "update" + ], + "detail": "X.509 date buffer overflow in wolfSSL_X509_notAfter / wolfSSL_X509_notBefore. A buffer overflow may occur when parsing date fields from a crafted X.509 certificate via the compatibility layer API. This is only triggered when calling these two APIs directly from an application, and does not affect TLS or certificate verify operations in wolfSSL.", + "fixed_versions": [ + "5.9.1" + ], + "remediation": "Update to wolfSSL 5.9.1 or later." + }, + "CVE-2026-5772": { + "state": "exploitable", + "response": [ + "update" + ], + "detail": "A 1-byte stack buffer over-read exists in the MatchDomainName function in src/internal.c when processing wildcard patterns with the LEFT_MOST_WILDCARD_ONLY flag active. When a wildcard '*' exhausts the entire hostname string (strLen reaches 0), the function proceeds to compare remaining pattern characters against the now-exhausted buffer without a bounds check, causing an out-of-bounds read.", + "fixed_versions": [ + "5.9.1" + ], + "remediation": "Update to wolfSSL 5.9.1 or later." + }, "CVE-2026-5778": { "state": "exploitable", "response": [ @@ -28,26 +259,53 @@ ], "remediation": "Update to wolfSSL 5.9.1 or later. Builds without --enable-sniffer are not affected." }, - "CVE-2026-11310": { + "CVE-2026-5393": { "state": "exploitable", "response": [ "update" ], - "detail": "X.509 trust-chain bypass in the OpenSSL compatibility certificate verifier (wolfSSL_X509_verify_cert()). This affects only builds with --enable-opensslextra (OPENSSL_EXTRA) and whose application validates certificates by calling X509_verify_cert() (OpenSSL compatibility layer function) with caller-supplied untrusted intermediate certificates; for those users it is critical, otherwise the library is unaffected.", + "detail": "Dual-Algorithm CertificateVerify out-of-bounds read. When processing a dual-algorithm CertificateVerify message, an out-of-bounds read can occur on crafted input. This can only occur when --enable-experimental and --enable-dual-alg-certs is used when building wolfSSL.", "fixed_versions": [ - "5.9.2" + "5.9.1" ], - "remediation": "Update to wolfSSL 5.9.2 or later.", + "remediation": "Update to wolfSSL 5.9.1 or later.", "requires_defines": [ - "OPENSSL_EXTRA" + "WOLFSSL_EXPERIMENTAL", + "WOLFSSL_DUAL_ALG_CERTS" + ], + "default_status": "off" + }, + "CVE-2026-6679": { + "state": "exploitable", + "response": [ + "update" + ], + "detail": "A heap buffer overflow could occur in the DTLS 1.3 ACK serialization path before the connecting peer is authenticated. The buffer overflow was due to an integer truncation when computing the length of the ACK record-number list, causing an undersized buffer to be allocated and then overrun. This affects builds using DTLS 1.3 and wolfSSL version 5.9.0 and earlier. A fix was added to the 5.9.1 release. Thanks to Nicholas Carlini from Anthropic for the report. Fixed in PR 10116.", + "fixed_versions": [ + "5.9.1" + ], + "remediation": "Update to wolfSSL 5.9.1 or later.", + "requires_defines": [ + "WOLFSSL_DTLS13" ] }, - "CVE-2026-11999": { + "CVE-2026-6681": { "state": "exploitable", "response": [ "update" ], - "detail": "X.509 trust-chain bypass (path-depth exhaustion) in the OpenSSL compatibility certificate verifier (wolfSSL_X509_verify_cert()). This affects only builds with --enable-opensslextra whose application calls X509_verify_cert() with caller-supplied untrusted intermediates; for those users it is critical, otherwise the library is unaffected.", + "detail": "The PKCS#7 decode path ignores the caller-supplied output buffer size (outputSz), allowing decoded content to be written past the bounds of the provided buffer. This affects wolfSSL 5.9.0 and earlier and was fixed in the 5.9.1 release. Thanks to Nicholas Carlini from Anthropic for the report. Fixed in PR 10116.", + "fixed_versions": [ + "5.9.1" + ], + "remediation": "Update to wolfSSL 5.9.1 or later." + }, + "CVE-2026-11310": { + "state": "exploitable", + "response": [ + "update" + ], + "detail": "X.509 trust-chain bypass in the OpenSSL compatibility certificate verifier (wolfSSL_X509_verify_cert()). This affects only builds with --enable-opensslextra (OPENSSL_EXTRA) and whose application validates certificates by calling X509_verify_cert() (OpenSSL compatibility layer function) with caller-supplied untrusted intermediate certificates; for those users it is critical, otherwise the library is unaffected.", "fixed_versions": [ "5.9.2" ], @@ -56,18 +314,18 @@ "OPENSSL_EXTRA" ] }, - "CVE-2026-6679": { + "CVE-2026-11999": { "state": "exploitable", "response": [ "update" ], - "detail": "A heap buffer overflow could occur in the DTLS 1.3 ACK serialization path before the connecting peer is authenticated. The buffer overflow was due to an integer truncation when computing the length of the ACK record-number list, causing an undersized buffer to be allocated and then overrun. This affects builds using DTLS 1.3 and wolfSSL version 5.9.0 and earlier. A fix was added to the 5.9.1 release. Thanks to Nicholas Carlini from Anthropic for the report. Fixed in PR 10116.", + "detail": "X.509 trust-chain bypass (path-depth exhaustion) in the OpenSSL compatibility certificate verifier (wolfSSL_X509_verify_cert()). This affects only builds with --enable-opensslextra whose application calls X509_verify_cert() with caller-supplied untrusted intermediates; for those users it is critical, otherwise the library is unaffected.", "fixed_versions": [ - "5.9.1" + "5.9.2" ], - "remediation": "Update to wolfSSL 5.9.1 or later.", + "remediation": "Update to wolfSSL 5.9.2 or later.", "requires_defines": [ - "WOLFSSL_DTLS13" + "OPENSSL_EXTRA" ] }, "CVE-2026-55958": { @@ -314,17 +572,6 @@ "OPENSSL_EXTRA" ] }, - "CVE-2026-6681": { - "state": "exploitable", - "response": [ - "update" - ], - "detail": "The PKCS#7 decode path ignores the caller-supplied output buffer size (outputSz), allowing decoded content to be written past the bounds of the provided buffer. This affects wolfSSL 5.9.0 and earlier and was fixed in the 5.9.1 release. Thanks to Nicholas Carlini from Anthropic for the report. Fixed in PR 10116.", - "fixed_versions": [ - "5.9.1" - ], - "remediation": "Update to wolfSSL 5.9.1 or later." - }, "CVE-2026-10512": { "state": "exploitable", "response": [ diff --git a/central/README.md b/central/README.md index f5104f1..735801f 100644 --- a/central/README.md +++ b/central/README.md @@ -3,27 +3,23 @@ These tools run for wolfSSL only. Do not vendor them into a product. - `gen-advisory` — the CSAF 2.0 and CycloneDX VEX generator. -- `advisory-completeness` — the release gate. It reconciles the CVEs a - release is supposed to cover against the CVE records and VEX overlay - entries present, and fails if any are missing: +- `advisory-completeness` — the release gate. Each product release is one + directory under `advisories/releases//` (`cves`, `ChangeLog.md`, + optional `prior-release.cves`, `mentions.cves`, `supplemental.cves`). + CI loops those directories; it does not name a version. - python3 central/advisory-completeness --cve-list advisories/releases/5.9.2.cves \ - --release 5.9.2 \ - --changelog central/testdata/ChangeLog-5.9.2.md \ - --prior-release advisories/releases/5.9.2.prior-release.cves \ - --mentions advisories/releases/5.9.2.mentions.cves \ - --require-fixed-version 5.9.2 + python3 central/advisory-completeness --release-dir advisories/releases/5.9.2 python3 central/advisory-completeness --release 5.9.2 \ --changelog ../wolfssl/ChangeLog.md It checks completeness only; it cannot judge whether a determination is - correct — that is human analysis. `--cve-list` is the CI path (this repo - does not contain the product ChangeLog). Count ChangeLog bullets of the - form `* [High] CVE-…` as members. The tool also computes a loose set of - every CVE id in the Vulnerabilities section and fails if the strict rule - dropped an id that is not listed in `--mentions`. `--release` must match - the CVE-list filename stem when both flags are set. + correct — that is human analysis. Count ChangeLog bullets of the form + `* [High] CVE-…` as members. The tool also computes a loose set of every + CVE id in the Vulnerabilities section and fails if the strict rule dropped + an id that is not listed in `mentions.cves`. `supplemental.cves` holds ids + fixed in this release but not a ChangeLog bullet here (late disclosure). + `--release` must match the CVE-list path when both flags are set. - `csaf-publish` — assemble the `.well-known/csaf` directory (hashes, index, provider-metadata, optional OpenPGP signatures via pgpy). Sign at deploy, not in git. Honors `SOURCE_DATE_EPOCH`. diff --git a/central/advisory-completeness b/central/advisory-completeness index 3ddeece..639b6a9 100755 --- a/central/advisory-completeness +++ b/central/advisory-completeness @@ -158,12 +158,14 @@ def records_present(records_dir): return {p.stem for p in d.glob('*.json') if _CVE_ID_RE.fullmatch(p.stem)} -def reconcile_changelog(strict, loose, pin, prior, mentions): - """Compare pin/prior/mentions lists to ChangeLog strict and loose sets. +def reconcile_changelog(strict, loose, pin, prior, mentions, supplemental=None): + """Compare pin/prior/mentions/supplemental lists to ChangeLog sets. - expected pin = strict bullets minus prior-release bullets + expected pin = (strict bullets minus prior-release) plus supplemental expected mentions = loose ids the strict rule dropped + supplemental: fixed in this release but not a ChangeLog bullet here """ + supplemental = list(supplemental or []) strict_set = set(strict) pin_set = set(pin) prior_set = set(prior) @@ -171,6 +173,9 @@ def reconcile_changelog(strict, loose, pin, prior, mentions): dropped = [c for c in loose if c not in strict_set] expected_pin = [c for c in strict if c not in prior_set] + for cid in supplemental: + if cid not in expected_pin: + expected_pin.append(cid) return { 'strict': strict, @@ -182,9 +187,43 @@ def reconcile_changelog(strict, loose, pin, prior, mentions): 'mentions_missing': [c for c in dropped if c not in mentions_set], 'mentions_extra': [c for c in mentions if c not in set(dropped)], 'prior_not_in_strict': [c for c in prior if c not in strict_set], + 'supplemental_in_strict': [c for c in supplemental if c in strict_set], } +def list_release_dirs(releases_root): + """Version directories under advisories/releases/ that contain a pin file.""" + root = pathlib.Path(releases_root) + if not root.is_dir(): + return [] + found = [] + for p in sorted(root.iterdir()): + if p.is_dir() and _VERSION_RE.match(p.name) and (p / 'cves').is_file(): + found.append(p) + return found + + +def inferred_release_from_cve_list(path): + """Release version implied by a pin file path. + + `advisories/releases/5.9.2/cves` -> 5.9.2 + `advisories/releases/5.9.2.cves` -> 5.9.2 + """ + path = pathlib.Path(path) + if path.name == 'cves' and _VERSION_RE.match(path.parent.name): + return path.parent.name + return path.stem + + +def optional_cve_list(path): + if path is None: + return [] + p = pathlib.Path(path) + if not p.is_file(): + return [] + return load_cve_list(p) + + def overlay_missing_fixed_version(pin, overlay_map, release): """Pin members whose overlay does not list `release` in fixed_versions.""" bad = [] @@ -259,6 +298,9 @@ def print_human(product, release, report): if ch['prior_not_in_strict']: print(f" prior-release not a ChangeLog bullet: " + ', '.join(ch['prior_not_in_strict'])) + if ch.get('supplemental_in_strict'): + print(f" supplemental already a ChangeLog bullet: " + + ', '.join(ch['supplemental_in_strict'])) if report.get('wrong_fixed_version'): print(f" overlay fixed_versions missing {release}: " + ', '.join(report['wrong_fixed_version'])) @@ -271,11 +313,15 @@ def main(): 'gen-advisory bundles).') p.add_argument('--release', default=None, help='Product release version, e.g. 5.9.1. Required unless ' - '--cve-list is given. Must match the CVE-list filename ' - 'stem when both are set.') + '--cve-list or --release-dir is given. Must match the ' + 'CVE-list path when both are set.') p.add_argument('--cve-list', default=None, help='Pinned CVE id list (one per line). Use this in CI ' 'when the product ChangeLog is not in this repo.') + p.add_argument('--release-dir', default=None, + help='Release directory (cves, ChangeLog.md, optional ' + 'prior-release.cves / mentions.cves / ' + 'supplemental.cves). Version is the directory name.') p.add_argument('--product', default='wolfSSL', help='Product name as it appears in the ChangeLog release ' 'header (default: wolfSSL).') @@ -289,6 +335,9 @@ def main(): p.add_argument('--mentions', default=None, help='CVE ids the strict bullet rule drops (body mentions ' 'or extra ids on the same bullet).') + p.add_argument('--supplemental', default=None, + help='CVE ids fixed in this release but not a ChangeLog ' + 'bullet for this version (late disclosure).') p.add_argument('--require-fixed-version', default=None, help='Every pin overlay entry must list this version in ' 'fixed_versions (catches a 5.9.1 fix pinned as 5.9.2).') @@ -302,17 +351,41 @@ def main(): changelog_path = None reconcile_pin_vs_changelog = False - if args.cve_list: + prior_path = args.prior_release + mentions_path = args.mentions + supplemental_path = args.supplemental + + if args.release_dir: + rel_dir = pathlib.Path(args.release_dir) + if not rel_dir.is_dir(): + sys.exit(f"ERROR: release directory not found: {rel_dir}") + if not _VERSION_RE.match(rel_dir.name): + sys.exit(f"ERROR: {rel_dir.name!r} is not a version like 5.9.1") + pin_file = rel_dir / 'cves' + if not pin_file.is_file(): + sys.exit(f"ERROR: pin file not found: {pin_file}") + release_cves = load_cve_list(pin_file) + args.release = rel_dir.name + changelog_path = pathlib.Path(args.changelog) if args.changelog \ + else rel_dir / 'ChangeLog.md' + if changelog_path.is_file(): + reconcile_pin_vs_changelog = True + prior_path = prior_path or str(rel_dir / 'prior-release.cves') + mentions_path = mentions_path or str(rel_dir / 'mentions.cves') + supplemental_path = supplemental_path or str(rel_dir / 'supplemental.cves') + if args.require_fixed_version is None: + args.require_fixed_version = args.release + elif args.cve_list: list_path = pathlib.Path(args.cve_list) if not list_path.is_file(): sys.exit(f"ERROR: CVE list not found: {list_path}") release_cves = load_cve_list(list_path) - list_stem = list_path.stem + inferred = inferred_release_from_cve_list(list_path) if args.release is None: - args.release = list_stem - elif args.release != list_stem: + args.release = inferred + elif args.release != inferred: sys.exit(f"ERROR: --release {args.release} does not match " - f"--cve-list stem {list_stem} ({list_path.name}).") + f"--cve-list {list_path} (inferred {inferred}).") if args.changelog: changelog_path = pathlib.Path(args.changelog) reconcile_pin_vs_changelog = True @@ -325,10 +398,10 @@ def main(): block = release_block(changelog_path.read_text(), args.product, args.release) release_cves = cves_fixed_in_release(block) - # Pin came from the ChangeLog. Still reconcile if prior/mentions given. - reconcile_pin_vs_changelog = bool(args.prior_release or args.mentions) + reconcile_pin_vs_changelog = bool( + args.prior_release or args.mentions or args.supplemental) else: - sys.exit("ERROR: pass --release (with a ChangeLog) or --cve-list.") + sys.exit("ERROR: pass --release-dir, --cve-list, or --release.") if not release_cves: sys.exit(f"ERROR: no CVEs found for {args.product} {args.release}.") @@ -349,13 +422,14 @@ def main(): changelog_path = pathlib.Path(args.changelog or DEFAULT_CHANGELOG) if not changelog_path.is_file(): sys.exit(f"ERROR: ChangeLog not found: {changelog_path}") - prior = load_cve_list(args.prior_release) if args.prior_release else [] - mentions = load_cve_list(args.mentions) if args.mentions else [] + prior = optional_cve_list(prior_path) + mentions = optional_cve_list(mentions_path) + supplemental = optional_cve_list(supplemental_path) block = release_block(changelog_path.read_text(), args.product, args.release) strict, loose = cves_in_vuln_sections(block) report['changelog'] = reconcile_changelog( - strict, loose, release_cves, prior, mentions) + strict, loose, release_cves, prior, mentions, supplemental) if args.json: print(json.dumps({ @@ -374,6 +448,7 @@ def main(): and not ch['mentions_missing'] and not ch['mentions_extra'] and not ch['prior_not_in_strict'] + and not ch.get('supplemental_in_strict') ) ok = (not report['missing_record'] diff --git a/central/test_advisory_completeness.py b/central/test_advisory_completeness.py index 982a367..11fdc31 100644 --- a/central/test_advisory_completeness.py +++ b/central/test_advisory_completeness.py @@ -142,6 +142,16 @@ def test_changelog_reconcile_fails_unclassified_drop(self): r = ac.reconcile_changelog(strict, loose, strict, [], []) self.assertEqual(r['mentions_missing'], ['CVE-2026-5460']) + def test_supplemental_ids_join_the_expected_pin(self): + strict = ['CVE-2026-5194'] + loose = ['CVE-2026-5194'] + pin = ['CVE-2026-5194', 'CVE-2026-6679'] + r = ac.reconcile_changelog(strict, loose, pin, [], [], + ['CVE-2026-6679']) + self.assertFalse(r['pin_missing']) + self.assertFalse(r['pin_extra']) + self.assertFalse(r['supplemental_in_strict']) + class OverlayLoadTests(unittest.TestCase): def test_comment_keys_ignored(self): @@ -169,66 +179,77 @@ def _run(self, args): [sys.executable, str(SCRIPT)] + args, capture_output=True, text=True) - def test_release_must_match_cve_list_stem(self): - pin = ROOT / 'advisories' / 'releases' / '5.9.2.cves' + def test_release_must_match_cve_list_path(self): + pin = ROOT / 'advisories' / 'releases' / '5.9.2' / 'cves' r = self._run(['--cve-list', str(pin), '--release', '9.9.9']) self.assertNotEqual(r.returncode, 0) self.assertIn('--release 9.9.9', r.stderr) + def test_release_dir_exits_0(self): + r = self._run(['--release-dir', + str(ROOT / 'advisories' / 'releases' / '5.9.1')]) + self.assertEqual(r.returncode, 0, r.stderr + r.stdout) -class Release592CatalogueTests(unittest.TestCase): - """The committed 5.9.2 pin list must be fully covered by records+overlay.""" - - def test_pinned_list_is_fully_covered(self): - pin = ROOT / 'advisories' / 'releases' / '5.9.2.cves' - cves = ac.load_cve_list(pin) - self.assertEqual(len(cves), 30) - self.assertNotIn('CVE-2026-5460', cves) - self.assertNotIn('CVE-2026-6679', cves) - self.assertNotIn('CVE-2026-6681', cves) - records = ac.records_present(ROOT / 'advisories' / 'records') - overlay = ac.load_overlay(str(ROOT / 'advisories' / 'vex-overlay.json')) - report = ac.build_report(cves, records, overlay) - self.assertFalse(report['missing_record'], report['missing_record']) - self.assertFalse(report['missing_overlay'], report['missing_overlay']) - self.assertFalse(report['orphan_overlay'], report['orphan_overlay']) - - def test_overlay_fixed_versions_are_5_9_2(self): - pin = ac.load_cve_list(ROOT / 'advisories' / 'releases' / '5.9.2.cves') - overlay = ac.load_overlay_map( - str(ROOT / 'advisories' / 'vex-overlay.json')) - bad = ac.overlay_missing_fixed_version(pin, overlay, '5.9.2') - self.assertFalse(bad, bad) - - def test_prior_release_ids_are_5_9_1_fixes(self): - prior = ac.load_cve_list( - ROOT / 'advisories' / 'releases' / '5.9.2.prior-release.cves') - self.assertEqual(prior, ['CVE-2026-6679', 'CVE-2026-6681']) - overlay = ac.load_overlay_map( - str(ROOT / 'advisories' / 'vex-overlay.json')) - for cve in prior: - self.assertIn('5.9.1', overlay[cve]['fixed_versions'], cve) - self.assertNotIn('5.9.2', overlay[cve]['fixed_versions'], cve) - - def test_pin_matches_frozen_changelog(self): - pin = ac.load_cve_list(ROOT / 'advisories' / 'releases' / '5.9.2.cves') - prior = ac.load_cve_list( - ROOT / 'advisories' / 'releases' / '5.9.2.prior-release.cves') - mentions = ac.load_cve_list( - ROOT / 'advisories' / 'releases' / '5.9.2.mentions.cves') - text = (HERE / 'testdata' / 'ChangeLog-5.9.2.md').read_text() - block = ac.release_block(text, 'wolfSSL', '5.9.2') - strict, loose = ac.cves_in_vuln_sections(block) - r = ac.reconcile_changelog(strict, loose, pin, prior, mentions) - self.assertFalse(r['pin_missing'], r) - self.assertFalse(r['pin_extra'], r) - self.assertFalse(r['mentions_missing'], r) - self.assertFalse(r['mentions_extra'], r) - self.assertFalse(r['prior_not_in_strict'], r) - self.assertEqual(mentions, ['CVE-2026-5460']) +class ReleaseCatalogueTests(unittest.TestCase): + """Every advisories/releases// directory is a complete catalogue.""" + + def setUp(self): + self.dirs = ac.list_release_dirs(ROOT / 'advisories' / 'releases') + self.records = ac.records_present(ROOT / 'advisories' / 'records') + self.overlay = ac.load_overlay_map( + str(ROOT / 'advisories' / 'vex-overlay.json')) -class Release592CdxRatingsTests(unittest.TestCase): + def test_discovers_5_9_1_and_5_9_2(self): + names = [p.name for p in self.dirs] + self.assertEqual(names, ['5.9.1', '5.9.2']) + + def test_every_release_is_fully_covered(self): + self.assertTrue(self.dirs) + for d in self.dirs: + pin = ac.load_cve_list(d / 'cves') + report = ac.build_report(pin, self.records, set(self.overlay)) + self.assertFalse(report['missing_record'], (d.name, report['missing_record'])) + self.assertFalse(report['missing_overlay'], (d.name, report['missing_overlay'])) + bad = ac.overlay_missing_fixed_version(pin, self.overlay, d.name) + self.assertFalse(bad, (d.name, bad)) + + def test_5_9_2_does_not_claim_5_9_1_fixes(self): + pin = ac.load_cve_list(ROOT / 'advisories' / 'releases' / '5.9.2' / 'cves') + self.assertEqual(len(pin), 30) + self.assertNotIn('CVE-2026-5460', pin) + self.assertNotIn('CVE-2026-6679', pin) + self.assertNotIn('CVE-2026-6681', pin) + + def test_5_9_1_includes_late_disclosures(self): + pin = ac.load_cve_list(ROOT / 'advisories' / 'releases' / '5.9.1' / 'cves') + self.assertEqual(len(pin), 24) + self.assertIn('CVE-2026-6679', pin) + self.assertIn('CVE-2026-6681', pin) + supp = ac.load_cve_list( + ROOT / 'advisories' / 'releases' / '5.9.1' / 'supplemental.cves') + self.assertEqual(supp, ['CVE-2026-6679', 'CVE-2026-6681']) + + def test_every_release_matches_its_frozen_changelog(self): + for d in self.dirs: + pin = ac.load_cve_list(d / 'cves') + prior = ac.optional_cve_list(d / 'prior-release.cves') + mentions = ac.optional_cve_list(d / 'mentions.cves') + supplemental = ac.optional_cve_list(d / 'supplemental.cves') + text = (d / 'ChangeLog.md').read_text() + block = ac.release_block(text, 'wolfSSL', d.name) + strict, loose = ac.cves_in_vuln_sections(block) + r = ac.reconcile_changelog(strict, loose, pin, prior, mentions, + supplemental) + self.assertFalse(r['pin_missing'], (d.name, r)) + self.assertFalse(r['pin_extra'], (d.name, r)) + self.assertFalse(r['mentions_missing'], (d.name, r)) + self.assertFalse(r['mentions_extra'], (d.name, r)) + self.assertFalse(r['prior_not_in_strict'], (d.name, r)) + self.assertFalse(r['supplemental_in_strict'], (d.name, r)) + + +class ReleaseCdxRatingsTests(unittest.TestCase): """CycloneDX is the machine-readable CVSS v4 path (CSAF 2.0 has no v4).""" def test_every_pinned_cve_has_cvss_v4_rating(self): @@ -236,24 +257,23 @@ def test_every_pinned_cve_has_cvss_v4_rating(self): spec = importlib.util.spec_from_loader('ga', ga_loader) ga = importlib.util.module_from_spec(spec) ga_loader.exec_module(ga) - pin = ac.load_cve_list(ROOT / 'advisories' / 'releases' / '5.9.2.cves') overlay = json.loads( (ROOT / 'advisories' / 'vex-overlay.json').read_text()) rec_dir = ROOT / 'advisories' / 'records' - advs = [] - for cve in pin: - rec = json.loads((rec_dir / f'{cve}.json').read_text()) - advs.append(ga.parse_record(rec)) - bom = ga.generate_cdx_vex(advs, overlay, 'wolfssl-5.9.2', - '2026-01-02T00:00:00Z') - self.assertEqual(len(bom['vulnerabilities']), 30) - missing = [] - for v in bom['vulnerabilities']: - ratings = v.get('ratings') or [] - if not any(r.get('method') == 'CVSSv4' and r.get('score') is not None - for r in ratings): - missing.append(v['id']) - self.assertFalse(missing, missing) + for d in ac.list_release_dirs(ROOT / 'advisories' / 'releases'): + pin = ac.load_cve_list(d / 'cves') + advs = [ga.parse_record(json.loads((rec_dir / f'{cve}.json').read_text())) + for cve in pin] + bom = ga.generate_cdx_vex(advs, overlay, f'wolfssl-{d.name}', + '2026-01-02T00:00:00Z') + self.assertEqual(len(bom['vulnerabilities']), len(pin), d.name) + missing = [] + for v in bom['vulnerabilities']: + ratings = v.get('ratings') or [] + if not any(r.get('method') == 'CVSSv4' and r.get('score') is not None + for r in ratings): + missing.append(v['id']) + self.assertFalse(missing, (d.name, missing)) if __name__ == '__main__': diff --git a/central/testdata/README.md b/central/testdata/README.md index 0585751..180bc51 100644 --- a/central/testdata/README.md +++ b/central/testdata/README.md @@ -9,4 +9,3 @@ the `.github/workflows/advisory.yml` jobs. Committed so the tests are hermetic | `CVE-2026-5501.json` | Real published wolfSSL CNA record (CVSS v4 only). | | `CVE-2026-5778.json` | Real published wolfSSL CNA record (CVSS v4 only). | | `CVE-2026-5999.json` | **Synthetic fixture, not a real CVE.** Carries a CVSS v3.1 block so the CSAF `scores[]` emission path (and the CVSS-consistency mandatory tests 6.1.8/6.1.9) is exercised; the v4-only records above never populate `scores[]` in CSAF 2.0. | -| `ChangeLog-5.9.2.md` | Frozen wolfSSL 5.9.2 release header and Vulnerabilities section. Completeness CI reconciles the pin list against this file so the gate does not need a sibling wolfssl checkout. |