diff --git a/library/server/wsf/security/filter/wsf_xss_filter.e b/library/server/wsf/security/filter/wsf_xss_filter.e new file mode 100644 index 00000000..c9bc3733 --- /dev/null +++ b/library/server/wsf/security/filter/wsf_xss_filter.e @@ -0,0 +1,36 @@ +note + description: "[ + {WSF_XSS_FILTER}. + Simple anti cross-site scripting (XSS) filter. + Remove all suspicious strings from request parameters (query strings and form) before returning them to the application + + ]" + date: "$Date$" + revision: "$Revision$" + +class + WSF_XSS_FILTER + +inherit + + WSF_FILTER + +feature -- Execution + + execute (req: WSF_REQUEST; res: WSF_RESPONSE) + -- Execute the filter. + do + execute_next (create {WSF_XSS_REQUEST}.make_from_request (req), res) + end + +note + copyright: "2011-2017, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Colin Adams, Eiffel Software and others" + license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" + source: "[ + Eiffel Software + 5949 Hollister Ave., Goleta, CA 93117 USA + Telephone 805-685-1006, Fax 805-685-6869 + Website http://www.eiffel.com + Customer support http://support.eiffel.com + ]" +end diff --git a/library/server/wsf/security/support/wsf_protection_patterns.e b/library/server/wsf/security/support/wsf_protection_patterns.e new file mode 100644 index 00000000..a41e3e74 --- /dev/null +++ b/library/server/wsf/security/support/wsf_protection_patterns.e @@ -0,0 +1,106 @@ +note + description: "[ + {WSF_PROTECTION_PATTERNS} + Provide application security parterns to assist in Cross Site Scripting + ]" + date: "$Date$" + revision: "$Revision$" + EIS: "name=OWASP XSS", "src=https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet", "protocol=uri" + EIS: "name=Regular expression protection", "src=https://docs.apigee.com/api-services/reference/regular-expression-protection", "protocol=uri" + +expanded class + WSF_PROTECTION_PATTERNS + + +feature -- xss PATTERNS + + XSS_regular_expression: REGULAR_EXPRESSION + note + EIS: "name= XSS", "src=https://community.apigee.com/questions/27198/xss-threat-protection-patterns.html#answer-27465", "protocol=uri" + local + p: STRING_32 + once + p := "((\%%3C)|<)[^\n]+((\%%3E)|>)" + Result := compiled_regexp (p, True) + end + + XSS_javascript_expression: REGULAR_EXPRESSION + note + EIS: "name=JavaScript Injection", "src=https://docs.apigee.com/api-services/reference/regular-expression-protection", "protocol=uri" + local + p: STRING_32 + once + p := "<\s*script\b[^>]*>[^<]+<\s*/\s*script\s*>" + Result := compiled_regexp (p, True) + end + +feature -- XPath injections Patterns + + XPath_abbreviated_expression: REGULAR_EXPRESSION + note + EIS: "name=XPath Abbreviated Syntax Injection", "src=https://docs.apigee.com/api-services/reference/regular-expression-protection", "protocol=uri" + local + p: STRING_32 + once + p := "(/(@?[\w_?\w:\*]+(\[[^]]+\])*)?)+" + Result := compiled_regexp (p, True) + end + + XPath_expanded_expression: REGULAR_EXPRESSION + note + EIS: "name=XPath Expanded Syntax Injection", "src=https://docs.apigee.com/api-services/reference/regular-expression-protection", "protocol=uri" + local + p: STRING_32 + once + p := "/?(ancestor(-or-self)?|descendant(-or-self)?|following(-sibling))" + Result := compiled_regexp (p, True) + end + +feature -- Server side injection + + Server_side_expression: REGULAR_EXPRESSION + note + EIS: "name=Server-Side Include Injection", "src=https://docs.apigee.com/api-services/reference/regular-expression-protection", "protocol=uri" + local + p: STRING_32 + once + p := ""> +"> +/'"> + +]" + r:= xss_pattern.XSS_regular_expression + r.match (s) + assert ("Filter bypass based polyglot", r.has_matched) + end + + + test_image_xss_js_directive + local + r: REGULAR_EXPRESSION + s: STRING + do + s:="[ + +]" + r:= xss_pattern.XSS_regular_expression + r.match (s) + assert ("Image XSS using the JavaScript directive", r.has_matched) + end + + + test_no_quotes_no_semicolon + local + r: REGULAR_EXPRESSION + s: STRING + do + s:="[ + +]" + r:= xss_pattern.XSS_regular_expression + r.match (s) + assert ("No quotes and no semicolon", r.has_matched) + end + + + test_case_insensitive_xss_vector + local + r: REGULAR_EXPRESSION + s: STRING + do + s:="[ + +]" + r:= xss_pattern.XSS_regular_expression + r.match (s) + assert ("Case insensitive XSS attack vector", r.has_matched) + end + + + test_html_entities + local + r: REGULAR_EXPRESSION + s: STRING + do + s:="[ + +]" + r:= xss_pattern.XSS_regular_expression + r.match (s) + assert ("HTML entities", r.has_matched) + end + + test_grave_accent_obfuscation + local + r: REGULAR_EXPRESSION + s: STRING + do + s:="[ + +]" + r:= xss_pattern.XSS_regular_expression + r.match (s) + assert ("Grave accent obfuscation", r.has_matched) + end + + + test_malformed_a_tags + local + r: REGULAR_EXPRESSION + s: STRING + do + -- Skip the HREF attribute and get to the meat of the XXS... Submitted by David Cross ~ Verified on Chrome + s:="[ +xxs link +]" + r:= xss_pattern.XSS_regular_expression + r.match (s) + assert ("Malformed A tags", r.has_matched) + end + + test_malformed_a_tags_2 + local + r: REGULAR_EXPRESSION + s: STRING + do + -- Chrome loves to replace missing quotes for you... if you ever get stuck just leave them off and Chrome will put them + -- in the right place and fix your missing quotes on a URL or script. + s:="[ +xxs link +]" + r:= xss_pattern.XSS_regular_expression + r.match (s) + assert ("Malformed A tags", r.has_matched) + end + + + test_malformed_img + local + r: REGULAR_EXPRESSION + s: STRING + do + s:="[ +"> +]" + r:= xss_pattern.XSS_regular_expression + r.match (s) + assert ("Malformed IMG tags", r.has_matched) + end + + + test_from_char_code + local + r: REGULAR_EXPRESSION + s: STRING + do + s:="[ + +]" + r:= xss_pattern.XSS_regular_expression + r.match (s) + assert ("fromCharCode", r.has_matched) + end + + + test_default_src_tag + local + r: REGULAR_EXPRESSION + s: STRING + do + s:="[ + +]" + r:= xss_pattern.XSS_regular_expression + r.match (s) + assert ("Default SRC tag to get past filters that check SRC domain", r.has_matched) + end + + + test_default_src_tag_2 + local + r: REGULAR_EXPRESSION + s: STRING + do + s:="[ + +]" + r:= xss_pattern.XSS_regular_expression + r.match (s) + assert ("Default SRC tag by leaving it empty", r.has_matched) + end + + test_default_src_tag_3 + local + r: REGULAR_EXPRESSION + s: STRING + do + s:="[ + +]" + r:= xss_pattern.XSS_regular_expression + r.match (s) + assert ("Default SRC tag by leaving it out entirely", r.has_matched) + end + + + + + + + +feature {NONE} -- Implementation + + xss_pattern: WSF_PROTECTION_PATTERNS + +end diff --git a/library/server/wsf/tests/tests.ecf b/library/server/wsf/tests/tests.ecf index 0f2564c8..c63fb036 100644 --- a/library/server/wsf/tests/tests.ecf +++ b/library/server/wsf/tests/tests.ecf @@ -3,9 +3,9 @@ + /EIFGENs$ /\.git$ /\.svn$ - /EIFGENs$ diff --git a/library/server/wsf/wsf.ecf b/library/server/wsf/wsf.ecf index 231927ad..c9c4ac34 100644 --- a/library/server/wsf/wsf.ecf +++ b/library/server/wsf/wsf.ecf @@ -3,9 +3,9 @@ + /EIFGENs$ /\.git$ /\.svn$ - /EIFGENs$ diff --git a/library/server/wsf/wsf_security.ecf b/library/server/wsf/wsf_security.ecf new file mode 100644 index 00000000..6684ccee --- /dev/null +++ b/library/server/wsf/wsf_security.ecf @@ -0,0 +1,22 @@ + + + + + + /EIFGENs$ + /\.git$ + /\.svn$ + + + + + + + + + + + + +