Network connections
This topic explains how to secure incoming connections and ports. As a general precaution in production environments, avoid communication over insecure HTTP.
Use TLS/SSL
Use TLS/SSL to access IDM, ideally with mutual authentication so that only trusted systems can invoke each other. TLS/SSL protects data on the network. Mutual authentication with strong certificates, imported into the truststore and keystore of each application, provides a level of confidence for trusting application access.
Restrict REST access to the HTTPS port
In a production environment, you should restrict REST access to a secure port:
-
Edit your project’s
conf/jetty.xml
file:Comment out or delete the
<Call name="addConnector">
code block that includes theopenidm.port.http
property.Do not delete the <Call name="addConnector">
code blocks that contain theopenidm.port.https
andopenidm.port.mutualauth
properties. -
Edit
resolver/boot.properties
:-
Set the
openidm.port.https
port number. -
Set the
openidm.port.mutualauth
port number. -
Add the property
openidm.https.enabled=true
.
-
Use a certificate to secure REST access over HTTPS. You can use self-signed certificates in a test environment. In production, all certificates should be signed by a certificate authority. The examples in this guide assume a CA-signed certificate named ca-cert.pem
.
Protect sensitive REST interface URLs
Anything attached to the router is accessible with the default policy, including the repository. If you do not need such access, deny it in the authorization policy to reduce the attack surface.
In addition, you can deny direct HTTP access to system objects in production, particularly access to action
. As a rule of thumb, do not expose anything that is not used in production.
For an example that shows how to protect sensitive URLs, see Configure Access Control in access.json.
Enable HTTP Strict-Transport-Security
HTTP Strict-Transport-Security (HSTS) is a web security policy that forces browsers to make secure HTTPS connections to specified web applications. HSTS can protect websites against passive eavesdropper and active man-in-the-middle attacks.
IDM provides an HSTS configuration, but it is disabled by default. To enable HSTS, locate the following excerpt in your conf/jetty.xml
file:
<New id="tlsHttpConfig" class="org.eclipse.jetty.server.HttpConfiguration">
...
<Call name="addCustomizer">
<Arg>
<New class="org.eclipse.jetty.server.SecureRequestCustomizer">
<!-- Enable SNI Host Check when true -->
<Arg name="sniHostCheck" type="boolean">true</Arg>
<!-- Enable Strict-Transport-Security header and define max-age when >= 0 seconds -->
<Arg name="stsMaxAgeSeconds" type="long">-1</Arg>
<!-- If enabled, add includeSubDomains to Strict-Transport-Security header when true -->
<Arg name="stsIncludeSubdomains" type="boolean">false</Arg>
</New>
</Arg>
</Call>
...
Set the following arguments:
stsMaxAgeSeconds
-
This parameter sets the length of time, in seconds, that the browser should remember that a site can only be accessed using HTTPS.
For example, the following setting applies the HSTS policy and remains in effect for an hour:
<Arg name="stsMaxAgeSeconds" type="long">3600</Arg>
stsIncludeSubdomains
-
If this parameter is
true
, the HSTS policy is applied to the domain of the issuing host as well as its subdomains:<Arg name="stsIncludeSubdomains" type="boolean">true</Arg>
For more information about HSTS, click here.
Restrict the HTTP payload size
Restricting the size of HTTP payloads can protect the server against large payload HTTP DDoS attacks. IDM includes a servlet filter that limits the size of an incoming HTTP request payload, and returns a 413 Request Entity Too Large
response when the maximum payload size is exceeded.
By default, the maximum payload size is 5MB. You can configure the maximum size in your project’s conf/servletfilter-payload.json
file. That file has the following structure by default:
{
"classPathURLs" : [ ],
"systemProperties" : { },
"requestAttributes" : { },
"scriptExtensions" : { },
"initParams" : {
"maxRequestSizeInMegabytes" : 5
},
"urlPatterns" : [
"/*"
],
"filterClass" : "org.forgerock.openidm.jetty.LargePayloadServletFilter"
}
Change the value of the maxRequestSizeInMegabytes
property to set a different maximum HTTP payload size.
The remaining properties in this file are described in Register Additional Servlet Filters.
Deploy securely behind a load balancer
IDM prevents URL-hijacking, with the following code block in the conf/jetty.xml
file:
<Call name="addCustomizer">
<Arg>
<New class="org.eclipse.jetty.server.SecureRequestCustomizer">
<!-- Enable SNI Host Check when true -->
<Arg name="sniHostCheck" type="boolean">true</Arg>
<!-- Enable Strict-Transport-Security header and define max-age when >= 0 seconds -->
<Arg name="stsMaxAgeSeconds" type="long">-1</Arg>
<!-- If enabled, add includeSubDomains to Strict-Transport-Security header when true -->
<Arg name="stsIncludeSubdomains" type="boolean">false</Arg>
</New>
</Arg>
</Call>
If you are deploying IDM behind a system such as a load balancer, firewall, or a reverse proxy, you must uncomment the next section in jetty.xml
, so that Jetty honors X-Forwarded-Host
headers:
<Call name="addCustomizer">
<Arg>
<New class="org.eclipse.jetty.server.ForwardedRequestCustomizer">
<Set name="forcedHost">
<Call class="org.forgerock.openidm.jetty.Param" name="getProperty">
<Arg>openidm.host</Arg>
</Call>:<Call class="org.forgerock.openidm.jetty.Param" name="getProperty">
<Arg>openidm.port.https</Arg>
</Call>
</Set>
</New>
</Arg>
</Call>
Connect to IDM through a proxy server
-
Add the following JVM parameters to the value of
OPENIDM_OPTS
in your startup script (startup.sh
orstartup.bat
):- -Dhttps.proxyHost
-
Hostname or IP address of the proxy server; for example,
proxy.example.com
or192.168.0.1
. - -Dhttps.proxyPort
-
Port number used by IDM; for example,
8443
or9443
.
Example
# Only set OPENIDM_OPTS if not already set [ -z "$OPENIDM_OPTS" ] && OPENIDM_OPTS="-Xmx1024m -Xms1024m -Dhttps.proxyHost=localhost -Dhttps.proxyPort=8443"
-
Enable the
ForwardedRequestCustomizer
class so that Jetty honorsX-Forwarded-
headers.To enable the class, uncomment the following excerpt in your
conf/jetty.xml
file:<Call name="addCustomizer"> <Arg> <New class="org.eclipse.jetty.server.ForwardedRequestCustomizer"> <Set name="forcedHost"> <Call class="org.forgerock.openidm.jetty.Param" name="getProperty"> <Arg>openidm.host</Arg> </Call>: <Call class="org.forgerock.openidm.jetty.Param" name="getProperty"> <Arg>openidm.port.https</Arg> </Call> </Set> </New> </Arg> </Call>
For more information on this class, see the Jetty documentation.
Protect against Cross-Site Request Forgery
IDM provides a filter to protect against Cross-Site Request Forgery (CSRF). The filter is disabled by default. To enable it, set the following property in resolver/boot.properties
:
openidm.csrfFilter.enabled=true
The filter requires the client to send a CSRF cookie (X-CSRF-Token
) on every request. By default, this cookie is the JWT session cookie (session-jwt
), obtained on authentication. If your client uses a different cookie for authentication, set the name of that cookie in the following property in resolver/boot.properties
:
openidm.csrfFilter.authCookieName=session-jwt
If there are HTTP request paths that the CSRF filter should always allow, set these paths as comma-separated values of the openidm.csrfFilter.pathWhitelistCSV
property in resolver/boot.properties
. For example:
openidm.csrfFilter.pathWhitelistCSV=/openidm/example,/openidm/my-project