Moved XSS protection to WSF_EXTENSION.
Updated code to protect meta_variables. Fixed typos. Updated ecf's to use 1-16-0.
This commit is contained in:
@@ -24,6 +24,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/).
|
|||||||
- `http_client`: Added support for multiple file in form data. Made clear what is the meaning of `upload_filename`, `upload_data` and `form_data`.
|
- `http_client`: Added support for multiple file in form data. Made clear what is the meaning of `upload_filename`, `upload_data` and `form_data`.
|
||||||
- `authentication`: HTTP_AUTHORIZATION acceps now READABLE_STRING_GENERAL for username and password argument.
|
- `authentication`: HTTP_AUTHORIZATION acceps now READABLE_STRING_GENERAL for username and password argument.
|
||||||
- `http_client`: fixed curl implementation by setting `Content-Type` to `x-www-form-urlencoded` (if not set) when POST send data as `x-www-form-urlencoded`.
|
- `http_client`: fixed curl implementation by setting `Content-Type` to `x-www-form-urlencoded` (if not set) when POST send data as `x-www-form-urlencoded`.
|
||||||
|
- `notification_email`: fixed the SMTP support for multiple recipients address.
|
||||||
### Security
|
### Security
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -95,40 +95,67 @@ feature -- Basic operation
|
|||||||
l_email: EMAIL
|
l_email: EMAIL
|
||||||
h: STRING
|
h: STRING
|
||||||
i: INTEGER
|
i: INTEGER
|
||||||
|
lst: LIST [READABLE_STRING_8]
|
||||||
do
|
do
|
||||||
create l_email.make_with_entry (a_email.from_address, addresses_to_header_line_value (a_email.to_addresses))
|
lst := a_email.to_addresses
|
||||||
if attached a_email.reply_to_address as l_reply_to then
|
if lst.is_empty then
|
||||||
l_email.add_header_entry ({EMAIL_CONSTANTS}.h_reply_to, l_reply_to)
|
-- Error ...
|
||||||
end
|
else
|
||||||
|
-- With EMAIL, there should be a unique recipient at creation.
|
||||||
if attached a_email.cc_addresses as lst then
|
create l_email.make_with_entry (a_email.from_address, lst.first)
|
||||||
l_email.add_header_entry ({EMAIL_CONSTANTS}.h_cc, addresses_to_header_line_value (lst))
|
if lst.count > 1 then
|
||||||
end
|
from
|
||||||
if attached a_email.bcc_addresses as lst then
|
lst.start
|
||||||
l_email.add_header_entry ({EMAIL_CONSTANTS}.h_bcc, addresses_to_header_line_value (lst))
|
lst.forth
|
||||||
end
|
until
|
||||||
l_email.set_message (a_email.content)
|
lst.off
|
||||||
l_email.add_header_entry ({EMAIL_CONSTANTS}.H_subject, a_email.subject)
|
loop
|
||||||
|
l_email.add_recipient_address (lst.item)
|
||||||
create h.make_empty
|
lst.forth
|
||||||
;(create {HTTP_DATE}.make_from_date_time (a_email.date)).append_to_rfc1123_string (h)
|
|
||||||
l_email.add_header_entry ("Date", h)
|
|
||||||
|
|
||||||
if attached a_email.additional_header_lines as lst then
|
|
||||||
across
|
|
||||||
lst as ic
|
|
||||||
loop
|
|
||||||
h := ic.item
|
|
||||||
i := h.index_of (':', 1)
|
|
||||||
if i > 0 then
|
|
||||||
l_email.add_header_entry (h.head (i - 1), h.substring (i + 1, h.count))
|
|
||||||
else
|
|
||||||
check is_header_line: False end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
if attached a_email.reply_to_address as l_reply_to then
|
||||||
|
l_email.add_header_entry ({EMAIL_CONSTANTS}.h_reply_to, l_reply_to)
|
||||||
|
end
|
||||||
|
|
||||||
smtp_send_email (l_email)
|
if attached a_email.cc_addresses as l_cc_addresses then
|
||||||
|
across
|
||||||
|
l_cc_addresses as ic
|
||||||
|
loop
|
||||||
|
l_email.add_recipient_address_in_cc (ic.item)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if attached a_email.bcc_addresses as l_bcc_addresses then
|
||||||
|
across
|
||||||
|
l_bcc_addresses as ic
|
||||||
|
loop
|
||||||
|
l_email.add_recipient_address_in_bcc (ic.item)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
l_email.set_message (a_email.content)
|
||||||
|
l_email.add_header_entry ({EMAIL_CONSTANTS}.H_subject, a_email.subject)
|
||||||
|
|
||||||
|
create h.make_empty
|
||||||
|
;(create {HTTP_DATE}.make_from_date_time (a_email.date)).append_to_rfc1123_string (h)
|
||||||
|
l_email.add_header_entry ("Date", h)
|
||||||
|
|
||||||
|
if attached a_email.additional_header_lines as l_lines then
|
||||||
|
across
|
||||||
|
l_lines as ic
|
||||||
|
loop
|
||||||
|
h := ic.item
|
||||||
|
i := h.index_of (':', 1)
|
||||||
|
if i > 0 then
|
||||||
|
l_email.add_header_entry (h.head (i - 1), h.substring (i + 1, h.count))
|
||||||
|
else
|
||||||
|
check is_header_line: False end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
smtp_send_email (l_email)
|
||||||
|
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
feature {NONE} -- Implementation
|
feature {NONE} -- Implementation
|
||||||
@@ -182,4 +209,3 @@ note
|
|||||||
Customer support http://support.eiffel.com
|
Customer support http://support.eiffel.com
|
||||||
]"
|
]"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -1,6 +1,6 @@
|
|||||||
note
|
note
|
||||||
description: "[
|
description: "[
|
||||||
{WSF_XSS_PROTECTION_PATTERNS}
|
{WSF_PROTECTION_PATTERNS}
|
||||||
Provide application security parterns to assist in Cross Site Scripting
|
Provide application security parterns to assist in Cross Site Scripting
|
||||||
]"
|
]"
|
||||||
date: "$Date$"
|
date: "$Date$"
|
||||||
@@ -9,7 +9,7 @@ note
|
|||||||
EIS: "name=Regular expression protection", "src=https://docs.apigee.com/api-services/reference/regular-expression-protection", "protocol=uri"
|
EIS: "name=Regular expression protection", "src=https://docs.apigee.com/api-services/reference/regular-expression-protection", "protocol=uri"
|
||||||
|
|
||||||
expanded class
|
expanded class
|
||||||
WSF_XSS_PROTECTION_PATTERNS
|
WSF_PROTECTION_PATTERNS
|
||||||
|
|
||||||
|
|
||||||
feature -- xss PATTERNS
|
feature -- xss PATTERNS
|
||||||
+45
-5
@@ -1,20 +1,19 @@
|
|||||||
note
|
note
|
||||||
description: "Return safe (XSS protection) data for WSF_REQUEST query and form paramters."
|
description: "Return safe (XSS protection) data for WSF_REQUEST query and form parameters."
|
||||||
date: "$Date$"
|
date: "$Date$"
|
||||||
revision: "$Revision$"
|
revision: "$Revision$"
|
||||||
|
|
||||||
class
|
class
|
||||||
WSF_XSS_UTILITIES
|
WSF_XSS_UTILITIES
|
||||||
|
|
||||||
|
|
||||||
-- TODO add header protection.
|
-- TODO add header protection.
|
||||||
|
|
||||||
feature -- Query parameters
|
feature -- Query parameters
|
||||||
|
|
||||||
safe_query_parameter (a_req: WSF_REQUEST; a_name: READABLE_STRING_GENERAL): detachable WSF_VALUE
|
safe_query_parameter (a_req: WSF_REQUEST; a_name: READABLE_STRING_GENERAL): detachable WSF_VALUE
|
||||||
-- Safe Query parameter for name `a_name'.
|
-- Safe Query parameter for name `a_name'.
|
||||||
local
|
local
|
||||||
l_wsf_xss: WSF_XSS_PROTECTION_PATTERNS
|
l_wsf_xss: WSF_PROTECTION_PATTERNS
|
||||||
r: REGULAR_EXPRESSION
|
r: REGULAR_EXPRESSION
|
||||||
do
|
do
|
||||||
r := l_wsf_xss.XSS_regular_expression
|
r := l_wsf_xss.XSS_regular_expression
|
||||||
@@ -37,8 +36,9 @@ feature -- Form Parameters
|
|||||||
safe_form_parameter (a_req: WSF_REQUEST; a_name: READABLE_STRING_GENERAL): detachable WSF_VALUE
|
safe_form_parameter (a_req: WSF_REQUEST; a_name: READABLE_STRING_GENERAL): detachable WSF_VALUE
|
||||||
-- Safe Form parameter for name `a_name'.
|
-- Safe Form parameter for name `a_name'.
|
||||||
local
|
local
|
||||||
l_wsf_xss: WSF_XSS_PROTECTION_PATTERNS
|
l_wsf_xss: WSF_PROTECTION_PATTERNS
|
||||||
r: REGULAR_EXPRESSION
|
r: REGULAR_EXPRESSION
|
||||||
|
not_first: BOOLEAN
|
||||||
do
|
do
|
||||||
r := l_wsf_xss.XSS_regular_expression
|
r := l_wsf_xss.XSS_regular_expression
|
||||||
Result := a_req.form_parameter (a_name)
|
Result := a_req.form_parameter (a_name)
|
||||||
@@ -51,10 +51,50 @@ feature -- Form Parameters
|
|||||||
if r.has_matched then
|
if r.has_matched then
|
||||||
create {WSF_STRING} Result.make (str.name, " ")
|
create {WSF_STRING} Result.make (str.name, " ")
|
||||||
end
|
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
|
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
|
note
|
||||||
copyright: "2011-2017, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Colin Adams, Eiffel Software and others"
|
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)"
|
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||||
@@ -97,8 +97,8 @@ alert(String.fromCharCode(88,83,83))//";alert(String.fromCharCode(88,83,83))//--
|
|||||||
r.match (s)
|
r.match (s)
|
||||||
assert ("No quotes and no semicolon", r.has_matched)
|
assert ("No quotes and no semicolon", r.has_matched)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
test_case_insensitive_xss_vector
|
test_case_insensitive_xss_vector
|
||||||
local
|
local
|
||||||
r: REGULAR_EXPRESSION
|
r: REGULAR_EXPRESSION
|
||||||
@@ -168,7 +168,7 @@ alert(String.fromCharCode(88,83,83))//";alert(String.fromCharCode(88,83,83))//--
|
|||||||
r.match (s)
|
r.match (s)
|
||||||
assert ("Malformed A tags", r.has_matched)
|
assert ("Malformed A tags", r.has_matched)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
test_malformed_img
|
test_malformed_img
|
||||||
local
|
local
|
||||||
@@ -196,7 +196,7 @@ alert(String.fromCharCode(88,83,83))//";alert(String.fromCharCode(88,83,83))//--
|
|||||||
r.match (s)
|
r.match (s)
|
||||||
assert ("fromCharCode", r.has_matched)
|
assert ("fromCharCode", r.has_matched)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
test_default_src_tag
|
test_default_src_tag
|
||||||
local
|
local
|
||||||
@@ -246,6 +246,6 @@ alert(String.fromCharCode(88,83,83))//";alert(String.fromCharCode(88,83,83))//--
|
|||||||
|
|
||||||
feature {NONE} -- Implementation
|
feature {NONE} -- Implementation
|
||||||
|
|
||||||
xss_pattern: WSF_XSS_PROTECTION_PATTERNS
|
xss_pattern: WSF_PROTECTION_PATTERNS
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||||
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-17-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-17-0 http://www.eiffel.com/developers/xml/configuration-1-17-0.xsd" name="wsf_tests" uuid="C4FF9CDA-B4E4-4841-97E0-7F799B85B657">
|
<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_tests" uuid="C4FF9CDA-B4E4-4841-97E0-7F799B85B657">
|
||||||
<target name="server">
|
<target name="server">
|
||||||
<root class="TEST" feature="make"/>
|
<root class="TEST" feature="make"/>
|
||||||
<file_rule>
|
<file_rule>
|
||||||
@@ -28,6 +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_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>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||||
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-17-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-17-0 http://www.eiffel.com/developers/xml/configuration-1-17-0.xsd" name="wsf" uuid="A37CE5AA-4D2A-4441-BC6A-0A1D7EC49647" library_target="wsf">
|
<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" uuid="A37CE5AA-4D2A-4441-BC6A-0A1D7EC49647" library_target="wsf">
|
||||||
<target name="wsf">
|
<target name="wsf">
|
||||||
<root all_classes="true"/>
|
<root all_classes="true"/>
|
||||||
<file_rule>
|
<file_rule>
|
||||||
@@ -18,7 +18,6 @@
|
|||||||
<library name="error" location="..\..\utility\general\error\error.ecf"/>
|
<library name="error" location="..\..\utility\general\error\error.ecf"/>
|
||||||
<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="pcre" location="$ISE_LIBRARY\unstable\library\text\regexp\pcre\pcre.ecf"/>
|
|
||||||
<library name="time" location="$ISE_LIBRARY\library\time\time.ecf"/>
|
<library name="time" location="$ISE_LIBRARY\library\time\time.ecf"/>
|
||||||
<library name="uri" location="$ISE_LIBRARY\library\text\uri\uri.ecf"/>
|
<library name="uri" location="$ISE_LIBRARY\library\text\uri\uri.ecf"/>
|
||||||
<library name="uri_template" location="..\..\text\parser\uri_template\uri_template.ecf"/>
|
<library name="uri_template" location="..\..\text\parser\uri_template\uri_template.ecf"/>
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
<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"/>
|
||||||
|
|||||||
Reference in New Issue
Block a user