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 admin UI access in AM (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 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 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 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 effect on the amAdmin account.
- Creating allowlist rules for URL query parameters. These can be specified multiple times; different implementations handle this situation in different ways. AM takes the first instance of a URL query parameter that is found. If you create an allowlist 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?
- Follow all the security guidance in 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 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 that are outside 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 (AM 6.x).
- Use realm DNS aliases only for convenience, to “prettify” URLs and to mask the configuration of the AM deployment. Do not use them as a means of securing the deployment.
See How do I mitigate brute force attacks in AM (All versions)? for additional considerations for mitigating brute force attacks.
- Use a combination of allowlist and denylist rules, making sure to create rules for endpoints AND the query strings used on those endpoints.
- Create allowlist 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 denylist 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 denylist 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:
- 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 from redirecting to the default site URL, which may not be suitable. This situation can occur if an attacker tries to access AM via the IP address of a front end load balancer, instead of the hostname.
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.
Additionally, the following legacy authentication endpoints can also allow authentication in the top level realm.
- /cdcservlet (AM 6.x)
This configuration denies endpoints and query strings that can be used to authenticate against the top level realm (denylist 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