Skip to content

Commit 0b34b21

Browse files
authored
JwkSet keys secrecy default (#983)
Ensured JwkSet `keys` parameter is not `secret` by default. Each JWK element should determine which members are secret or not. Resolves #976.
1 parent 053855f commit 0b34b21

File tree

5 files changed

+12
-10
lines changed

5 files changed

+12
-10
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ This patch release:
99
[Issue 947](https://github.com/jwtk/jjwt/issues/947).
1010
* Fixes a decompression memory leak in concurrent/multi-threaded environments introduced in 0.12.0 when decompressing JWTs with a `zip` header of `GZIP`. See [Issue 949](https://github.com/jwtk/jjwt/issues/949).
1111
* Upgrades BouncyCastle to 1.78 via [PR 941](https://github.com/jwtk/jjwt/pull/941).
12+
* Ensures that a `JwkSet`'s `keys` list member is no longer considered secret and is not redacted by default. However, each individual JWK element within the `keys` list may still have [redacted private or secret members](https://github.com/jwtk/jjwt?tab=readme-ov-file#jwk-tostring-safety) as expected. See [Issue 976](https://github.com/jwtk/jjwt/issues/976).
1213

1314
### 0.12.5
1415

impl/src/main/java/io/jsonwebtoken/impl/security/DefaultJwkSet.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@ static Parameter<Set<Jwk<?>>> param(Converter<Jwk<?>, ?> converter) {
3535
return Parameters.builder(JwkConverter.JWK_CLASS)
3636
.setConverter(converter).set()
3737
.setId("keys").setName("JSON Web Keys")
38-
.setSecret(true)
3938
.build();
4039
}
4140

impl/src/main/java/io/jsonwebtoken/impl/security/JwkSetConverter.java

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -91,9 +91,6 @@ public JwkSet applyFrom(Object o) {
9191
String msg = "JWK Set " + PARAM + " value cannot be null.";
9292
throw new MalformedKeySetException(msg);
9393
}
94-
if (val instanceof Supplier<?>) {
95-
val = ((Supplier<?>) val).get();
96-
}
9794
if (!(val instanceof Collection)) {
9895
String msg = "JWK Set " + PARAM + " value must be a Collection (JSON Array). Type found: " +
9996
val.getClass().getName();

impl/src/test/groovy/io/jsonwebtoken/impl/security/DefaultJwkSetBuilderTest.groovy

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,9 @@ class DefaultJwkSetBuilderTest {
278278
key_ops: ['sign', 'encrypt'] // unrelated operations
279279
]
280280

281-
String msg = "Invalid Map ${DefaultJwkSet.KEYS} value: <redacted>. Unable to create JWK: Unrelated key " +
281+
String msg = "Invalid Map ${DefaultJwkSet.KEYS} value: " +
282+
"[{kty=${badMap.kty}, k=${badMap.k}, key_ops=${badMap.key_ops}}]. " +
283+
"Unable to create JWK: Unrelated key " +
282284
"operations are not allowed. KeyOperation [${Jwks.OP.ENCRYPT}] is unrelated to " +
283285
"[${Jwks.OP.SIGN}]."
284286

impl/src/test/groovy/io/jsonwebtoken/impl/security/DefaultJwkSetTest.groovy

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -67,14 +67,17 @@ class DefaultJwkSetTest {
6767
}
6868

6969
/**
70-
* Asserts that the raw keys value is a RedactedSupplier and not a raw value due to potential sensitivity if
71-
* the JwkSet contains secret or private JWKs.
70+
* Asserts that the raw 'keys' value is not a RedactedSupplier per https://github.com/jwtk/jjwt/issues/976,
71+
* but an internal secret key parameter does have a RedactedSupplier
7272
*/
7373
@Test
74-
void testKeysFromGetIsRedactedSupplier() {
74+
void testGetKeysNotRedactedSupplier() {
7575
def jwk = Jwks.builder().key(TestKeys.HS256).build()
7676
def set = new DefaultJwkSet(DefaultJwkSet.KEYS, [keys: [jwk]])
77-
def result = set.get('keys')
78-
assertTrue result instanceof RedactedSupplier
77+
def keys = set.get('keys')
78+
assertFalse keys instanceof RedactedSupplier
79+
keys = keys as List
80+
def element = keys[0] as Map// result is an array/list, so get first JWK in the list
81+
assertTrue element.k instanceof RedactedSupplier // 'k' is a secret property, should be redacted
7982
}
8083
}

0 commit comments

Comments
 (0)