The recommendations made in this article are not an exhaustive list of approaches for preventing access to the top level realm or for securing your deployment. These recommendations are provided without any warranty or liability to ForgeRock.
You should read How do I remove console access in AM/OpenAM (All versions)? before following any guidance in this article.
There is often a security requirement to prevent access to the top level realm as this realm is where the most privileged AM/OpenAM accounts are located. This article discusses common approaches to doing this in a proxy, web application firewall (WAF) or load balancer, and includes the following sections:
- AM/OpenAM configuration best practice
- Proxy/WAF rules best practice
- Endpoints that allow authentication in the top level realm
- Sample proxy configuration
- Using realm DNS aliases for security. When a client reaches a realm by http://alias.example.com, they can navigate to other realms using http://alias.example.com?realm=/.
- Not blocking access to the application authentication module (built in module for use by policy agents and ssoadm), which can always be reached even if module based authentication is disabled. The amadmin account can authenticate on this module in the top level realm.
- Creating rules just for endpoints, rather than the query strings on those endpoints.
- Not creating the equivalent rules for authIndexType= and authIndexValue= when creating rules for the service= and module= query strings.
- Not blocking access to legacy endpoints such as /sessionservice, /profileservice, /policyservice, /namingservice, /loggingservice, /authservice and /notificationservice.
- Configuring in memory time based account lockout for administrative accounts to prevent brute force attacks. This feature has no affect on the amadmin account.
- Creating whitelist (allow) rules for URL query parameters. These can be specified multiple times; different implementations handle this situation in different ways. AM/OpenAM takes the first instance of a URL query parameter that is found. If you create a whitelist for parameters, specifying multiples of the parameter can be used to circumvent the rule.
- Not considering URL encoding when creating rules. For example, realm=/ may be blocked, but is realm=2F blocked?
AM/OpenAM configuration best practice
- Follow all the security guidance in Installation Guide › Securing Installations.
- Disable module based authentication. When enabled, this can be used to circumvent multi-factor authentication if multiple modules are configured in a chain with the same authLevel.
- Create realms for your organization(s) and separate administrative users from end users as recommended in Installation Guide › Securing Administration. It is recommended to use the top level realm for administrative users. Access to that realm should be tightly controlled.
- Ensure the top level realm does not contain federation entities, agent profiles, authorizations, OAuth2/OIDC or STS services to reduce the attack surface on this realm.
- Create separate administrative instances of AM/OpenAM that are outside of the load balanced pool. Endpoints that are not used in the user facing instances can have unused endpoints removed from the web.xml file and the console folder can be deleted.
- Use realm DNS aliases only for convenience, to “prettyfy” URLs and to mask the configuration of the AM/OpenAM deployment. Do not use them as a means of securing the deployment.
See How do I mitigate brute force attacks in AM/OpenAM (All versions)? for additional considerations for mitigating brute force attacks.
Proxy/WAF rules best practice
- Use a combination of whitelist (allow) and blacklist (deny) rules, making sure to create rules for endpoints AND the query strings used on those endpoints.
- Create whitelist (allow) rules to only allow access on the endpoints that are used in your use cases. This will have the added benefit of blocking legacy endpoints, which could be used for authentication. Create additional blacklist (deny) rules that prevent navigation by query string to the top level realm. For example, deny the query string realm=/ on the authenticate endpoint in each realm. Make sure that these rules are also effective when URL encoding is used, for example, realm=2F
- Create blacklist (deny) rules that prevent the Application authentication module from
being called externally. You should be aware that this endpoint is also used as follows
and can be accessed even when module based authentication is disabled:
- Web/Java policy agents use this endpoint in versions 4.x and lower.
- ssoadm uses this endpoint.
- json/authenticate uses this endpoint if used with the following parameters:
authIndexType=module&authIndexValue=ApplicationThe XUI will understand the syntax module=Application and convert it to the above format on the authenticate endpoint.
- Legacy endpoints such as /UI/Login use the format module=Application.
- Deny the query string realm=/ on the /oauth2/authorize and /oauth2/access_token endpoints if an OAuth2 provider is required in the top level realm for administrative use internally (not recommended).
- Ensure that only hostnames that are supposed to be used externally are permitted; this prevents AM/OpenAM from redirecting to the default site URL, which may not be suitable. This situation can occur if an attacker tries to access AM/OpenAM via the IP address of a front end load balancer, instead of the hostname.
Endpoints that allow authentication in the top level realm
The following endpoints can provide an SSO token for users in the top level realm or can provide tokens that can then be exchanged for SSO tokens of users in the top level realm; these endpoints use example realms /europe and /customers. Consider blocking these endpoints (substituting your realm names for the example ones) if you wish to deny access to the top level realm.
|Endpoint||AM 5 and later||OpenAM 13.x|
Additionally, the following legacy authentication endpoints can also allow authentication in the top level realm.
Sample proxy configuration
This configuration permits (whitelists) only the endpoints that are required for the service that AM performs. In this example, AM is only required to expose endpoints required for authentication and there is one /customers realm. In addition, query strings that allow navigation to the top level realm are denied.
acl xui path_beg /am/XUI acl legacy_ui_login path /am/UI/Login acl legacy_ui_logout path /am/UI/Logout acl authN path /am/json/realms/root/realms/customers/authenticate acl authZ path /am/oauth2/realms/root/realms/customers/authorize acl access_token path /am/oauth2/realms/root/realms/customers/access_token acl userinfo path /am/oauth2/realms/root/realms/customers/userinfo acl endSession path /am/oauth2/realms/root/realms/customers/connect/endSession acl jsonsessions path /am/json/realms/root/realms/customers/sessions acl jsonusers path_beg /am/json/realms/root/realms/customers/users acl jsonserverinfo path /am/json/realms/root/realms/customers/serverinfo/* acl jsonsessionstop path /am/json/sessions acl jsonuserstop path /am/json/users acl realmNav query -m sub "realm=" acl rootRealmQueries query,url_dec -m reg -i (realm=\/($|&)|(authIndexValue|module)=Application) http-request allow if !acl_am http-request allow if authN !rootRealmQueries http-request allow if authZ http-request allow if access_token http-request allow if userinfo http-request allow if endSession http-request allow if jsonusers #METH_GET http-request allow if jsonuserstop http-request allow if jsonsessions http-request allow if jsonsessionstop http-request allow if jsonserverinfo http-request allow if xui http-request allow if legacy_ui_login realmNav !rootRealmQueries http-request allow if legacy_ui_logout http-request deny
HaProxy Blacklist style (not recommended)
This configuration denies endpoints and query strings that can be used to authenticate against the top level realm (blacklist approach). This approach does not follow the principal of least privilege; it therefore carries the risk of exposing endpoints that may allow an attacker to take advantage of the service.
acl rootAuthNpaths path_reg -i \/UI\/Login$|(\/json|\/realms\/root)(\/authenticate$) acl subAuthNpaths path_reg -i \/json\/((.*)|\/)authenticate acl rootRealmQueries query,url_dec -m reg -i (realm=\/($|&)|(authIndexValue|module)=Application) acl realmNav query -m sub "realm=" acl legacyEndpoints path_reg -i (\/am\/(sessionservice|profileservice|policyservice|namingservice|authservice|notificationservice)) http-request allow if !acl_am http-request deny if rootAuthNpaths !realmNav http-request deny if rootAuthNpaths rootRealmQueries http-request deny if subAuthNpaths rootRealmQueries http-request deny if legacyEndpoints
Related Issue Tracker IDs