From c56a2fb18c177975cffb9ca3d2c41cc4c8de1732 Mon Sep 17 00:00:00 2001 From: Nilambar Sharma Date: Fri, 29 Dec 2023 12:30:02 +0545 Subject: [PATCH 1/2] Update Code Obfuscation Check to display multiple errors --- .../Checker/Checks/Abstract_File_Check.php | 46 +++++++++++ .../Checker/Checks/Code_Obfuscation_Check.php | 78 ++++++++++--------- 2 files changed, 88 insertions(+), 36 deletions(-) diff --git a/includes/Checker/Checks/Abstract_File_Check.php b/includes/Checker/Checks/Abstract_File_Check.php index 157afdc98..72fbc0752 100644 --- a/includes/Checker/Checks/Abstract_File_Check.php +++ b/includes/Checker/Checks/Abstract_File_Check.php @@ -141,6 +141,30 @@ final protected static function file_preg_match( $pattern, array $files, array & return false; } + /** + * Returns matched files performing a regular expression match on the file contents of the given list of files. + * + * @since n.e.x.t + * + * @param string $pattern The pattern to search for. + * @param array $files List of absolute file paths. + * @return array|bool Array of file paths and matched string/pattern if matches were found, false otherwise. + */ + final protected static function files_preg_match( $pattern, array $files ) { + $matched_files = array(); + + foreach ( $files as $file ) { + $matches = array(); + + $matched_file_name = self::file_preg_match( $pattern, array( $file ), $matches ); + + if ( false !== $matched_file_name ) { + $matched_files[] = array( $matched_file_name, $matches[0] ); + } + } + return count( $matched_files ) > 0 ? $matched_files : false; + } + /** * Performs a check indicating if the needle is contained in the file contents of the given list of files. * @@ -163,6 +187,28 @@ final protected static function file_str_contains( array $files, $needle ) { return false; } + /** + * Returns matched files performing a check indicating if the needle is contained in the file contents of the given list of files. + * + * @since n.e.x.t + * + * @param array $files List of absolute file paths. + * @param string $needle The substring to search for. + * @return array|bool Array of file path and matched string if needle was found, false otherwise. + */ + final protected static function files_str_contains( array $files, $needle ) { + $matched_files = array(); + + foreach ( $files as $file ) { + $matched_file_name = self::file_str_contains( array( $file ), $needle ); + + if ( false !== $matched_file_name ) { + $matched_files[] = array( $matched_file_name, $needle ); + } + } + return count( $matched_files ) > 0 ? $matched_files : false; + } + /** * Gets the contents of the given file. * diff --git a/includes/Checker/Checks/Code_Obfuscation_Check.php b/includes/Checker/Checks/Code_Obfuscation_Check.php index cfa540d7e..1679cb7da 100644 --- a/includes/Checker/Checks/Code_Obfuscation_Check.php +++ b/includes/Checker/Checks/Code_Obfuscation_Check.php @@ -94,18 +94,20 @@ protected function check_files( Check_Result $result, array $files ) { * @param array $php_files List of absolute PHP file paths. */ protected function look_for_zendguard( Check_Result $result, array $php_files ) { - $obfuscated_file = self::file_preg_match( '/(<\?php \@Zend;)|(This file was encoded by)/', $php_files ); - if ( $obfuscated_file ) { - $this->add_result_error_for_file( - $result, - sprintf( - /* translators: %s: tool name */ - __( 'Code Obfuscation tools are not permitted. Detected: %s', 'plugin-check' ), - __( 'Zend Guard', 'plugin-check' ) - ), - 'obfuscated_code_detected', - $obfuscated_file - ); + $obfuscated_files = self::files_preg_match( '/(<\?php \@Zend;)|(This file was encoded by)/', $php_files ); + if ( $obfuscated_files ) { + foreach ( $obfuscated_files as $obfuscated_file ) { + $this->add_result_error_for_file( + $result, + sprintf( + /* translators: %s: tool name */ + __( 'Code Obfuscation tools are not permitted. Detected: %s', 'plugin-check' ), + __( 'Zend Guard', 'plugin-check' ) + ), + 'obfuscated_code_detected', + $obfuscated_file[0] + ); + } } } @@ -118,18 +120,20 @@ protected function look_for_zendguard( Check_Result $result, array $php_files ) * @param array $php_files List of absolute PHP file paths. */ protected function look_for_sourceguardian( Check_Result $result, array $php_files ) { - $obfuscated_file = self::file_preg_match( "/(sourceguardian\.com)|(function_exists\('sg_load'\))|(\$__x=)/", $php_files ); - if ( $obfuscated_file ) { - $this->add_result_error_for_file( - $result, - sprintf( - /* translators: %s: tool name */ - __( 'Code Obfuscation tools are not permitted. Detected: %s', 'plugin-check' ), - __( 'Source Guardian', 'plugin-check' ) - ), - 'obfuscated_code_detected', - $obfuscated_file - ); + $obfuscated_files = self::files_preg_match( "/(sourceguardian\.com)|(function_exists\('sg_load'\))|(\$__x=)/", $php_files ); + if ( $obfuscated_files ) { + foreach ( $obfuscated_files as $obfuscated_file ) { + $this->add_result_error_for_file( + $result, + sprintf( + /* translators: %s: tool name */ + __( 'Code Obfuscation tools are not permitted. Detected: %s', 'plugin-check' ), + __( 'Source Guardian', 'plugin-check' ) + ), + 'obfuscated_code_detected', + $obfuscated_file[0] + ); + } } } @@ -142,18 +146,20 @@ protected function look_for_sourceguardian( Check_Result $result, array $php_fil * @param array $php_files List of absolute PHP file paths. */ protected function look_for_ioncube( Check_Result $result, array $php_files ) { - $obfuscated_file = self::file_str_contains( $php_files, 'ionCube' ); - if ( $obfuscated_file ) { - $this->add_result_error_for_file( - $result, - sprintf( - /* translators: %s: tool name */ - __( 'Code Obfuscation tools are not permitted. Detected: %s', 'plugin-check' ), - __( 'ionCube', 'plugin-check' ) - ), - 'obfuscated_code_detected', - $obfuscated_file - ); + $obfuscated_files = self::files_str_contains( $php_files, 'ionCube' ); + if ( $obfuscated_files ) { + foreach ( $obfuscated_files as $obfuscated_file ) { + $this->add_result_error_for_file( + $result, + sprintf( + /* translators: %s: tool name */ + __( 'Code Obfuscation tools are not permitted. Detected: %s', 'plugin-check' ), + __( 'ionCube', 'plugin-check' ) + ), + 'obfuscated_code_detected', + $obfuscated_file[0] + ); + } } } } From bd5b13c33fbccdb65c167398d9fe58d09dc4a54b Mon Sep 17 00:00:00 2001 From: Nilambar Sharma Date: Fri, 29 Dec 2023 15:04:38 +0545 Subject: [PATCH 2/2] Update tests for Code Obfuscation --- .../load.php | 17 ++++++++ .../obfuscated.php | 1 + .../load.php | 19 +++++++++ .../obfuscated.php | 4 ++ .../obfuscated2.php | 2 + .../load.php | 24 +++++++++++ .../obfuscated.php | 3 ++ .../obfuscated2.php | 2 + .../Checks/Code_Obfuscation_Check_Tests.php | 42 +++++++++++++++++++ 9 files changed, 114 insertions(+) create mode 100644 tests/phpunit/testdata/plugins/test-plugin-code-obfuscation-ioncube-multiple-errors/load.php create mode 100644 tests/phpunit/testdata/plugins/test-plugin-code-obfuscation-ioncube-multiple-errors/obfuscated.php create mode 100644 tests/phpunit/testdata/plugins/test-plugin-code-obfuscation-sourceguardian-multiple-errors/load.php create mode 100644 tests/phpunit/testdata/plugins/test-plugin-code-obfuscation-sourceguardian-multiple-errors/obfuscated.php create mode 100644 tests/phpunit/testdata/plugins/test-plugin-code-obfuscation-sourceguardian-multiple-errors/obfuscated2.php create mode 100644 tests/phpunit/testdata/plugins/test-plugin-code-obfuscation-zendguard-multiple-errors/load.php create mode 100644 tests/phpunit/testdata/plugins/test-plugin-code-obfuscation-zendguard-multiple-errors/obfuscated.php create mode 100644 tests/phpunit/testdata/plugins/test-plugin-code-obfuscation-zendguard-multiple-errors/obfuscated2.php diff --git a/tests/phpunit/testdata/plugins/test-plugin-code-obfuscation-ioncube-multiple-errors/load.php b/tests/phpunit/testdata/plugins/test-plugin-code-obfuscation-ioncube-multiple-errors/load.php new file mode 100644 index 000000000..3d2f06a7a --- /dev/null +++ b/tests/phpunit/testdata/plugins/test-plugin-code-obfuscation-ioncube-multiple-errors/load.php @@ -0,0 +1,17 @@ +assertSame( 'obfuscated_code_detected', $errors[ $expected_file ][0][0][0]['code'] ); } + /** + * @dataProvider data_obfuscation_services_multiple_files + */ + public function test_run_with_obfuscation_multiple_errors( $type_flag, $plugin_basename, $expected_files ) { + $check_context = new Check_Context( UNIT_TESTS_PLUGIN_DIR . $plugin_basename ); + $check_result = new Check_Result( $check_context ); + + $check = new Code_Obfuscation_Check( $type_flag ); + $check->run( $check_result ); + + $errors = $check_result->get_errors(); + + $this->assertNotEmpty( $errors ); + $this->assertSame( sort( $expected_files ), sort( array_keys( $errors ) ) ); + $this->assertSame( 2, $check_result->get_error_count() ); + + $this->assertTrue( isset( $errors[ $expected_files[0] ][0][0][0] ) ); + $this->assertSame( 'obfuscated_code_detected', $errors[ $expected_files[0] ][0][0][0]['code'] ); + $this->assertTrue( isset( $errors[ $expected_files[1] ][0][0][0] ) ); + $this->assertSame( 'obfuscated_code_detected', $errors[ $expected_files[1] ][0][0][0]['code'] ); + } + public function data_obfuscation_services() { return array( 'Zend Guard' => array( @@ -52,6 +74,26 @@ public function data_obfuscation_services() { ); } + public function data_obfuscation_services_multiple_files() { + return array( + 'Zend Guard Multiple' => array( + Code_Obfuscation_Check::TYPE_ZEND, + 'test-plugin-code-obfuscation-zendguard-multiple-errors/load.php', + array( 'obfuscated.php', 'obfuscated2.php' ), + ), + 'Source Guardian Multiple' => array( + Code_Obfuscation_Check::TYPE_SOURCEGUARDIAN, + 'test-plugin-code-obfuscation-sourceguardian-multiple-errors/load.php', + array( 'obfuscated.php', 'obfuscated2.php' ), + ), + 'ionCube Multiple' => array( + Code_Obfuscation_Check::TYPE_IONCUBE, + 'test-plugin-code-obfuscation-ioncube-multiple-errors/load.php', + array( 'load.php', 'obfuscated.php' ), + ), + ); + } + public function test_run_without_any_obfuscation_errors() { // Test plugin without any obfuscation. $check_context = new Check_Context( UNIT_TESTS_PLUGIN_DIR . 'test-plugin-i18n-usage-without-errors/load.php' );