UrlEncryptionFilter
The UrlEncryptionFilter supports full and partial URL and query encryption. The encrypted URL and query can consist of several encrypted and plain parts, depending on the verification policy. Such a URL will be blocked or passed decrypted to the backend. The UrlEncryptionFilter also supports session stickiness for CSRF protection.
If multiple UrlEncryptionFilters are configured, they have to share the same Encryption_Key, Encryption_StatusCode, and Encryption_Provider. For a description of these parameters, see the table UrlEncryptionFilter configuration below.
A UrlEncryptionFilter with fully encrypted URLs does not support Set-Cookie headers with the path attribute. This is because on the client side the path will not match the encrypted URL.
If a fully encrypted URL contains an URL-encoded slash (#2F) after the decoding, it will reach the backend (still containing the URL-encoded slash) regardless of the configuration of AllowEncodedSlashes
in navajo.xml.
Limitations
Due to the complexity of inline JavaScript code, URL encryption may not work correctly in some cases. For example if a specific function aJavaScriptFunction does not only perform checks, but also calls URLs, the following content will not work well:
<a href="#" onclick="aJavaScriptFunction()">Some Text</a>
You should replace it with the following content:
<a href="#" onclick="aJavaScriptFunction(); return false">Some Text</a>
So to avoid potential pitfalls, we recommend using as little inline JavaScript as possible. Instead, include JavaScript files that contain the code.
ch::nevis::isiweb4::filter::lua::encryption::UrlEncryptionFilter
libLuaFilter.so.1
+NEEDS_SWITCHING_PROTOCOLS
Configuration
Encryption_EntryPoint
Type: List of newline separated strings
Usage Constraint: required
Defines the application/back-end entry points, in the form of a newline-separated list of entry point URLs. These are the only URLs that can always be accessed without being encrypted, irrespectively of the enforcement policy.
Encryption_Provider
Type: Enum
Possible values: EncryptionDefaultProvider, EncryptionWithMacProvider
Usage Constraint: optional
Default: EncryptionDefaultProvider
Secure Default: EncryptionWithMacProvider
Defines the method that is used to encrypt and decrypt URLs. Both encryption providers encrypt the URL. The provider EncryptionWithMacProvider additionally tags the encrypted URL with a MAC (Message Authentication Code), to prevent modifications. Encryption is done with the AES-128-CBC algorithm, MAC with HmacSHA1 algorithms. This parameter must be the same for all UrlEncryptionFilters in the same instance. So if you change the default in one UrlEncryptionFilter of an instance, also adapt it in the instance's other UrlEncryptionFilters.
Encryption_Key
Type: String
Usage Constraint: required
Defines the key used for encryption. For safety reasons it should be at least 16 characters long.
Encryption_MyHosts
Type: String
Usage Constraint: optional
Defines a list of hosts which points to us where an absolute URL containing one of those hosts must be encrypted, all other absolute URLs will not be encrypted.
Encryption_UrlEnforcement
Type: Enum
Possible values: plain, partial, encrypted
Usage Constraint: optional
Default: plain
Secure Default: encrypted
Defines the enforcement policy:
- Plain: encryption is not needed.
- Partial: a part of the URL must be encrypted.
- Encrypted: The whole URL must be encrypted. Query is not included.
Encryption_Query
Type: String
Usage Constraint: optional
Default: not set
Secure Default: encrypted
Defines if and how the query must be encrypted:
if this attribute is not configured, the query is unaffected by the UrlEncryptionFilter.
set either
encrypted
for full query encryptionlist of
<parameter-name>=both|value
whereboth
means name and value are encrypted, andvalue
means only the value is encrypted.Examplepasswd = both
userid = both
id = value
Encryption_Url
Type: Enum
Possible values: plain, encrypted
Usage Constraint: optional
Default: encrypted
Secure Default: encrypted
Defines if the url should be encrypted or not.
Encryption_QueryWhiteList
Type: newline separated list of strings
Usage Constraint: optional
Defines which query parameter names do not need to be encrypted. The white list is effectively applied to the Encryption_Query parameter. The white listed names are interpreted as Lua regular expressions.
param1
order_[0-9]+
myprefix_.*
Encryption_Mapping
Type: Newline separated list of rules
Usage Constraint: optional
Syntax: <content-type-lua-regex> <encrypter>
Defines which encryption engine to use based on the response's content type. The <encrypter>
can be either:
- HtmlUrlEncrypter: Use this encrypter for all HTML pages
- GenericUrlEncrypter: Use this option if you expect no relative URL in the page. If you set this value, also specify the parameter Encryption_GenericEncrypterPatterns
- GenericUrlRelativeUrlsResolverEncrypter: Use this option if you do expect relative URLs in the page. If you set this value, also specify the parameter Encryption_GenericUrlRelativeUrlsResolverEncrypter_PatternsMapping
- ExtendedHtmlUrlEncrypter: Use this option for all HTML pages (text/HTML), if you need additional rules for special inline JavaScript URLs. If you set this value, also specify the parameter Encryption_ExtendedHtmlUrlEncrypter_Patterns.
If more engines match the content type, they will be executed in the order they are defined.
Encryption_GenericUrlRelativeUrlsResolverEncrypter_PatternsMapping
Type: Newline separated list of rules
Usage Constraint: optional
Syntax: <content-type-lua-regex> <pattern-parameter-name>
This parameter is required if the parameter Encryption_Mapping uses the "GenericUrlRelativeUrlsResolverEncrypter" encrypter.
<content-type-lua-regex>
: The content type of the response to be encrypted<pattern-parameter-name>
: The name of the parameter containing the pattern rules. This parameter has the same syntax as the parameter Encryption_GenericEncrypterPatterns. The parameter name has to start with "Encryption_".
<init-param>
<param-name>Encryption_Mapping</param-name>
<param-value>
text/html.* HtmlUrlEncrypter
text/css.* GenericUrlRelativeUrlsResolverEncrypter
</param-value>
</init-param>
<init-param>
<param-name>Encryption_GenericUrlRelativeUrlsResolverEncrypter_PatternsMapping</param-name>
<param-value>
text/css.* Encryption_CssPatterns
</param-value>
</init-param>
<init-param>
<param-name>Encryption_CssPatterns</param-name>
<param-value>
(url%()([^%)]*)(%)) => false true false
</param-value>
</init-param>
Encryption_ExtendedHtmlUrlEncrypter_Patterns
Type: Newline separated list of rules
Usage Constraint: optional
This parameter is required if the parameter Encryption_Mapping uses the "GenericUrlRelativeUrlsResolverEncrypter" encrypter. This parameter has the same syntax as the parameter Encryption_GenericEncrypterPatterns.
<init-param>
<param-name>Encryption_ExtendedHtmlUrlEncrypter_Patterns</param-name>
<param-value>
(addEventListener%("click", function%(")([^%)]*)("%)) => false true false
</param-value>
</init-param>
<init-param>
<param-name>Encryption_Mapping</param-name>
<param-value>
text/html.* ExtendedHtmlUrlEncrypter
</param-value>
</init-param>
Encryption_SessionSticky
Type: Enum
Possible values: on, off
Usage Constraint: optional
Default: off
Defines if the URL encryption is bound to a session. If this is set to "on", only URLs which where encrypted in a given session are allowed, all others get blocked.
Encryption_StatusCode
Type: Integer
Usage Constraint: optional
Default: 403
Defines the status code to return if an invalid URL is sent by the front end.
Encryption_StaticIv
Type: Boolean
Usage Constraint: optional
Default: false
Secure Default: false
If StaticIv is set to true, all encrypted values are not-randomized and the same original URL produces always the same encrypted URL. Setting this value to true is not recommended.
Encryption_VerifyBody
Type: Boolean
Usage Constraint: optional
Default: false
Enables verification of the query parameters found within the request body. Thus, it is not possible to bypass verification. When using html forms that send POST requests on submit, you have to allow the form's parameters to be received by the proxy unencrypted. This can be achieved by listing the parameters that needs to be encrypted in Encrypt_Query or when Encrypt_Query is set to "encrypted", adding the form's parameters to Encrypt_QueryWhitelist. In normal cases, the forms' parameters are the input tags inside the form in the html source, so each input's name attribute have to be listed in the whitelist (even the hidden input).
Encryption_GenericEncrypterPatterns
Type: Newline separated list of rules
Usage Constraint: optional
Syntax: <lua-regex> => <one or more booleans which part to encrypt>
This parameter is required if you have a GenericUrlEncrypter configured in the parameter Encryption_Mapping. For example: (href=')(.-)(') => false true false
will encrypt the part between href='
and '
Encryption_PlainTextUrls
Type: Newline separated list of Lua regular expressions
Usage Constraint: optional
This parameter defines a newline separated list of Lua regular expressions for URLs that should not be encrypted. Anchors are not yet supported.
Example
The web.xml contains the encryption and enforcement of the URL encryption. Let's say on the /a/b
you want to have encryption, then just map the following filter to /a/b/*
. Let us further assume that the connector's name is my.host.ch
.
<filter>
<filter-name>HTMLUrlEncryption</filter-name>
<filter-class>ch::nevis::isiweb4::filter::lua::encryption::UrlEncryptionFilter</filter-class>
<init-param>
<param-name>Encryption_Key</param-name>
<param-value>1234567890</param-value>
</init-param>
<init-param>
<param-name>Encryption_EntryPoint</param-name>
<param-value>/a/b/index.html</param-value>
</init-param>
<init-param>
<param-name>Encryption_UrlEnforcement</param-name>
<param-value>encrypted</param-value>
</init-param>
<init-param>
<param-name>Encryption_Mapping</param-name>
<param-value>
text/html.* HtmlUrlEncrypter
</param-value>
</init-param>
<init-param>
<param-name>Encryption_MyHosts</param-name>
<param-value>https://my.host.ch</param-value>
</init-param>
</filter>
If you also have JavaScript inside HTML and as external resource to rewrite, add a follow-up filter right after the filter "HTMLUrlEncryption".
<filter>
<filter-name>JSUrlEncryptionFixUp</filter-name>
<filter-class>ch::nevis::isiweb4::filter::lua::encryption::UrlEncryptionFilter</filter-class>
<init-param>
<param-name>Encryption_Key</param-name>
<param-value>1234567890</param-value>
</init-param>
<init-param>
<param-name>Encryption_EntryPoint</param-name>
<param-value>/a/b/index.html</param-value>
</init-param>
<init-param>
<param-name>Encryption_Mapping</param-name>
<param-value>
text/.* GenericUrlEncrypter
application/x%-javascript.* GenericUrlEncrypter
</param-value>
</init-param>
<init-param>
<param-name>Encryption_GenericEncrypterPatterns</param-name>
<param-value>
(var.=.")(.-)("(wink) => false true false
</param-value>
</init-param>
<init-param>
<param-name>Encryption_MyHosts</param-name>
<param-value>https://my.host.ch</param-value>
</init-param>
</filter>
If you have only external JavaScript to rewrite, you can define this all in the above "HTMLUrlEncryption" filter definition.