From 71a7bf3fbc7b4336ff131513f0686dd43992ef55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jer=C3=B4me=20Bakker?= Date: Thu, 6 Oct 2022 15:46:03 +0200 Subject: [PATCH] security(request): validate the request HOST header This will prevent malicious requests from tricking users into clicking on wrongly generated links. --- engine/classes/Elgg/Http/Request.php | 50 ++++++++++++++++++++++++---- languages/en.php | 1 + 2 files changed, 44 insertions(+), 7 deletions(-) diff --git a/engine/classes/Elgg/Http/Request.php b/engine/classes/Elgg/Http/Request.php index 39851dfd6c3..bf5ba28ba2f 100644 --- a/engine/classes/Elgg/Http/Request.php +++ b/engine/classes/Elgg/Http/Request.php @@ -432,7 +432,41 @@ public function getFile($input_name, $check_for_validity = true) { * @throws HttpException */ public function validate() { + $this->validateRequestHostHeader(); + $this->validateRequestBodyTruncated(); + } + + /** + * Validate that the request was made on the correct host + * + * This will prevent malicious requests from being processed + * + * @return void + * @throws BadRequestException + * @since 3.3.25 + */ + protected function validateRequestHostHeader() { + $config = _elgg_services()->config; + if (empty($config->wwwroot)) { + return; + } + + $config_host = parse_url($config->wwwroot, PHP_URL_HOST); + if ($config_host === $this->getHost()) { + return; + } + + throw new BadRequestException(elgg_echo('BadRequestException:invalid_host_header')); + } + /** + * Validate that the request body hasn't been truncated (eg. exceeded POST max size) + * + * @return void + * @throws BadRequestException + * @since 3.0 + */ + protected function validateRequestBodyTruncated(): void { $reported_bytes = $this->server->get('CONTENT_LENGTH'); // Requests with multipart content type @@ -460,13 +494,15 @@ public function validate() { return true; }; - if (!$is_valid()) { - $error_msg = elgg_trigger_plugin_hook('action_gatekeeper:upload_exceeded_msg', 'all', [ - 'post_size' => $reported_bytes, - 'visible_errors' => true, - ], elgg_echo('actiongatekeeper:uploadexceeded')); - - throw new BadRequestException($error_msg); + if ($is_valid()) { + return; } + + $error_msg = elgg_trigger_plugin_hook('action_gatekeeper:upload_exceeded_msg', 'all', [ + 'post_size' => $reported_bytes, + 'visible_errors' => true, + ], elgg_echo('actiongatekeeper:uploadexceeded')); + + throw new BadRequestException($error_msg); } } diff --git a/languages/en.php b/languages/en.php index d75a7c8d65b..e199d6868d7 100644 --- a/languages/en.php +++ b/languages/en.php @@ -129,6 +129,7 @@ 'EntityPermissionsException' => 'You do not have sufficient permissions for this action.', 'GatekeeperException' => 'You do not have permissions to view the page you are trying to access', 'BadRequestException' => 'Bad request', + 'BadRequestException:invalid_host_header' => 'The request contains an invalid HOST header', 'ValidationException' => 'Submitted data did not meet the requirements, please check your input.', 'LogicException:InterfaceNotImplemented' => '%s must implement %s',