Compare commits
14 Commits
es_rev1010
...
es_rev1010
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
24eb0a4002 | ||
|
|
7d738a164d | ||
|
|
1037256ea6 | ||
|
|
4d79bba04b | ||
|
|
5de024923e | ||
|
|
8b90241986 | ||
|
|
da1c0b8545 | ||
|
|
603bedf71d | ||
|
|
5fedad7f2e | ||
|
|
e83f5654d8 | ||
|
|
25446cac12 | ||
|
|
ccff084642 | ||
|
|
830adbe10c | ||
|
|
e6d998953e |
@@ -1,10 +1,8 @@
|
||||
language: eiffel
|
||||
before_script:
|
||||
- export current_dir=$PWD ; echo current_dir=$current_dir ; cd ..
|
||||
- export ISE_VERSION=17.05; export ISE_BUILD=100416
|
||||
- curl -sSL http://downloads.sourceforge.net/eiffelstudio/Eiffel_${ISE_VERSION}_gpl_${ISE_BUILD}-linux-x86-64.tar.bz2 | tar -x --bzip2
|
||||
- export ISE_EIFFEL=$PWD/Eiffel_${ISE_VERSION} ; export ISE_PLATFORM=linux-x86-64
|
||||
- export PATH=$PATH:$ISE_EIFFEL/studio/spec/$ISE_PLATFORM/bin:$PATH:$ISE_EIFFEL/tools/spec/$ISE_PLATFORM/bin
|
||||
- curl -sSL https://www.eiffel.org/setup/install.sh | bash
|
||||
- source eiffel_latest.rc
|
||||
- echo `ec -version`
|
||||
- cd $current_dir
|
||||
- echo Check projects compilation status...
|
||||
|
||||
@@ -11,6 +11,8 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/).
|
||||
- `http_client`: added support for ciphers setting in the libcurl implementation only.
|
||||
- `http_client`: added convenient `get` and `custom` functions on HTTP_CLIENT directly.
|
||||
- `websocket`: added `on_timer` solution to allow the server to check for external events and send notification to websocket clients.
|
||||
- `wsf`: added `WSF_EXECUTE_HANDLER`, and `WSF_CGI_HANDLER`. Demonstration of `WSF_CGI_HANDLER` in the new `tools/httpd` project.
|
||||
- `wsf_security`: new security library, providing support for XSS injection protection and similar.
|
||||
|
||||
### Changed
|
||||
- adopted ecf version 1-16-0 and use a single .ecf file (the -safe.ecf are now redirection to normal .ecf)
|
||||
@@ -23,6 +25,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`.
|
||||
- `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`.
|
||||
- `notification_email`: fixed the SMTP support for multiple recipients address.
|
||||
### Security
|
||||
|
||||
|
||||
|
||||
12
README.md
12
README.md
@@ -13,14 +13,14 @@ Currently EWF offers a collection of Eiffel libraries designed to be integrated
|
||||
|
||||
There is a growing ecosystem around EWF, that provides useful components:
|
||||
* OpenID and OAuth consumer library
|
||||
* Various hypermedia format such as HAL, Collection+json, …
|
||||
* Various hypermedia format such as HAL, Collection+json, ...
|
||||
* Websocket server and client
|
||||
* Template engine
|
||||
* API Auto-documentation with swagger
|
||||
* A simple experimental CMS.
|
||||
* ...
|
||||
|
||||
So if you want to build a website, a web api, RESTful service, …or even if you want to consume other web api, EWF is a solution.
|
||||
So if you want to build a website, a web api, RESTful service, ... or even if you want to consume other web api, EWF is a solution.
|
||||
|
||||
EWF brings with it all the advantages of the Eiffel technology and tools with its powerful features such as Design by Contract, debugging, testing tools which enable to build efficient systems expected to be repeatedly refined, extended, and improved in a predictable and controllable way so as to become with time bugfree systems. Enjoy the full power of debugging your web server application from the IDE.
|
||||
|
||||
@@ -51,11 +51,11 @@ Tasks and issues are managed with github issue system
|
||||
## How to get the source code?
|
||||
|
||||
Using git
|
||||
* git clone https://github.com/EiffelWebFramework/EWF.git
|
||||
* `git clone https://github.com/EiffelWebFramework/EWF.git`
|
||||
|
||||
* And to build the required and related Clibs
|
||||
* cd contrib/ise_library/cURL
|
||||
* geant compile
|
||||
* `cd contrib/ise_library/cURL`
|
||||
* `geant compile`
|
||||
|
||||
## Libraries under 'library'
|
||||
|
||||
@@ -64,7 +64,7 @@ Using git
|
||||
* connectors: various web server connectors for EWSGI
|
||||
* libfcgi: Wrapper for libfcgi SDK
|
||||
* __wsf__: Web Server Framework [read more](library/server/wsf)
|
||||
* __router__: URL dispatching/routing based on uri, uri_template, or custom [read more](library/server/wsf/router)
|
||||
* __router__: URL dispatching/routing based on `uri`, `uri_template`, or custom [read more](library/server/wsf/router)
|
||||
|
||||
### protocol
|
||||
* __http__: HTTP related classes, constants for status code, content types, ... [read more](library/network/protocol/http)
|
||||
|
||||
@@ -95,40 +95,67 @@ feature -- Basic operation
|
||||
l_email: EMAIL
|
||||
h: STRING
|
||||
i: INTEGER
|
||||
lst: LIST [READABLE_STRING_8]
|
||||
do
|
||||
create l_email.make_with_entry (a_email.from_address, addresses_to_header_line_value (a_email.to_addresses))
|
||||
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
|
||||
|
||||
if attached a_email.cc_addresses as lst then
|
||||
l_email.add_header_entry ({EMAIL_CONSTANTS}.h_cc, addresses_to_header_line_value (lst))
|
||||
end
|
||||
if attached a_email.bcc_addresses as lst then
|
||||
l_email.add_header_entry ({EMAIL_CONSTANTS}.h_bcc, addresses_to_header_line_value (lst))
|
||||
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 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
|
||||
lst := a_email.to_addresses
|
||||
if lst.is_empty then
|
||||
-- Error ...
|
||||
else
|
||||
-- With EMAIL, there should be a unique recipient at creation.
|
||||
create l_email.make_with_entry (a_email.from_address, lst.first)
|
||||
if lst.count > 1 then
|
||||
from
|
||||
lst.start
|
||||
lst.forth
|
||||
until
|
||||
lst.off
|
||||
loop
|
||||
l_email.add_recipient_address (lst.item)
|
||||
lst.forth
|
||||
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
|
||||
|
||||
feature {NONE} -- Implementation
|
||||
@@ -182,4 +209,3 @@ note
|
||||
Customer support http://support.eiffel.com
|
||||
]"
|
||||
end
|
||||
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
note
|
||||
description : "Objects that ..."
|
||||
author : "$Author$"
|
||||
date : "$Date$"
|
||||
revision : "$Revision$"
|
||||
description: "[
|
||||
Handler that can also play the role of a filter, i.e.
|
||||
than can pre-process incoming data and post-process outgoing data.
|
||||
]"
|
||||
author: "$Author$"
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
deferred class
|
||||
WSF_EXECUTE_FILTER_HANDLER
|
||||
@@ -22,7 +25,7 @@ feature -- Execution
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "2011-2013, Jocelyn Fiat, Javier Velilla, Olivier Ligot, 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)"
|
||||
source: "[
|
||||
Eiffel Software
|
||||
|
||||
@@ -8,10 +8,19 @@ deferred class
|
||||
WSF_URI_FILTER_HANDLER
|
||||
|
||||
inherit
|
||||
WSF_EXECUTE_FILTER_HANDLER
|
||||
WSF_FILTER_HANDLER [WSF_URI_HANDLER]
|
||||
|
||||
WSF_URI_HANDLER
|
||||
|
||||
feature -- Execution
|
||||
|
||||
execute_next (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
do
|
||||
if attached next as n then
|
||||
n.execute (req, res)
|
||||
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)"
|
||||
|
||||
@@ -11,7 +11,9 @@ inherit
|
||||
WSF_EXECUTE_RESPONSE_AGENT_HANDLER
|
||||
|
||||
WSF_URI_RESPONSE_HANDLER
|
||||
|
||||
undefine
|
||||
execute
|
||||
end
|
||||
create
|
||||
make
|
||||
|
||||
|
||||
@@ -22,6 +22,14 @@ feature -- Response
|
||||
Result_attached: Result /= Void
|
||||
end
|
||||
|
||||
feature -- Execution
|
||||
|
||||
execute (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
-- Execute request handler
|
||||
do
|
||||
res.send (response (req))
|
||||
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)"
|
||||
|
||||
@@ -8,10 +8,19 @@ deferred class
|
||||
WSF_URI_TEMPLATE_FILTER_HANDLER
|
||||
|
||||
inherit
|
||||
WSF_EXECUTE_FILTER_HANDLER
|
||||
WSF_FILTER_HANDLER [WSF_URI_TEMPLATE_HANDLER]
|
||||
|
||||
WSF_URI_TEMPLATE_HANDLER
|
||||
|
||||
feature -- Execution
|
||||
|
||||
execute_next (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
do
|
||||
if attached next as n then
|
||||
n.execute (req, res)
|
||||
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)"
|
||||
|
||||
@@ -11,6 +11,9 @@ inherit
|
||||
WSF_EXECUTE_RESPONSE_AGENT_HANDLER
|
||||
|
||||
WSF_URI_TEMPLATE_RESPONSE_HANDLER
|
||||
undefine
|
||||
execute
|
||||
end
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
@@ -22,6 +22,14 @@ feature -- Response
|
||||
Result_attached: Result /= Void
|
||||
end
|
||||
|
||||
feature -- Execution
|
||||
|
||||
execute (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
-- Execute request handler
|
||||
do
|
||||
res.send (response (req))
|
||||
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)"
|
||||
|
||||
36
library/server/wsf/security/filter/wsf_xss_filter.e
Normal file
36
library/server/wsf/security/filter/wsf_xss_filter.e
Normal file
@@ -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
|
||||
94
library/server/wsf/security/support/wsf_protection.e
Normal file
94
library/server/wsf/security/support/wsf_protection.e
Normal file
@@ -0,0 +1,94 @@
|
||||
note
|
||||
description: "[
|
||||
Security protection on values.
|
||||
|
||||
It could be to protect against XSS, SQL ... injections.
|
||||
]"
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
EIS: "name=OWASP", "src=https://www.owasp.org/", "protocol=uri"
|
||||
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"
|
||||
|
||||
deferred class
|
||||
WSF_PROTECTION
|
||||
|
||||
feature -- Status report
|
||||
|
||||
is_valid: BOOLEAN
|
||||
-- Is valid protection?
|
||||
deferred
|
||||
end
|
||||
|
||||
feature -- String Protection
|
||||
|
||||
string_8 (s: READABLE_STRING_8): detachable READABLE_STRING_8
|
||||
-- Safe string value from `s`.
|
||||
-- If a thread is detected, either return Void, or filter out the threat.
|
||||
require
|
||||
is_valid: is_valid
|
||||
deferred
|
||||
end
|
||||
|
||||
feature -- Value Protection
|
||||
|
||||
string_value (v: WSF_STRING): detachable WSF_STRING
|
||||
-- Safe string value from `v`.
|
||||
-- If a thread is detected, either return Void, or filter out the threat.
|
||||
require
|
||||
is_valid: is_valid
|
||||
deferred
|
||||
end
|
||||
|
||||
value (v: WSF_VALUE): detachable WSF_VALUE
|
||||
-- Safe value from `v`.
|
||||
-- If a thread is detected, either return Void, or filter out the threat.
|
||||
require
|
||||
is_valid: is_valid
|
||||
do
|
||||
if attached {WSF_STRING} v as s then
|
||||
Result := string_value (s)
|
||||
elseif attached {WSF_MULTIPLE_STRING} v as ms then
|
||||
Result := multiple_string_value (ms)
|
||||
else
|
||||
-- TODO
|
||||
Result := v
|
||||
end
|
||||
end
|
||||
|
||||
multiple_string_value (mv: WSF_MULTIPLE_STRING): detachable WSF_MULTIPLE_STRING
|
||||
-- Safe multiple string value from `mv`.
|
||||
-- If a thread is detected in any of the item, either return Void, or filter out the threat.
|
||||
require
|
||||
is_valid: is_valid
|
||||
local
|
||||
v: detachable WSF_STRING
|
||||
do
|
||||
-- TODO: check if the whole structure should be Void
|
||||
-- when one item is filtered out, or if the structure could have
|
||||
-- holes.
|
||||
across
|
||||
mv as ic
|
||||
loop
|
||||
v := string_value (ic.item)
|
||||
if v = Void then
|
||||
Result := Void
|
||||
elseif Result = Void then
|
||||
create Result.make_with_value (v)
|
||||
else
|
||||
Result.add_value (v)
|
||||
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
|
||||
490
library/server/wsf/security/support/wsf_protection_policy.e
Normal file
490
library/server/wsf/security/support/wsf_protection_policy.e
Normal file
@@ -0,0 +1,490 @@
|
||||
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: ITERABLE [WSF_PROTECTION]): 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_PROTECTIONS} 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: ITERABLE [WSF_PROTECTION]): 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_PROTECTIONS} 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: ITERABLE [WSF_PROTECTION]): 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_PROTECTIONS} 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: ITERABLE [WSF_PROTECTION]): 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: ITERABLE [WSF_PROTECTION]): 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: ITERABLE [WSF_PROTECTION]): 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: ITERABLE [WSF_PROTECTION]): 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: ITERABLE [WSF_PROTECTION]): 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: ITERABLE [WSF_PROTECTION]): 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: ITERABLE [WSF_PROTECTION]): 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: ITERABLE [WSF_PROTECTION]): 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: ITERABLE [WSF_PROTECTION]): 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: ITERABLE [WSF_PROTECTION]): 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: ITERABLE [WSF_PROTECTION]): 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: ITERABLE [WSF_PROTECTION]): 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: ITERABLE [WSF_PROTECTION]): 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: ITERABLE [WSF_PROTECTION]): 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: ITERABLE [WSF_PROTECTION]): 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: ITERABLE [WSF_PROTECTION]): 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: ITERABLE [WSF_PROTECTION]): 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: ITERABLE [WSF_PROTECTION]): 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: ITERABLE [WSF_PROTECTION]): 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: ITERABLE [WSF_PROTECTION]): 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: ITERABLE [WSF_PROTECTION]): 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: ITERABLE [WSF_PROTECTION]): detachable WSF_VALUE
|
||||
-- Return value `a_value` filtered by all protections policy.
|
||||
do
|
||||
Result := filter_wsf_value (a_value, a_protections )
|
||||
end
|
||||
|
||||
custom_string_value (a_value: detachable READABLE_STRING_8; a_protections: ITERABLE [WSF_PROTECTION]): detachable READABLE_STRING_8
|
||||
-- Return value `a_value` filtered by all protections policy.
|
||||
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_PROTECTIONS
|
||||
do
|
||||
Result := filter_wsf_value (a_value,
|
||||
<<
|
||||
l_wsf_xss.XSS,
|
||||
l_wsf_xss.server_side,
|
||||
l_wsf_xss.sql_injection,
|
||||
l_wsf_xss.xpath_abbreviated,
|
||||
l_wsf_xss.xpath_expanded
|
||||
>>)
|
||||
end
|
||||
|
||||
xss_value (a_value: detachable WSF_VALUE): detachable WSF_VALUE
|
||||
-- Return value `a_value` filtered by xss protection.
|
||||
local
|
||||
l_wsf_xss: WSF_PROTECTIONS
|
||||
do
|
||||
Result := filter_wsf_value (a_value, <<l_wsf_xss.XSS>>)
|
||||
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_PROTECTIONS
|
||||
do
|
||||
Result := filter_wsf_value (a_value, <<l_wsf_xss.XSS_javascript>>)
|
||||
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_PROTECTIONS
|
||||
do
|
||||
Result := filter_wsf_value (a_value, <<l_wsf_xss.SQL_injection>>)
|
||||
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_PROTECTIONS
|
||||
do
|
||||
Result := filter_wsf_value (a_value, <<l_wsf_xss.Server_side>>)
|
||||
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_PROTECTIONS
|
||||
do
|
||||
Result := filter_wsf_value (a_value, <<l_wsf_xss.Xpath_abbreviated>>)
|
||||
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_PROTECTIONS
|
||||
do
|
||||
Result := filter_wsf_value (a_value, <<l_wsf_xss.Xpath_expanded>>)
|
||||
end
|
||||
|
||||
filter_wsf_value (a_value: detachable WSF_VALUE; a_protections: ITERABLE [WSF_PROTECTION]): detachable WSF_VALUE
|
||||
-- Filter value `a_value` with an array of protections policy `a_protections`.
|
||||
require
|
||||
a_protections_valid: across a_protections as ic all ic.item.is_valid end
|
||||
local
|
||||
prot: WSF_PROTECTION
|
||||
do
|
||||
if a_value /= Void then
|
||||
Result := a_value
|
||||
across
|
||||
a_protections as ic
|
||||
until
|
||||
Result = Void
|
||||
loop
|
||||
prot := ic.item
|
||||
check is_valid: prot.is_valid end
|
||||
Result := prot.value (Result)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
filter_string_value (a_value: detachable READABLE_STRING_8; a_protections: ITERABLE [WSF_PROTECTION] ): detachable READABLE_STRING_8
|
||||
-- Filter value `a_value` with an array of protections policy `a_protections`.
|
||||
require
|
||||
all_protections_valid: across a_protections as ic all ic.item.is_valid end
|
||||
local
|
||||
v: WSF_STRING
|
||||
prot: WSF_PROTECTION
|
||||
do
|
||||
if a_value /= Void then
|
||||
Result := a_value
|
||||
across
|
||||
a_protections as ic
|
||||
until
|
||||
Result = Void
|
||||
loop
|
||||
prot := ic.item
|
||||
check is_valid: prot.is_valid end
|
||||
Result := prot.string_8 (Result)
|
||||
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
|
||||
114
library/server/wsf/security/support/wsf_protection_regexp.e
Normal file
114
library/server/wsf/security/support/wsf_protection_regexp.e
Normal file
@@ -0,0 +1,114 @@
|
||||
note
|
||||
description: "Security protection based on Regular expression."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
EIS: "name=Regular expression protection", "src=https://docs.apigee.com/api-services/reference/regular-expression-protection", "protocol=uri"
|
||||
|
||||
class
|
||||
WSF_PROTECTION_REGEXP
|
||||
|
||||
inherit
|
||||
WSF_PROTECTION
|
||||
|
||||
create
|
||||
make,
|
||||
make_caseless,
|
||||
make_with_regexp
|
||||
|
||||
convert
|
||||
make_with_regexp ({REGULAR_EXPRESSION})
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make (a_regexp_pattern: READABLE_STRING_8; a_caseless: BOOLEAN)
|
||||
local
|
||||
r: REGULAR_EXPRESSION
|
||||
do
|
||||
create r
|
||||
r.set_caseless (a_caseless)
|
||||
r.compile (a_regexp_pattern)
|
||||
make_with_regexp (r)
|
||||
end
|
||||
|
||||
make_caseless (a_regexp_pattern: READABLE_STRING_8)
|
||||
do
|
||||
make (a_regexp_pattern, True)
|
||||
end
|
||||
|
||||
make_with_regexp (a_regexp: REGULAR_EXPRESSION)
|
||||
do
|
||||
regexp := a_regexp
|
||||
end
|
||||
|
||||
|
||||
feature -- Access
|
||||
|
||||
regexp: REGULAR_EXPRESSION
|
||||
|
||||
feature -- String Protection
|
||||
|
||||
string_8 (s: READABLE_STRING_8): detachable READABLE_STRING_8
|
||||
local
|
||||
reg: like regexp
|
||||
do
|
||||
reg := regexp
|
||||
reg.match (s)
|
||||
if reg.has_matched then
|
||||
Result := Void
|
||||
else
|
||||
Result := s
|
||||
end
|
||||
end
|
||||
|
||||
string_value (v: WSF_STRING): detachable WSF_STRING
|
||||
local
|
||||
vs: READABLE_STRING_8
|
||||
do
|
||||
vs := v.url_encoded_value
|
||||
if attached string_8 (vs) as s then
|
||||
if vs = s then
|
||||
Result := v
|
||||
else
|
||||
create Result.make (v.name, s)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
feature -- Status report
|
||||
|
||||
is_valid: BOOLEAN
|
||||
-- <Precursor>
|
||||
-- i.e: if the association regular expression is successfully compiled.
|
||||
do
|
||||
Result := is_compiled
|
||||
end
|
||||
|
||||
is_compiled: BOOLEAN
|
||||
do
|
||||
Result := regexp.is_compiled
|
||||
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
|
||||
is_compiled: 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
|
||||
100
library/server/wsf/security/support/wsf_protections.e
Normal file
100
library/server/wsf/security/support/wsf_protections.e
Normal file
@@ -0,0 +1,100 @@
|
||||
note
|
||||
description: "[
|
||||
{WSF_PROTECTIONS}
|
||||
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_PROTECTIONS
|
||||
|
||||
feature -- XSS patterns
|
||||
|
||||
XSS: WSF_PROTECTION_REGEXP
|
||||
note
|
||||
EIS: "name= XSS", "src=https://community.apigee.com/questions/27198/xss-threat-protection-patterns.html#answer-27465", "protocol=uri"
|
||||
once
|
||||
create Result.make_caseless ("((\%%3C)|<)[^\n]+((\%%3E)|>)")
|
||||
ensure
|
||||
is_compiled: Result.is_compiled
|
||||
end
|
||||
|
||||
XSS_javascript: WSF_PROTECTION_REGEXP
|
||||
note
|
||||
EIS: "name=JavaScript Injection", "src=https://docs.apigee.com/api-services/reference/regular-expression-protection", "protocol=uri"
|
||||
once
|
||||
Result := compiled_regexp ("<\s*script\b[^>]*>[^<]+<\s*/\s*script\s*>", True)
|
||||
ensure
|
||||
is_compiled: Result.is_compiled
|
||||
end
|
||||
|
||||
feature -- XPath injections Patterns
|
||||
|
||||
XPath_abbreviated: WSF_PROTECTION_REGEXP
|
||||
note
|
||||
EIS: "name=XPath Abbreviated Syntax Injection", "src=https://docs.apigee.com/api-services/reference/regular-expression-protection", "protocol=uri"
|
||||
once
|
||||
Result := compiled_regexp ("(/(@?[\w_?\w:\*]+(\[[^]]+\])*)?)+", True)
|
||||
ensure
|
||||
is_compiled: Result.is_compiled
|
||||
end
|
||||
|
||||
XPath_expanded: WSF_PROTECTION_REGEXP
|
||||
note
|
||||
EIS: "name=XPath Expanded Syntax Injection", "src=https://docs.apigee.com/api-services/reference/regular-expression-protection", "protocol=uri"
|
||||
once
|
||||
Result := compiled_regexp ("/?(ancestor(-or-self)?|descendant(-or-self)?|following(-sibling))", True)
|
||||
ensure
|
||||
is_compiled: Result.is_compiled
|
||||
end
|
||||
|
||||
feature -- Server side injection
|
||||
|
||||
Server_side: WSF_PROTECTION_REGEXP
|
||||
note
|
||||
EIS: "name=Server-Side Include Injection", "src=https://docs.apigee.com/api-services/reference/regular-expression-protection", "protocol=uri"
|
||||
once
|
||||
|
||||
Result := compiled_regexp ("<!--#(include|exec|echo|config|printenv)\s+.*", True)
|
||||
ensure
|
||||
is_compiled: Result.is_compiled
|
||||
end
|
||||
|
||||
feature -- SQL injection Patterns
|
||||
|
||||
SQL_injection: WSF_PROTECTION_REGEXP
|
||||
note
|
||||
EIS: "name= SQL Injection", "src=https://docs.apigee.com/api-services/reference/regular-expression-protection", "protocol=uri"
|
||||
once
|
||||
Result := compiled_regexp ("[\s]*((delete)|(exec)|(drop\s*table)|(insert)|(shutdown)|(update)|(\bor\b))", True)
|
||||
ensure
|
||||
is_compiled: Result.is_compiled
|
||||
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
|
||||
is_compiled: 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
|
||||
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_PROTECTIONS}.XSS: WSF_PROTECTION
|
||||
|
||||
]"
|
||||
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_PROTECTIONS
|
||||
do
|
||||
Result := custom_http_accept (Current, <<l_protection.xss>>)
|
||||
end
|
||||
|
||||
http_accept_charset: detachable READABLE_STRING_8
|
||||
-- <Precursor>
|
||||
local
|
||||
l_protection: WSF_PROTECTIONS
|
||||
do
|
||||
Result := custom_http_accept_charset (Current, <<l_protection.xss>>)
|
||||
end
|
||||
|
||||
http_accept_encoding: detachable READABLE_STRING_8
|
||||
-- <Precursor>
|
||||
local
|
||||
l_protection: WSF_PROTECTIONS
|
||||
do
|
||||
Result := custom_http_accept_encoding (Current, <<l_protection.xss>>)
|
||||
end
|
||||
|
||||
http_accept_language: detachable READABLE_STRING_8
|
||||
-- <Precursor>
|
||||
local
|
||||
l_protection: WSF_PROTECTIONS
|
||||
do
|
||||
Result := custom_http_accept_language (Current, <<l_protection.xss>>)
|
||||
end
|
||||
|
||||
http_connection: detachable READABLE_STRING_8
|
||||
-- <Precursor>
|
||||
local
|
||||
l_protection: WSF_PROTECTIONS
|
||||
do
|
||||
Result := custom_http_connection (Current, <<l_protection.xss>>)
|
||||
end
|
||||
|
||||
http_expect: detachable READABLE_STRING_8
|
||||
-- <Precursor>
|
||||
local
|
||||
l_protection: WSF_PROTECTIONS
|
||||
do
|
||||
Result := custom_http_expect (Current, <<l_protection.xss>>)
|
||||
end
|
||||
|
||||
http_host: detachable READABLE_STRING_8
|
||||
-- <Precursor>
|
||||
local
|
||||
l_protection: WSF_PROTECTIONS
|
||||
do
|
||||
Result := custom_http_host (Current, <<l_protection.xss>>)
|
||||
end
|
||||
|
||||
http_referer: detachable READABLE_STRING_8
|
||||
-- <Precursor>
|
||||
local
|
||||
l_protection: WSF_PROTECTIONS
|
||||
do
|
||||
Result := custom_http_referer (Current, <<l_protection.xss>>)
|
||||
end
|
||||
|
||||
http_user_agent: detachable READABLE_STRING_8
|
||||
-- <Precursor>
|
||||
local
|
||||
l_protection: WSF_PROTECTIONS
|
||||
do
|
||||
Result := custom_http_user_agent (Current, <<l_protection.xss>>)
|
||||
end
|
||||
|
||||
http_authorization: detachable READABLE_STRING_8
|
||||
-- <Precursor>
|
||||
local
|
||||
l_protection: WSF_PROTECTIONS
|
||||
do
|
||||
Result := custom_http_authorization (Current, <<l_protection.xss>>)
|
||||
end
|
||||
|
||||
http_transfer_encoding: detachable READABLE_STRING_8
|
||||
-- <Precursor>
|
||||
local
|
||||
l_protection: WSF_PROTECTIONS
|
||||
do
|
||||
Result := custom_http_transfer_encoding (Current, <<l_protection.xss>>)
|
||||
end
|
||||
|
||||
http_access_control_request_headers: detachable READABLE_STRING_8
|
||||
-- <Precursor>
|
||||
local
|
||||
l_protection: WSF_PROTECTIONS
|
||||
do
|
||||
Result := custom_http_access_control_request_headers (Current, <<l_protection.xss>>)
|
||||
end
|
||||
|
||||
http_if_match: detachable READABLE_STRING_8
|
||||
-- <Precursor>
|
||||
local
|
||||
l_protection: WSF_PROTECTIONS
|
||||
do
|
||||
Result := custom_http_if_match (Current, <<l_protection.xss>>)
|
||||
end
|
||||
|
||||
http_if_modified_since: detachable READABLE_STRING_8
|
||||
-- <Precursor>
|
||||
local
|
||||
l_protection: WSF_PROTECTIONS
|
||||
do
|
||||
Result := custom_http_if_modified_since (Current, <<l_protection.xss>>)
|
||||
end
|
||||
|
||||
http_if_none_match: detachable READABLE_STRING_8
|
||||
-- <Precursor>
|
||||
local
|
||||
l_protection: WSF_PROTECTIONS
|
||||
do
|
||||
Result := custom_http_if_none_match (Current, <<l_protection.xss>>)
|
||||
end
|
||||
|
||||
http_if_range: detachable READABLE_STRING_8
|
||||
-- <Precursor>
|
||||
local
|
||||
l_protection: WSF_PROTECTIONS
|
||||
do
|
||||
Result := custom_http_if_range (Current, <<l_protection.xss>>)
|
||||
end
|
||||
|
||||
http_if_unmodified_since: detachable READABLE_STRING_8
|
||||
-- <Precursor>
|
||||
local
|
||||
l_protection: WSF_PROTECTIONS
|
||||
do
|
||||
Result := custom_http_if_unmodified_since (Current, <<l_protection.xss>>)
|
||||
end
|
||||
|
||||
http_last_modified: detachable READABLE_STRING_8
|
||||
-- <Precursor>
|
||||
local
|
||||
l_protection: WSF_PROTECTIONS
|
||||
do
|
||||
Result := custom_http_last_modified (Current, <<l_protection.xss>>)
|
||||
end
|
||||
|
||||
http_range: detachable READABLE_STRING_8
|
||||
-- <Precursor>
|
||||
local
|
||||
l_protection: WSF_PROTECTIONS
|
||||
do
|
||||
Result := custom_http_range (Current, <<l_protection.xss>>)
|
||||
end
|
||||
|
||||
http_content_range: detachable READABLE_STRING_8
|
||||
-- <Precursor>
|
||||
local
|
||||
l_protection: WSF_PROTECTIONS
|
||||
do
|
||||
Result := custom_http_content_range (Current, <<l_protection.xss>>)
|
||||
end
|
||||
|
||||
http_content_encoding: detachable READABLE_STRING_8
|
||||
-- <Precursor>
|
||||
local
|
||||
l_protection: WSF_PROTECTIONS
|
||||
do
|
||||
Result := custom_http_content_encoding (Current, <<l_protection.xss>>)
|
||||
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_PROTECTIONS
|
||||
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>", sec.custom_http_expect (req, <<l_protection.xss>>) = Void)
|
||||
end
|
||||
|
||||
|
||||
test_http_expect_attack_with_xss_js_protection
|
||||
local
|
||||
req: WSF_REQUEST
|
||||
sec: WSF_PROTECTION_POLICY
|
||||
l_protection: WSF_PROTECTIONS
|
||||
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>", sec.custom_http_expect (req, <<l_protection.xss_javascript>>) = Void )
|
||||
end
|
||||
|
||||
test_http_referer_attack_with_xss_js_protection_fails
|
||||
local
|
||||
req: WSF_REQUEST
|
||||
sec: WSF_PROTECTION_POLICY
|
||||
l_protection: WSF_PROTECTIONS
|
||||
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 sec.custom_http_referer (req, <<l_protection.xss_javascript>>) 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_PROTECTIONS
|
||||
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, <<l_protection.xss>>) 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
|
||||
252
library/server/wsf/tests/src/test_xss_patterns.e
Normal file
252
library/server/wsf/tests/src/test_xss_patterns.e
Normal file
@@ -0,0 +1,252 @@
|
||||
note
|
||||
description: "Summary description for {TEST_XSS_PATTERNS}."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
EIS: "name=XSS Filter Evasion Cheat Sheet", "src=https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet", "protocol=uri"
|
||||
|
||||
class
|
||||
TEST_XSS_PATTERNS
|
||||
|
||||
inherit
|
||||
EQA_TEST_SET
|
||||
|
||||
feature -- Tests
|
||||
|
||||
test_xss_locator
|
||||
local
|
||||
xss: WSF_XSS_REQUEST
|
||||
r: REGULAR_EXPRESSION
|
||||
s: STRING
|
||||
do
|
||||
s:= "[
|
||||
';alert(String.fromCharCode(88,83,83))//';alert(String.fromCharCode(88,83,83))//";
|
||||
alert(String.fromCharCode(88,83,83))//";alert(String.fromCharCode(88,83,83))//--
|
||||
></SCRIPT>">'><SCRIPT>alert(String.fromCharCode(88,83,83))</SCRIPT>
|
||||
]"
|
||||
r:= xss_pattern.XSS.regexp
|
||||
r.match (s)
|
||||
assert ("XSS locator", r.has_matched)
|
||||
end
|
||||
|
||||
test_xss_locator_short
|
||||
local
|
||||
r: REGULAR_EXPRESSION
|
||||
s: STRING
|
||||
do
|
||||
s:="[
|
||||
'';!--"<XSS>=&{()}
|
||||
]"
|
||||
r:= xss_pattern.XSS.regexp
|
||||
r.match (s)
|
||||
assert ("XSS locator short", r.has_matched)
|
||||
end
|
||||
|
||||
test_no_filter_evasion
|
||||
local
|
||||
r: REGULAR_EXPRESSION
|
||||
s: STRING
|
||||
do
|
||||
s:="[
|
||||
<SCRIPT SRC=http://xss.rocks/xss.js></SCRIPT>
|
||||
]"
|
||||
r:= xss_pattern.XSS.regexp
|
||||
r.match (s)
|
||||
assert ("No filter evasion", r.has_matched)
|
||||
end
|
||||
|
||||
test_filter_bypass_based_polyglot
|
||||
local
|
||||
r: REGULAR_EXPRESSION
|
||||
s: STRING
|
||||
do
|
||||
s:="[
|
||||
'">><marquee><img src=x onerror=confirm(1)></marquee>"></plaintext\></|\><plaintext/onmouseover=prompt(1)>
|
||||
<script>prompt(1)</script>@gmail.com<isindex formaction=javascript:alert(/XSS/) type=submit>'-->"></script>
|
||||
<script>alert(document.cookie)</script>">
|
||||
<img/id="confirm(1)"/alt="/"src="/"onerror=eval(id)>'">
|
||||
<img src="http://www.shellypalmer.com/wp-content/images/2015/07/hacked-compressor.jpg">
|
||||
]"
|
||||
r:= xss_pattern.XSS.regexp
|
||||
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:="[
|
||||
<IMG SRC="javascript:alert('XSS');">
|
||||
]"
|
||||
r:= xss_pattern.XSS.regexp
|
||||
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:="[
|
||||
<IMG SRC=javascript:alert('XSS')>
|
||||
]"
|
||||
r:= xss_pattern.XSS.regexp
|
||||
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:="[
|
||||
<IMG SRC=JaVaScRiPt:alert('XSS')>
|
||||
]"
|
||||
r:= xss_pattern.XSS.regexp
|
||||
r.match (s)
|
||||
assert ("Case insensitive XSS attack vector", r.has_matched)
|
||||
end
|
||||
|
||||
|
||||
test_html_entities
|
||||
local
|
||||
r: REGULAR_EXPRESSION
|
||||
s: STRING
|
||||
do
|
||||
s:="[
|
||||
<IMG SRC=javascript:alert("XSS")>
|
||||
]"
|
||||
r:= xss_pattern.XSS.regexp
|
||||
r.match (s)
|
||||
assert ("HTML entities", r.has_matched)
|
||||
end
|
||||
|
||||
test_grave_accent_obfuscation
|
||||
local
|
||||
r: REGULAR_EXPRESSION
|
||||
s: STRING
|
||||
do
|
||||
s:="[
|
||||
<IMG SRC=`javascript:alert("RSnake says, 'XSS'")`>
|
||||
]"
|
||||
r:= xss_pattern.XSS.regexp
|
||||
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:="[
|
||||
<a onmouseover="alert(document.cookie)">xxs link</a>
|
||||
]"
|
||||
r:= xss_pattern.XSS.regexp
|
||||
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:="[
|
||||
<a onmouseover=alert(document.cookie)>xxs link</a>
|
||||
]"
|
||||
r:= xss_pattern.XSS.regexp
|
||||
r.match (s)
|
||||
assert ("Malformed A tags", r.has_matched)
|
||||
end
|
||||
|
||||
|
||||
test_malformed_img
|
||||
local
|
||||
r: REGULAR_EXPRESSION
|
||||
s: STRING
|
||||
do
|
||||
s:="[
|
||||
<IMG """><SCRIPT>alert("XSS")</SCRIPT>">
|
||||
]"
|
||||
r:= xss_pattern.XSS.regexp
|
||||
r.match (s)
|
||||
assert ("Malformed IMG tags", r.has_matched)
|
||||
end
|
||||
|
||||
|
||||
test_from_char_code
|
||||
local
|
||||
r: REGULAR_EXPRESSION
|
||||
s: STRING
|
||||
do
|
||||
s:="[
|
||||
<IMG SRC=javascript:alert(String.fromCharCode(88,83,83))>
|
||||
]"
|
||||
r:= xss_pattern.XSS.regexp
|
||||
r.match (s)
|
||||
assert ("fromCharCode", r.has_matched)
|
||||
end
|
||||
|
||||
|
||||
test_default_src_tag
|
||||
local
|
||||
r: REGULAR_EXPRESSION
|
||||
s: STRING
|
||||
do
|
||||
s:="[
|
||||
<IMG SRC=# onmouseover="alert('xxs')">
|
||||
]"
|
||||
r:= xss_pattern.XSS.regexp
|
||||
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:="[
|
||||
<IMG SRC= onmouseover="alert('xxs')">
|
||||
]"
|
||||
r:= xss_pattern.XSS.regexp
|
||||
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:="[
|
||||
<IMG onmouseover="alert('xxs')">
|
||||
]"
|
||||
r:= xss_pattern.XSS.regexp
|
||||
r.match (s)
|
||||
assert ("Default SRC tag by leaving it out entirely", r.has_matched)
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
feature {NONE} -- Implementation
|
||||
|
||||
xss_pattern: WSF_PROTECTIONS
|
||||
|
||||
end
|
||||
@@ -3,9 +3,9 @@
|
||||
<target name="server">
|
||||
<root class="TEST" feature="make"/>
|
||||
<file_rule>
|
||||
<exclude>/EIFGENs$</exclude>
|
||||
<exclude>/\.git$</exclude>
|
||||
<exclude>/\.svn$</exclude>
|
||||
<exclude>/EIFGENs$</exclude>
|
||||
</file_rule>
|
||||
<option debug="false" warning="true">
|
||||
<assertions precondition="true" postcondition="true" check="true" loop="true" supplier_precondition="true"/>
|
||||
@@ -21,12 +21,14 @@
|
||||
</library>
|
||||
<library name="http" location="..\..\..\network\protocol\http\http.ecf" readonly="false"/>
|
||||
<library name="http_client" location="..\..\..\network\http_client\net_http_client.ecf" readonly="false"/>
|
||||
<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="wsf" location="..\wsf.ecf" readonly="false">
|
||||
<option>
|
||||
<assertions precondition="true" postcondition="true" check="true" supplier_precondition="true"/>
|
||||
</option>
|
||||
</library>
|
||||
<library name="wsf_security" location="..\wsf_security.ecf" readonly="false"/>
|
||||
<library name="wsf_standalone" location="..\..\wsf\connector\standalone.ecf" readonly="false"/>
|
||||
<cluster name="server" location=".\server\" recursive="true"/>
|
||||
</target>
|
||||
|
||||
@@ -3,9 +3,9 @@
|
||||
<target name="wsf">
|
||||
<root all_classes="true"/>
|
||||
<file_rule>
|
||||
<exclude>/EIFGENs$</exclude>
|
||||
<exclude>/\.git$</exclude>
|
||||
<exclude>/\.svn$</exclude>
|
||||
<exclude>/EIFGENs$</exclude>
|
||||
</file_rule>
|
||||
<option warning="true">
|
||||
</option>
|
||||
|
||||
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>
|
||||
@@ -46,7 +46,7 @@ echo Uninstall framework: ewf
|
||||
|
||||
echo Uninstall ewf examples
|
||||
%RDCMD% %TMP_CONTRIB_DIR%\examples\web\ewf
|
||||
%RDCMD% %TMP_CONTRIB_DIR%\examples\ewb\ewf_precomp
|
||||
%RDCMD% %TMP_CONTRIB_DIR%\examples\web\ewf_precomp
|
||||
|
||||
echo Uninstall ewf wizard
|
||||
%RDCMD% %TMP_TARGET_DIR%\help\wizards\ewf
|
||||
|
||||
Reference in New Issue
Block a user