11/*
2- * Copyright 2002-2021 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.
5151import org .springframework .util .StringUtils ;
5252
5353/**
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,
5758 * required fields, custom editors, etc.
5859 *
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.
6668 *
6769 * <p>The binding results can be examined via the {@link BindingResult} interface,
6870 * extending the {@link Errors} interface: see the {@link #getBindingResult()} method.
9698 * @author Rob Harrop
9799 * @author Stephane Nicoll
98100 * @author Kazuki Shimizu
101+ * @author Sam Brannen
99102 * @see #setAllowedFields
100103 * @see #setRequiredFields
101104 * @see #registerCustomEditor
@@ -418,15 +421,21 @@ public boolean isIgnoreInvalidFields() {
418421 }
419422
420423 /**
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
423427 * 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
430439 * @see #setDisallowedFields
431440 * @see #isAllowed(String)
432441 */
@@ -435,34 +444,54 @@ public void setAllowedFields(@Nullable String... allowedFields) {
435444 }
436445
437446 /**
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...)
440450 */
441451 @ Nullable
442452 public String [] getAllowedFields () {
443453 return this .allowedFields ;
444454 }
445455
446456 /**
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
449460 * 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
456475 * @see #setAllowedFields
457476 * @see #isAllowed(String)
458477 */
459478 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+ }
461489 }
462490
463491 /**
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...)
466495 */
467496 @ Nullable
468497 public String [] getDisallowedFields () {
@@ -774,16 +803,20 @@ protected void checkAllowedFields(MutablePropertyValues mpvs) {
774803 }
775804
776805 /**
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.
785818 * @param field the field to check
786- * @return if the field is allowed
819+ * @return {@code true} if the field is allowed
787820 * @see #setAllowedFields
788821 * @see #setDisallowedFields
789822 * @see org.springframework.util.PatternMatchUtils#simpleMatch(String, String)
@@ -792,7 +825,7 @@ protected boolean isAllowed(String field) {
792825 String [] allowed = getAllowedFields ();
793826 String [] disallowed = getDisallowedFields ();
794827 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 () )));
796829 }
797830
798831 /**
0 commit comments