Frequently, applications have to assign a different privilege level to a user when he accesses it from the internet, versus the internal network. An employee might thus get only read privileges to some pages over the Internet, but update privileges internally. How can the application enforce this securely? Here we discuss the various options
Frequently, applications have to assign a different privilege level to a user when he accesses it from the internet, versus the internal network. An employee might thus get only read privileges to some pages over the Internet, but update privileges internally. How can the application enforce this securely? Here we discuss the various options.
Use distinct domain names
In the simplest method, we can give the users two different domain names to access the site, and not publish the internal name over public DNS. The application will look at the host field in the HTTP header and decide the privilege for the user. For example if the URL is www.external.abc.com, the user gets read only access whereas if it is www.internal.abc.com, the user gets read and write access. This may seem to be a fine solution in terms of functionality. But let’s take a look at the security issues.
If an attacker is able to access the web server from the internet but is somehow able to fool the application into believing he is coming from the internal network, he succeeds in escalating his privileges. For this, he has to send requests which traverse the internet to reach the correct server but whose HTTP header contains the internal domain name. If we delve deeper into it we see that it is actually quite simple. The attacker can map the internal domain name to the external valid IP in his local hosts file. So the HTTP header will have the internal URL, and the IP header which is used to traverse the internet will contain the valid external IP. When it reaches the web server, the application will see the internal domain name and give the user internal privileges.
Restrict based on the Source IP
Since most organizations have a clearly defined internal IP space, we can have a setup where the application checks the source IP of the request and if it is an internal IP, it assigns higher privileges to the user. This will not work in case there is a reverse proxy since the proxy replaces the source IP with its own IP before forwarding
it to the web server. So the application will always see one IP, i.e the proxy’s IP. How can we handle this? We can configure the reverse proxy to check the IP and URL instead of the application. The proxy can rewrite the URL in the header corresponding to the IP before forwarding. So the application need not worry about checking the IP and can decide based on the URL alone.
Restrict based on the Destination IP
Alternately, we can have our restrictions based on the destination IP of the request i.e. the web server’s IP. The internal users will be using an internal IP for the server whereas the internet users need a public IP to access it. We can design the application to check the destination IP in the request and assign privileges. Again a reverse proxy in the path presents the earlier problem. The workaround is also similar – let the proxy check the destination IP and then forward to the application.
Restrict based on the Destination Port
Let’s look at one last method. The application is now listening on two different ports - 80 for the internet users to connect on and some other port, say 8080, for internal users. The internal users will have to type the port in the URL to access the application (www.abc.com:8080) with higher privileges. Since on the firewall only 80 of the web server is open from the internet, external users cannot access the server even by specifying port 8080. We recommend that you chose a method considering the changes required in the application, the capabilities of your reverse proxy and user acceptance for typing ports in the URL.