diff options
author | Daimona Eaytoy <daimona.wiki@gmail.com> | 2022-06-29 01:38:15 +0200 |
---|---|---|
committer | Ollie Shotton <oliver.shotton@wikimedia.de> | 2022-06-29 11:12:56 +0100 |
commit | 6d75779017f2cd2b879b7241d7680c84bfaff6b8 (patch) | |
tree | 6a5055f9ea634cf058aa6b7a134fd0010f7424c3 /includes | |
parent | 7f3de1a582acd6bfa80ac0b7ce90f84efda31520 (diff) | |
download | mediawikicore-6d75779017f2cd2b879b7241d7680c84bfaff6b8.tar.gz mediawikicore-6d75779017f2cd2b879b7241d7680c84bfaff6b8.zip |
Rest: ensure there are no extraneous params in JSON bodies
This patch adds another validation layer to JsonBodyValidator, i.e. that
all parameters in the request body are known to the handler. This is
especially useful for optional parameter if the client uses the wrong
name, since otherwise it may be difficult for them to realize what's
wrong.
Bug: T305973
Depends-On: I7efe73d21f1751552614b4c3e2351010693b23bf
Change-Id: I854046efe15dba3b00eae4323f7bb591e145b6b9
Diffstat (limited to 'includes')
-rw-r--r-- | includes/Rest/Validator/JsonBodyValidator.php | 13 | ||||
-rw-r--r-- | includes/Rest/i18n/en.json | 1 | ||||
-rw-r--r-- | includes/Rest/i18n/qqq.json | 1 |
3 files changed, 15 insertions, 0 deletions
diff --git a/includes/Rest/Validator/JsonBodyValidator.php b/includes/Rest/Validator/JsonBodyValidator.php index bcbaa4980f29..299d27522158 100644 --- a/includes/Rest/Validator/JsonBodyValidator.php +++ b/includes/Rest/Validator/JsonBodyValidator.php @@ -5,6 +5,8 @@ namespace MediaWiki\Rest\Validator; use FormatJson; use MediaWiki\Rest\LocalizedHttpException; use MediaWiki\Rest\RequestInterface; +use Wikimedia\Message\ListParam; +use Wikimedia\Message\ListType; use Wikimedia\Message\MessageValue; use Wikimedia\ParamValidator\ParamValidator; @@ -42,6 +44,7 @@ class JsonBodyValidator implements BodyValidator { throw new LocalizedHttpException( new MessageValue( 'rest-bad-json-body' ), 400 ); } + $uncheckedBodyKeys = array_fill_keys( array_keys( $data ), true ); foreach ( $this->bodyParamSettings as $name => $settings ) { if ( !empty( $settings[ParamValidator::PARAM_REQUIRED] ) && !isset( $data[$name] ) ) { throw new LocalizedHttpException( @@ -53,8 +56,18 @@ class JsonBodyValidator implements BodyValidator { $data[$name] = $settings[ParamValidator::PARAM_DEFAULT] ?? null; } + unset( $uncheckedBodyKeys[$name] ); // TODO: use a ParamValidator to check field value, etc! } + if ( $uncheckedBodyKeys ) { + throw new LocalizedHttpException( + new MessageValue( + 'rest-extraneous-body-fields', + [ new ListParam( ListType::COMMA, array_keys( $uncheckedBodyKeys ) ) ] + ), + 400 + ); + } return $data; } diff --git a/includes/Rest/i18n/en.json b/includes/Rest/i18n/en.json index ba021a748dc2..dd90c14fdc1f 100644 --- a/includes/Rest/i18n/en.json +++ b/includes/Rest/i18n/en.json @@ -37,6 +37,7 @@ "rest-bad-json-body": "Bad request body, must be a JSON object.", "rest-json-body-parse-error": "Parsing request body as JSON failed: $1", "rest-missing-body-field": "Mandatory field \"$1\" missing from request body.", + "rest-extraneous-body-fields": "Extraneous fields found in request body: $1", "rest-bad-content-model": "Bad content model: $1", "rest-update-cannot-create-page": "The page \"$1\" cannot be created since it already exists. To update the existing page, provide the base revision ID in the structure under \"latest\" key in the request body.", "rest-extraneous-csrf-token": "Extraneous CSRF token found. CSRF tokens must not be used when using authentication mechanisms such as OAuth that are safe against CSRF attacks.", diff --git a/includes/Rest/i18n/qqq.json b/includes/Rest/i18n/qqq.json index c17ff60f3275..9cede1e1f987 100644 --- a/includes/Rest/i18n/qqq.json +++ b/includes/Rest/i18n/qqq.json @@ -41,6 +41,7 @@ "rest-bad-json-body": "Error message for REST API debugging, shown when request body did not contain a JSON encoded object.", "rest-json-body-parse-error": "Error message for REST API debugging, shown when parsing the JSON body failed. Parameters:\n* $1: the error message from the JSON parser.", "rest-missing-body-field": "Error message for REST API debugging, shown when there is a mandatory field missing from the request body. Parameters:\n* $1: The field name", + "rest-extraneous-body-fields": "Error message for REST API debugging, shown when there are extraneous fields in the request body. Parameters:\n* $1: A comma-separated list of unrecognized fields", "rest-bad-content-model": "Error message for REST API debugging, shown when an unknown content model is specified. Parameters:\n* $1: The content model name", "rest-update-cannot-create-page": "Error message for REST API debugging, shown when creation of a page was requested via a PUT with no base revision ID, but the page already exists. Parameters:\n* $1: The title of the page", "rest-extraneous-csrf-token": "Error message for REST API debugging, shown when an CSRF token was provided by the client, even though the authentication mechanisms used is safe against CSRF attacks.", |