Skip to content

Commit 53d50f6

Browse files
committed
Remove global default typing
This commits remove global default typing for better security and use instead a custom PolymorphicTypeValidator. See https://cowtowncoder.medium.com/jackson-2-10-safe-default-typing-2d018f0ce2ba for more details. See gh-17832 Signed-off-by: Sébastien Deleuze <sdeleuze@users.noreply.github.com>
1 parent 5b0f1a7 commit 53d50f6

File tree

58 files changed

+399
-597
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

58 files changed

+399
-597
lines changed

cas/src/main/java/org/springframework/security/cas/jackson/AssertionImplMixin.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545
* @see CasJacksonModule
4646
* @see org.springframework.security.jackson.SecurityJacksonModules
4747
*/
48-
@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY)
48+
@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS)
4949
@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY, getterVisibility = JsonAutoDetect.Visibility.NONE,
5050
isGetterVisibility = JsonAutoDetect.Visibility.NONE)
5151
@JsonIgnoreProperties(ignoreUnknown = true)
@@ -61,7 +61,8 @@ class AssertionImplMixin {
6161
* @param attributes the key/value pairs for this attribute.
6262
*/
6363
@JsonCreator
64-
AssertionImplMixin(@JsonProperty("principal") AttributePrincipal principal,
64+
AssertionImplMixin(
65+
@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS) @JsonProperty("principal") AttributePrincipal principal,
6566
@JsonProperty("validFromDate") Date validFromDate, @JsonProperty("validUntilDate") Date validUntilDate,
6667
@JsonProperty("authenticationDate") Date authenticationDate,
6768
@JsonProperty("attributes") Map<String, Object> attributes) {

cas/src/main/java/org/springframework/security/cas/jackson/AttributePrincipalImplMixin.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@
4343
* @see CasJacksonModule
4444
* @see org.springframework.security.jackson.SecurityJacksonModules
4545
*/
46-
@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY)
46+
@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS)
4747
@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY, getterVisibility = JsonAutoDetect.Visibility.NONE,
4848
isGetterVisibility = JsonAutoDetect.Visibility.NONE)
4949
@JsonIgnoreProperties(ignoreUnknown = true)

cas/src/main/java/org/springframework/security/cas/jackson/CasAuthenticationTokenMixin.java

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@
5252
* @see CasJacksonModule
5353
* @see org.springframework.security.jackson.SecurityJacksonModules
5454
*/
55-
@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY)
55+
@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS)
5656
@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY, isGetterVisibility = JsonAutoDetect.Visibility.NONE,
5757
getterVisibility = JsonAutoDetect.Visibility.NONE, creatorVisibility = JsonAutoDetect.Visibility.ANY)
5858
@JsonIgnoreProperties(ignoreUnknown = true)
@@ -75,10 +75,13 @@ class CasAuthenticationTokenMixin {
7575
* principal and how to obtain a proxy ticket for the user.
7676
*/
7777
@JsonCreator
78-
CasAuthenticationTokenMixin(@JsonProperty("keyHash") Integer keyHash, @JsonProperty("principal") Object principal,
79-
@JsonProperty("credentials") Object credentials,
80-
@JsonProperty("authorities") Collection<? extends GrantedAuthority> authorities,
81-
@JsonProperty("userDetails") UserDetails userDetails, @JsonProperty("assertion") Assertion assertion) {
78+
CasAuthenticationTokenMixin(@JsonProperty("keyHash") Integer keyHash,
79+
@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS) @JsonProperty("principal") Object principal,
80+
@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS) @JsonProperty("credentials") Object credentials,
81+
@JsonTypeInfo(
82+
use = JsonTypeInfo.Id.CLASS) @JsonProperty("authorities") Collection<? extends GrantedAuthority> authorities,
83+
@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS) @JsonProperty("userDetails") UserDetails userDetails,
84+
@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS) @JsonProperty("assertion") Assertion assertion) {
8285
}
8386

8487
}

