Page tree
Skip to end of metadata
Go to start of metadata

This article provides advice for ensuring a secure environment for Redesign applications.   The SSDT uses a number of standard tools and frameworks (Tomcat, Spring Security, etc) which implement best practices for web application security.   In March 2019, a "Penetration Test" was executed against USPS-R and USAS-R to help ensure the applications were performing as expected.   The results of the test revealed several minor potential vulnerabilities.  The SSDT has made adjustments to the software to resolve the issues which can be handled in code.

However, some issues can only be handled by correct configuration of the environment at the ITC.  This article will provide advice for correctly configuring your environment.   It is expected that this article will evolve over time as new issues or risks are identified.

Properly Configure Reverse Proxy

Internally, the USxS-R applications run under Apache Tomcat 8.5 listening on unencrypted port 8080.  The intention is to never allow direct access to this port.  

The default docker configuration recommended by the SSDT does not expose port 8080 on the docker engine.   The port should only be accessible by the reverse proxy running on the same server as the application containers.  However, if the ITC is using an external reverse proxy, then port 8080 will be exposed on the docker engine, but must not be exposed to the public internet thru the firewall.  If possible, access to port 8080 should be limited to the reverse proxy.

Force Redirect of port 80

If the reverse proxy accepts connections to port 80 (or any unsecured port), then the reverse proxy must do a forced redirect to port 433 (secured port).  The reverse proxy must not allow any request to reach the application using an unsecured connection.  This is important so that the "session cookie" is created by the application is never transmitted over a unsecured connection.    It is also important that the reverse proxy redirects for both "root" path access and "deep linking".   For example, if the browser attempts a request to "http://yourserver/vui/login", the reverse proxy should redirect to "https://yourserver/vui/login". 

HSTS Headers

The reverse proxy should automatically apply the HSTS (HTTP Strict Transport Security) header to all responses on the HTTPS port.   This header instructs the browser to never contact the host name in the URL on an unsecured port.  It effectively causes the browser to automatically redirect if the user enters an unsecure URL.  Again, this ensures that the "session cookie" created by the application is never transmitted over an unsecure connection.

The example reverse proxy configuration provided by the SSDT using the "nginx-proxy" image automatically implement both the forced redirect and HSTS headers.  If you are using 'nginx-proxy' configured with an SSL certificate or Let's Encrypt, then the reverse proxy will implement the above recommendations.

Verify Correct Proxy Behavior

You can use CURL (or other utilities, including Chrome's developer tools) to verify the correct behavior of the reverse proxy.  Below are a few examples of using CURL to test redirect and security headers.  These examples were executed against the SSDT Demo server that is using nginx-proxy using a wildcard SSL certificate. 

 Request to port 80 at root path redirects to 443: 

curl --head
HTTP/1.1 301 Moved Permanently
Server: nginx/1.14.1
Date: Thu, 11 Apr 2019 18:14:46 GMT
Content-Type: text/html
Content-Length: 185
Connection: keep-alive

Request to port 80 with path redirects to port 433 at same path (i.e. "deep linking"):

curl --head
HTTP/1.1 301 Moved Permanently
Server: nginx/1.14.1
Date: Thu, 11 Apr 2019 18:17:16 GMT
Content-Type: text/html
Content-Length: 185
Connection: keep-alive

Request to 443 at root includes 'Strict-Transport-Security" header:

> curl --head
HTTP/2 302
server: nginx/1.14.1
date: Thu, 11 Apr 2019 18:32:21 GMT
content-type: text/html;charset=ISO-8859-1
cache-control: private,max-age=0
set-cookie: JSESSIONID=EDC5041E1B872C164C4772029B332677; Path=/; HttpOnly
strict-transport-security: max-age=31536000

Request to 443 with URL path includes "Strict-Transport-Security" header (i.e. "deep linking")

$ curl --head
HTTP/2 302
server: nginx/1.14.1
date: Thu, 11 Apr 2019 18:34:29 GMT
set-cookie: JSESSIONID=B187DCAE08077163C03D732DF3AFA9B8; Path=/; HttpOnly
cache-control: no-cache, no-store, max-age=0, must-revalidate
pragma: no-cache
expires: 0
strict-transport-security: max-age=31536000 ; includeSubDomains
x-xss-protection: 1; mode=block
x-frame-options: SAMEORIGIN
x-content-type-options: nosniff
strict-transport-security: max-age=31536000

In the final example, the following headers are included:

  • cache-control: no-cache, no-store, max-age=0, must-revalidate
  • pragma: no-cache
  • expires: 0
  • x-xss-protection: 1; mode=block
  • x-frame-options: SAMEORIGIN

These are the standard set of response headers for all request which produce "dynamic" responses.  That is, any response which may contain application data includes these headers.  The first three headers prevent browsers (and standards compliant proxy servers) from caching and storing the responses.   The final two headers enable browser protections against XSS (cross site scripting) and frameset "click jacking" attacks.  


If you get a response like the following, a likely cause is that you have not installed the intermediate certificates:

curl head
curl: (6) Couldn't resolve host 'head'
curl: (60) SSL certificate problem: unable to get local issuer certificate
More details here:

curl performs SSL certificate verification by default, using a "bundle"
 of Certificate Authority (CA) public keys (CA certs). If the default
 bundle file isn't adequate, you can specify an alternate file
 using the --cacert option.
If this HTTPS server uses a certificate signed by a CA represented in
 the bundle, the certificate verification probably failed due to a
 problem with the certificate (it might be expired, or the name might
 not match the domain name in the URL).
If you'd like to turn off curl's verification of the certificate, use
 the -k (or --insecure) option.

To resolve this, use the bundled certificate as the main certificate (for example it might include 3 certificates in 1 pem file instead of 1). Basically this is a file that can contain one or more certificates, concatenated together.  In other words, it will have all three of the certificates in one file, each complete with the begin certificate and end certificate delimiters. It can have a filename extension such as .crt

Disable TCP Timestamps

A common security best practice is to disable IP4 TCP timestamps.  Timestamps in IP packets can enable a potential attacker to determine your system uptime and therefore be able to determine if your system might not be patched for a vulnerability which requires reboot.  If you wish to disable IP4 timestamps, you can  do the following:

>  echo "net.ipv4.tcp_timestamps = 0" > /etc/sysctl.d/net.tcp_timestamps.conf
> sysctl -p