Found while reviewing #351 (the #347 sender-binding fix). Ruled explicitly not a widening of that defect, so it is filed on its own rather than folded in. It is not a child of the #247 map — it is an ordinary product bug the audit did not surface.
The claim in the code
pg-wasm/src/lib.rs:161-171 and :220-230 seal with skipEncryption, whose comment says the container is sealed "such that everyone can decrypt". It seals to a fixed, publicly known policy:
timestamp: 0
con: [ Attribute { atype: "default", value: Some("Default") } ]
Why that does not hold
The claim requires the PKG to issue a USK for that policy, and it will not:
pg-pkg/src/handlers/key.rs builds the USK policy strictly from AuthResult.con.
pg-pkg/src/middleware/auth.rs fills AuthResult.con only from authenticated disclosures — real Yivi attribute types on the IRMA/JWT path, and a hardcoded pbdf.* table on the API-key path.
Neither path can produce an attribute typed default, and a client cannot ask for an arbitrary policy. So no caller can obtain the USK the DEM key derives from, and a skipEncryption container is not decryptable through a real PKG at all — by anyone, not just by "everyone".
It appears to work only in tests, where TestSetup derives USKs straight from the MSK and therefore answers for any policy the test names.
Note the security direction is the safe one — this is not the inverse bug. If the PKG did issue that USK, the DEM key would be universally derivable and every skipEncryption container would be readable by anyone; that was checked first and is not the case.
What to settle
- Is
skipEncryption used by anything shipped? If it is dead in every consumer, deleting it is cheaper than making it work, and it removes a comment that reads as a security guarantee.
- If it is used, decide what "everyone can decrypt" should mean given the PKG will not cooperate — a PKG-side well-known policy the issuance path deliberately allows, a plaintext/no-op container mode that does not pretend to be sealed, or nothing at all.
- Either way the comment is wrong today and should not survive: it describes a property the surrounding code cannot deliver, which is the shape of thing someone eventually builds on.
Acceptance
Whichever way (1) goes, the outcome is a tree in which no comment claims a decryptability property the PKG's issuance path contradicts — and if the mode survives, a test that exercises it against a policy the real issuance path could produce, rather than against TestSetup's direct-from-MSK derivation, which cannot tell the two cases apart.
Found while reviewing #351 (the
#347sender-binding fix). Ruled explicitly not a widening of that defect, so it is filed on its own rather than folded in. It is not a child of the#247map — it is an ordinary product bug the audit did not surface.The claim in the code
pg-wasm/src/lib.rs:161-171and:220-230seal withskipEncryption, whose comment says the container is sealed "such that everyone can decrypt". It seals to a fixed, publicly known policy:Why that does not hold
The claim requires the PKG to issue a USK for that policy, and it will not:
pg-pkg/src/handlers/key.rsbuilds the USK policy strictly fromAuthResult.con.pg-pkg/src/middleware/auth.rsfillsAuthResult.cononly from authenticated disclosures — real Yivi attribute types on the IRMA/JWT path, and a hardcodedpbdf.*table on the API-key path.Neither path can produce an attribute typed
default, and a client cannot ask for an arbitrary policy. So no caller can obtain the USK the DEM key derives from, and askipEncryptioncontainer is not decryptable through a real PKG at all — by anyone, not just by "everyone".It appears to work only in tests, where
TestSetupderives USKs straight from the MSK and therefore answers for any policy the test names.Note the security direction is the safe one — this is not the inverse bug. If the PKG did issue that USK, the DEM key would be universally derivable and every
skipEncryptioncontainer would be readable by anyone; that was checked first and is not the case.What to settle
skipEncryptionused by anything shipped? If it is dead in every consumer, deleting it is cheaper than making it work, and it removes a comment that reads as a security guarantee.Acceptance
Whichever way (1) goes, the outcome is a tree in which no comment claims a decryptability property the PKG's issuance path contradicts — and if the mode survives, a test that exercises it against a policy the real issuance path could produce, rather than against
TestSetup's direct-from-MSK derivation, which cannot tell the two cases apart.