cas/src/main/java/org/springframework/security/cas/jackson/CasJacksonModule.java

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,10 @@
1919
import org.apereo.cas.client.authentication.AttributePrincipalImpl;
2020
import org.apereo.cas.client.validation.AssertionImpl;
2121
import tools.jackson.core.Version;
22-
import tools.jackson.databind.cfg.MapperBuilder;
23-
import tools.jackson.databind.module.SimpleModule;
22+
import tools.jackson.databind.jsontype.BasicPolymorphicTypeValidator;
2423

2524
import org.springframework.security.cas.authentication.CasAuthenticationToken;
26-
import org.springframework.security.jackson.AllowlistTypeResolverBuilder;
25+
import org.springframework.security.jackson.SecurityJacksonModule;
2726
import org.springframework.security.jackson.SecurityJacksonModules;
2827

2928
/**
@@ -47,15 +46,19 @@
4746
* @since 7.0
4847
* @see SecurityJacksonModules
4948
*/
50-
public class CasJacksonModule extends SimpleModule {
49+
public class CasJacksonModule extends SecurityJacksonModule {
5150

5251
public CasJacksonModule() {
5352
super(CasJacksonModule.class.getName(), new Version(1, 0, 0, null, null, null));
5453
}
5554

55+
@Override
56+
protected void configurePolymorphicTypeValidator(BasicPolymorphicTypeValidator.Builder builder) {
57+
builder.allowIfSubType(AssertionImpl.class).allowIfSubType(AttributePrincipalImpl.class);
58+
}
59+
5660
@Override
5761
public void setupModule(SetupContext context) {
58-
((MapperBuilder<?, ?>) context.getOwner()).setDefaultTyping(new AllowlistTypeResolverBuilder());
5962
context.setMixIn(AssertionImpl.class, AssertionImplMixin.class);
6063
context.setMixIn(AttributePrincipalImpl.class, AttributePrincipalImplMixin.class);
6164
context.setMixIn(CasAuthenticationToken.class, CasAuthenticationTokenMixin.class);

cas/src/test/java/org/springframework/security/cas/jackson/CasAuthenticationTokenMixinTests.java

Lines changed: 7 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@
2828
import org.junit.jupiter.api.BeforeEach;
2929
import org.junit.jupiter.api.Test;
3030
import org.skyscreamer.jsonassert.JSONAssert;
31-
import tools.jackson.databind.cfg.DateTimeFeature;
3231
import tools.jackson.databind.json.JsonMapper;
3332

3433
import org.springframework.security.cas.authentication.CasAuthenticationToken;
@@ -56,11 +55,9 @@ public class CasAuthenticationTokenMixinTests {
5655

5756
public static final String AUTHORITY_JSON = "{\"@class\": \"org.springframework.security.core.authority.SimpleGrantedAuthority\", \"authority\": \"ROLE_USER\"}";
5857

59-
public static final String AUTHORITIES_SET_JSON = "[\"java.util.Collections$UnmodifiableSet\", [" + AUTHORITY_JSON
60-
+ "]]";
58+
public static final String AUTHORITIES_SET_JSON = "[" + AUTHORITY_JSON + "]";
6159

62-
public static final String AUTHORITIES_ARRAYLIST_JSON = "[\"java.util.Collections$UnmodifiableRandomAccessList\", ["
63-
+ AUTHORITY_JSON + "]]";
60+
public static final String AUTHORITIES_ARRAYLIST_JSON = "[" + AUTHORITY_JSON + "]";
6461

6562
// @formatter:off
6663
public static final String USER_JSON = "{"
@@ -81,13 +78,10 @@ public class CasAuthenticationTokenMixinTests {
8178
+ "," + "\"authenticated\": true, " + "\"details\": null," + "\"assertion\": {"
8279
+ "\"@class\": \"org.apereo.cas.client.validation.AssertionImpl\", " + "\"principal\": {"
8380
+ "\"@class\": \"org.apereo.cas.client.authentication.AttributePrincipalImpl\", "
84-
+ "\"name\": \"assertName\", " + "\"attributes\": {\"@class\": \"java.util.Collections$EmptyMap\"}, "
85-
+ "\"proxyGrantingTicket\": null, " + "\"proxyRetriever\": null" + "}, "
86-
+ "\"validFromDate\": [\"java.util.Date\", " + START_DATE.getTime() + "], "
87-
+ "\"validUntilDate\": [\"java.util.Date\", " + END_DATE.getTime() + "],"
88-
+ "\"authenticationDate\": [\"java.util.Date\", " + START_DATE.getTime() + "], "
89-
+ "\"attributes\": {\"@class\": \"java.util.Collections$EmptyMap\"},"
90-
+ "\"context\": {\"@class\":\"java.util.HashMap\"}" + "}" + "}";
81+
+ "\"name\": \"assertName\", " + "\"attributes\": {}, " + "\"proxyGrantingTicket\": null, "
82+
+ "\"proxyRetriever\": null" + "}, " + "\"validFromDate\":\"" + START_DATE.toInstant() + "\", "
83+
+ "\"validUntilDate\":\"" + END_DATE.toInstant() + "\"," + "\"authenticationDate\":\""
84+
+ START_DATE.toInstant() + "\", " + "\"attributes\": {}," + "\"context\": {}" + "}" + "}";
9185

9286
private static final String CAS_TOKEN_CLEARED_JSON = CAS_TOKEN_JSON.replaceFirst(PASSWORD, "null");
9387

@@ -96,10 +90,7 @@ public class CasAuthenticationTokenMixinTests {
9690
@BeforeEach
9791
public void setup() {
9892
ClassLoader loader = getClass().getClassLoader();
99-
this.mapper = JsonMapper.builder()
100-
.addModules(SecurityJacksonModules.getModules(loader))
101-
.enable(DateTimeFeature.WRITE_DATES_AS_TIMESTAMPS)
102-
.build();
93+
this.mapper = JsonMapper.builder().addModules(SecurityJacksonModules.getModules(loader)).build();
10394
}
10495

10596
@Test
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/*
2+
* Copyright 2004-present the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.security.jackson;
18+
19+
import java.util.Collection;
20+
21+
import com.fasterxml.jackson.annotation.JsonTypeInfo;
22+
import org.jspecify.annotations.Nullable;
23+
24+
import org.springframework.security.core.GrantedAuthority;
25+
26+
public class AbstractAuthenticationTokenMixin {
27+
28+
@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS)
29+
private final @Nullable Collection<GrantedAuthority> authorities = null;
30+
31+
@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS)
32+
private @Nullable Object details = null;
33+
34+
}

core/src/main/java/org/springframework/security/jackson/AllowlistTypeResolverBuilder.java

Lines changed: 0 additions & 163 deletions
This file was deleted.

core/src/main/java/org/springframework/security/jackson/AnonymousAuthenticationTokenMixin.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@
4747
* @see CoreJacksonModule
4848
* @see SecurityJacksonModules
4949
*/
50-
@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY)
50+
@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS)
5151
@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY, isGetterVisibility = JsonAutoDetect.Visibility.NONE,
5252
getterVisibility = JsonAutoDetect.Visibility.NONE, creatorVisibility = JsonAutoDetect.Visibility.ANY)
5353
@JsonIgnoreProperties(ignoreUnknown = true)
@@ -63,8 +63,9 @@ class AnonymousAuthenticationTokenMixin {
6363
*/
6464
@JsonCreator
6565
AnonymousAuthenticationTokenMixin(@JsonProperty("keyHash") Integer keyHash,
66-
@JsonProperty("principal") Object principal,
67-
@JsonProperty("authorities") Collection<? extends GrantedAuthority> authorities) {
66+
@JsonProperty("principal") @JsonTypeInfo(use = JsonTypeInfo.Id.CLASS) Object principal,
67+
@JsonProperty("authorities") @JsonTypeInfo(
68+
use = JsonTypeInfo.Id.CLASS) Collection<? extends GrantedAuthority> authorities) {
6869
}
6970

7071
}

core/src/main/java/org/springframework/security/jackson/BadCredentialsExceptionMixin.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141
* @since 7.0
4242
* @see CoreJacksonModule
4343
*/
44-
@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY)
44+
@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS)
4545
@JsonIgnoreProperties(ignoreUnknown = true, value = { "cause", "stackTrace", "authenticationRequest" })
4646
class BadCredentialsExceptionMixin {
4747

0 commit comments

Comments
 (0)