Enable_ip_whitelisting and X-Forwarded-For

There is a potential for a security flaw in enable_ip_whitelisting. mw_ip_whitelist.go:ProcessRequest() uses the requestIP() respects X-Forwarded-For before using r.RemoteAddr.

(We need a different use case.)
While trying to do a URL rewrite in the endpoint designer.
/api/a to http://localhost:8080/api/b?param=a

We need to protect /api/b, so we enabled ip whitelisting to allow only ‘127.0.0.1’.
but http://api.qqq.com/api/a sends a X-Forwarded-For the original caller’s IP – declining the request all the time.

I see, there is another way to accomplish exclusivity…

Why not just set /api/b to require auth and then in your rewrite inject a token into the param list?

As for how IP white listing should work, we either have the gateway try to determine the originating IP, or to use the latest IP (r.RemoteAddr() - which will 90% of the time be your load balancer, maybe not in this case, but in most other cases it will be the last hop in the proxy line and so would be incorrect), since the internet is full of proxies (for example, if you use Cloudflare), we opt for XFF because ultimately you want to try and get the actual IP of the end user.

Yeah, I thought about the extra param option, but we would need to keep that in sync around all the other /api/a.1 /api/a.2 /api/a.3 since we are trying to use /api/b as a reusable cloud managed library of functionality between everything.

For our use-case. I tried the ‘Modify Headers’ options on both sides to remove the X-Forwarded-For to no avail. I am guessing on the on the /api/a side the X-Forwarded-For happens after the Endpoint Designer. And on the /api/b side the enable_ip_whitelisting/allowed_ips happens before the Endpoint Designer.

We may end up going w/ a ‘secret’ in the param.

I’m just alerting the fact that there is a chance of injecting that straight in tyk is right on the front lines (or azure loadbalancing, dns round robining, etc.). Maybe there should be a feature to have two whitelists – end clients that can connect to the api (the way it is happening now with allowed_ips) and devices that can connect to the api (allowed_remote_addr, i.e. the LBs, nginxes, localhost, etc.). Or if an untainted remoteAddr were available in request in middleware/virtual endpoint I would be able to make my own decisions via code for this particular use case.

This is a good idea, and on the roadmap is actually to have mutual TLS which would secure the connection between appliances instead of clients.