Commit 3275e21
authored
Merge pull request from GHSA-rm8v-mxj3-5rmq
### Summary
Decrypting AES-CBC encrypted JWE has Potential Padding Oracle Attack Vulnerability.
### Details
On [v2.0.10](https://github.com/lestrrat-go/jwx/releases/tag/v2.0.10), decrypting AES-CBC encrypted JWE may return an error "failed to generate plaintext from decrypted blocks: invalid padding":
https://github.com/lestrrat-go/jwx/blob/8840ffd4afc5839f591ff0e9ba9034af52b1643e/jwe/internal/aescbc/aescbc.go#L210-L213
```go
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](https://en.wikipedia.org/wiki/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.
https://github.com/lestrrat-go/jwx/blob/796b2a9101cf7e7cb66455e4d97f3c158ee10904/jwe/internal/aescbc/aescbc.go#L33-L66
```go
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.1 parent 796b2a9 commit 3275e21
2 files changed
Lines changed: 52 additions & 34 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
7 | 7 | | |
8 | 8 | | |
9 | 9 | | |
| 10 | + | |
10 | 11 | | |
11 | 12 | | |
12 | 13 | | |
| |||
30 | 31 | | |
31 | 32 | | |
32 | 33 | | |
33 | | - | |
34 | | - | |
35 | | - | |
36 | | - | |
37 | | - | |
38 | | - | |
39 | | - | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
40 | 42 | | |
41 | 43 | | |
42 | | - | |
43 | | - | |
44 | | - | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
45 | 48 | | |
46 | | - | |
47 | | - | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
48 | 55 | | |
49 | | - | |
50 | | - | |
51 | | - | |
52 | | - | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
53 | 62 | | |
54 | 63 | | |
55 | | - | |
56 | | - | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
57 | 78 | | |
58 | | - | |
59 | | - | |
60 | | - | |
61 | | - | |
62 | | - | |
63 | | - | |
| 79 | + | |
| 80 | + | |
64 | 81 | | |
65 | | - | |
| 82 | + | |
| 83 | + | |
66 | 84 | | |
67 | 85 | | |
68 | 86 | | |
| |||
199 | 217 | | |
200 | 218 | | |
201 | 219 | | |
202 | | - | |
203 | | - | |
204 | | - | |
205 | | - | |
206 | 220 | | |
207 | 221 | | |
208 | 222 | | |
209 | 223 | | |
210 | | - | |
211 | | - | |
212 | | - | |
| 224 | + | |
| 225 | + | |
| 226 | + | |
| 227 | + | |
213 | 228 | | |
| 229 | + | |
| 230 | + | |
214 | 231 | | |
215 | 232 | | |
216 | 233 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
71 | 71 | | |
72 | 72 | | |
73 | 73 | | |
74 | | - | |
75 | | - | |
| 74 | + | |
| 75 | + | |
76 | 76 | | |
77 | 77 | | |
| 78 | + | |
78 | 79 | | |
79 | 80 | | |
80 | 81 | | |
| |||
0 commit comments