Repository navigation
v1.21.3
Bundle signature verification could be side-stepped (GHSA-g2pf-6v5v-qcc8)
An attacker able to alter bundle bytes could supply arbitrary policy and data to an OPA that was configured
to verify bundle signatures. This could happen if the attacker controls any of:
- OPA bundle/discovery service (including an artifact store it uses)
- MitM between OPA and bundle/discovery service
- write access to a file:// bundle path or the bundle persistence directory
Two separate side-steps are fixed:
Issue 1. Signature verification keyed on keyid rather than on the signing block
OPA only required a .signatures.json file when signing.keyid was set, so a bundle stripped of its signature was
accepted if only e.g. bundles[_].signing was set instead of bundles[_].signing.keyid. Verification now depends on
the presence of a signing block, as documented; keyid only selects which key to use.
Affected:
bundles[_].signingordiscovery.signingconfigured withoutkeyid: an empty block, or one with onlyscopeor
exclude_files.- Embedders (SDK, custom plugins,
v1/loader,v1/compile) callingbundle.NewVerificationConfig(keys, "", ...)with
an empty key id.
Not affected:
- Configurations with an explicit
bundles[_].signing.keyidordiscovery.signing.keyid. opa run/opa eval/opa buildwith--verification-key, which defaults--verification-key-idtodefault.
Passing--verification-key-id ""explicitly was affected.- Configurations with top-level
keysbut nosigningblock: not a verification opt-in before or after this fix.
Unsigned bundles are still accepted, and OPA now logs a warning at startup for bundles in this state.
Workaround: on affected versions, set an explicit keyid on every bundle that must be signed:
bundles:
authz:
service: acmecorp
resource: bundle.tar.gz
signing:
keyid: my_key # must name an entry under the top-level `keys`
discovery:
resource: /discovery.tar.gz
signing:
keyid: my_discovery_key
keys:
my_key:
algorithm: RS256
key: |
-----BEGIN PUBLIC KEY-----
...Further behaviour changes:
- A
signingblock with no entries under the top-levelkeysis now a startup configuration error, rather than a
configuration that rejects every signed bundle while accepting unsigned ones. bundle.NewVerificationConfignow requires signatures by default. Embedders can opt out with
WithSkipBundleVerification(true)or the new(*VerificationConfig).WithOptionalSignature().
Issue 2. Unsigned delta bundle downgrade
Delta bundles skipped verification entirely, so an attacker could replace a signed snapshot bundle with an unsigned
delta bundle on the same resource. The signed policy stays active while the attacker controls any data inside the
bundle's roots. Delta bundles not supporting signing
was documented, but unenforced. OPA now rejects them with delta bundles do not support signature verification.
Affected:
- Any bundle or discovery configuration with a
signingblock, with or withoutkeyid. opa run/opa evalwith--verification-key.
Not affected:
- Configurations that don't verify signatures: no
signingblock, or--skip-verify. Nothing was verified to begin
with.
Workaround: there is no configuration that makes affected versions reject delta bundles. Until upgrading, ensure
the integrity of the bundle bytes themselves: TLS terminated by OPA or a trusted hop, restricted write access to the
bundle service, artifact store and bundle persistence directory.
Bundle services that must keep serving unsigned delta bundles after upgrading can opt out per bundle with the new
bundles[_].signing.allow_unsigned_delta_bundles (or discovery.signing.allow_unsigned_delta_bundles) field.
Snapshot bundles must still be signed.
Reported by Brian Willows (@BrianWillows, Graith Internet, graith.co.uk), authored by @johanfylling.