Updated xss support.
Added a new library wsf_security. Updated test cases to cover protections policy. Added a simple filter using an XSS implementation with WSF_XSS_REQUEST, but it's possible to build custom filters and request using different protection patterns.
This commit is contained in:
@@ -1,51 +0,0 @@
|
|||||||
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
|
|
||||||
|
|
||||||
feature {NONE} -- Implementation
|
|
||||||
|
|
||||||
compiled_regexp (p: STRING; caseless: BOOLEAN): REGULAR_EXPRESSION
|
|
||||||
require
|
|
||||||
p /= Void
|
|
||||||
do
|
|
||||||
create Result
|
|
||||||
Result.set_caseless (caseless)
|
|
||||||
Result.compile (p)
|
|
||||||
ensure
|
|
||||||
Result.is_compiled
|
|
||||||
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
|
|
||||||
@@ -1,108 +0,0 @@
|
|||||||
note
|
|
||||||
description: "Return safe (XSS protection) data for WSF_REQUEST query and form parameters."
|
|
||||||
date: "$Date$"
|
|
||||||
revision: "$Revision$"
|
|
||||||
|
|
||||||
class
|
|
||||||
WSF_XSS_UTILITIES
|
|
||||||
|
|
||||||
-- TODO add header protection.
|
|
||||||
|
|
||||||
feature -- Query parameters
|
|
||||||
|
|
||||||
safe_query_parameter (a_req: WSF_REQUEST; a_name: READABLE_STRING_GENERAL): detachable WSF_VALUE
|
|
||||||
-- Safe Query parameter for name `a_name'.
|
|
||||||
local
|
|
||||||
l_wsf_xss: WSF_PROTECTION_PATTERNS
|
|
||||||
r: REGULAR_EXPRESSION
|
|
||||||
do
|
|
||||||
r := l_wsf_xss.XSS_regular_expression
|
|
||||||
Result := a_req.query_parameter (a_name)
|
|
||||||
if Result /= Void then
|
|
||||||
if
|
|
||||||
attached {WSF_STRING} Result as str and then
|
|
||||||
r.is_compiled
|
|
||||||
then
|
|
||||||
r.match (str.value)
|
|
||||||
if r.has_matched then
|
|
||||||
create {WSF_STRING} Result.make (str.name, " ")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
feature -- Form Parameters
|
|
||||||
|
|
||||||
safe_form_parameter (a_req: WSF_REQUEST; a_name: READABLE_STRING_GENERAL): detachable WSF_VALUE
|
|
||||||
-- Safe Form parameter for name `a_name'.
|
|
||||||
local
|
|
||||||
l_wsf_xss: WSF_PROTECTION_PATTERNS
|
|
||||||
r: REGULAR_EXPRESSION
|
|
||||||
not_first: BOOLEAN
|
|
||||||
do
|
|
||||||
r := l_wsf_xss.XSS_regular_expression
|
|
||||||
Result := a_req.form_parameter (a_name)
|
|
||||||
if Result /= Void then
|
|
||||||
if
|
|
||||||
attached {WSF_STRING} Result as str and then
|
|
||||||
r.is_compiled
|
|
||||||
then
|
|
||||||
r.match (str.value)
|
|
||||||
if r.has_matched then
|
|
||||||
create {WSF_STRING} Result.make (str.name, " ")
|
|
||||||
end
|
|
||||||
elseif
|
|
||||||
attached {WSF_MULTIPLE_STRING} Result as l_multi_str and then
|
|
||||||
r.is_compiled
|
|
||||||
then
|
|
||||||
across l_multi_str as ic loop
|
|
||||||
r.match (ic.item.value)
|
|
||||||
if r.has_matched then
|
|
||||||
if not_first and then attached {WSF_MULTIPLE_STRING} Result as l_result then
|
|
||||||
l_result.add_value ( (create {WSF_STRING}.make (ic.item.name, " ")))
|
|
||||||
else
|
|
||||||
create {WSF_MULTIPLE_STRING} Result.make_with_string (ic.item.name, " ")
|
|
||||||
not_first := True
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
feature -- Meta Variables
|
|
||||||
|
|
||||||
safe_meta_variable (a_req: WSF_REQUEST; a_name: READABLE_STRING_GENERAL): detachable WSF_STRING
|
|
||||||
-- CGI Meta variable related to `a_name'
|
|
||||||
require
|
|
||||||
a_name_valid: a_name /= Void and then not a_name.is_empty
|
|
||||||
local
|
|
||||||
l_wsf_xss: WSF_PROTECTION_PATTERNS
|
|
||||||
r: REGULAR_EXPRESSION
|
|
||||||
do
|
|
||||||
r := l_wsf_xss.XSS_regular_expression
|
|
||||||
Result := a_req.meta_variable (a_name)
|
|
||||||
if Result /= Void then
|
|
||||||
if
|
|
||||||
attached {WSF_STRING} Result as str and then
|
|
||||||
r.is_compiled
|
|
||||||
then
|
|
||||||
r.match (str.value)
|
|
||||||
if r.has_matched then
|
|
||||||
create {WSF_STRING} Result.make (str.name, " ")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
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
|
|
||||||
@@ -1,59 +0,0 @@
|
|||||||
note
|
|
||||||
description: "[
|
|
||||||
XSS request, redefine query_parameter and form_parameters filtering the data (using XSS protection)
|
|
||||||
before return the value.
|
|
||||||
]"
|
|
||||||
date: "$Date$"
|
|
||||||
revision: "$Revision$"
|
|
||||||
|
|
||||||
class
|
|
||||||
WSF_XSS_REQUEST
|
|
||||||
|
|
||||||
inherit
|
|
||||||
WSF_REQUEST
|
|
||||||
redefine
|
|
||||||
query_parameter,
|
|
||||||
form_parameter
|
|
||||||
end
|
|
||||||
|
|
||||||
WSF_REQUEST_EXPORTER
|
|
||||||
|
|
||||||
WSF_XSS_UTILITIES
|
|
||||||
|
|
||||||
create
|
|
||||||
make_from_request
|
|
||||||
|
|
||||||
feature {NONE} -- Creation
|
|
||||||
|
|
||||||
make_from_request (req: WSF_REQUEST)
|
|
||||||
do
|
|
||||||
make_from_wgi (req.wgi_request)
|
|
||||||
end
|
|
||||||
|
|
||||||
feature -- Query parameters
|
|
||||||
|
|
||||||
query_parameter (a_name: READABLE_STRING_GENERAL): detachable WSF_VALUE
|
|
||||||
-- Query parameter for name `a_name'.
|
|
||||||
do
|
|
||||||
Result := safe_query_parameter (Current, a_name)
|
|
||||||
end
|
|
||||||
|
|
||||||
feature -- Form Parameters
|
|
||||||
|
|
||||||
form_parameter (a_name: READABLE_STRING_GENERAL): detachable WSF_VALUE
|
|
||||||
do
|
|
||||||
Result := safe_form_parameter (Current, a_name)
|
|
||||||
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
|
|
||||||
106
library/server/wsf/security/support/wsf_protection_patterns.e
Normal file
106
library/server/wsf/security/support/wsf_protection_patterns.e
Normal file
@@ -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 := "<!--#(include|exec|echo|config|printenv)\s+.*"
|
||||||
|
Result := compiled_regexp (p, True)
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- SQL injection Patterns
|
||||||
|
|
||||||
|
SQL_injection_regular_expression: REGULAR_EXPRESSION
|
||||||
|
note
|
||||||
|
EIS: "name= SQL Injection", "src=https://docs.apigee.com/api-services/reference/regular-expression-protection", "protocol=uri"
|
||||||
|
local
|
||||||
|
p: STRING_32
|
||||||
|
once
|
||||||
|
p := "[\s]*((delete)|(exec)|(drop\s*table)|(insert)|(shutdown)|(update)|(\bor\b))"
|
||||||
|
Result := compiled_regexp (p, True)
|
||||||
|
end
|
||||||
|
|
||||||
|
feature {NONE} -- Implementation
|
||||||
|
|
||||||
|
compiled_regexp (p: STRING; caseless: BOOLEAN): REGULAR_EXPRESSION
|
||||||
|
require
|
||||||
|
p /= Void
|
||||||
|
do
|
||||||
|
create Result
|
||||||
|
Result.set_caseless (caseless)
|
||||||
|
Result.compile (p)
|
||||||
|
ensure
|
||||||
|
Result.is_compiled
|
||||||
|
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
|
||||||
518
library/server/wsf/security/support/wsf_protection_policy.e
Normal file
518
library/server/wsf/security/support/wsf_protection_policy.e
Normal file
@@ -0,0 +1,518 @@
|
|||||||
|
note
|
||||||
|
description: "Return data for WSF_REQUEST query and form parameters using different types of protection policy"
|
||||||
|
date: "$Date$"
|
||||||
|
revision: "$Revision$"
|
||||||
|
|
||||||
|
class
|
||||||
|
WSF_PROTECTION_POLICY
|
||||||
|
|
||||||
|
-- TODO add header protection.
|
||||||
|
|
||||||
|
feature -- Query parameters
|
||||||
|
|
||||||
|
custom_query_parameter (a_req: WSF_REQUEST; a_name: READABLE_STRING_GENERAL; a_protections: ARRAY [REGULAR_EXPRESSION]): detachable WSF_VALUE
|
||||||
|
-- Filtered Query parameter name `a_name' with custom protections.
|
||||||
|
do
|
||||||
|
Result := custom_wsf_value (a_req.query_parameter (a_name), a_protections)
|
||||||
|
end
|
||||||
|
|
||||||
|
predefined_query_parameter (a_req: WSF_REQUEST; a_name: READABLE_STRING_GENERAL): detachable WSF_VALUE
|
||||||
|
-- Filtered Query parameter name `a_name' with all predefined protections.
|
||||||
|
-- check {WSF_PROTECTION_PATTERNS} class.
|
||||||
|
do
|
||||||
|
Result := predefined_value (a_req.query_parameter (a_name))
|
||||||
|
end
|
||||||
|
|
||||||
|
xss_query_parameter (a_req: WSF_REQUEST; a_name: READABLE_STRING_GENERAL): detachable WSF_VALUE
|
||||||
|
-- Filtered Query parameter name `a_name' with xss protection.
|
||||||
|
do
|
||||||
|
Result := xss_value (a_req.query_parameter (a_name))
|
||||||
|
end
|
||||||
|
|
||||||
|
xss_js_query_parameter (a_req: WSF_REQUEST; a_name: READABLE_STRING_GENERAL): detachable WSF_VALUE
|
||||||
|
-- Filtered Query parameter name `a_name' with xss protection.
|
||||||
|
do
|
||||||
|
Result := xss_js_value (a_req.query_parameter (a_name))
|
||||||
|
end
|
||||||
|
|
||||||
|
sql_query_parameter (a_req: WSF_REQUEST; a_name: READABLE_STRING_GENERAL): detachable WSF_VALUE
|
||||||
|
-- Filtered Query parameter name `a_name' with sql injection protection.
|
||||||
|
do
|
||||||
|
Result := sql_value (a_req.query_parameter (a_name))
|
||||||
|
end
|
||||||
|
|
||||||
|
server_side_query_parameter (a_req: WSF_REQUEST; a_name: READABLE_STRING_GENERAL): detachable WSF_VALUE
|
||||||
|
-- Filtered Query parameter name `a_name' with server side injection protection.
|
||||||
|
do
|
||||||
|
Result := server_side_value (a_req.query_parameter (a_name))
|
||||||
|
end
|
||||||
|
|
||||||
|
xpath_abbreviated_query_parameter (a_req: WSF_REQUEST; a_name: READABLE_STRING_GENERAL): detachable WSF_VALUE
|
||||||
|
-- Filtered Query parameter name `a_name' with XPath_abbreviated injection protection.
|
||||||
|
do
|
||||||
|
Result := xpath_abbreviated_value (a_req.query_parameter (a_name))
|
||||||
|
end
|
||||||
|
|
||||||
|
xpath_expanded_query_parameter (a_req: WSF_REQUEST; a_name: READABLE_STRING_GENERAL): detachable WSF_VALUE
|
||||||
|
-- Filtered Query parameter name `a_name' with XPath expanded injection protection.
|
||||||
|
do
|
||||||
|
Result := xpath_expanded_value (a_req.query_parameter (a_name))
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Form Parameters
|
||||||
|
|
||||||
|
custom_form_parameter (a_req: WSF_REQUEST; a_name: READABLE_STRING_GENERAL; a_protections: ARRAY [REGULAR_EXPRESSION]): detachable WSF_VALUE
|
||||||
|
-- Filtered Form parameter name `a_name' with custom protections.
|
||||||
|
do
|
||||||
|
Result := custom_wsf_value (a_req.form_parameter (a_name), a_protections)
|
||||||
|
end
|
||||||
|
|
||||||
|
predefined_form_parameter (a_req: WSF_REQUEST; a_name: READABLE_STRING_GENERAL): detachable WSF_VALUE
|
||||||
|
-- Filtered Form parameter name `a_name' with all predefined protections.
|
||||||
|
-- check {WSF_PROTECTION_PATTERNS} class.
|
||||||
|
do
|
||||||
|
Result := predefined_value (a_req.form_parameter (a_name))
|
||||||
|
end
|
||||||
|
|
||||||
|
xss_form_parameter (a_req: WSF_REQUEST; a_name: READABLE_STRING_GENERAL): detachable WSF_VALUE
|
||||||
|
-- Filtered Form parameter name `a_name' with xss protection.
|
||||||
|
do
|
||||||
|
Result := xss_value (a_req.form_parameter (a_name))
|
||||||
|
end
|
||||||
|
|
||||||
|
xss_js_form_parameter (a_req: WSF_REQUEST; a_name: READABLE_STRING_GENERAL): detachable WSF_VALUE
|
||||||
|
-- Filtered Form parameter name `a_name' with xss protection.
|
||||||
|
do
|
||||||
|
Result := xss_js_value (a_req.form_parameter (a_name))
|
||||||
|
end
|
||||||
|
|
||||||
|
sql_form_parameter (a_req: WSF_REQUEST; a_name: READABLE_STRING_GENERAL): detachable WSF_VALUE
|
||||||
|
-- Filtered Form parameter name `a_name' with sql injection protection.
|
||||||
|
do
|
||||||
|
Result := sql_value (a_req.form_parameter (a_name))
|
||||||
|
end
|
||||||
|
|
||||||
|
server_side_form_parameter (a_req: WSF_REQUEST; a_name: READABLE_STRING_GENERAL): detachable WSF_VALUE
|
||||||
|
-- Filtered Form parameter name `a_name' with server side injection protection.
|
||||||
|
do
|
||||||
|
Result := server_side_value (a_req.form_parameter (a_name))
|
||||||
|
end
|
||||||
|
|
||||||
|
xpath_abbreviated_form_parameter (a_req: WSF_REQUEST; a_name: READABLE_STRING_GENERAL): detachable WSF_VALUE
|
||||||
|
-- Filtered Form parameter name `a_name' with server Xpath abbreviated injection protection.
|
||||||
|
do
|
||||||
|
Result := xpath_abbreviated_value (a_req.form_parameter (a_name))
|
||||||
|
end
|
||||||
|
|
||||||
|
xpath_expanded_form_parameter (a_req: WSF_REQUEST; a_name: READABLE_STRING_GENERAL): detachable WSF_VALUE
|
||||||
|
-- Filtered Form parameter name `a_name' with server Xpath expanded injection protection.
|
||||||
|
do
|
||||||
|
Result := xpath_expanded_value (a_req.form_parameter (a_name))
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Meta Variables
|
||||||
|
|
||||||
|
custom_meta_variable (a_req: WSF_REQUEST; a_name: READABLE_STRING_GENERAL; a_protections: ARRAY [REGULAR_EXPRESSION]): detachable WSF_VALUE
|
||||||
|
-- Filtered CGI Meta variable name `a_name' with custom protections.
|
||||||
|
require
|
||||||
|
a_name_valid: a_name /= Void and then not a_name.is_empty
|
||||||
|
do
|
||||||
|
if attached {WSF_STRING} custom_wsf_value (a_req.meta_variable (a_name), a_protections) as l_result then
|
||||||
|
Result := l_result
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
predefined_meta_variable (a_req: WSF_REQUEST; a_name: READABLE_STRING_GENERAL): detachable WSF_VALUE
|
||||||
|
-- Filtered CGI Meta variable name `a_name' with predefined protections.
|
||||||
|
-- check {WSF_PROTECTION_PATTERNS} class.
|
||||||
|
require
|
||||||
|
a_name_valid: a_name /= Void and then not a_name.is_empty
|
||||||
|
do
|
||||||
|
if attached {WSF_STRING} predefined_value (a_req.meta_variable (a_name)) as l_result then
|
||||||
|
Result := l_result
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
xss_meta_variable (a_req: WSF_REQUEST; a_name: READABLE_STRING_GENERAL): detachable WSF_STRING
|
||||||
|
-- Filtered CGI Meta variable name `a_name' with xss protection.
|
||||||
|
require
|
||||||
|
a_name_valid: a_name /= Void and then not a_name.is_empty
|
||||||
|
do
|
||||||
|
if attached {WSF_STRING} xss_value (a_req.meta_variable (a_name)) as l_result then
|
||||||
|
Result := l_result
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
xss_js_meta_variable (a_req: WSF_REQUEST; a_name: READABLE_STRING_GENERAL): detachable WSF_STRING
|
||||||
|
-- Filtered CGI Meta variable name `a_name' with xss protection.
|
||||||
|
require
|
||||||
|
a_name_valid: a_name /= Void and then not a_name.is_empty
|
||||||
|
do
|
||||||
|
if attached {WSF_STRING} xss_js_value (a_req.meta_variable (a_name)) as l_result then
|
||||||
|
Result := l_result
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
sql_meta_variable (a_req: WSF_REQUEST; a_name: READABLE_STRING_GENERAL): detachable WSF_STRING
|
||||||
|
-- Filtered CGI Meta variable name `a_name' with sql injection protection.
|
||||||
|
require
|
||||||
|
a_name_valid: a_name /= Void and then not a_name.is_empty
|
||||||
|
do
|
||||||
|
if attached {WSF_STRING} sql_value (a_req.meta_variable (a_name)) as l_result then
|
||||||
|
Result := l_result
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
server_side_meta_variable (a_req: WSF_REQUEST; a_name: READABLE_STRING_GENERAL): detachable WSF_STRING
|
||||||
|
-- Filtered CGI Meta variable name `a_name' with server side injection protection.
|
||||||
|
require
|
||||||
|
a_name_valid: a_name /= Void and then not a_name.is_empty
|
||||||
|
do
|
||||||
|
if attached {WSF_STRING} server_side_value (a_req.meta_variable (a_name)) as l_result then
|
||||||
|
Result := l_result
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
xpath_abbreviated_side_meta_variable (a_req: WSF_REQUEST; a_name: READABLE_STRING_GENERAL): detachable WSF_STRING
|
||||||
|
-- Filtered CGI Meta variable name `a_name' with Xpath abbreviated injection protection.
|
||||||
|
require
|
||||||
|
a_name_valid: a_name /= Void and then not a_name.is_empty
|
||||||
|
do
|
||||||
|
if attached {WSF_STRING} xpath_abbreviated_value (a_req.meta_variable (a_name)) as l_result then
|
||||||
|
Result := l_result
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
xpath_expanded_side_meta_variable (a_req: WSF_REQUEST; a_name: READABLE_STRING_GENERAL): detachable WSF_STRING
|
||||||
|
-- Filtered CGI Meta variable name `a_name' with Xpath abbreviated injection protection.
|
||||||
|
require
|
||||||
|
a_name_valid: a_name /= Void and then not a_name.is_empty
|
||||||
|
do
|
||||||
|
if attached {WSF_STRING} xpath_expanded_value (a_req.meta_variable (a_name)) as l_result then
|
||||||
|
Result := l_result
|
||||||
|
end
|
||||||
|
end
|
||||||
|
feature -- HTTP_*
|
||||||
|
|
||||||
|
custom_http_accept (a_req: WSF_REQUEST; a_protections: ARRAY [REGULAR_EXPRESSION]): detachable READABLE_STRING_8
|
||||||
|
-- Filtered http_accept header with custom protections `a_protections`.
|
||||||
|
-- Contents of the Accept: header from the current wgi_request, if there is one.
|
||||||
|
-- Example: 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8'
|
||||||
|
do
|
||||||
|
Result := custom_string_value (a_req.http_accept, a_protections)
|
||||||
|
end
|
||||||
|
|
||||||
|
custom_http_accept_charset (a_req: WSF_REQUEST; a_protections: ARRAY [REGULAR_EXPRESSION]): detachable READABLE_STRING_8
|
||||||
|
-- Filtered http_accept_charset header with custom protections `a_protections`.
|
||||||
|
-- Contents of the Accept-Charset: header from the current wgi_request, if there is one.
|
||||||
|
-- Example: 'iso-8859-1,*,utf-8'.
|
||||||
|
|
||||||
|
do
|
||||||
|
Result := custom_string_value (a_req.http_accept_charset, a_protections)
|
||||||
|
end
|
||||||
|
|
||||||
|
custom_http_accept_encoding (a_req: WSF_REQUEST; a_protections: ARRAY [REGULAR_EXPRESSION]): detachable READABLE_STRING_8
|
||||||
|
-- Filtered http_accept_encoding header with custom protections `a_protections`.
|
||||||
|
-- Contents of the Accept-Encoding: header from the current wgi_request, if there is one.
|
||||||
|
-- Example: 'gzip'.
|
||||||
|
do
|
||||||
|
Result := custom_string_value (a_req.http_accept_encoding, a_protections)
|
||||||
|
end
|
||||||
|
|
||||||
|
custom_http_accept_language (a_req: WSF_REQUEST; a_protections: ARRAY [REGULAR_EXPRESSION]): detachable READABLE_STRING_8
|
||||||
|
-- Filtered http_accept_language header with custom protections `a_protections`.
|
||||||
|
-- Contents of the Accept-Language: header from the current wgi_request, if there is one.
|
||||||
|
-- Example: 'en'.
|
||||||
|
do
|
||||||
|
Result := custom_string_value (a_req.http_accept_language, a_protections)
|
||||||
|
end
|
||||||
|
|
||||||
|
custom_http_connection (a_req: WSF_REQUEST; a_protections: ARRAY [REGULAR_EXPRESSION]): detachable READABLE_STRING_8
|
||||||
|
-- Filtered http_connection header with custom protections `a_protections`.
|
||||||
|
-- Contents of the Connection: header from the current wgi_request, if there is one.
|
||||||
|
-- Example: 'keep-alive'.
|
||||||
|
do
|
||||||
|
Result := custom_string_value (a_req.http_connection, a_protections)
|
||||||
|
end
|
||||||
|
|
||||||
|
custom_http_expect (a_req: WSF_REQUEST; a_protections: ARRAY [REGULAR_EXPRESSION]): detachable READABLE_STRING_8
|
||||||
|
-- Filtered http_expect header with custom protections `a_protections`.
|
||||||
|
-- The Expect request-header field is used to indicate that particular server behaviors are required by the client.
|
||||||
|
-- Example: '100-continue'.
|
||||||
|
do
|
||||||
|
Result := custom_string_value (a_req.http_expect, a_protections)
|
||||||
|
end
|
||||||
|
|
||||||
|
custom_http_host (a_req: WSF_REQUEST; a_protections: ARRAY [REGULAR_EXPRESSION]): detachable READABLE_STRING_8
|
||||||
|
-- Filtered http_host header with custom protections `a_protections`.
|
||||||
|
-- Contents of the Host: header from the current wgi_request, if there is one.
|
||||||
|
do
|
||||||
|
Result := custom_string_value (a_req.http_host, a_protections)
|
||||||
|
end
|
||||||
|
|
||||||
|
custom_http_referer (a_req: WSF_REQUEST; a_protections: ARRAY [REGULAR_EXPRESSION]): detachable READABLE_STRING_8
|
||||||
|
-- Filtered http_referer header with custom protections `a_protections`.
|
||||||
|
-- The address of the page (if any) which referred the user agent to the current page.
|
||||||
|
-- This is set by the user agent.
|
||||||
|
-- Not all user agents will set this, and some provide the ability to modify HTTP_REFERER as a feature.
|
||||||
|
-- In short, it cannot really be trusted.
|
||||||
|
do
|
||||||
|
Result := custom_string_value (a_req.http_referer, a_protections)
|
||||||
|
end
|
||||||
|
|
||||||
|
custom_http_user_agent (a_req: WSF_REQUEST; a_protections: ARRAY [REGULAR_EXPRESSION]): detachable READABLE_STRING_8
|
||||||
|
-- Filtered http_user_agent header with custom protections `a_protections`.
|
||||||
|
-- Contents of the User-Agent: header from the current wgi_request, if there is one.
|
||||||
|
-- This is a string denoting the user agent being which is accessing the page.
|
||||||
|
-- A typical example is: Mozilla/4.5 [en] (X11; U; Linux 2.2.9 i586).
|
||||||
|
-- Among other things, you can use this value to tailor your page's
|
||||||
|
-- output to the capabilities of the user agent.
|
||||||
|
do
|
||||||
|
Result := custom_string_value (a_req.http_user_agent, a_protections)
|
||||||
|
end
|
||||||
|
|
||||||
|
custom_http_authorization (a_req: WSF_REQUEST; a_protections: ARRAY [REGULAR_EXPRESSION]): detachable READABLE_STRING_8
|
||||||
|
-- Filtered http_authorization header with custom protections `a_protections`.
|
||||||
|
-- Contents of the Authorization: header from the current wgi_request, if there is one.
|
||||||
|
do
|
||||||
|
Result := custom_string_value (a_req.http_authorization, a_protections)
|
||||||
|
end
|
||||||
|
|
||||||
|
custom_http_transfer_encoding (a_req: WSF_REQUEST; a_protections: ARRAY [REGULAR_EXPRESSION]): detachable READABLE_STRING_8
|
||||||
|
-- Filtered http_transfer_encoding header with custom protections `a_protections`.
|
||||||
|
-- Transfer-Encoding
|
||||||
|
-- for instance chunked.
|
||||||
|
do
|
||||||
|
Result := custom_string_value (a_req.http_transfer_encoding, a_protections)
|
||||||
|
end
|
||||||
|
|
||||||
|
custom_http_access_control_request_headers (a_req: WSF_REQUEST; a_protections: ARRAY [REGULAR_EXPRESSION]): detachable READABLE_STRING_8
|
||||||
|
-- Filtered http_access_control_request_headers header with custom protections `a_protections`.
|
||||||
|
-- Indicates which headers will be used in the actual request
|
||||||
|
-- as part of the preflight request
|
||||||
|
do
|
||||||
|
Result := custom_string_value (a_req.http_access_control_request_headers, a_protections)
|
||||||
|
end
|
||||||
|
|
||||||
|
custom_http_if_match (a_req: WSF_REQUEST; a_protections: ARRAY [REGULAR_EXPRESSION]): detachable READABLE_STRING_8
|
||||||
|
-- Filtered http_if_match header with custom protections `a_protections`.
|
||||||
|
-- Existence check on resource.
|
||||||
|
do
|
||||||
|
Result := custom_string_value (a_req.http_if_match, a_protections)
|
||||||
|
end
|
||||||
|
|
||||||
|
custom_http_if_modified_since (a_req: WSF_REQUEST; a_protections: ARRAY [REGULAR_EXPRESSION]): detachable READABLE_STRING_8
|
||||||
|
-- Filtered http_if_modified_since header with custom protections `a_protections`.
|
||||||
|
-- Modification check on resource.
|
||||||
|
do
|
||||||
|
Result := custom_string_value (a_req.http_if_modified_since, a_protections)
|
||||||
|
end
|
||||||
|
|
||||||
|
custom_http_if_none_match (a_req: WSF_REQUEST; a_protections: ARRAY [REGULAR_EXPRESSION]): detachable READABLE_STRING_8
|
||||||
|
-- Filtered http_if_none_match header with custom protections `a_protections`.
|
||||||
|
-- Existence check on resource.
|
||||||
|
do
|
||||||
|
Result := custom_string_value (a_req.http_if_none_match, a_protections)
|
||||||
|
end
|
||||||
|
|
||||||
|
custom_http_if_range (a_req: WSF_REQUEST; a_protections: ARRAY [REGULAR_EXPRESSION]): detachable READABLE_STRING_8
|
||||||
|
-- Filtered http_if_range header with custom protections `a_protections`.
|
||||||
|
-- Existence check on resource.
|
||||||
|
do
|
||||||
|
Result := custom_string_value (a_req.http_if_range, a_protections)
|
||||||
|
end
|
||||||
|
|
||||||
|
custom_http_if_unmodified_since (a_req: WSF_REQUEST; a_protections: ARRAY [REGULAR_EXPRESSION]): detachable READABLE_STRING_8
|
||||||
|
-- Filtered http_if_unmodified_since header with custom protections `a_protections`.
|
||||||
|
-- Modification check on resource.
|
||||||
|
do
|
||||||
|
Result := custom_string_value (a_req.http_if_unmodified_since, a_protections)
|
||||||
|
end
|
||||||
|
|
||||||
|
custom_http_last_modified (a_req: WSF_REQUEST; a_protections: ARRAY [REGULAR_EXPRESSION]): detachable READABLE_STRING_8
|
||||||
|
-- Filtered http_last_modified header with custom protections `a_protections`.
|
||||||
|
-- Modification check on resource.
|
||||||
|
do
|
||||||
|
Result := custom_string_value (a_req.http_last_modified, a_protections)
|
||||||
|
end
|
||||||
|
|
||||||
|
custom_http_range (a_req: WSF_REQUEST; a_protections: ARRAY [REGULAR_EXPRESSION]): detachable READABLE_STRING_8
|
||||||
|
-- Filtered http_range header with custom protections `a_protections`.
|
||||||
|
-- Requested byte-range of resource.
|
||||||
|
do
|
||||||
|
Result := custom_string_value (a_req.http_range, a_protections)
|
||||||
|
end
|
||||||
|
|
||||||
|
custom_http_content_range (a_req: WSF_REQUEST; a_protections: ARRAY [REGULAR_EXPRESSION]): detachable READABLE_STRING_8
|
||||||
|
-- Filtered http_content_range header with custom protections `a_protections`.
|
||||||
|
-- Partial range of selected representation enclosed in message payload.
|
||||||
|
do
|
||||||
|
Result := custom_string_value (a_req.http_content_range, a_protections)
|
||||||
|
end
|
||||||
|
|
||||||
|
custom_http_content_encoding (a_req: WSF_REQUEST; a_protections: ARRAY [REGULAR_EXPRESSION]): detachable READABLE_STRING_8
|
||||||
|
-- Filtered http_content_encoding header with custom protections `a_protections`.
|
||||||
|
-- Encoding (usually compression) of message payload.
|
||||||
|
do
|
||||||
|
Result := custom_string_value (a_req.http_content_encoding, a_protections)
|
||||||
|
end
|
||||||
|
|
||||||
|
feature {NONE} -- Implementation
|
||||||
|
|
||||||
|
custom_wsf_value (a_value: detachable WSF_VALUE; a_protections: ARRAY [REGULAR_EXPRESSION]): detachable WSF_VALUE
|
||||||
|
-- Return value `a_value` filtered by all protections policy.
|
||||||
|
local
|
||||||
|
l_wsf_xss: WSF_PROTECTION_PATTERNS
|
||||||
|
do
|
||||||
|
Result := filter_wsf_value (a_value, a_protections )
|
||||||
|
end
|
||||||
|
|
||||||
|
custom_string_value (a_value: detachable READABLE_STRING_8; a_protections: ARRAY [REGULAR_EXPRESSION]): detachable READABLE_STRING_8
|
||||||
|
-- Return value `a_value` filtered by all protections policy.
|
||||||
|
local
|
||||||
|
l_wsf_xss: WSF_PROTECTION_PATTERNS
|
||||||
|
do
|
||||||
|
Result := filter_string_value (a_value, a_protections )
|
||||||
|
end
|
||||||
|
|
||||||
|
predefined_value (a_value: detachable WSF_VALUE): detachable WSF_VALUE
|
||||||
|
-- Return value `a_value` filtered by all predefined protections policy.
|
||||||
|
local
|
||||||
|
l_wsf_xss: WSF_PROTECTION_PATTERNS
|
||||||
|
do
|
||||||
|
Result := filter_wsf_value (a_value,
|
||||||
|
{ARRAY [REGULAR_EXPRESSION]}<<
|
||||||
|
l_wsf_xss.XSS_regular_expression,
|
||||||
|
l_wsf_xss.server_side_expression,
|
||||||
|
l_wsf_xss.sql_injection_regular_expression,
|
||||||
|
l_wsf_xss.xpath_abbreviated_expression,
|
||||||
|
l_wsf_xss.xpath_expanded_expression>>)
|
||||||
|
end
|
||||||
|
|
||||||
|
xss_value (a_value: detachable WSF_VALUE): detachable WSF_VALUE
|
||||||
|
-- Return value `a_value` filtered by xss protection.
|
||||||
|
local
|
||||||
|
l_wsf_xss: WSF_PROTECTION_PATTERNS
|
||||||
|
do
|
||||||
|
Result := filter_wsf_value (a_value, {ARRAY [REGULAR_EXPRESSION]}<<l_wsf_xss.XSS_regular_expression>>)
|
||||||
|
end
|
||||||
|
|
||||||
|
xss_js_value (a_value: detachable WSF_VALUE): detachable WSF_VALUE
|
||||||
|
-- Return value `a_value` filtered by xss-javascript protection.
|
||||||
|
local
|
||||||
|
l_wsf_xss: WSF_PROTECTION_PATTERNS
|
||||||
|
do
|
||||||
|
Result := filter_wsf_value (a_value, {ARRAY [REGULAR_EXPRESSION]} <<l_wsf_xss.XSS_javascript_expression>>)
|
||||||
|
end
|
||||||
|
|
||||||
|
sql_value (a_value: detachable WSF_VALUE): detachable WSF_VALUE
|
||||||
|
-- Return value `a_value` filtered by sql injection protection.
|
||||||
|
local
|
||||||
|
l_wsf_xss: WSF_PROTECTION_PATTERNS
|
||||||
|
do
|
||||||
|
Result := filter_wsf_value (a_value, {ARRAY [REGULAR_EXPRESSION]} <<l_wsf_xss.SQL_injection_regular_expression>>)
|
||||||
|
end
|
||||||
|
|
||||||
|
server_side_value (a_value: detachable WSF_VALUE): detachable WSF_VALUE
|
||||||
|
-- Return value `a_value` filtered by server side injection protection.
|
||||||
|
local
|
||||||
|
l_wsf_xss: WSF_PROTECTION_PATTERNS
|
||||||
|
do
|
||||||
|
Result := filter_wsf_value (a_value, {ARRAY [REGULAR_EXPRESSION]} <<l_wsf_xss.Server_side_expression>>)
|
||||||
|
end
|
||||||
|
|
||||||
|
xpath_abbreviated_value (a_value: detachable WSF_VALUE): detachable WSF_VALUE
|
||||||
|
-- Return value `a_value` filtered by xpath_abbreviated injection protection.
|
||||||
|
local
|
||||||
|
l_wsf_xss: WSF_PROTECTION_PATTERNS
|
||||||
|
do
|
||||||
|
Result := filter_wsf_value (a_value, {ARRAY [REGULAR_EXPRESSION]} <<l_wsf_xss.Xpath_abbreviated_expression>>)
|
||||||
|
end
|
||||||
|
|
||||||
|
xpath_expanded_value (a_value: detachable WSF_VALUE): detachable WSF_VALUE
|
||||||
|
-- Return value `a_value` filtered by Xpath expanded injection protection.
|
||||||
|
local
|
||||||
|
l_wsf_xss: WSF_PROTECTION_PATTERNS
|
||||||
|
do
|
||||||
|
Result := filter_wsf_value (a_value, {ARRAY [REGULAR_EXPRESSION]} <<l_wsf_xss.Xpath_expanded_expression>>)
|
||||||
|
end
|
||||||
|
|
||||||
|
filter_wsf_value (a_value: detachable WSF_VALUE; a_regex: ARRAY [REGULAR_EXPRESSION] ): detachable WSF_VALUE
|
||||||
|
-- Filter value `a_value` with an array of protections policy `a_regex`.
|
||||||
|
local
|
||||||
|
not_first: BOOLEAN
|
||||||
|
do
|
||||||
|
Result := a_value
|
||||||
|
if Result /= Void then
|
||||||
|
if
|
||||||
|
attached {WSF_STRING} Result as str and then
|
||||||
|
a_regex.for_all (agent is_compiled)
|
||||||
|
then
|
||||||
|
a_regex.do_all (agent match (?, str.value))
|
||||||
|
if a_regex.there_exists (agent has_matched) then
|
||||||
|
create {WSF_STRING} Result.make (str.name, " ")
|
||||||
|
end
|
||||||
|
elseif
|
||||||
|
attached {WSF_MULTIPLE_STRING} Result as l_multi_str and then
|
||||||
|
a_regex.for_all (agent is_compiled)
|
||||||
|
then
|
||||||
|
across l_multi_str as ic loop
|
||||||
|
a_regex.do_all (agent match (?, ic.item.value))
|
||||||
|
if a_regex.there_exists (agent has_matched ) then
|
||||||
|
if not_first and then attached {WSF_MULTIPLE_STRING} Result as l_result then
|
||||||
|
l_result.add_value ( (create {WSF_STRING}.make (ic.item.name, " ")))
|
||||||
|
else
|
||||||
|
create {WSF_MULTIPLE_STRING} Result.make_with_string (ic.item.name, " ")
|
||||||
|
not_first := True
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
filter_string_value (a_value: detachable READABLE_STRING_8; a_regex: ARRAY [REGULAR_EXPRESSION] ): detachable READABLE_STRING_8
|
||||||
|
-- Filter value `a_value` with an array of protections policy `a_regex`.
|
||||||
|
do
|
||||||
|
Result := a_value
|
||||||
|
if Result /= Void then
|
||||||
|
if
|
||||||
|
attached a_value as l_value and then
|
||||||
|
a_regex.for_all (agent is_compiled)
|
||||||
|
then
|
||||||
|
a_regex.do_all (agent match (?, l_value))
|
||||||
|
if a_regex.there_exists (agent has_matched) then
|
||||||
|
create {STRING_8} Result.make_empty
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
is_compiled (a_regex: REGULAR_EXPRESSION): BOOLEAN
|
||||||
|
-- Is the regular expression 'a_regex' compiled?
|
||||||
|
do
|
||||||
|
Result := a_regex.is_compiled
|
||||||
|
end
|
||||||
|
|
||||||
|
match (a_regex: REGULAR_EXPRESSION; a_value: READABLE_STRING_32)
|
||||||
|
do
|
||||||
|
a_regex.match (a_value)
|
||||||
|
end
|
||||||
|
|
||||||
|
has_matched (a_regex: REGULAR_EXPRESSION): BOOLEAN
|
||||||
|
do
|
||||||
|
Result := a_regex.has_matched
|
||||||
|
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
|
||||||
260
library/server/wsf/security/wsf_xss_request.e
Normal file
260
library/server/wsf/security/wsf_xss_request.e
Normal file
@@ -0,0 +1,260 @@
|
|||||||
|
note
|
||||||
|
description: "[
|
||||||
|
XSS request, redefine query_parameter and form_parameters filtering the data (using XSS protection)
|
||||||
|
before return the value.
|
||||||
|
The XSS protection pattern used is defined here :{WSF_PROTECTION_PATTERNS}.XSS_regular_expression: REGULAR_EXPRESSION
|
||||||
|
|
||||||
|
]"
|
||||||
|
date: "$Date$"
|
||||||
|
revision: "$Revision$"
|
||||||
|
|
||||||
|
class
|
||||||
|
WSF_XSS_REQUEST
|
||||||
|
|
||||||
|
inherit
|
||||||
|
WSF_REQUEST
|
||||||
|
redefine
|
||||||
|
query_parameter,
|
||||||
|
form_parameter,
|
||||||
|
meta_variable,
|
||||||
|
http_accept,
|
||||||
|
http_accept_charset,
|
||||||
|
http_accept_encoding,
|
||||||
|
http_accept_language,
|
||||||
|
http_connection,
|
||||||
|
http_expect,
|
||||||
|
http_host,
|
||||||
|
http_referer,
|
||||||
|
http_user_agent,
|
||||||
|
http_authorization,
|
||||||
|
http_transfer_encoding,
|
||||||
|
http_access_control_request_headers,
|
||||||
|
http_if_match,
|
||||||
|
http_if_modified_since,
|
||||||
|
http_if_none_match,
|
||||||
|
http_if_range,
|
||||||
|
http_if_unmodified_since,
|
||||||
|
http_last_modified,
|
||||||
|
http_range,
|
||||||
|
http_content_range,
|
||||||
|
http_content_encoding
|
||||||
|
end
|
||||||
|
|
||||||
|
WSF_REQUEST_EXPORTER
|
||||||
|
|
||||||
|
WSF_PROTECTION_POLICY
|
||||||
|
|
||||||
|
create
|
||||||
|
make_from_request
|
||||||
|
|
||||||
|
feature {NONE} -- Creation
|
||||||
|
|
||||||
|
make_from_request (req: WSF_REQUEST)
|
||||||
|
do
|
||||||
|
make_from_wgi (req.wgi_request)
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Query parameters
|
||||||
|
|
||||||
|
query_parameter (a_name: READABLE_STRING_GENERAL): detachable WSF_VALUE
|
||||||
|
-- <Precursor>
|
||||||
|
do
|
||||||
|
Result := xss_query_parameter (Current, a_name)
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Form Parameters
|
||||||
|
|
||||||
|
form_parameter (a_name: READABLE_STRING_GENERAL): detachable WSF_VALUE
|
||||||
|
-- <Precursor>
|
||||||
|
do
|
||||||
|
Result := xss_form_parameter (Current, a_name)
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Meta Variable
|
||||||
|
|
||||||
|
meta_variable (a_name: READABLE_STRING_GENERAL): detachable WSF_STRING
|
||||||
|
-- <Precursor>
|
||||||
|
do
|
||||||
|
Result := xss_meta_variable (Current, a_name)
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- HTTP_*
|
||||||
|
|
||||||
|
http_accept: detachable READABLE_STRING_8
|
||||||
|
-- <Precursor>
|
||||||
|
local
|
||||||
|
l_protection: WSF_PROTECTION_PATTERNS
|
||||||
|
do
|
||||||
|
Result := custom_http_accept (Current, {ARRAY [REGULAR_EXPRESSION]}<<l_protection.xss_regular_expression>>)
|
||||||
|
end
|
||||||
|
|
||||||
|
http_accept_charset: detachable READABLE_STRING_8
|
||||||
|
-- <Precursor>
|
||||||
|
local
|
||||||
|
l_protection: WSF_PROTECTION_PATTERNS
|
||||||
|
do
|
||||||
|
Result := custom_http_accept_charset (Current, {ARRAY [REGULAR_EXPRESSION]}<<l_protection.xss_regular_expression>>)
|
||||||
|
end
|
||||||
|
|
||||||
|
http_accept_encoding: detachable READABLE_STRING_8
|
||||||
|
-- <Precursor>
|
||||||
|
local
|
||||||
|
l_protection: WSF_PROTECTION_PATTERNS
|
||||||
|
do
|
||||||
|
Result := custom_http_accept_encoding (Current, {ARRAY [REGULAR_EXPRESSION]}<<l_protection.xss_regular_expression>>)
|
||||||
|
end
|
||||||
|
|
||||||
|
http_accept_language: detachable READABLE_STRING_8
|
||||||
|
-- <Precursor>
|
||||||
|
local
|
||||||
|
l_protection: WSF_PROTECTION_PATTERNS
|
||||||
|
do
|
||||||
|
Result := custom_http_accept_language (Current, {ARRAY [REGULAR_EXPRESSION]}<<l_protection.xss_regular_expression>>)
|
||||||
|
end
|
||||||
|
|
||||||
|
http_connection: detachable READABLE_STRING_8
|
||||||
|
-- <Precursor>
|
||||||
|
local
|
||||||
|
l_protection: WSF_PROTECTION_PATTERNS
|
||||||
|
do
|
||||||
|
Result := custom_http_connection (Current, {ARRAY [REGULAR_EXPRESSION]}<<l_protection.xss_regular_expression>>)
|
||||||
|
end
|
||||||
|
|
||||||
|
http_expect: detachable READABLE_STRING_8
|
||||||
|
-- <Precursor>
|
||||||
|
local
|
||||||
|
l_protection: WSF_PROTECTION_PATTERNS
|
||||||
|
do
|
||||||
|
Result := custom_http_expect (Current, {ARRAY [REGULAR_EXPRESSION]}<<l_protection.xss_regular_expression>>)
|
||||||
|
end
|
||||||
|
|
||||||
|
http_host: detachable READABLE_STRING_8
|
||||||
|
-- <Precursor>
|
||||||
|
local
|
||||||
|
l_protection: WSF_PROTECTION_PATTERNS
|
||||||
|
do
|
||||||
|
Result := custom_http_host (Current, {ARRAY [REGULAR_EXPRESSION]}<<l_protection.xss_regular_expression>>)
|
||||||
|
end
|
||||||
|
|
||||||
|
http_referer: detachable READABLE_STRING_8
|
||||||
|
-- <Precursor>
|
||||||
|
local
|
||||||
|
l_protection: WSF_PROTECTION_PATTERNS
|
||||||
|
do
|
||||||
|
Result := custom_http_referer (Current, {ARRAY [REGULAR_EXPRESSION]}<<l_protection.xss_regular_expression>>)
|
||||||
|
end
|
||||||
|
|
||||||
|
http_user_agent: detachable READABLE_STRING_8
|
||||||
|
-- <Precursor>
|
||||||
|
local
|
||||||
|
l_protection: WSF_PROTECTION_PATTERNS
|
||||||
|
do
|
||||||
|
Result := custom_http_user_agent (Current, {ARRAY [REGULAR_EXPRESSION]}<<l_protection.xss_regular_expression>>)
|
||||||
|
end
|
||||||
|
|
||||||
|
http_authorization: detachable READABLE_STRING_8
|
||||||
|
-- <Precursor>
|
||||||
|
local
|
||||||
|
l_protection: WSF_PROTECTION_PATTERNS
|
||||||
|
do
|
||||||
|
Result := custom_http_authorization (Current, {ARRAY [REGULAR_EXPRESSION]}<<l_protection.xss_regular_expression>>)
|
||||||
|
end
|
||||||
|
|
||||||
|
http_transfer_encoding: detachable READABLE_STRING_8
|
||||||
|
-- <Precursor>
|
||||||
|
local
|
||||||
|
l_protection: WSF_PROTECTION_PATTERNS
|
||||||
|
do
|
||||||
|
Result := custom_http_transfer_encoding (Current, {ARRAY [REGULAR_EXPRESSION]}<<l_protection.xss_regular_expression>>)
|
||||||
|
end
|
||||||
|
|
||||||
|
http_access_control_request_headers: detachable READABLE_STRING_8
|
||||||
|
-- <Precursor>
|
||||||
|
local
|
||||||
|
l_protection: WSF_PROTECTION_PATTERNS
|
||||||
|
do
|
||||||
|
Result := custom_http_access_control_request_headers (Current, {ARRAY [REGULAR_EXPRESSION]}<<l_protection.xss_regular_expression>>)
|
||||||
|
end
|
||||||
|
|
||||||
|
http_if_match: detachable READABLE_STRING_8
|
||||||
|
-- <Precursor>
|
||||||
|
local
|
||||||
|
l_protection: WSF_PROTECTION_PATTERNS
|
||||||
|
do
|
||||||
|
Result := custom_http_if_match (Current, {ARRAY [REGULAR_EXPRESSION]}<<l_protection.xss_regular_expression>>)
|
||||||
|
end
|
||||||
|
|
||||||
|
http_if_modified_since: detachable READABLE_STRING_8
|
||||||
|
-- <Precursor>
|
||||||
|
local
|
||||||
|
l_protection: WSF_PROTECTION_PATTERNS
|
||||||
|
do
|
||||||
|
Result := custom_http_if_modified_since (Current, {ARRAY [REGULAR_EXPRESSION]}<<l_protection.xss_regular_expression>>)
|
||||||
|
end
|
||||||
|
|
||||||
|
http_if_none_match: detachable READABLE_STRING_8
|
||||||
|
-- <Precursor>
|
||||||
|
local
|
||||||
|
l_protection: WSF_PROTECTION_PATTERNS
|
||||||
|
do
|
||||||
|
Result := custom_http_if_none_match (Current, {ARRAY [REGULAR_EXPRESSION]}<<l_protection.xss_regular_expression>>)
|
||||||
|
end
|
||||||
|
|
||||||
|
http_if_range: detachable READABLE_STRING_8
|
||||||
|
-- <Precursor>
|
||||||
|
local
|
||||||
|
l_protection: WSF_PROTECTION_PATTERNS
|
||||||
|
do
|
||||||
|
Result := custom_http_if_range (Current, {ARRAY [REGULAR_EXPRESSION]}<<l_protection.xss_regular_expression>>)
|
||||||
|
end
|
||||||
|
|
||||||
|
http_if_unmodified_since: detachable READABLE_STRING_8
|
||||||
|
-- <Precursor>
|
||||||
|
local
|
||||||
|
l_protection: WSF_PROTECTION_PATTERNS
|
||||||
|
do
|
||||||
|
Result := custom_http_if_unmodified_since (Current, {ARRAY [REGULAR_EXPRESSION]}<<l_protection.xss_regular_expression>>)
|
||||||
|
end
|
||||||
|
|
||||||
|
http_last_modified: detachable READABLE_STRING_8
|
||||||
|
-- <Precursor>
|
||||||
|
local
|
||||||
|
l_protection: WSF_PROTECTION_PATTERNS
|
||||||
|
do
|
||||||
|
Result := custom_http_last_modified (Current, {ARRAY [REGULAR_EXPRESSION]}<<l_protection.xss_regular_expression>>)
|
||||||
|
end
|
||||||
|
|
||||||
|
http_range: detachable READABLE_STRING_8
|
||||||
|
-- <Precursor>
|
||||||
|
local
|
||||||
|
l_protection: WSF_PROTECTION_PATTERNS
|
||||||
|
do
|
||||||
|
Result := custom_http_range (Current, {ARRAY [REGULAR_EXPRESSION]}<<l_protection.xss_regular_expression>>)
|
||||||
|
end
|
||||||
|
|
||||||
|
http_content_range: detachable READABLE_STRING_8
|
||||||
|
-- <Precursor>
|
||||||
|
local
|
||||||
|
l_protection: WSF_PROTECTION_PATTERNS
|
||||||
|
do
|
||||||
|
Result := custom_http_content_range (Current, {ARRAY [REGULAR_EXPRESSION]}<<l_protection.xss_regular_expression>>)
|
||||||
|
end
|
||||||
|
|
||||||
|
http_content_encoding: detachable READABLE_STRING_8
|
||||||
|
-- <Precursor>
|
||||||
|
local
|
||||||
|
l_protection: WSF_PROTECTION_PATTERNS
|
||||||
|
do
|
||||||
|
Result := custom_http_content_encoding (Current, {ARRAY [REGULAR_EXPRESSION]}<<l_protection.xss_regular_expression>>)
|
||||||
|
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
|
||||||
129
library/server/wsf/tests/src/test_wsf_protection_policy.e
Normal file
129
library/server/wsf/tests/src/test_wsf_protection_policy.e
Normal file
@@ -0,0 +1,129 @@
|
|||||||
|
note
|
||||||
|
description: "Summary description for {TEST_WSF_PROTECTION_POLICY}."
|
||||||
|
author: ""
|
||||||
|
date: "$Date$"
|
||||||
|
revision: "$Revision$"
|
||||||
|
|
||||||
|
class
|
||||||
|
TEST_WSF_PROTECTION_POLICY
|
||||||
|
|
||||||
|
inherit
|
||||||
|
EQA_TEST_SET
|
||||||
|
WSF_SERVICE
|
||||||
|
undefine
|
||||||
|
default_create
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Test
|
||||||
|
|
||||||
|
test_http_expect_attack_without_xss_protection
|
||||||
|
local
|
||||||
|
req: WSF_REQUEST
|
||||||
|
|
||||||
|
do
|
||||||
|
--| Case HTTP header expect attack, no filtered.
|
||||||
|
req := new_request (<<
|
||||||
|
["REQUEST_METHOD", "GET"],
|
||||||
|
["QUERY_STRING", ""],
|
||||||
|
["REQUEST_URI", "/cookie"],
|
||||||
|
["HTTP_EXPECT", "<script>alert(XSS attack)</script>"]
|
||||||
|
>>
|
||||||
|
)
|
||||||
|
-- no filter
|
||||||
|
assert ("HTTP_EXPECT <script>alert(XSS attack)</script>", attached req.http_expect as v and then v.is_case_insensitive_equal ("<script>alert(XSS attack)</script>"))
|
||||||
|
end
|
||||||
|
|
||||||
|
test_http_expect_attack_with_xss_protection
|
||||||
|
local
|
||||||
|
req: WSF_REQUEST
|
||||||
|
sec: WSF_PROTECTION_POLICY
|
||||||
|
l_protection: WSF_PROTECTION_PATTERNS
|
||||||
|
do
|
||||||
|
create sec
|
||||||
|
--| Case HTTP header expect attack, filtered using {xss_regular_expression}
|
||||||
|
req := new_request (<<
|
||||||
|
["REQUEST_METHOD", "GET"],
|
||||||
|
["QUERY_STRING", ""],
|
||||||
|
["REQUEST_URI", "/xss_example"],
|
||||||
|
["HTTP_EXPECT", "<script>alert(XSS attack)</script>"]
|
||||||
|
>>
|
||||||
|
)
|
||||||
|
assert ("HTTP_EXPECT <script>alert(XSS attack)</script>", attached {READABLE_STRING_8} sec.custom_http_expect (req, {ARRAY [REGULAR_EXPRESSION]}<<l_protection.xss_regular_expression>>) as v and then v.is_empty )
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
test_http_expect_attack_with_xss_js_protection
|
||||||
|
local
|
||||||
|
req: WSF_REQUEST
|
||||||
|
sec: WSF_PROTECTION_POLICY
|
||||||
|
l_protection: WSF_PROTECTION_PATTERNS
|
||||||
|
do
|
||||||
|
create sec
|
||||||
|
--| Case HTTP header expect attack, filtered using {xss_javascript_expression}
|
||||||
|
req := new_request (<<
|
||||||
|
["REQUEST_METHOD", "GET"],
|
||||||
|
["QUERY_STRING", ""],
|
||||||
|
["REQUEST_URI", "/xss_example"],
|
||||||
|
["HTTP_EXPECT", "<script>alert(XSS attack)</script>"]
|
||||||
|
>>
|
||||||
|
)
|
||||||
|
assert ("HTTP_EXPECT <script>alert(XSS attack)</script>", attached {READABLE_STRING_8} sec.custom_http_expect (req, {ARRAY [REGULAR_EXPRESSION]}<<l_protection.xss_javascript_expression>>) as v and then v.is_empty )
|
||||||
|
end
|
||||||
|
|
||||||
|
test_http_referer_attack_with_xss_js_protection_fails
|
||||||
|
local
|
||||||
|
req: WSF_REQUEST
|
||||||
|
sec: WSF_PROTECTION_POLICY
|
||||||
|
l_protection: WSF_PROTECTION_PATTERNS
|
||||||
|
l_str: STRING
|
||||||
|
do
|
||||||
|
l_str:= "[
|
||||||
|
Referer: http://www.google.com/search?hl=en&q=fe525"-alert(1)-"d116a885fd5
|
||||||
|
]"
|
||||||
|
create sec
|
||||||
|
--| Case HTTP header referer attack, filtered using {xss_javascript_expression}
|
||||||
|
req := new_request (<<
|
||||||
|
["REQUEST_METHOD", "GET"],
|
||||||
|
["QUERY_STRING", ""],
|
||||||
|
["REQUEST_URI", "/xss_example"],
|
||||||
|
["HTTP_REFERER", l_str]
|
||||||
|
>>
|
||||||
|
)
|
||||||
|
assert ("HTTP_REFERER", attached {READABLE_STRING_8} sec.custom_http_referer (req, {ARRAY [REGULAR_EXPRESSION]}<<l_protection.xss_javascript_expression>>) as v and then not v.is_empty )
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
test_http_referer_attack_with_xss_protection
|
||||||
|
local
|
||||||
|
req: WSF_REQUEST
|
||||||
|
sec: WSF_PROTECTION_POLICY
|
||||||
|
l_protection: WSF_PROTECTION_PATTERNS
|
||||||
|
l_str: STRING
|
||||||
|
do
|
||||||
|
l_str:= "[
|
||||||
|
Referer: http://www.google.com/search?hl=en&q=fe525"-alert(1)-"d116a885fd5
|
||||||
|
]"
|
||||||
|
create sec
|
||||||
|
--| Case HTTP header referer attack, filtered using {xss_javascript_expression}
|
||||||
|
req := new_request (<<
|
||||||
|
["REQUEST_METHOD", "GET"],
|
||||||
|
["QUERY_STRING", ""],
|
||||||
|
["REQUEST_URI", "/xss_example"],
|
||||||
|
["HTTP_REFERER", l_str]
|
||||||
|
>>
|
||||||
|
)
|
||||||
|
assert ("HTTP_REFERER", attached {READABLE_STRING_8} sec.custom_http_referer (req, {ARRAY [REGULAR_EXPRESSION]}<<l_protection.xss_regular_expression>>) as v and then not v.is_empty )
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
feature {NONE} -- Implementation
|
||||||
|
|
||||||
|
new_request (a_meta: ARRAY [TUPLE [name: READABLE_STRING_8; value: READABLE_STRING_8]]): WSF_REQUEST_NULL
|
||||||
|
local
|
||||||
|
wgi_req: WGI_REQUEST
|
||||||
|
do
|
||||||
|
create {WGI_REQUEST_NULL} wgi_req.make_with_file (a_meta, io.input)
|
||||||
|
create Result.make_from_wgi (wgi_req)
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
@@ -28,7 +28,7 @@
|
|||||||
<assertions precondition="true" postcondition="true" check="true" supplier_precondition="true"/>
|
<assertions precondition="true" postcondition="true" check="true" supplier_precondition="true"/>
|
||||||
</option>
|
</option>
|
||||||
</library>
|
</library>
|
||||||
<library name="wsf_extension" location="..\wsf_extension.ecf" readonly="false"/>
|
<library name="wsf_security" location="..\wsf_security.ecf" readonly="false"/>
|
||||||
<library name="wsf_standalone" location="..\..\wsf\connector\standalone.ecf" readonly="false"/>
|
<library name="wsf_standalone" location="..\..\wsf\connector\standalone.ecf" readonly="false"/>
|
||||||
<cluster name="server" location=".\server\" recursive="true"/>
|
<cluster name="server" location=".\server\" recursive="true"/>
|
||||||
</target>
|
</target>
|
||||||
|
|||||||
@@ -14,7 +14,6 @@
|
|||||||
<library name="ewsgi" location="..\ewsgi\ewsgi.ecf"/>
|
<library name="ewsgi" location="..\ewsgi\ewsgi.ecf"/>
|
||||||
<library name="http" location="..\..\network\protocol\http\http.ecf"/>
|
<library name="http" location="..\..\network\protocol\http\http.ecf"/>
|
||||||
<library name="process" location="$ISE_LIBRARY\library\process\base\base_process.ecf"/>
|
<library name="process" location="$ISE_LIBRARY\library\process\base\base_process.ecf"/>
|
||||||
<library name="pcre" location="$ISE_LIBRARY\unstable\library\text\regexp\pcre\pcre.ecf"/>
|
|
||||||
<library name="wsf" location="wsf.ecf"/>
|
<library name="wsf" location="wsf.ecf"/>
|
||||||
<library name="wsf_router_context" location="wsf_router_context.ecf" readonly="true"/>
|
<library name="wsf_router_context" location="wsf_router_context.ecf" readonly="true"/>
|
||||||
<cluster name="extension" location=".\extension\" recursive="true"/>
|
<cluster name="extension" location=".\extension\" recursive="true"/>
|
||||||
|
|||||||
22
library/server/wsf/wsf_security.ecf
Normal file
22
library/server/wsf/wsf_security.ecf
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||||
|
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-16-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-16-0 http://www.eiffel.com/developers/xml/configuration-1-16-0.xsd" name="wsf_security" uuid="6684959A-6F63-4861-A98E-7E144AE77F2E" library_target="wsf_security">
|
||||||
|
<target name="wsf_security">
|
||||||
|
<root all_classes="true"/>
|
||||||
|
<file_rule>
|
||||||
|
<exclude>/EIFGENs$</exclude>
|
||||||
|
<exclude>/\.git$</exclude>
|
||||||
|
<exclude>/\.svn$</exclude>
|
||||||
|
</file_rule>
|
||||||
|
<option warning="true">
|
||||||
|
</option>
|
||||||
|
<library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/>
|
||||||
|
<library name="encoder" location="..\..\text\encoder\encoder.ecf"/>
|
||||||
|
<library name="ewsgi" location="..\ewsgi\ewsgi.ecf"/>
|
||||||
|
<library name="http" location="..\..\network\protocol\http\http.ecf"/>
|
||||||
|
<library name="pcre" location="$ISE_LIBRARY\unstable\library\text\regexp\pcre\pcre.ecf"/>
|
||||||
|
<library name="process" location="$ISE_LIBRARY\library\process\base\base_process.ecf"/>
|
||||||
|
<library name="wsf" location="wsf.ecf"/>
|
||||||
|
<library name="wsf_router_context" location="wsf_router_context.ecf" readonly="true"/>
|
||||||
|
<cluster name="security" location=".\security\" recursive="true"/>
|
||||||
|
</target>
|
||||||
|
</system>
|
||||||
Reference in New Issue
Block a user