openbadgeslib 1.3.0
Security-hardening release on top of the v1.2.0 OpenBadges 3.0 / DID feature set. Mostly a drop-in upgrade — see the one behaviour change below.
⚠️ Behaviour change
openbadges-verifier --json now sets its exit status from issuer trust, not just signature validity:
0— valid and issuer-trusted2— signature valid but the issuer is not anchored (an OB2 badge-embedded key, or a self-asserteddid:key)1— any failure
In v1.2.0 a valid-but-untrusted badge exited 0, so a CI gate keying on the exit code could accept a signature that does not prove issuer identity. The JSON body (valid / trusted / reason) is unchanged. Update any automation that gated on exit 0.
Security
-
SSRF protection in
download_file. The URLs it fetches are attacker-influenced (an OB2 badge/issuer/revocationListURL, an OB3did:webhost, an OB3credentialStatuslist), so it now resolves the destination host and refuses any private, loopback, link-local, reserved, multicast, unspecified or carrier-grade-NAT (100.64.0.0/10) address; the check is re-applied to redirect targets. Previously a crafted badge could steer a verifier into GETting cloud-metadata endpoints or internal hosts. Anallow_private=Trueopt-out is available for private deployments. -
OB3 issuer binding for DID-anchored verifiers.
OB3Verifier.for_issuer_did()now requires the credential's own issuer id to equal the DID whose key was resolved.did:webis not self-certifying, so without this a credential signed by the resolved key could claim a different (trusted) issuer and still verify. Verifiers built directly from a public key are unchanged (the caller vouches for the key). -
--jsonexit status reflects issuer trust (see the behaviour change above), so machine consumers cannot gate on a valid-but-untrusted signature. -
A resolved
did:keyis reported untrusted. With--resolve-did, a self-asserteddid:keyissuer is nowtrusted: false(with a warning), mirroring OB2's badge-embedded-key case; only an operator-supplied key or a DNS/TLS-anchoreddid:webis trusted.
Fixes
-
OB3 Bitstring Status List
statusSize > 1now fails closed. The bit reader assumed one bit per entry; a multi-bit list would have read the wrong bit and could report a revoked credential as valid. An unsupportedstatusSizeis now rejected rather than misread. -
confparserresolves a relative[paths] baseagainst the config-file directory (not the process CWD). Previously only a bare.was handled and its value replaced wholesale, silently dropping the suffix of./dataor../sharedand misplacing key/log/image trees. A$in the config directory path is now handled correctly.
Docs
- Ed25519 (EdDSA) support documented across the README and wiki (key types, algorithms,
openbadges-keygeneratorkey_type, the shipped config example); the--jsonexit-status scheme documented; and stale crypto-library / dependency notes corrected.
See Changelog.txt for the full list.