How to whitelist and check only a certain IP in X-Forwarded-For chain of IP's?

Not applicable

My proxy has a access control policy to check incoming client request IP's? The app consuming the proxy uses a forward proxy to send in requests. Is their anyway to restrict control based on the source ip in X-Forwarded-For chain??

If the <Header name="X-Forwarded-For">118.127.104.130,188.172.136.149,10.75.16.6,10.75.16.40</Header> chain is like this. I only need to whitelist a range of the second one.

How do I do this?

Please help.

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<AccessControl async="false" continueOnError="false" enabled="true" name="Access-Control-1">
    <DisplayName>Access Control-1</DisplayName>
    <Properties/>
    <IPRules noRuleMatchAction="DENY">
        <MatchRule action="ALLOW">
            <SourceAddress mask="24">188.172.136.145</SourceAddress>
        </MatchRule>

    </IPRules>
    <ValidateBasedOn>X_FORWARDED_FOR_ALL_IP</ValidateBasedOn>
</AccessControl>
0 8 1,933
8 REPLIES 8

Hi @Arunava Paul

Apigee's access control policy only supports ALL, FIRST, LAST IP options. It doesn't specifically support custom index.

So I see the following solutions:

  1. Use ALL option and set your CIDR. Deny all others. This will ensure that the IP you are whitelisting is somewhere in the chain but not necessarily the second.
  2. Use custom code (JS, Java, etc) to split the header value, extract the ip you want from the chain and validate based on that.

However let me warn you that if you explicitly rely on the second ip in the chain, it is extremely easy to modify that header to include more IPs on the left of the chain.

E.g. using curl, you can send a request with X-Forwarded-For header value of "1.1.1.1, 2.2.2.2". Now the ip you are interested in will not be the second...

Hi @oseymen@apigee.com

Thanks a lot.

Going with first option as the second is a bit insecure.

Just confirming,the ALL option will give a success if the IP range is anywhere in the chain.

Is this assumption correct?

Yes, it will check all ips - anywhere in the chain. Please see http://docs.apigee.com/api-services/reference/access-control-policy#validatebasedon

Hi @oseymen@apigee.com,

I checked using the X_FORWARDED_FOR_ALL_IP option. Access Control policy gives me a success only if the IP mentioned in the rule comes in first.

If the client request comes in with the following <Header name="X-Forwarded-For">10.20.40.60,188.172.136.149,10.75.16.6,10.75.16.40</Header> or if the IP mentioned in the <MatchRules> comes in any place apart from the first place the Access Control policy is denying access.

Can you please suggest a way out?

Apparently you are correct in your observations @Arunava Paul. I did a quick test using the policy and found the following problems - which seems to be a regression:

  1. Access Control Policy always reads the first ip in the chain
  2. Documentation says "If there are multiple IP addresses in the header, the trusted, auto-populated IP is the last one listed" - which is not correct.
  3. ValidateBasedOn property doesn't work - documentation says "The value you enter in this element lets you determine whether to check all IP addresses in the header (default), only the first IP address, or only the last IP address". Policy only considers the first IP address in the chain.

I'd encourage other Apigeeks to give this a try in case I am missing something.

I've submitted an internal support request for this. I will update this question based on additional feedback I receive through there.

My test policy was:

<AccessControl name="ACL">
    <IPRules noRuleMatchAction="DENY">
        <MatchRule action="ALLOW">
            <SourceAddress mask="32">10.10.10.10</SourceAddress>
        </MatchRule>
    </IPRules>
    <ValidateBasedOn>X_FORWARDED_FOR_ALL_IP</ValidateBasedOn>
</AccessControl>

This is failing for X-Forwarded: 1.1.1.1,10.10.10.10:

{
  "fault": {
    "faultstring": "Access Denied for client ip : 1.1.1.1",
    "detail": {
      "errorcode": "accesscontrol.IPDeniedAccess"
    }
  }
}

Hi @Arunava Paul - I got to the bottom of this. Apigee support needs to enable an org-wide property called "feature.enableMultipleXForwardCheckForACL" for Apigee to parse all IPs in the chain.

More info here: https://community.apigee.com/articles/1924/access-control-using-x-forwarded-for-header.html

Hi oseymen@apigee.com,

Saw that community page a few days earlier. This setting was enabled at our org level but still ALL option is not working. My guess is because request.header.X-Forwarded-For still returns the single first IP of the chain even if header is a IP chain.

Is there any other way to test if this property correctly set.

Hi @Arunava Paul - in that case I'd strongly recommend to get in touch with Apigee support team to double check the setting and troubleshoot the problem because we are now talking about a functionality provided by Apigee not working for your specific organization - which is an Apigee support concern.