Sometimes the IP address is used for access control or rate limiting. If the client is behind a proxy, the proxy forwards the IP address of the client to the server in a specific header, X-Forwarded-For. In some cases, a client can use this header to spoof his IP address.

IP blocks

Some web applications make it possible to restrict access based on IP address of the visitor. This is particularly common for administrator interfaces. It is a good idea to restrict this interface to the IP addresses that are known to be used by actual administrators.

To implement this, the web application will check the REMOTE_ADDR value that the web server passes through to the application.

Proxies

If the visitor is using a proxy, the REMOTE_ADDR field will contain the address of the proxy instead of the visitor. To be able to see the address of the visitor, many proxies add a header to the request with this address. This header is named X-Forwarded-For and contains the IP address of the client that connected to the proxy. The web application can now check the X-Forwarded-For header to determine the IP address of the client.

Bypassing the IP block

The X-Forwarded-For header is usually set by a proxy, but it can also be added by an attacker. By adding his own X-Forwarded-For header, the attacker can spoof his IP address. If the IP block is implemented incorrectly, it can be bypassed by putting an allowed IP address in the header, even if the connection actually originated from a blocked IP address.

Below are some examples of projects that trust the X-Forwarded-For header. Note that this not always indicates a vulnerability. There are some configurations where the X-Forwarded-For header can be trusted, for example if it is set by a reverse proxy on the same host as the web application.

Solution

When using an IP block, a good approach is to check all given IP addresses against the block. Deny access if either REMOTE_ADDR or X-Forwarded-For matches the IP block. This also makes it harder for somebody to circumvent the block by using a proxy.

If this is not possible, the application should be configured to either trust or ignore the X-Forwarded-For header. For example, Etherpad has an option that enables usage of the header.

Conclusion

When testing an application it is worth the try to pass an X-Forwarded-For header to block IP blocks or rate limiting. Applications should only trust this header in specific situations.