From a93adbaae4d2c8145dbb757b56e7969257f54c58 Mon Sep 17 00:00:00 2001 From: dkmyta Date: Tue, 30 Jul 2024 10:16:16 -0700 Subject: [PATCH 1/6] Parse request body when method used is not POST --- projects/packages/waf/src/class-waf-request.php | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/projects/packages/waf/src/class-waf-request.php b/projects/packages/waf/src/class-waf-request.php index 61be3d6dbb028..0a2776cf3f892 100644 --- a/projects/packages/waf/src/class-waf-request.php +++ b/projects/packages/waf/src/class-waf-request.php @@ -334,12 +334,21 @@ public function get_get_vars() { * @return array{string, scalar}[] */ public function get_post_vars() { + $content_type = $this->get_header( 'content-type' ); + // Attempt to decode JSON requests. - if ( strpos( $this->get_header( 'content-type' ), 'application/json' ) !== false ) { + if ( strpos( $content_type, 'application/json' ) !== false ) { $decoded_json = json_decode( $this->get_body(), true ) ?? array(); return flatten_array( $decoded_json, 'json', true ); } + // Attempt to retrieve all parameters when method used isn't POST + if ( strpos( $content_type, 'application/x-www-form-urlencoded' ) !== false ) { + $body = $this->get_body(); + parse_str( $body, $params ); + return flatten_array( array_merge( $_POST, $params ) ); + } + return flatten_array( $_POST ); } From 1688453d0a9104e6bf05dbf56addf68915e59f39 Mon Sep 17 00:00:00 2001 From: dkmyta Date: Tue, 30 Jul 2024 10:17:48 -0700 Subject: [PATCH 2/6] changelog --- projects/packages/waf/changelog/fix-waf-request-body-problem | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 projects/packages/waf/changelog/fix-waf-request-body-problem 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 From 93b327b54a98e0b45d229b6be1f892bb4884c1e3 Mon Sep 17 00:00:00 2001 From: dkmyta Date: Tue, 30 Jul 2024 10:20:31 -0700 Subject: [PATCH 3/6] Simplify --- projects/packages/waf/src/class-waf-request.php | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/projects/packages/waf/src/class-waf-request.php b/projects/packages/waf/src/class-waf-request.php index 0a2776cf3f892..4f5fefa6168d6 100644 --- a/projects/packages/waf/src/class-waf-request.php +++ b/projects/packages/waf/src/class-waf-request.php @@ -334,22 +334,18 @@ public function get_get_vars() { * @return array{string, scalar}[] */ public function get_post_vars() { - $content_type = $this->get_header( 'content-type' ); - - // Attempt to decode JSON requests. - if ( strpos( $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 ); - } - - // Attempt to retrieve all parameters when method used isn't POST - if ( strpos( $content_type, 'application/x-www-form-urlencoded' ) !== false ) { + } else { + // Attempt to retrieve all parameters when method used isn't POST $body = $this->get_body(); parse_str( $body, $params ); return flatten_array( array_merge( $_POST, $params ) ); } - - return flatten_array( $_POST ); } /** From 64cbec332abd1559aa69ef72f1a22cc323b5f6a7 Mon Sep 17 00:00:00 2001 From: dkmyta Date: Tue, 30 Jul 2024 13:03:20 -0700 Subject: [PATCH 4/6] Fix tests --- .../packages/waf/src/class-waf-request.php | 2 +- .../waf/tests/php/unit/test-waf-request.php | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/projects/packages/waf/src/class-waf-request.php b/projects/packages/waf/src/class-waf-request.php index 4f5fefa6168d6..32ac5eb3923a3 100644 --- a/projects/packages/waf/src/class-waf-request.php +++ b/projects/packages/waf/src/class-waf-request.php @@ -344,7 +344,7 @@ public function get_post_vars() { // Attempt to retrieve all parameters when method used isn't POST $body = $this->get_body(); parse_str( $body, $params ); - return flatten_array( array_merge( $_POST, $params ) ); + return flatten_array( $params ); } } 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..2834c9eeb3d0f 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,23 @@ 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' => 'value', + ) + ); + $value = $request->get_post_vars(); + $this->assertIsArray( $value ); + $this->assertContains( array( 'value', '' ), $value ); + + unset( $_SERVER['CONTENT_TYPE'] ); + } + /** * Test that the Waf_Request class transforms and returns $_FILES data correctly via Waf_Request::get_files(). */ From 993bfe0e624a68bd7057d06b9e7df6db647b4f90 Mon Sep 17 00:00:00 2001 From: dkmyta <43220201+dkmyta@users.noreply.github.com> Date: Tue, 6 Aug 2024 08:55:34 -0700 Subject: [PATCH 5/6] Update projects/packages/waf/tests/php/unit/test-waf-request.php Co-authored-by: Nate Weller --- .../waf/tests/php/unit/test-waf-request.php | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) 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 2834c9eeb3d0f..4d9d93469ab3c 100644 --- a/projects/packages/waf/tests/php/unit/test-waf-request.php +++ b/projects/packages/waf/tests/php/unit/test-waf-request.php @@ -336,12 +336,22 @@ public function testGetVarsPostHttpMethodNotPost() { $_SERVER['CONTENT_TYPE'] = 'application/x-www-form-urlencoded'; $request = $this->mock_request( array( - 'body' => 'value', + '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( 'value', '' ), $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'] ); } From 02a7f462eb22560be43f72f5450b0987b218eb05 Mon Sep 17 00:00:00 2001 From: Nate Weller Date: Tue, 6 Aug 2024 10:49:10 -0600 Subject: [PATCH 6/6] Fix phpcs issues --- .../waf/tests/php/unit/test-waf-request.php | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) 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 4d9d93469ab3c..f7ccf4388ebd7 100644 --- a/projects/packages/waf/tests/php/unit/test-waf-request.php +++ b/projects/packages/waf/tests/php/unit/test-waf-request.php @@ -337,12 +337,14 @@ public function testGetVarsPostHttpMethodNotPost() { $request = $this->mock_request( array( 'body' => ( - http_build_query( array( - 'str' => 'value', - 'arr' => array( 'a', 'b', 'c' ), - 'obj' => (object) array( 'foo' => 'bar' ), - ) ) - ) + http_build_query( + array( + 'str' => 'value', + 'arr' => array( 'a', 'b', 'c' ), + 'obj' => (object) array( 'foo' => 'bar' ), + ) + ) + ), ) ); $value = $request->get_post_vars();