Skip to content

Commit 1fd11b6

Browse files
rstoyanchevcesarhernandezgt
authored andcommitted
Make use of PatternMatchUtils ignoreCase option
Closes spring-projectsgh-34801
1 parent b5a660e commit 1fd11b6

File tree

1 file changed

+39
-25
lines changed

1 file changed

+39
-25
lines changed

spring-context/src/main/java/org/springframework/validation/DataBinder.java

Lines changed: 39 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2018 the original author or authors.
2+
* Copyright 2002-2022 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -23,7 +23,6 @@
2323
import java.util.Collections;
2424
import java.util.HashMap;
2525
import java.util.List;
26-
import java.util.Locale;
2726
import java.util.Map;
2827
import java.util.Optional;
2928

@@ -53,18 +52,20 @@
5352
import org.springframework.util.StringUtils;
5453

5554
/**
56-
* Binder that allows for setting property values onto a target object,
57-
* including support for validation and binding result analysis.
58-
* The binding process can be customized through specifying allowed fields,
55+
* Binder that allows for setting property values on a target object, including
56+
* support for validation and binding result analysis.
57+
*
58+
* <p>The binding process can be customized by specifying allowed field patterns,
5959
* required fields, custom editors, etc.
6060
*
61-
* <p>Note that there are potential security implications in failing to set an array
62-
* of allowed fields. In the case of HTTP form POST data for example, malicious clients
63-
* can attempt to subvert an application by supplying values for fields or properties
64-
* that do not exist on the form. In some cases this could lead to illegal data being
65-
* set on command objects <i>or their nested objects</i>. For this reason, it is
66-
* <b>highly recommended to specify the {@link #setAllowedFields allowedFields} property</b>
67-
* on the DataBinder.
61+
* <p><strong>WARNING</strong>: Data binding can lead to security issues by exposing
62+
* parts of the object graph that are not meant to be accessed or modified by
63+
* external clients. Therefore, the design and use of data binding should be considered
64+
* carefully with regard to security. For more details, please refer to the dedicated
65+
* sections on data binding for
66+
* <a href="https://docs.spring.io/spring-framework/docs/current/reference/html/web.html#mvc-ann-initbinder-model-design">Spring Web MVC</a> and
67+
* <a href="https://docs.spring.io/spring-framework/docs/current/reference/html/web-reactive.html#webflux-ann-initbinder-model-design">Spring WebFlux</a>
68+
* in the reference manual.
6869
*
6970
* <p>The binding results can be examined via the {@link BindingResult} interface,
7071
* extending the {@link Errors} interface: see the {@link #getBindingResult()} method.
@@ -174,7 +175,7 @@ public class DataBinder implements PropertyEditorRegistry, TypeConverter {
174175
* if the binder is just used to convert a plain parameter value)
175176
* @see #DEFAULT_OBJECT_NAME
176177
*/
177-
public DataBinder(Object target) {
178+
public DataBinder(Object target) {
178179
this(target, DEFAULT_OBJECT_NAME);
179180
}
180181

@@ -292,7 +293,7 @@ protected AbstractPropertyBindingResult createBeanPropertyBindingResult() {
292293
public void initDirectFieldAccess() {
293294
Assert.state(this.bindingResult == null,
294295
"DataBinder is already initialized - call initDirectFieldAccess before other configuration methods");
295-
this.bindingResult = createDirectFieldBindingResult();
296+
this.directFieldAccess = true;
296297
}
297298

298299
/**
@@ -427,13 +428,21 @@ public boolean isIgnoreInvalidFields() {
427428
}
428429

429430
/**
430-
* Register fields that should be allowed for binding. Default is all
431-
* fields. Restrict this for example to avoid unwanted modifications
432-
* by malicious users when binding HTTP request parameters.
433-
* <p>Supports "xxx*", "*xxx" and "*xxx*" patterns. More sophisticated matching
434-
* can be implemented by overriding the {@code isAllowed} method.
435-
* <p>Alternatively, specify a list of <i>disallowed</i> fields.
436-
* @param allowedFields array of field names
431+
* Register field patterns that should be allowed for binding.
432+
* <p>Default is all fields.
433+
* <p>Restrict this for example to avoid unwanted modifications by malicious
434+
* users when binding HTTP request parameters.
435+
* <p>Supports {@code "xxx*"}, {@code "*xxx"}, {@code "*xxx*"}, and
436+
* {@code "xxx*yyy"} matches (with an arbitrary number of pattern parts), as
437+
* well as direct equality.
438+
* <p>The default implementation of this method stores allowed field patterns
439+
* in {@linkplain PropertyAccessorUtils#canonicalPropertyName(String) canonical}
440+
* form. Subclasses which override this method must therefore take this into
441+
* account.
442+
* <p>More sophisticated matching can be implemented by overriding the
443+
* {@link #isAllowed} method.
444+
* <p>Alternatively, specify a list of <i>disallowed</i> field patterns.
445+
* @param allowedFields array of allowed field patterns
437446
* @see #setDisallowedFields
438447
* @see #isAllowed(String)
439448
* @see org.springframework.web.bind.ServletRequestDataBinder
@@ -479,8 +488,7 @@ public void setDisallowedFields(String... disallowedFields) {
479488
else {
480489
String[] fieldPatterns = new String[disallowedFields.length];
481490
for (int i = 0; i < fieldPatterns.length; i++) {
482-
String field = PropertyAccessorUtils.canonicalPropertyName(disallowedFields[i]);
483-
fieldPatterns[i] = field.toLowerCase(Locale.ROOT);
491+
fieldPatterns[i] = PropertyAccessorUtils.canonicalPropertyName(disallowedFields[i]);
484492
}
485493
this.disallowedFields = fieldPatterns;
486494
}
@@ -577,6 +585,7 @@ public void setValidator(Validator validator) {
577585
this.validators.clear();
578586
this.validators.add(validator);
579587
}
588+
}
580589

581590
private void assertValidators(Validator... validators) {
582591
Assert.notNull(validators, "Validators required");
@@ -813,8 +822,13 @@ protected void checkAllowedFields(MutablePropertyValues mpvs) {
813822
protected boolean isAllowed(String field) {
814823
String[] allowed = getAllowedFields();
815824
String[] disallowed = getDisallowedFields();
816-
return ((ObjectUtils.isEmpty(allowed) || PatternMatchUtils.simpleMatch(allowed, field)) &&
817-
(ObjectUtils.isEmpty(disallowed) || !PatternMatchUtils.simpleMatch(disallowed, field.toLowerCase(Locale.ROOT))));
825+
if (!ObjectUtils.isEmpty(allowed) && !PatternMatchUtils.simpleMatch(allowed, field)) {
826+
return false;
827+
}
828+
if (!ObjectUtils.isEmpty(disallowed)) {
829+
return !PatternMatchUtils.simpleMatchIgnoreCase(disallowed, field);
830+
}
831+
return true;
818832
}
819833

820834
/**

0 commit comments

Comments
 (0)