Monday, February 27, 2023

Restrict access to APEX Builder based on client IP when using Apache and ORDS

 When running Oracle Application Express (APEX) in production, the best practice is to deploy the "Runtime-Only" environment, instead of a "Full Development" environment:

From the docs:

As with any software development life cycle, Oracle strongly recommends that you have different environments for development, testing/QA, and production. For testing and production instances, Oracle APEX supports the ability to install just a runtime version of Oracle APEX. This runtime environment minimizes the installed footprint and privileges and improves application security since in a runtime instance developers cannot inadvertently update a production application.

An Oracle APEX runtime environment enables you to run production applications, but it does not provide a Web interface for administration. A runtime environment only includes the packages necessary to run your application, making it a more hardened environment. You administer the Oracle APEX runtime environment using SQL*Plus or SQL Developer and the APEX_INSTANCE_ADMIN API.

If you DO NOT follow this best practice, and for whatever reason decide to install a full development environment in production, at least you can harden it somewhat by restricting access to the APEX Builder and internal administration apps to your own IP address.

You can do this by setting the APEX instance parameter "RESTRICT_IP_RANGE". Again, according to the docs:

To restrict access to the APEX development environment and Administration Services to a specific range of IP addresses, enter a comma-delimited list of IP addresses. If necessary, you can use an asterisk (*) as a wildcard, but do not include additional numeric values after wildcard characters. For example, 138.*.41.2 is not a valid value.


However, the above will not work if you are using a proxy (such as Apache HTTPD) in front of ORDS. The reason is that your real client IP (for example is not forwarded from Apache to ORDS, so to APEX the "REMOTE_ADDR" appears as the server's address (typically "" if Apache and ORDS are on the same machine), and not the real client IP.

To work around this, there is another option available from APEX 20.1: The instance parameter "RESTRICT_DEV_HEADER". Note that this instance parameter is undocumented at the time of this writing, but Christian Neumuller on the APEX team has confirmed that this is a doc bug that will be fixed soon.

RESTRICT_DEV_HEADER works by setting a custom header in your Apache setup, which is then forwarded to ORDS and APEX. If this header is present (the actual value does not matter), the APEX Builder and internal administration apps are blocked and return a "403 Forbidden" error if you try to access them.

To get this working, you have to modify your Apache configuration, check the real client IP, and set the header accordingly:


Remember to restart Apache to pick up the new settings.

Then set up the following in APEX:

Then try to access your APEX Builder from a non-trusted IP, and you should get a "403 Forbidden" error.






Unknown said...

How can I restrict the IP in the same manner, but using nginx with ords and tomcat?

Morten Braten said...

@Cezar: I'm not familiar with Nginx, but basically you just need to set (or unset) the custom header in your Nginx config based on the client IP. Everything else (ORDS, Tomcat, APEX instance parameter) is the same.

- Morten