1
1
/*
2
- * Copyright 2002-2021 the original author or authors.
2
+ * Copyright 2002-2022 the original author or authors.
3
3
*
4
4
* Licensed under the Apache License, Version 2.0 (the "License");
5
5
* you may not use this file except in compliance with the License.
51
51
import org .springframework .util .StringUtils ;
52
52
53
53
/**
54
- * Binder that allows for setting property values onto a target object,
55
- * including support for validation and binding result analysis.
56
- * The binding process can be customized through specifying allowed fields,
54
+ * Binder that allows for setting property values on a target object, including
55
+ * support for validation and binding result analysis.
56
+ *
57
+ * <p>The binding process can be customized by specifying allowed field patterns,
57
58
* required fields, custom editors, etc.
58
59
*
59
- * <p>Note that there are potential security implications in failing to set an array
60
- * of allowed fields. In the case of HTTP form POST data for example, malicious clients
61
- * can attempt to subvert an application by supplying values for fields or properties
62
- * that do not exist on the form. In some cases this could lead to illegal data being
63
- * set on command objects <i>or their nested objects</i>. For this reason, it is
64
- * <b>highly recommended to specify the {@link #setAllowedFields allowedFields} property</b>
65
- * on the DataBinder.
60
+ * <p><strong>WARNING</strong>: Data binding can lead to security issues by exposing
61
+ * parts of the object graph that are not meant to be accessed or modified by
62
+ * external clients. Therefore the design and use of data binding should be considered
63
+ * carefully with regard to security. For more details, please refer to the dedicated
64
+ * sections on data binding for
65
+ * <a href="https://docs.spring.io/spring-framework/docs/current/reference/html/web.html#mvc-ann-initbinder-model-design">Spring Web MVC</a> and
66
+ * <a href="https://docs.spring.io/spring-framework/docs/current/reference/html/web-reactive.html#webflux-ann-initbinder-model-design">Spring WebFlux</a>
67
+ * in the reference manual.
66
68
*
67
69
* <p>The binding results can be examined via the {@link BindingResult} interface,
68
70
* extending the {@link Errors} interface: see the {@link #getBindingResult()} method.
96
98
* @author Rob Harrop
97
99
* @author Stephane Nicoll
98
100
* @author Kazuki Shimizu
101
+ * @author Sam Brannen
99
102
* @see #setAllowedFields
100
103
* @see #setRequiredFields
101
104
* @see #registerCustomEditor
@@ -418,15 +421,21 @@ public boolean isIgnoreInvalidFields() {
418
421
}
419
422
420
423
/**
421
- * Register fields that should be allowed for binding. Default is all fields.
422
- * Restrict this for example to avoid unwanted modifications by malicious
424
+ * Register field patterns that should be allowed for binding.
425
+ * <p>Default is all fields.
426
+ * <p>Restrict this for example to avoid unwanted modifications by malicious
423
427
* users when binding HTTP request parameters.
424
- * <p>Supports "xxx*", "*xxx", "*xxx*" and "xxx*yyy" matches (with an
425
- * arbitrary number of pattern parts), as well as direct equality. More
426
- * sophisticated matching can be implemented by overriding the
427
- * {@code isAllowed} method.
428
- * <p>Alternatively, specify a list of <i>disallowed</i> fields.
429
- * @param allowedFields array of field names
428
+ * <p>Supports {@code "xxx*"}, {@code "*xxx"}, {@code "*xxx*"}, and
429
+ * {@code "xxx*yyy"} matches (with an arbitrary number of pattern parts), as
430
+ * well as direct equality.
431
+ * <p>The default implementation of this method stores allowed field patterns
432
+ * in {@linkplain PropertyAccessorUtils#canonicalPropertyName(String) canonical}
433
+ * form. Subclasses which override this method must therefore take this into
434
+ * account.
435
+ * <p>More sophisticated matching can be implemented by overriding the
436
+ * {@link #isAllowed} method.
437
+ * <p>Alternatively, specify a list of <i>disallowed</i> field patterns.
438
+ * @param allowedFields array of allowed field patterns
430
439
* @see #setDisallowedFields
431
440
* @see #isAllowed(String)
432
441
*/
@@ -435,34 +444,54 @@ public void setAllowedFields(@Nullable String... allowedFields) {
435
444
}
436
445
437
446
/**
438
- * Return the fields that should be allowed for binding.
439
- * @return array of field names
447
+ * Return the field patterns that should be allowed for binding.
448
+ * @return array of allowed field patterns
449
+ * @see #setAllowedFields(String...)
440
450
*/
441
451
@ Nullable
442
452
public String [] getAllowedFields () {
443
453
return this .allowedFields ;
444
454
}
445
455
446
456
/**
447
- * Register fields that should <i>not</i> be allowed for binding. Default
448
- * is none. Mark fields as disallowed for example to avoid unwanted
457
+ * Register field patterns that should <i>not</i> be allowed for binding.
458
+ * <p>Default is none.
459
+ * <p>Mark fields as disallowed, for example to avoid unwanted
449
460
* modifications by malicious users when binding HTTP request parameters.
450
- * <p>Supports "xxx*", "*xxx", "*xxx*" and "xxx*yyy" matches (with an
451
- * arbitrary number of pattern parts), as well as direct equality.
452
- * More sophisticated matching can be implemented by overriding the
453
- * {@code isAllowed} method.
454
- * <p>Alternatively, specify a list of <i>allowed</i> fields.
455
- * @param disallowedFields array of field names
461
+ * <p>Supports {@code "xxx*"}, {@code "*xxx"}, {@code "*xxx*"}, and
462
+ * {@code "xxx*yyy"} matches (with an arbitrary number of pattern parts), as
463
+ * well as direct equality.
464
+ * <p>The default implementation of this method stores disallowed field patterns
465
+ * in {@linkplain PropertyAccessorUtils#canonicalPropertyName(String) canonical}
466
+ * form. As of Spring Framework 5.2.21, the default implementation also transforms
467
+ * disallowed field patterns to {@linkplain String#toLowerCase() lowercase} to
468
+ * support case-insensitive pattern matching in {@link #isAllowed}. Subclasses
469
+ * which override this method must therefore take both of these transformations
470
+ * into account.
471
+ * <p>More sophisticated matching can be implemented by overriding the
472
+ * {@link #isAllowed} method.
473
+ * <p>Alternatively, specify a list of <i>allowed</i> field patterns.
474
+ * @param disallowedFields array of disallowed field patterns
456
475
* @see #setAllowedFields
457
476
* @see #isAllowed(String)
458
477
*/
459
478
public void setDisallowedFields (@ Nullable String ... disallowedFields ) {
460
- this .disallowedFields = PropertyAccessorUtils .canonicalPropertyNames (disallowedFields );
479
+ if (disallowedFields == null ) {
480
+ this .disallowedFields = null ;
481
+ }
482
+ else {
483
+ String [] fieldPatterns = new String [disallowedFields .length ];
484
+ for (int i = 0 ; i < fieldPatterns .length ; i ++) {
485
+ fieldPatterns [i ] = PropertyAccessorUtils .canonicalPropertyName (disallowedFields [i ]).toLowerCase ();
486
+ }
487
+ this .disallowedFields = fieldPatterns ;
488
+ }
461
489
}
462
490
463
491
/**
464
- * Return the fields that should <i>not</i> be allowed for binding.
465
- * @return array of field names
492
+ * Return the field patterns that should <i>not</i> be allowed for binding.
493
+ * @return array of disallowed field patterns
494
+ * @see #setDisallowedFields(String...)
466
495
*/
467
496
@ Nullable
468
497
public String [] getDisallowedFields () {
@@ -774,16 +803,20 @@ protected void checkAllowedFields(MutablePropertyValues mpvs) {
774
803
}
775
804
776
805
/**
777
- * Return if the given field is allowed for binding.
778
- * Invoked for each passed-in property value.
779
- * <p>The default implementation checks for "xxx*", "*xxx", "*xxx*" and "xxx*yyy"
780
- * matches (with an arbitrary number of pattern parts), as well as direct equality,
781
- * in the specified lists of allowed fields and disallowed fields. A field matching
782
- * a disallowed pattern will not be accepted even if it also happens to match a
783
- * pattern in the allowed list.
784
- * <p>Can be overridden in subclasses.
806
+ * Determine if the given field is allowed for binding.
807
+ * <p>Invoked for each passed-in property value.
808
+ * <p>Checks for {@code "xxx*"}, {@code "*xxx"}, {@code "*xxx*"}, and
809
+ * {@code "xxx*yyy"} matches (with an arbitrary number of pattern parts), as
810
+ * well as direct equality, in the configured lists of allowed field patterns
811
+ * and disallowed field patterns.
812
+ * <p>Matching against allowed field patterns is case-sensitive; whereas,
813
+ * matching against disallowed field patterns is case-insensitive.
814
+ * <p>A field matching a disallowed pattern will not be accepted even if it
815
+ * also happens to match a pattern in the allowed list.
816
+ * <p>Can be overridden in subclasses, but care must be taken to honor the
817
+ * aforementioned contract.
785
818
* @param field the field to check
786
- * @return if the field is allowed
819
+ * @return {@code true} if the field is allowed
787
820
* @see #setAllowedFields
788
821
* @see #setDisallowedFields
789
822
* @see org.springframework.util.PatternMatchUtils#simpleMatch(String, String)
@@ -792,7 +825,7 @@ protected boolean isAllowed(String field) {
792
825
String [] allowed = getAllowedFields ();
793
826
String [] disallowed = getDisallowedFields ();
794
827
return ((ObjectUtils .isEmpty (allowed ) || PatternMatchUtils .simpleMatch (allowed , field )) &&
795
- (ObjectUtils .isEmpty (disallowed ) || !PatternMatchUtils .simpleMatch (disallowed , field )));
828
+ (ObjectUtils .isEmpty (disallowed ) || !PatternMatchUtils .simpleMatch (disallowed , field . toLowerCase () )));
796
829
}
797
830
798
831
/**
0 commit comments