Summary
Decrypting AES-CBC encrypted JWE has Potential Padding Oracle Attack Vulnerability.
Details
On v2.0.10, decrypting AES-CBC encrypted JWE may return an error "failed to generate plaintext from decrypted blocks: invalid padding":
|
plaintext, err := unpad(buf, c.blockCipher.BlockSize()) |
|
if err != nil { |
|
return nil, fmt.Errorf(`failed to generate plaintext from decrypted blocks: %w`, err) |
|
} |
Reporting padding error causes Padding Oracle Attack Vulnerability.
RFC 7516 JSON Web Encryption (JWE) says that we MUST NOT do this.
11.5. Timing Attacks
To mitigate the attacks described in RFC 3218 [RFC3218], the
recipient MUST NOT distinguish between format, padding, and length
errors of encrypted keys. It is strongly recommended, in the event
of receiving an improperly formatted key, that the recipient
substitute a randomly generated CEK and proceed to the next step, to
mitigate timing attacks.
In addition, the time to remove padding depends on the length of the padding.
It may leak the length of the padding by Timing Attacks.
|
func unpad(buf []byte, n int) ([]byte, error) { |
|
lbuf := len(buf) |
|
rem := lbuf % n |
|
|
|
// First, `buf` must be a multiple of `n` |
|
if rem != 0 { |
|
return nil, fmt.Errorf("input buffer must be multiple of block size %d", n) |
|
} |
|
|
|
// Find the last byte, which is the encoded padding |
|
// i.e. 0x1 == 1 byte worth of padding |
|
last := buf[lbuf-1] |
|
|
|
// This is the number of padding bytes that we expect |
|
expected := int(last) |
|
|
|
if expected == 0 || /* we _have_ to have padding here. therefore, 0x0 is not an option */ |
|
expected > n || /* we also must make sure that we don't go over the block size (n) */ |
|
expected > lbuf /* finally, it can't be more than the buffer itself. unlikely, but could happen */ { |
|
return nil, fmt.Errorf(`invalid padding byte at the end of buffer`) |
|
} |
|
|
|
// start i = 1 because we have already established that expected == int(last) where |
|
// last = buf[lbuf-1]. |
|
// |
|
// we also don't check against lbuf-i in range, because we have established expected <= lbuf |
|
for i := 1; i < expected; i++ { |
|
if buf[lbuf-i] != last { |
|
return nil, fmt.Errorf(`invalid padding`) |
|
} |
|
} |
|
|
|
return buf[:lbuf-expected], nil |
|
} |
To mitigate Timing Attacks, it MUST be done in constant time.
Impact
The authentication tag is verified, so it is not an immediate attack.
Summary
Decrypting AES-CBC encrypted JWE has Potential Padding Oracle Attack Vulnerability.
Details
On v2.0.10, decrypting AES-CBC encrypted JWE may return an error "failed to generate plaintext from decrypted blocks: invalid padding":
jwx/jwe/internal/aescbc/aescbc.go
Lines 210 to 213 in 8840ffd
Reporting padding error causes Padding Oracle Attack Vulnerability.
RFC 7516 JSON Web Encryption (JWE) says that we MUST NOT do this.
In addition, the time to remove padding depends on the length of the padding.
It may leak the length of the padding by Timing Attacks.
jwx/jwe/internal/aescbc/aescbc.go
Lines 33 to 66 in 796b2a9
To mitigate Timing Attacks, it MUST be done in constant time.
Impact
The authentication tag is verified, so it is not an immediate attack.