allow-file-control
Section: server
Default Value: false
Valid Values: true, false
Changes Take Effect: Immediately
True to enable the file upload control for the GMS Storage. Configure the list of supported mime files in the allowed-mime-types option. For additional details, refer to the GMS Storage API.
allowed-mime-types
Section: server
Default Value: Empty
Valid Values: String
Changes Take Effect: Immediately
Comma-separated list of mime types that GMS allows for storage. Refer to IANA Media Type Reference for a detailed list of possible mime types.
http.proxy-ttl
Section: gms
Default Value: 5
Valid Values: Any integer
Changes Take Effect: Immediately
Specifies the interval to refresh PAC content.
http.proxy-cache-size
Section: gms
Default Value: 32
Valid Values: Any integer
Changes Take Effect: Immediately
Size of the cache that stores URLs that were already processed. If the requested URL is in the cache, GMS will not process the PAC file.
http.proxy-auto-config-file
Section: gms
Default Value: No default value
Valid Values: Any valid URL
Changes Take Effect: Immediately
Specifies the proxy auto-config (PAC) file location. For example:
- file:///C:/GMS/proxy.pacfor a local file
- http://127.0.0.1:8082/deploy/proxy.pac
Secure GMS Access Control
This page covers the list of security points, mechanisms, and procedures that you can implement to secure your Genesys Mobile Environment.
Use HTTPS to avoid unsecured connections to GMS
HTTPS (Hypertext Transfer Protocol Secure) is an internet communication protocol that protects the integrity and the confidentiality of your users' data between the user's computer and the GMS. Implementing HTTPS connections with GMS prevents the following Transport Confidentiality attacks:
Attack | Description |
---|---|
MITM | Man In The Middle |
BEAST | Browser Exploit Against SSL/TLS |
CRIME | Compression Ratio Info-leak Made Easy |
In 8.5.2, The Jetty server that GMS runs on was upgraded to release 9.4.7.v20170914. As a result, GMS requires JVM 1.8 or later. In accordance with RFC 7231 recommendations, the Content-Type response header will provide charset values in lowercase: Content-Type → application/json;charset=utf-8
Add a Certificate to JETTY
- Request a Certificate from a Certificate Authority (CA) to sign your key/certificate.
- Once the CA has sent you a certificate, load it into a JSSE keystore. Run the JDK's keytool to load a certificate in PEM form directly into a keystore. The following command loads a PEM encoded certificate in the jetty.crt (JETTY) file into a JSSE keystore:
$ keytool -keystore mykeystore -import -alias jetty -file jetty.crt -trustcacerts
- To add the certificate to JETTY, copy the mykeystore file to JETTY's etc folder, then edit jetty-ssl-context.xml to setup the certificate info.
Private key and cert files have to be in the keystore. You may also need to convert PEM-format keys to JKS format and PKCS12 to a JKS file. The PEM format is the most common format that Certificate Authorities issue certificates in.
PEM certificates usually have extensions such as .pem, .crt, .cer, and .key. They are Base64-encoded ASCII files and contain "----BEGIN CERTIFICATE---" and "---END CERTIFICATE----" statements. Server certificates, intermediate certificates, and private keys can all be put into the PEM format. Several PEM certificates and even the private key can be included in one file, one below the other.
Here are some command examples to help you to manage .pfx certificate files and the Jetty's keystore:
Get the key only:
e:\openssl\openssl pkcs12 -in e:\certtest\upmc.pfx -nocerts -out e:\certtest\upmckey.pem
Get the cert only:
e:\openssl\openssl pkcs12 -in e:\certtest\upmc.pfx -clcerts -nokeys -out e:\certtest\upmccert.pem
Remove the passphrase from the key:
e:\openssl\openssl rsa -in e:\certtest\upmckey.pem -out e:\certtest\upmcserver.key
Create a combined .p12 file that you can import in the keystore:
e:\openssl\openssl pkcs12 -export -in E:\certtest\upmccert.pem -inkey e:\certtest\upmcserver.key -out e:\certtest\combined.p12 -name upmc_cert -CAfile
e:\certtest\my_ca_bundle.crt -caname root
Add the combined key/cert to the keystore:
keytool -importkeystore -deststorepass **** -destkeypass **** -destkeystore mykeystore -srckeystore combined.p12 -srcstoretype PKCS12 -srcstorepass ****
Configure JETTY Secured Ports
- Setup the secured port in the jetty-ssl.xml and jetty.xml files. The default HTTPS port is 8443.
- Remove the content of the jetty-http.xml file (not relevant). Moreover, you will need to setup (operating system) firewall rules to control access to Jetty HTTP unsecured port (8080 by default).
<?xml version="1.0"?> <!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd"> <!-- ============================================================= --> <!-- Configure the Jetty Server instance with an ID "Server" --> <!-- by adding a HTTP connector. --> <!-- This configuration must be used in conjunction with jetty.xml --> <!-- ============================================================= --> <Configure id="Server" class="org.eclipse.jetty.server.Server"> <!-- =========================================================== --> <!-- Add a HTTP Connector. --> <!-- Configure an o.e.j.server.ServerConnector with a single --> <!-- HttpConnectionFactory instance using the common httpConfig --> <!-- instance defined in jetty.xml --> <!-- --> <!-- Consult the javadoc of o.e.j.server.ServerConnector and --> <!-- o.e.j.server.HttpConnectionFactory for all configuration --> <!-- that may be set here. --> <!-- =========================================================== --> <!-- <Call name="addConnector"> <Arg> <New id="httpConnector" class="org.eclipse.jetty.server.ServerConnector"> <Arg name="server"><Ref refid="Server" /></Arg> <Arg name="acceptors" type="int"><Property name="jetty.http.acceptors" deprecated="http.acceptors" default="-1"/></Arg> <Arg name="selectors" type="int"><Property name="jetty.http.selectors" deprecated="http.selectors" default="-1"/></Arg> <Arg name="factories"> <Array type="org.eclipse.jetty.server.ConnectionFactory"> <Item> <New class="org.eclipse.jetty.server.HttpConnectionFactory"> <Arg name="config"><Ref refid="httpConfig" /></Arg> <Arg name="compliance"><Call class="org.eclipse.jetty.http.HttpCompliance" name="valueOf"><Arg><Property name="jetty.http.compliance" default="RFC7230"/></Arg></Call></Arg> </New> </Item> </Array> </Arg> <Set name="host"><Property name="jetty.http.host" deprecated="jetty.host" /></Set> <Set name="port"><Property name="jetty.http.port" deprecated="jetty.port" default="8080" /></Set> <Set name="idleTimeout"><Property name="jetty.http.idleTimeout" deprecated="http.timeout" default="30000"/></Set> <Set name="soLingerTime"><Property name="jetty.http.soLingerTime" deprecated="http.soLingerTime" default="-1"/></Set> <Set name="acceptorPriorityDelta"><Property name="jetty.http.acceptorPriorityDelta" deprecated="http.acceptorPriorityDelta" default="0"/></Set> <Set name="acceptQueueSize"><Property name="jetty.http.acceptQueueSize" deprecated="http.acceptQueueSize" default="0"/></Set> </New> </Arg> </Call> --> </Configure>
- Update the start.ini file in <GMS_HOME> directory with the following text:
module=server,jsp,jmx,resources,websocket,ext,plus,annotations,deploy,security,servlets,continuation,rewrite,ssl,https ... ... #=========================================================== jetty.httpConfig.sendServerVersion=false jetty.sslContext.keyStorePath=etc/keystore jetty.sslContext.keyStorePassword=<keystorepassword> jetty.sslContext.keyManagerPassword=<keystorepassword> jetty.sslContext.trustStorePath=etc/ANT1MEAPPS01 jetty.sslContext.trustStorePassword=OBF:<encrypted keystore="" password="">
In your production environment, you should place your mykeystore file in a private directory with restricted access, not in a directory relative to the JETTY home directory. The mykeystore file in the example above is relative to the JETTY home directory.
The jetty.sslContext.keyStorePassword and jetty.sslContext.keyManagerPassword properties can also contain obfuscated passwords (OBF). Check the jetty-ssl-context.xml file (as an example). You can use the same process that is used for the jetty.sslContext.trustStorePassword OBF password generation.
ImportantFor production, choose a private directory with restricted access to keep your keystore in. Even though it has a password on it, the password may be configured into the runtime environment and is vulnerable to theft. You can now start Jetty the normal way (make sure that in your text cert.jar, jnet.jar, and jsse.jar are on your classpath) and SSL can be used with a URL like: https://localhost:8443/You should encode the the_password value, for example by using the embedded password tool:
If the password is ?, the user will be prompted for the password.C:\8.5.2>java -cp lib/jetty-http-9.4.7.v20170914.jar;lib/jetty-util-9.4.7.v20170914.jar org.eclipse.jetty.util.security.Password username userpassword Usage - java org.eclipse.jetty.security.Password [<user>] <password>
- In 8.5.200.07 and 8.5.201.04, skip this step. In other versions, force the use of the TLS protocol by adding a new sslConnector connector or by disabling the
unsecured port. To modify the secured port, edit the etc/jetty-ssl.xml file:
<?xml version="1.0" encoding="UTF-8"?> <Call name="addConnector"> <Arg> <New id="sslConnector" class="org.eclipse.jetty.server.ServerConnector"> <Arg name="server"> <Ref refid="Server" /> </Arg> <Arg name="acceptors" type="int"> <Property name="jetty.ssl.acceptors" deprecated="ssl.acceptors" default="-1" /> </Arg> <Arg name="selectors" type="int"> <Property name="jetty.ssl.selectors" deprecated="ssl.selectors" default="-1" /> </Arg> <Arg name="factories"> <Array type="org.eclipse.jetty.server.ConnectionFactory"> <!-- uncomment to support proxy protocol: <Item> <New class="org.eclipse.jetty.server.ProxyConnectionFactory"/> </Item>--> </Array> </Arg> <Set name="host"> <Property name="jetty.ssl.host" deprecated="jetty.host" /> </Set> <Set name="port"> <Property name="jetty.ssl.port" deprecated="ssl.port" default="8443" /> </Set> <Set name="idleTimeout"> <Property name="jetty.ssl.idleTimeout" deprecated="ssl.timeout" default="30000" /> </Set> <Set name="soLingerTime"> <Property name="jetty.ssl.soLingerTime" deprecated="ssl.soLingerTime" default="-1" /> </Set> <Set name="acceptorPriorityDelta"> <Property name="jetty.ssl.acceptorPriorityDelta" deprecated="ssl.acceptorPriorityDelta" default="0" /> </Set> <Set name="acceptQueueSize"> <Property name="jetty.ssl.acceptQueueSize" deprecated="ssl.acceptQueueSize" default="0" /> </Set> <Get name="SelectorManager"> <Set name="connectTimeout"> <Property name="jetty.ssl.connectTimeout" default="15000" /> </Set> <Set name="reservedThreads"> <Property name="jetty.ssl.reservedThreads" default="-2" /> </Set> </Get> </New> </Arg> </Call>
- Edit your ORS DFM files to point to the new secured port of the TLS connector (8443 in our example).
<dfm name='gsgCallback' namespace='http://www.genesyslab.com/modules/dfm/gsgCallback/v1'> <protocols> <protocol type='http'> <params> <param name='timeout' expr='20'/> </params> <globalevents> <event name='done' mapping='200'/> <event name='error' mapping='0,400-510'/> </globalevents> </protocol> <protocol type='https'> <params> <param name='retries' expr='4' /> <param name='timeout' expr='20' /> </params> <globalevents> <event name='done' mapping='200' /> <event name='error' mapping='400-510' /> </globalevents> </protocol> </protocols> <connections> <connection name='HTTP_round_robin' type='https' selectionmode='round-robin'> <servers> <server name='gsg1' host='1XX.1XX.10.01' port='8443' /> <server name='gsg2' host='1XX.1XX.10.02' port='8443' /> <server name='gsg3' host='1XX.1XX.10.03' port='8443' /> <server name='gsg4' host='1XX.1XX.10.04' port='8443' /> </servers> </connection> </connections> <transports> <transport name='HTTP_GET' conntype='HTTP_round_robin'> <param name='method' expr='GET'/> <param name='enctype' expr='application/x-www-form-urlencoded' /> </transport> <transport name='HTTP_POST' conntype='HTTP_round_robin'> <param name='method' expr='POST'/> <param name='enctype' expr='application/x-www-form-urlencoded' /> </transport> <transport name='HTTP_DELETE' conntype='HTTP_round_robin'> <param name='method' expr='DELETE'/> <param name='enctype' expr='application/x-www-form-urlencoded' /> </transport> <transport name='HTTP_PUT' conntype='HTTP_round_robin'> <param name='method' expr='PUT'/> <param name='enctype' expr='application/json' /> </transport> </transports> <actions> <action name='start-callback' transport='HTTP_POST' > <overrides> <param name='url' expr= '/genesys/${apiVersion}/service/callback/${callbackexecutionname}'/> </overrides> <attributes> <attribute name='apiVersion' type='String' optional='false' /> <attribute name='callbackexecutionname' type='String' optional='false' /> <attribute name='content' type='Expression' optional='false' mapping='content'/> </attributes> </action> <action name='cancel-callback' transport='HTTP_DELETE' > <overrides> <param name='url' expr='/genesys/${apiVersion}/service/callback/${callbackexecutionname}/${service_id}'/> </overrides> <attributes> <attribute name='apiVersion' type='String' optional='false' /> <attribute name='callbackexecutionname' type='String' optional='false' /> <attribute name='service_id' type='String' optional='false' /> </attributes> </action> <action name='reschedule-callback' transport='HTTP_PUT' > <overrides> <param name='url' expr= '/genesys/${apiVersion}/service/callback/${callbackexecutionname}/${service_id}' /> </overrides> <attributes> <attribute name='apiVersion' type='String' optional='false' /> <attribute name='callbackexecutionname' type='String' optional='false' /> <attribute name='service_id' type='String' optional='false' /> <attribute name='content' type='Expression' optional='false' mapping='content'/> </attributes> </action> <action name='query-callback' transport='HTTP_GET' > <overrides> <param name='url' expr='/genesys/${apiVersion}/service/callback/${callbackexecutionname} ?customer_number=${customer_number_value}'/> </overrides> <attributes> <attribute name='apiVersion' type='String' optional='false' /> <attribute name='callbackexecutionname' type='String' optional='false' /> <attribute name='customer_number_value' type='String' optional='false' /> </attributes> </action> <action name='query-availability-timestamp' transport='HTTP_GET' > <overrides> <param name='url' expr='/genesys/${apiVersion}/service/callback/${callbackexecutionname} /availability?timestamp=${timestamp_value}'/> </overrides> <attributes> <attribute name='apiVersion' type='String' optional='false' /> <attribute name='callbackexecutionname' type='String' optional='false' /> <attribute name='timestamp_value' type='String' optional='false'/> </attributes> </action> <action name='query-availability' transport='HTTP_GET' > <overrides> <param name='url' expr='/genesys/${apiVersion}/service/callback/${callbackexecutionname} /availability'/> </overrides> <attributes> <attribute name='apiVersion' type='String' optional='false' /> <attribute name='callbackexecutionname' type='String' optional='false' /> </attributes> </action> </actions> </dfm>
-
In 8.5.200.07 and 8.5.201.04, additional steps are required for Jetty 9.4.
- Download and copy the following files to <GMS_HOME>/etc directory:
- Update the start.ini file by adding "etc/jetty-ssl-context.xml" to the following list:
etc/jetty.xml etc/jetty-ssl.xml etc/jetty-ssl-context.xml etc/jetty-deploy.xml etc/jetty-http.xml etc/jetty-https.xml etc/jetty-rewrite.xml #etc/jetty-overlay.xml #etc/jetty-webapps.xml #etc/jetty-contexts.xml
Redirect HTTP requests to HTTPS
If you want to keep an unsecured port (for instance port 8080) and redirect HTTP to HTTPS, the webapp should indicate that it needs CONFIDENTIAL or INTEGRAL connections from users. This is done in <GMS_HOME>/etc/webdefault.xml
<web-app>
<security-constraint>
<web-resource-collection>
<web-resource-name>Everything</web-resource-name>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<user-data-constraint>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
</security-constraint>
GMS Options to Setup
Set the following options set in your GMS application at the server level, not the cluster level:
[server]
external_url_base=https://gmshost:8443/
web_port=8443
web_scheme=https
Configure HTTP Strict Transport Security
By default, HTTP Strict Transport Security (HSTS) is configured in GMS as follows:
- Strict-Transport-Security max age: 31536000
- Include subdomain: true
To update this configuration, edit the etc/jetty-ssl.xml file in the GMS installation directory as follows:
<New id="sslHttpConfig" class="org.eclipse.jetty.server.HttpConfiguration">
<Arg>
<Ref refid="httpConfig" />
</Arg>
<Call name="addCustomizer">
<Arg>
<New class="org.eclipse.jetty.server.SecureRequestCustomizer">
<Arg name="sniHostCheck" type="boolean">
<Property name="jetty.ssl.sniHostCheck" default="true" />
</Arg>
<Arg name="stsMaxAgeSeconds" type="int">
<Property name="jetty.ssl.stsMaxAgeSeconds" default="31536000" />
</Arg>
<Arg name="stsIncludeSubdomains" type="boolean">
<Property name="jetty.ssl.stsIncludeSubdomains" default="true" />
</Arg>
</New>
</Arg>
</Call>
</New>
Secure Access to Proxy Configuration
GMS can send outbound HTTP requests to Push Notification servers through the following notification services:
- APNS (Apple Push Notification Service)
- FCM (Firebase Cloud Messaging Service)
- Third Party Servers for custom notification
To secure access, GMS provides a Proxy Auto-Configuration file (PAC) mechanism. You can configure a PAC file in your GMS Application's settings, section gms:
Option | Type | Default value | Restriction on value | Description |
---|---|---|---|---|
http.proxy-auto-config-file | String | Optional Valid URL | Location of the proxy auto-config (PAC) file. For example:
| |
http.proxy-cache-size | Integer | 32 | Valid integer (optional) | Size of the cache that stores URLs that were already processed. If the requested URL is in the cache, GMS will not process the PAC file. |
http.proxy-ttl | Integer | 5 | Valid integer (Optional) | Interval in minutes before refreshing the PAC content. |
You can use the following PAC file to secure GMS access for Apple and Google Servers:
function FindProxyForURL(url, host) {
if (dnsDomainIs(host, ".googleapis.com"))
return "PROXY 127.0.0.1:808";
if (dnsDomainIs(host, ".wns.windows.com"))
return "PROXY 127.0.0.1:808";
if (dnsDomainIs(host, ".apple.com"))
return "SOCKS 127.0.0.1:1080";
return "DIRECT";
}
Possible Values for Access-Control-Allow-Origin Header (CORS)
By default, the value for all the properties mentioned below is set to *, meaning all origins.
If you need to configure CORS for a specific domain, method, or header, then edit the launcher.xml file as described below; the following are the three types of properties used to configure CORS.
- com.genesyslab.common.cors.allowed-origins
- com.genesyslab.common.cors.allowed-methods
- com.genesyslab.common.cors.allowed-headers
Example:
<filter>
<filter-name>cross-origin</filter-name>
<filter-class>org.eclipse.jetty.servlets.CrossOriginFilter</filter-class>
<async-supported>true</async-supported>
<!-- default init-param !-->
<init-param>
<param-name>allowedOrigins</param-name>
<param-value>*</param-value>
</init-param>
<init-param>
<param-name>allowedMethods</param-name>
<param-value>GET,POST,OPTIONS,DELETE,PUT,HEAD</param-value>
</init-param>
<init-param>
<param-name>allowedHeaders</param-name>
<param-value>origin, content-type, accept, authorization,Access-Control-Request-Method, gms_user</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>cross-origin</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Allowed Origins
This is the list of allowed origins that can be specific origins. For example, https://domain1.com. A matched origin is listed in the 'Access-Control-Allow-Origin' response header of preflight actual CORS requests.
If the below property is not available, then, by default, all origins are allowed.
<parameter name="cors-allowed-origins" displayName="cors-allowed-origins" mandatory="false">
<description><![CDATA[This should have the origins which we need to allow in CORS policy, multiple origins can be
separated by coma]]></description>
<valid-description><![CDATA[]]></valid-description>
<effective-description/>
<format type="string" default="-Dcom.genesyslab.common.cors.allowed-origins=http://sample1.com,https://sample1
.com,http://sample2:8080,https://sample2:8080" />
<validation/>
</parameter>
- The value for this property should be a literal match for the string, that is, http://sample1.com is not equal to https://sample1.com.
- There are no line breaks in between domains or domain names.
- Blank spaces are not permitted in between domains or domain names.
Allowed Methods
Set the HTTP methods to allow specific methods, for example, GET, POST, and so on. By default all methods are allowed.
<parameter name="allowed-method" displayName="com.genesyslab.common.cors.allowed-methods" mandatory="false">
<description><![CDATA[This should have the methods which we need to allow in cors policy, multiple methods can be separated by coma]]></description>
<valid-description><![CDATA[]]></valid-description>
<effective-description/>
<format type="string" default="-Dcom.genesyslab.common.cors.allowed-methods=GET,POST,PUT" />
<validation></validation>
</parameter>
- There are no line breaks in between method names.
- Blank spaces are not permitted in between method names.
Allowed Headers
Set the list of headers that a pre-flight request can list as allowed for use during an actual request. As per the CORS spec, the header name is not required to be listed if it is one of the below:
- Cache-Control
- Content-Language
- Expires
- Last-Modified
- Pragma
<parameter name="allowed-header" displayName="allowed-header" mandatory="false">
<description><![CDATA[This should have the headers which we need to allow in cors policy, multiple headers can be separated by coma]]></description>
<valid-description><![CDATA[]]></valid-description>
<effective-description/>
<format type="string" default="-Dcom.genesyslab.common.cors.allowed-headers=X-Requested-With,Origin" />
<validation></validation>
</parameter>
- There are no line breaks in between header names.
- Blank spaces are not permitted in between header names.
Add Custom Headers
To add custom headers to the GMS response (X-Frame-Options, X-Content-Type-Options, XSS-Protection, Content-Security-Policy, Access-Control-Allow-Headers, and so on), use Jetty to rewrite handles. This procedure is documented in the Rewrite Handler chapter of the official Jetty documentation. For instance, the following snippets added to the jetty-rewrite.xml file create the appropriate custom headers for the Storage API, based on the /genesys/1/storage/* pattern attribute:
<Call name="addRule">
<Arg>
<New class="org.eclipse.jetty.rewrite.handler.HeaderPatternRule">
<Set name="pattern">/genesys/1/storage/*</Set>
<Set name="name">Access-Control-Allow-Credentials</Set>
<Set name="value">false</Set>
</New>
</Arg>
</Call>
<Call name="addRule">
<Arg>
<New class="org.eclipse.jetty.rewrite.handler.HeaderPatternRule">
<Set name="pattern">/genesys/1/storage/*</Set>
<Set name="name">X-Frame-Options</Set>
<Set name="value">SAMEORIGIN</Set>
</New>
</Arg>
</Call>
<Call name="addRule">
<Arg>
<New class="org.eclipse.jetty.rewrite.handler.HeaderPatternRule">
<Set name="pattern">/genesys/1/storage/*</Set>
<Set name="name">X-XSS-Protection</Set>
<Set name="value">1; mode=block</Set>
</New>
</Arg>
</Call>
<Call name="addRule">
<Arg>
<New class="org.eclipse.jetty.rewrite.handler.HeaderPatternRule">
<Set name="pattern">/genesys/1/storage/*</Set>
<Set name="name">Content-Security-Policy</Set>
<Set name="value">default-src 'self'</Set>
<Set name="terminating">true</Set>
</New>
</Arg>
</Call>
<Call name="addRule">
<Arg>
<New class="org.eclipse.jetty.rewrite.handler.HeaderPatternRule">
<Set name="pattern">/genesys/1/storage/*</Set>
<Set name="name">Access-Control-Allow-Headers</Set>
<Set name="value">customerHeader1,customerHeader2</Set>
</New>
</Arg>
</Call>
As a result, you will get the following storage response:
HTTP/1.1 200 OK
Access-Control-Allow-Credentials: false
X-Frame-Options: SAMEORIGIN
X-XSS-Protection: 1; mode=block
Content-Security-Policy: default-src 'self'
Content-Type: application/json;charset=utf-8
Transfer-Encoding: chunked
{"GMS_KEY":"GMS_VALUE"}
Set up DoS Filters to Limit Requests
An attacker can consume all of some required resources by generating enough traffic from your host to prevent legitimate users from using the system. See Application Denial of Service
The Denial of Service (DoS) filter limits exposure to request flooding, whether malicious or as a result of a misconfigured client. The DoS filter keeps track of the number of requests from a connection per second. If the number of requests exceeds the limit, JETTY rejects, delays, or throttles additional requests, and sends a warning message. The filter works on the assumption that the attacker might be written in a simple blocking style, so by suspending requests you are hopefully consuming the attacker's resources.
To configure the DoS filter in GMS, edit the <GMS_HOME>/etc/webdefault.xml file. Configure the options list below, save, and restart GMS to take the new settings into account.
Parameter name | Default Value | Description |
---|---|---|
maxRequestsPerSec | 25 | Maximum number of requests per second from a connection. Additional requests are first delayed, then throttled. |
delayMs | 100 | Delay in milliseconds that all requests over the rate limit must wait before they get processed:
|
maxWaitMs | 50 | Maximum time to wait, in milliseconds, blocking for the throttle semaphore. |
throttledRequests | 5 | Number of requests over the rate limit able to be considered at once. |
throttleMs | 30000L | Time, in milliseconds, to asynchronously wait for the throttle semaphore. |
maxRequestMs | 30000 | Time, in milliseconds, to allow the request to run. |
maxIdleTrackerMs | 30000 | Time, in milliseconds, to keep track of request rates for a connection, before deciding that the user has gone away, and discarding it. |
insertHeaders | true | Keep true to insert the DoSFilter headers into the response; otherwise, false. |
trackSessions | true | True to track the usage rate by session if a session exists. |
remotePort | false | Set to true to not use session tracking, then track by IP+port (effectively connection). |
ipWhitelist | A comma-separated list of IP addresses that will not be rate-limited. | |
managedAttr | Set to true to set this servlet as a ServletContext attribute with the filter name as the attribute name. This allows a context external mechanism such as for example JMX via ContextHandler.MANAGED_ATTRIBUTES) to manage the configuration of the filter. |
The following code is an example of DoS Filter file.
<filter>
<filter-name>DoSFilter</filter-name>
<filter-class>org.eclipse.jetty.servlets.DoSFilter</filter-class>
<async-supported>true</async-supported>
<init-param>
<param-name>maxRequestsPerSec</param-name>
<param-value>200</param-value>
</init-param>
<init-param>
<param-name>ipWhitelist</param-name>
<param-value>127.0.0.1</param-value>
</init-param>
</filter>
Secure your GMS Sessions
Attack | Description |
---|---|
Session Fixation | Session fixation attacks represent a potential risk where a malicious attacker tries to create a session by accessing a site, then persuades other users to log in with the same session by sending them a link containing the session identifier as a parameter, for example. |
To prevent attacks on your sessions, you should configure the following mechanisms.
Mechanism | Description |
---|---|
HttpOnly flag is true by default | HttpOnly is an additional flag included in a Set-Cookie HTTP response header. Using the HttpOnly flag when generating a cookie helps mitigate the risk of client side script accessing the protected cookie (if the browser supports it). |
Enable the secure flag in HTTPS environment |
The secure flag is an option that you can set in the application server when sending a new cookie to the user within an HTTP Response. The purpose of the secure flag is to prevent cookies from being observed by unauthorized parties due to the transmission of a cookie in clear text. To enable it, navigate to the <GMS_HOME>/etc folder and edit the webdefault.xml file. Secure flag setting <session-config>
<session-timeout>20</session-timeout>
<cookie-config>
<secure>false</secure> <!-- true if HTTPS is used-->
<path>/genesys</path>
<http-only>true</http-only>
<max-age>86400</max-age>
</cookie-config>
</session-config> |
Session timeout (default is 20 minutes) | To change this timeout, navigate to the <GMS_HOME>/etc/ folder, and the edit webdefault.xml file.
Session timeout setting <session-config>
<session-timeout>20</session-timeout> <!-- Value is in minute-->
...
</session-config> The session timeout defines the action window time for a user, and thus, the period while an attacker can try to steal and use an existing user session.
|
Configure Access Rules for Security Gateway in Front of Genesys Mobile Services
The following access rules should be used as a model for your environment, allowing a list of services provided by your Genesys Mobile Services deployment to be accessed while restricting the use of internal-only services.
Allow access from the end-user application or proxy - mobile, web, etc: -- async notifications over HTTP API: If client is using cometd transport (typically for chat): {base url:port}/genesys/cometd -- service API: {base url:port}/genesys/{version}/service/{service name} {base url:port}/genesys/{version}/service/{id}/storage {base url:port}/genesys/{version}/service/{id} {base url:port}/genesys/{version}/service/{id}/{request name} -- chat media API: {base url:port}/genesys/{version}/service/{id}/ixn/chat {base url:port}/genesys/{version}/service/{id}/ixn/chat/refresh {base url:port}/genesys/{version}/service/{id}/ixn/chat/disconnect {base url:port}/genesys/{version}/service/{id}/ixn/chat/startTyping {base url:port}/genesys/{version}/service/{id}/ixn/chat/stopTyping {base url:port}/genesys/{version}/service/{id}/ixn/chat/*
Only when client need direct access allow (in most cases only
ORS/scxml need it):
-- storage API {base url:port}/genesys/{version}/storage/{ttl} {base url:port}/genesys/{version}/storage/{data id}/{ttl} {base url:port}/genesys/{version}/storage/{data id} {base url:port}/genesys/{version}/storage/{data id}/{key}
-- callback (management) API {base url:port}/genesys/{version}/service/callback
/{callback-execution-name}/{service_id}
{base url:port}/genesys/{version}/service/callback
/{callback-execution-name}/{service_id}
{base url:port}/genesys/{version}/service/callback
/{callback-execution-name}/availability?{timestamp=value}
{base url:port}/genesys/{version}/admin/callback
/queues?target={target_name}&end_time={iso_end_time}
Allow access from load balancer for node health check: {base url:port}/genesys/{version}/node
Allow access from the intranet: -- admin UI {base url:port}/genesys/admin/* {base url:port}/genesys/{version}/admin/* {base url:port}/genesys/{version}/reports/* {base url:port}/genesys/{version}/statistic/* -- datadepot (typically accessed from ORS/scxml): {base url:port}/genesys/{version}/datadepot/{tenantId}
/{activityName}/dates
{base url:port}/genesys/{version}/datadepot/{tenantId}/activities
{base url:port}/genesys/{version}/datadepot/{tenantId}
/{activityName}/aggregates
{base url:port}/genesys/{version}/datadepot/{tenantId}
/{activityName}/aggregates/unique
-- all built-in services (except chat) {base url:port}/genesys/{version}/service/request-access {base url:port}/genesys/{version}/service/match-interaction -- notification API (typically accessed from ORS/scxml): {base url:port}/genesys/{version}/notification/subscription {base url:port}/genesys/{version}/notification/subscription/{id} {base url:port}/genesys/{version}/notification/publish
Mobile Native Push Notification Configuration Details
Three major mobile platforms are currently supported: Android, Apple, and Windows. Details about Genesys Mobile Services configuration could be found on the Push Notification Service page of the API Reference.
You can set sensitive options in different sections of your application configuration. In the following example, the configuration structure allows you to set the password in another section.
[push]
apple=apple-desc;
debug-apple=debug-apple-desc
...
[apple-desc]
password=*********
apple.keystore=xxxxxxxxxxx
[debug-apple-desc]
password=*********
apple.keystore=xxxxxxxxxxx
In case of:
- IOS (APNS): The password option is used instead of "apple.keystorePassword".
- Android (FCM): The password option is used instead of "fcm.apiKey".
- Microsoft (WNS): The password option is used instead of "wns.clientSecret".
Set all the mandatory options and keep optional options in the push section. See the options' detail for more information.
If GMS is deployed behind a firewall, edit your rules to allow the server fcm.googleapis.com and range 5228-5230 for ports, as detailed in the FCM ports and your firewall section of the Firebase Cloud Messaging documentation.
Hide Sensitive Data in Logs
Genesys recommends using log data filtering to hide sensitive configuration data in log files. The given product will then use that filter to determine what content should be filtered or masked when creating log files. The only real interfaces to Genesys Mobile Services are APIs and having to configure filter criteria every time you add a new parameter or API is cumbersome and complicated. Therefore, Genesys Mobile Services supports filtering and masking data in log files for any API parameter that matches the following naming convention:
- Filter: Any parameter name that is prefixed with XXX will be filtered out of the log files entirely. Example: XXX_FilterParam
- Mask: Any parameter name that is prefixed with MMM will be masked in the log files, showing in the log with the letters MMM. Example: MMM_MaskParam
Use of the Storage API
For security reasons, if you plan using the GMS Storage API, you can define a list of supported mime types in the allowed-mime-types option and configure allow-file-control = true to enable file control.