From 310bb515e85b0ceec7c0ee648c619b07b50c31a4 Mon Sep 17 00:00:00 2001 From: Derrick Tennant Date: Thu, 26 Mar 2015 11:24:48 -0400 Subject: [PATCH 01/44] VIP Scanner: filter_files() now accepts arrays of file types for more efficient scanning. I made this change so that when searching for XSS vulnerabilities, I wouldn't have to run through two foreach ( $this->filter_files() ) blocks. One for php and one for html. It should make scanning multiple types at once much easier. --- vip-scanner/class-base-check.php | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/vip-scanner/class-base-check.php b/vip-scanner/class-base-check.php index 584aaab..ecc1477 100644 --- a/vip-scanner/class-base-check.php +++ b/vip-scanner/class-base-check.php @@ -55,11 +55,23 @@ protected function get_all_files( $files ) { protected function filter_files( $files, $type = '' ) { $files = (array) $files; - if( $type ) { - if( isset( $files[$type] ) ) - return $files[$type]; - else - return array(); + if ( $type ) { + if ( is_array( $type ) ) { + $file_types = array(); + foreach ( $type as $single_type ) { + if ( isset( $files[ $single_type ] ) ) { + $file_types = array_merge( $file_types, $files[ $single_type ] ); + } + } + return $file_types; + } else { + if ( isset( $files[ $type ] ) ) { + return $files[ $type ]; + } + else { + return array(); + } + } } return $files; } From ef287015537d51e7cf14e62cf46b97ce097dae7a Mon Sep 17 00:00:00 2001 From: Derrick Tennant Date: Thu, 26 Mar 2015 11:29:35 -0400 Subject: [PATCH 02/44] VIP Scanner: Added preliminary support for XSS checks. Includes checks for: javascript in tag href attributes javascript in all HTML tags' style attributes -moz-binding CSS attribute --- tests/checks/test-XSSVectorsCheck.php | 61 +++++++++++++++++ vip-scanner/checks/XSSVectorsCheck.php | 90 ++++++++++++++++++++++++++ 2 files changed, 151 insertions(+) create mode 100644 tests/checks/test-XSSVectorsCheck.php create mode 100644 vip-scanner/checks/XSSVectorsCheck.php diff --git a/tests/checks/test-XSSVectorsCheck.php b/tests/checks/test-XSSVectorsCheck.php new file mode 100644 index 0000000..e334f31 --- /dev/null +++ b/tests/checks/test-XSSVectorsCheck.php @@ -0,0 +1,61 @@ + +EOT; + $error_slugs = $this->runCheck( $file_contents ); + $this->assertContains( 'xss-in-link-tag-href', $error_slugs ); + } + + public function test_obfuscated_xss_in_link_tag_href() { + $file_contents = <<<'EOT' + +EOT; + $error_slugs = $this->runCheck( $file_contents ); + $this->assertContains( 'xss-in-link-tag-href', $error_slugs ); + } + + public function test_xss_not_in_link_tag_href() { + $file_contents = <<<'EOT' + +EOT; + $error_slugs = $this->runCheck( $file_contents ); + $this->assertNotContains( 'xss-in-link-tag-href', $error_slugs ); + } + + public function test_xss_in_tag_style_attr() { + $file_contents = <<<'EOT' +
+EOT; + $error_slugs = $this->runCheck( $file_contents ); + $this->assertContains( 'xss-in-style-attribute', $error_slugs ); + } + + public function test_xss_not_in_tag_style_attr() { + $file_contents = <<<'EOT' +
+EOT; + $error_slugs = $this->runCheck( $file_contents ); + $this->assertNotContains( 'xss-in-style-attribute', $error_slugs ); + } + + public function test_moz_binding_in_tag_style() { + $file_contents = <<<'EOT' + +EOT; + $error_slugs = $this->runCheck( $file_contents ); + $this->assertContains( 'moz-binding-xss-in-style-tag', $error_slugs ); + } + + public function test_moz_binding_not_in_tag_style() { + $file_contents = <<<'EOT' + +EOT; + $error_slugs = $this->runCheck( $file_contents ); + $this->assertNotContains( 'moz-binding-xss-in-style-tag', $error_slugs ); + } + +} \ No newline at end of file diff --git a/vip-scanner/checks/XSSVectorsCheck.php b/vip-scanner/checks/XSSVectorsCheck.php new file mode 100644 index 0000000..47bf6e3 --- /dev/null +++ b/vip-scanner/checks/XSSVectorsCheck.php @@ -0,0 +1,90 @@ +increment_check_count(); + foreach ( $this->filter_files( $files, array( 'html', 'php' ) ) as $file_path => $file_content ) { + $regex = '/]*?)href(?:\s)*?=(?:\s)*?(?[\\\'\"])*(?.*?)\k(?:.*?)>/ims'; + if ( preg_match_all( $regex, $file_content, $matches ) ) { + $lines = array(); + foreach ( $matches['HREF'] as $match ) { + $sanitized_string = str_replace( array( '/', '\\' ), '', $match ); + if ( strpos( $sanitized_string, 'javascript:' ) !== false ) { + $filename = $this->get_filename( $file_path ); + $lines = array_merge( $this->grep_content( $match, $file_content ), $lines ); + $this->add_error( + 'xss-in-link-tag-href', + "XSS Attack Vector found in tag attribute", + 'Warning', + $filename, + $lines + ); + $result = false; + } + } + } + } + + /** + * Checks for javascript within style attribute in all HTML tags + */ + $this->increment_check_count(); + foreach ( $this->filter_files( $files, array( 'html', 'php' ) ) as $file_path => $file_content ) { + $regex = '/<[a-z]*(?:[^\>]*?)style(?:\s)*?=(?:\s)*?(?[\\\'\"])*(?.*?)\k(?:.*?)>/ims'; + if ( preg_match_all( $regex, $file_content, $matches ) ) { + $lines = array(); + foreach ( $matches['ATTR'] as $match ) { + $sanitized_string = str_replace( array( '/', '\\' ), '', $match ); + if ( strpos( $sanitized_string, 'javascript:' ) !== false ) { + $filename = $this->get_filename( $file_path ); + $lines = array_merge( $this->grep_content( $match, $file_content ), $lines ); + $this->add_error( + 'xss-in-style-attribute', + "XSS Attack Vector found in HTML tag style attribute", + 'Warning', + $filename, + $lines + ); + $result = false; + } + } + } + } + + /** + * Checks for -moz-binding within style tags + */ + $this->increment_check_count(); + foreach ( $this->filter_files( $files, array( 'html', 'php' ) ) as $file_path => $file_content ) { + $regex = '/<[\s]*?style(?:.*?)?>(?.*?)<[\s]*?\/[\s]*?[a-z]*?[\s]*?>/ims'; + if ( preg_match_all( $regex, $file_content, $matches ) ) { + $lines = array(); + foreach ( $matches['CONTENT'] as $match ) { + $sanitized_string = str_replace( array( '/', '\\' ), '', $match ); + if ( strpos( $sanitized_string, '-moz-binding' ) !== false ) { + $filename = $this->get_filename( $file_path ); + $lines = array_merge( $this->grep_content( $match, $file_content ), $lines ); + $this->add_error( + 'moz-binding-xss-in-style-tag', + "XSS Attack Vector found in STYLE tag (-moz-binding)", + 'Warning', + $filename, + $lines + ); + $result = false; + } + } + } + } + + return $result; + } +} \ No newline at end of file From 9581b5352350dd300347c91e3bd016bc2b5e534f Mon Sep 17 00:00:00 2001 From: Derrick Tennant Date: Thu, 26 Mar 2015 11:44:27 -0400 Subject: [PATCH 03/44] VIP Scanner: Added XSSVectorsCheck to config-vip-scanner.php so it will now scan in the plugin as well. --- vip-scanner/config-vip-scanner.php | 1 + 1 file changed, 1 insertion(+) diff --git a/vip-scanner/config-vip-scanner.php b/vip-scanner/config-vip-scanner.php index 60ac394..286dc2b 100644 --- a/vip-scanner/config-vip-scanner.php +++ b/vip-scanner/config-vip-scanner.php @@ -73,6 +73,7 @@ 'WordPressCodingStandardsCheck', 'ClamAVCheck', // Pass null to lookup the check normally 'AdBustersCheck', + 'XSSVectorsCheck', ), array( 'PHPAnalyzer', 'CustomResourceAnalyzer', From fc6d9366c244e5fe441894f0e7d2897167bab75a Mon Sep 17 00:00:00 2001 From: Derrick Tennant Date: Thu, 26 Mar 2015 12:04:42 -0400 Subject: [PATCH 04/44] VIP Scanner: Added search for -moz-binding in HTML tag style attributes --- tests/checks/test-XSSVectorsCheck.php | 16 ++++++++ vip-scanner/checks/XSSVectorsCheck.php | 52 ++++++++++++++++++++++++++ 2 files changed, 68 insertions(+) diff --git a/tests/checks/test-XSSVectorsCheck.php b/tests/checks/test-XSSVectorsCheck.php index e334f31..2dc0acc 100644 --- a/tests/checks/test-XSSVectorsCheck.php +++ b/tests/checks/test-XSSVectorsCheck.php @@ -42,6 +42,22 @@ public function test_xss_not_in_tag_style_attr() { $this->assertNotContains( 'xss-in-style-attribute', $error_slugs ); } + public function test_moz_binding_in_tag_style_attr() { + $file_contents = <<<'EOT' +
+EOT; + $error_slugs = $this->runCheck( $file_contents ); + $this->assertContains( 'moz-binding-xss-in-style-attribute', $error_slugs ); + } + + public function test_moz_binding_not_in_tag_style_attr() { + $file_contents = <<<'EOT' +
+EOT; + $error_slugs = $this->runCheck( $file_contents ); + $this->assertNotContains( 'moz-binding-xss-in-style-attribute', $error_slugs ); + } + public function test_moz_binding_in_tag_style() { $file_contents = <<<'EOT' diff --git a/vip-scanner/checks/XSSVectorsCheck.php b/vip-scanner/checks/XSSVectorsCheck.php index 47bf6e3..15b3936 100644 --- a/vip-scanner/checks/XSSVectorsCheck.php +++ b/vip-scanner/checks/XSSVectorsCheck.php @@ -85,6 +85,58 @@ function check( $files ) { } } + /** + * Checks for -moz-binding within style attribute in all HTML tags + */ + $this->increment_check_count(); + foreach ( $this->filter_files( $files, array( 'html', 'php' ) ) as $file_path => $file_content ) { + $regex = '/<[a-z]*(?:[^\>]*?)style(?:\s)*?=(?:\s)*?(?[\\\'\"])*(?.*?)\k(?:.*?)>/ims'; + if ( preg_match_all( $regex, $file_content, $matches ) ) { + $lines = array(); + foreach ( $matches['ATTR'] as $match ) { + $sanitized_string = str_replace( array( '/', '\\' ), '', $match ); + if ( strpos( $sanitized_string, '-moz-binding' ) !== false ) { + $filename = $this->get_filename( $file_path ); + $lines = array_merge( $this->grep_content( $match, $file_content ), $lines ); + $this->add_error( + 'moz-binding-xss-in-style-attribute', + "XSS Attack Vector found in STYLE tag (-moz-binding)", + 'Warning', + $filename, + $lines + ); + $result = false; + } + } + } + } + + /** + * Checks for -moz-binding within style tags + */ + $this->increment_check_count(); + foreach ( $this->filter_files( $files, array( 'html', 'php' ) ) as $file_path => $file_content ) { + $regex = '/<[\s]*?style(?:.*?)?>(?.*?)<[\s]*?\/[\s]*?[a-z]*?[\s]*?>/ims'; + if ( preg_match_all( $regex, $file_content, $matches ) ) { + $lines = array(); + foreach ( $matches['CONTENT'] as $match ) { + $sanitized_string = str_replace( array( '/', '\\' ), '', $match ); + if ( strpos( $sanitized_string, '-moz-binding' ) !== false ) { + $filename = $this->get_filename( $file_path ); + $lines = array_merge( $this->grep_content( $match, $file_content ), $lines ); + $this->add_error( + 'moz-binding-xss-in-style-tag', + "XSS Attack Vector found in STYLE tag (-moz-binding)", + 'Warning', + $filename, + $lines + ); + $result = false; + } + } + } + } + return $result; } } \ No newline at end of file From b3980b5f7801e97198f8d8b32045e290ac934d15 Mon Sep 17 00:00:00 2001 From: Derrick Tennant Date: Thu, 26 Mar 2015 12:07:14 -0400 Subject: [PATCH 05/44] VIP Scanner: Created a seperate function sanitize_string() to use instead of adding more sanitization code to each check. --- vip-scanner/checks/XSSVectorsCheck.php | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/vip-scanner/checks/XSSVectorsCheck.php b/vip-scanner/checks/XSSVectorsCheck.php index 15b3936..581c164 100644 --- a/vip-scanner/checks/XSSVectorsCheck.php +++ b/vip-scanner/checks/XSSVectorsCheck.php @@ -4,6 +4,20 @@ * */ class XSSVectorsCheck extends BaseCheck { + function sanitize_string( $string ) { + + /** + * Removes slashes + */ + $string = str_replace( array( '/', '\\' ), '', $string ); + + /** + * Removes comment blocks + */ + $string = preg_replace( '(/\*.*?\*/)', '', $string ); + + } + function check( $files ) { $result = true; From 9373b7f05c9271161ab4698e5ffae6e4b503a79d Mon Sep 17 00:00:00 2001 From: Derrick Tennant Date: Thu, 26 Mar 2015 12:58:26 -0400 Subject: [PATCH 06/44] VIP Scanner: Checks inside XSSVectorsCheck now use the sanitize_string() helper function. --- vip-scanner/checks/XSSVectorsCheck.php | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/vip-scanner/checks/XSSVectorsCheck.php b/vip-scanner/checks/XSSVectorsCheck.php index 581c164..4918ba9 100644 --- a/vip-scanner/checks/XSSVectorsCheck.php +++ b/vip-scanner/checks/XSSVectorsCheck.php @@ -16,6 +16,7 @@ function sanitize_string( $string ) { */ $string = preg_replace( '(/\*.*?\*/)', '', $string ); + return $string; } function check( $files ) { @@ -30,7 +31,7 @@ function check( $files ) { if ( preg_match_all( $regex, $file_content, $matches ) ) { $lines = array(); foreach ( $matches['HREF'] as $match ) { - $sanitized_string = str_replace( array( '/', '\\' ), '', $match ); + $sanitized_string = $this->sanitize_string( $match ); if ( strpos( $sanitized_string, 'javascript:' ) !== false ) { $filename = $this->get_filename( $file_path ); $lines = array_merge( $this->grep_content( $match, $file_content ), $lines ); @@ -56,7 +57,7 @@ function check( $files ) { if ( preg_match_all( $regex, $file_content, $matches ) ) { $lines = array(); foreach ( $matches['ATTR'] as $match ) { - $sanitized_string = str_replace( array( '/', '\\' ), '', $match ); + $sanitized_string = $this->sanitize_string( $match ); if ( strpos( $sanitized_string, 'javascript:' ) !== false ) { $filename = $this->get_filename( $file_path ); $lines = array_merge( $this->grep_content( $match, $file_content ), $lines ); @@ -82,7 +83,7 @@ function check( $files ) { if ( preg_match_all( $regex, $file_content, $matches ) ) { $lines = array(); foreach ( $matches['CONTENT'] as $match ) { - $sanitized_string = str_replace( array( '/', '\\' ), '', $match ); + $sanitized_string = $this->sanitize_string( $match ); if ( strpos( $sanitized_string, '-moz-binding' ) !== false ) { $filename = $this->get_filename( $file_path ); $lines = array_merge( $this->grep_content( $match, $file_content ), $lines ); @@ -108,7 +109,7 @@ function check( $files ) { if ( preg_match_all( $regex, $file_content, $matches ) ) { $lines = array(); foreach ( $matches['ATTR'] as $match ) { - $sanitized_string = str_replace( array( '/', '\\' ), '', $match ); + $sanitized_string = $this->sanitize_string( $match ); if ( strpos( $sanitized_string, '-moz-binding' ) !== false ) { $filename = $this->get_filename( $file_path ); $lines = array_merge( $this->grep_content( $match, $file_content ), $lines ); @@ -134,7 +135,7 @@ function check( $files ) { if ( preg_match_all( $regex, $file_content, $matches ) ) { $lines = array(); foreach ( $matches['CONTENT'] as $match ) { - $sanitized_string = str_replace( array( '/', '\\' ), '', $match ); + $sanitized_string = $this->sanitize_string( $match ); if ( strpos( $sanitized_string, '-moz-binding' ) !== false ) { $filename = $this->get_filename( $file_path ); $lines = array_merge( $this->grep_content( $match, $file_content ), $lines ); From e2752bf816f070846d7f371c6ac73ec40adf5563 Mon Sep 17 00:00:00 2001 From: Derrick Tennant Date: Thu, 26 Mar 2015 12:59:13 -0400 Subject: [PATCH 07/44] VIP Scanner: New XSS check for javascript inside of (From https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet) --- tests/checks/test-XSSVectorsCheck.php | 16 ++++++++++++++++ vip-scanner/checks/XSSVectorsCheck.php | 26 ++++++++++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/tests/checks/test-XSSVectorsCheck.php b/tests/checks/test-XSSVectorsCheck.php index 2dc0acc..8515d41 100644 --- a/tests/checks/test-XSSVectorsCheck.php +++ b/tests/checks/test-XSSVectorsCheck.php @@ -74,4 +74,20 @@ public function test_moz_binding_not_in_tag_style() { $this->assertNotContains( 'moz-binding-xss-in-style-tag', $error_slugs ); } + public function test_xss_in_style_tag() { + $file_contents = <<<'EOT' + +EOT; + $error_slugs = $this->runCheck( $file_contents ); + $this->assertContains( 'xss-javascript-in-style-tag', $error_slugs ); + } + + public function test_xss_not_in_style_tag() { + $file_contents = <<<'EOT' + +EOT; + $error_slugs = $this->runCheck( $file_contents ); + $this->assertNotContains( 'xss-javascript-in-style-tag', $error_slugs ); + } + } \ No newline at end of file diff --git a/vip-scanner/checks/XSSVectorsCheck.php b/vip-scanner/checks/XSSVectorsCheck.php index 4918ba9..6e76610 100644 --- a/vip-scanner/checks/XSSVectorsCheck.php +++ b/vip-scanner/checks/XSSVectorsCheck.php @@ -152,6 +152,32 @@ function check( $files ) { } } + /** + * Checks for 'javascript:' within style tags + */ + $this->increment_check_count(); + foreach ( $this->filter_files( $files, array( 'html', 'php' ) ) as $file_path => $file_content ) { + $regex = '/<[\s]*?style(?:.*?)?>(?.*?)<[\s]*?\/[\s]*?[a-z]*?[\s]*?>/ims'; + if ( preg_match_all( $regex, $file_content, $matches ) ) { + $lines = array(); + foreach ( $matches['CONTENT'] as $match ) { + $sanitized_string = $this->sanitize_string( $match ); + if ( strpos( $sanitized_string, 'javascript:' ) !== false ) { + $filename = $this->get_filename( $file_path ); + $lines = array_merge( $this->grep_content( $match, $file_content ), $lines ); + $this->add_error( + 'xss-javascript-in-style-tag', + "XSS Attack Vector found in STYLE tag (javascript:)", + 'Warning', + $filename, + $lines + ); + $result = false; + } + } + } + } + return $result; } } \ No newline at end of file From 99d8a952a0083f72e0cbc690eececd95c2a21d35 Mon Sep 17 00:00:00 2001 From: Derrick Tennant Date: Thu, 26 Mar 2015 13:10:33 -0400 Subject: [PATCH 08/44] VIP Scanner: New XSS check for CSS expression properties. Examples:
(From https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet) --- tests/checks/test-XSSVectorsCheck.php | 32 ++++++++++++++++ vip-scanner/checks/XSSVectorsCheck.php | 52 ++++++++++++++++++++++++++ 2 files changed, 84 insertions(+) diff --git a/tests/checks/test-XSSVectorsCheck.php b/tests/checks/test-XSSVectorsCheck.php index 8515d41..01bf8bc 100644 --- a/tests/checks/test-XSSVectorsCheck.php +++ b/tests/checks/test-XSSVectorsCheck.php @@ -90,4 +90,36 @@ public function test_xss_not_in_style_tag() { $this->assertNotContains( 'xss-javascript-in-style-tag', $error_slugs ); } + public function test_css_expression_xss_in_style_tag() { + $file_contents = <<<'EOT' + +EOT; + $error_slugs = $this->runCheck( $file_contents ); + $this->assertContains( 'css-expression-xss-in-style-tag', $error_slugs ); + } + + public function test_css_expression_xss_not_in_style_tag() { + $file_contents = <<<'EOT' + +EOT; + $error_slugs = $this->runCheck( $file_contents ); + $this->assertNotContains( 'css-expression-xss-in-style-tag', $error_slugs ); + } + + public function test_css_expression_xss_in_style_attribute() { + $file_contents = <<<'EOT' +
> +EOT; + $error_slugs = $this->runCheck( $file_contents ); + $this->assertContains( 'css-expression-xss-in-style-attribute', $error_slugs ); + } + + public function test_css_expression_xss_not_in_style_attribute() { + $file_contents = <<<'EOT' +
+EOT; + $error_slugs = $this->runCheck( $file_contents ); + $this->assertNotContains( 'css-expression-xss-in-style-attribute', $error_slugs ); + } + } \ No newline at end of file diff --git a/vip-scanner/checks/XSSVectorsCheck.php b/vip-scanner/checks/XSSVectorsCheck.php index 6e76610..67f305d 100644 --- a/vip-scanner/checks/XSSVectorsCheck.php +++ b/vip-scanner/checks/XSSVectorsCheck.php @@ -178,6 +178,58 @@ function check( $files ) { } } + /** + * Checks for CSS expression() property within style attribute in all HTML tags + */ + $this->increment_check_count(); + foreach ( $this->filter_files( $files, array( 'html', 'php' ) ) as $file_path => $file_content ) { + $regex = '/<[a-z]*(?:[^\>]*?)style(?:\s)*?=(?:\s)*?(?[\\\'\"])*(?.*?)\k(?:.*?)>/ims'; + if ( preg_match_all( $regex, $file_content, $matches ) ) { + $lines = array(); + foreach ( $matches['ATTR'] as $match ) { + $sanitized_string = $this->sanitize_string( $match ); + if ( strpos( $sanitized_string, 'expression(' ) !== false ) { + $filename = $this->get_filename( $file_path ); + $lines = array_merge( $this->grep_content( $match, $file_content ), $lines ); + $this->add_error( + 'css-expression-xss-in-style-attribute', + "XSS Attack Vector found in STYLE tag (CSS expression property)", + 'Warning', + $filename, + $lines + ); + $result = false; + } + } + } + } + + /** + * Checks for CSS expression() property within style tags + */ + $this->increment_check_count(); + foreach ( $this->filter_files( $files, array( 'html', 'php' ) ) as $file_path => $file_content ) { + $regex = '/<[\s]*?style(?:.*?)?>(?.*?)<[\s]*?\/[\s]*?[a-z]*?[\s]*?>/ims'; + if ( preg_match_all( $regex, $file_content, $matches ) ) { + $lines = array(); + foreach ( $matches['CONTENT'] as $match ) { + $sanitized_string = $this->sanitize_string( $match ); + if ( strpos( $sanitized_string, 'expression(' ) !== false ) { + $filename = $this->get_filename( $file_path ); + $lines = array_merge( $this->grep_content( $match, $file_content ), $lines ); + $this->add_error( + 'css-expression-xss-in-style-tag', + "XSS Attack Vector found in STYLE tag (CSS expression property)", + 'Warning', + $filename, + $lines + ); + $result = false; + } + } + } + } + return $result; } } \ No newline at end of file From 84ac45d947148967594b49dbbf1487572d78f2c4 Mon Sep 17 00:00:00 2001 From: Derrick Tennant Date: Thu, 26 Mar 2015 13:56:55 -0400 Subject: [PATCH 09/44] VIP Scanner: Moved current XSS checks to array to iterate over them while scanning, like in VIPRestrictedPatternsCheck. This may work right now for the current XSS checks, but that is no guarantee that we will not have to write more specific checks for unique XSS cases. --- tests/checks/test-XSSVectorsCheck.php | 8 + vip-scanner/checks/XSSVectorsCheck.php | 263 ++++++------------------- 2 files changed, 70 insertions(+), 201 deletions(-) diff --git a/tests/checks/test-XSSVectorsCheck.php b/tests/checks/test-XSSVectorsCheck.php index 01bf8bc..d293800 100644 --- a/tests/checks/test-XSSVectorsCheck.php +++ b/tests/checks/test-XSSVectorsCheck.php @@ -114,6 +114,14 @@ public function test_css_expression_xss_in_style_attribute() { $this->assertContains( 'css-expression-xss-in-style-attribute', $error_slugs ); } + public function test_obfuscated_css_expression_xss_in_style_attribute() { + $file_contents = <<<'EOT' + +EOT; + $error_slugs = $this->runCheck( $file_contents ); + $this->assertContains( 'css-expression-xss-in-style-attribute', $error_slugs ); + } + public function test_css_expression_xss_not_in_style_attribute() { $file_contents = <<<'EOT'
diff --git a/vip-scanner/checks/XSSVectorsCheck.php b/vip-scanner/checks/XSSVectorsCheck.php index 67f305d..950b47a 100644 --- a/vip-scanner/checks/XSSVectorsCheck.php +++ b/vip-scanner/checks/XSSVectorsCheck.php @@ -22,209 +22,70 @@ function sanitize_string( $string ) { function check( $files ) { $result = true; - /** - * Checks for javascript within href attribute of link tags - */ - $this->increment_check_count(); - foreach ( $this->filter_files( $files, array( 'html', 'php' ) ) as $file_path => $file_content ) { - $regex = '/]*?)href(?:\s)*?=(?:\s)*?(?[\\\'\"])*(?.*?)\k(?:.*?)>/ims'; - if ( preg_match_all( $regex, $file_content, $matches ) ) { - $lines = array(); - foreach ( $matches['HREF'] as $match ) { - $sanitized_string = $this->sanitize_string( $match ); - if ( strpos( $sanitized_string, 'javascript:' ) !== false ) { - $filename = $this->get_filename( $file_path ); - $lines = array_merge( $this->grep_content( $match, $file_content ), $lines ); - $this->add_error( - 'xss-in-link-tag-href', - "XSS Attack Vector found in tag attribute", - 'Warning', - $filename, - $lines - ); - $result = false; - } - } - } - } - - /** - * Checks for javascript within style attribute in all HTML tags - */ - $this->increment_check_count(); - foreach ( $this->filter_files( $files, array( 'html', 'php' ) ) as $file_path => $file_content ) { - $regex = '/<[a-z]*(?:[^\>]*?)style(?:\s)*?=(?:\s)*?(?[\\\'\"])*(?.*?)\k(?:.*?)>/ims'; - if ( preg_match_all( $regex, $file_content, $matches ) ) { - $lines = array(); - foreach ( $matches['ATTR'] as $match ) { - $sanitized_string = $this->sanitize_string( $match ); - if ( strpos( $sanitized_string, 'javascript:' ) !== false ) { - $filename = $this->get_filename( $file_path ); - $lines = array_merge( $this->grep_content( $match, $file_content ), $lines ); - $this->add_error( - 'xss-in-style-attribute', - "XSS Attack Vector found in HTML tag style attribute", - 'Warning', - $filename, - $lines - ); - $result = false; - } - } - } - } + $checks = array( + 'xss-in-link-tag-href' => array( + 'expression' => '/]*?)href(?:\s)*?=(?:\s)*?(?[\\\'\"])*(?.*?)\k(?:.*?)>/ims', + 'match-text' => 'javascript:', + 'level' => 'Warning', + 'note' => 'XSS Attack Vector found in tag href attribute (javascript:)', + ), + 'xss-javascript-in-style-tag' => array( + 'expression' => '/<[\s]*?style(?:.*?)?>(?.*?)<[\s]*?\/[\s]*?[a-z]*?[\s]*?>/ims', + 'match-text' => 'javascript:', + 'level' => 'Warning', + 'note' => 'XSS Attack Vector found in +EOT; + $error_slugs = $this->runCheck( $file_contents ); + $this->assertContains( 'xss-javascript-in-style-tag', $error_slugs ); + } + + public function test_xss_not_in_style_tag() { + $file_contents = <<<'EOT' + +EOT; + $error_slugs = $this->runCheck( $file_contents ); + $this->assertNotContains( 'xss-javascript-in-style-tag', $error_slugs ); + } + + /* + * XSS -moz-binding in style attributes and style tag + */ public function test_moz_binding_in_tag_style_attr() { $file_contents = <<<'EOT'
@@ -74,22 +99,9 @@ public function test_moz_binding_not_in_tag_style() { $this->assertNotContains( 'moz-binding-xss-in-style-tag', $error_slugs ); } - public function test_xss_in_style_tag() { - $file_contents = <<<'EOT' - -EOT; - $error_slugs = $this->runCheck( $file_contents ); - $this->assertContains( 'xss-javascript-in-style-tag', $error_slugs ); - } - - public function test_xss_not_in_style_tag() { - $file_contents = <<<'EOT' - -EOT; - $error_slugs = $this->runCheck( $file_contents ); - $this->assertNotContains( 'xss-javascript-in-style-tag', $error_slugs ); - } - + /* + * XSS CSS expression property in style attribute and style tag + */ public function test_css_expression_xss_in_style_tag() { $file_contents = <<<'EOT' From 69c28c4b1a13008e6307e2e65710b3f8f2f4a0b8 Mon Sep 17 00:00:00 2001 From: Derrick Tennant Date: Thu, 26 Mar 2015 14:10:36 -0400 Subject: [PATCH 12/44] VIP Scanner: New XSS check for CSS expression properties. Examples:
(From https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet) --- tests/checks/test-XSSVectorsCheck.php | 35 ++++++++++++++++++++++++++ vip-scanner/checks/XSSVectorsCheck.php | 12 +++++++++ 2 files changed, 47 insertions(+) diff --git a/tests/checks/test-XSSVectorsCheck.php b/tests/checks/test-XSSVectorsCheck.php index 39fe95e..967ae12 100644 --- a/tests/checks/test-XSSVectorsCheck.php +++ b/tests/checks/test-XSSVectorsCheck.php @@ -142,4 +142,39 @@ public function test_css_expression_xss_not_in_style_attribute() { $this->assertNotContains( 'css-expression-xss-in-style-attribute', $error_slugs ); } + /* + * XSS CSS behavior property in style attribute and style tag + */ + public function test_css_behavior_xss_in_style_tag() { + $file_contents = <<<'EOT' + +EOT; + $error_slugs = $this->runCheck( $file_contents ); + $this->assertContains( 'css-behavior-xss-in-style-tag', $error_slugs ); + } + + public function test_css_behavior_xss_not_in_style_tag() { + $file_contents = <<<'EOT' + +EOT; + $error_slugs = $this->runCheck( $file_contents ); + $this->assertNotContains( 'css-behavior-xss-in-style-attribute', $error_slugs ); + } + + public function test_css_behavior_xss_in_style_attribute() { + $file_contents = <<<'EOT' +
> +EOT; + $error_slugs = $this->runCheck( $file_contents ); + $this->assertContains( 'css-behavior-xss-in-style-attribute', $error_slugs ); + } + + public function test_css_behavior_xss_not_in_style_attribute() { + $file_contents = <<<'EOT' +
+EOT; + $error_slugs = $this->runCheck( $file_contents ); + $this->assertNotContains( 'css-behavior-xss-in-style-attribute', $error_slugs ); + } + } \ No newline at end of file diff --git a/vip-scanner/checks/XSSVectorsCheck.php b/vip-scanner/checks/XSSVectorsCheck.php index 8e66b4d..033ad29 100644 --- a/vip-scanner/checks/XSSVectorsCheck.php +++ b/vip-scanner/checks/XSSVectorsCheck.php @@ -65,6 +65,18 @@ function check( $files ) { 'level' => 'Warning', 'note' => 'XSS Attack Vector found in