diff --git a/projects/packages/waf/changelog/fix-waf-request-body-problem b/projects/packages/waf/changelog/fix-waf-request-body-problem new file mode 100644 index 0000000000000..fa5384f4ccf25 --- /dev/null +++ b/projects/packages/waf/changelog/fix-waf-request-body-problem @@ -0,0 +1,4 @@ +Significance: patch +Type: security + +Parse request body when method used is not POST diff --git a/projects/packages/waf/src/class-waf-request.php b/projects/packages/waf/src/class-waf-request.php index 61be3d6dbb028..32ac5eb3923a3 100644 --- a/projects/packages/waf/src/class-waf-request.php +++ b/projects/packages/waf/src/class-waf-request.php @@ -334,13 +334,18 @@ public function get_get_vars() { * @return array{string, scalar}[] */ public function get_post_vars() { - // Attempt to decode JSON requests. - if ( strpos( $this->get_header( 'content-type' ), 'application/json' ) !== false ) { + if ( ! empty( $_POST ) ) { + return flatten_array( $_POST ); + } elseif ( strpos( $this->get_header( 'content-type' ), 'application/json' ) !== false ) { + // Attempt to decode JSON requests. $decoded_json = json_decode( $this->get_body(), true ) ?? array(); return flatten_array( $decoded_json, 'json', true ); + } else { + // Attempt to retrieve all parameters when method used isn't POST + $body = $this->get_body(); + parse_str( $body, $params ); + return flatten_array( $params ); } - - return flatten_array( $_POST ); } /** diff --git a/projects/packages/waf/tests/php/unit/test-waf-request.php b/projects/packages/waf/tests/php/unit/test-waf-request.php index 523ab75420c0a..f7ccf4388ebd7 100644 --- a/projects/packages/waf/tests/php/unit/test-waf-request.php +++ b/projects/packages/waf/tests/php/unit/test-waf-request.php @@ -297,6 +297,8 @@ public function testGetVarsPost() { $this->assertContains( array( 'test_var', 'test_value' ), $value ); $this->assertContains( array( 'test_2[child]', 'value' ), $value ); $this->assertContains( array( 'test_num[0]', 'value1' ), $value ); + + $_POST = array(); } /** @@ -327,6 +329,35 @@ public function testGetVarsPostWithJson() { unset( $_SERVER['CONTENT_TYPE'] ); } + /** + * Test that the Waf_Request class returns any parameters when HTTP method isn't POST. + */ + public function testGetVarsPostHttpMethodNotPost() { + $_SERVER['CONTENT_TYPE'] = 'application/x-www-form-urlencoded'; + $request = $this->mock_request( + array( + 'body' => ( + http_build_query( + array( + 'str' => 'value', + 'arr' => array( 'a', 'b', 'c' ), + 'obj' => (object) array( 'foo' => 'bar' ), + ) + ) + ), + ) + ); + $value = $request->get_post_vars(); + $this->assertIsArray( $value ); + $this->assertContains( array( 'str', 'value' ), $value ); + $this->assertContains( array( 'arr[0]', 'a' ), $value ); + $this->assertContains( array( 'arr[1]', 'b' ), $value ); + $this->assertContains( array( 'arr[2]', 'c' ), $value ); + $this->assertContains( array( 'obj[foo]', 'bar' ), $value ); + + unset( $_SERVER['CONTENT_TYPE'] ); + } + /** * Test that the Waf_Request class transforms and returns $_FILES data correctly via Waf_Request::get_files(). */