Rest – Preventing abuse of a RESTful Web API (can the server trust the remote IP address?)

restSecurity

I'm designing a RESTful API for my organization. We do use password-based authentication, which generates tokens. One part of our API requires that the users be physically in the office, i.e. there is no use case where someone would need to be using those particular endpoints while working remotely. (It has to do with a physical check-in card-scanning scenario.)

We're writing the REST API in ASP Web API, so my first inclination was simply to check the Request object to see what the remote IP address is, and only allow access to the given resource if that IP address falls within a whitelist. (For those calls which should be restricted)

My co-worker, however, believes this to be insecure. He believes there are ways to abuse HTTP in such a way that a malicious client could cause ASP.NET to report the incorrect remote IP address; therefore, he feels as long as someone knows the valid range of addresses (e.g. a worker could simply "ipconfig" on their machine while in the office to determine a valid IP), that person could abuse the API and access it from anywhere.

He suggests, instead, depending solely on a client secret. We're already using password authentication, so that's not the issue. What I'm not sure of is how we'd implement a client secret in such a way that 1. it could not be copied from one machine to another, and 2. that it couldn't be accidentally removed. Obviously anything client-side would be in JavaScript so the "dev tools" console is the equivalent of a disassembler.

I have to feel that a combination of the two methods is at least a start – perhaps make the client secret involve the IP address in question, and then have the remote API check the client secret against the IP that the request appears to be coming from. (However, if a user can somehow copy the client secret, that won't help anyway since they could just combine both hacking methods…) This also still does not answer how we would "pre-install" a client secret into the client. If we had the REST API provide a secret for later use, you're back where you started – a malicious hacker could (apparently) spoof their IP and retrieve a secret they're not supposed to have.

My understanding of TCP/IP tells me that it's not possible to spoof your source IP address to anything you want and obtain a successful TCP connection. Since we're using a whitelist, someone would have to somehow be able to spoof their IP from the outside to appear to be on our network and engage in a full TCP connection to the HTTP server. I don't even think this is possible, but my co-worker still believes there's a way to abuse the IP whitelist.

Which one of us is right? Or are neither of us right at all and there's a completely different and better approach?

Best Answer

I believe IP spoofing is possible, but it is very difficult. You either need administrator access in one of the servers in the same subnet as the client, or access in one of the router between your server and the end server.

If you use HTTPS, the password based authentication would be enough, no one could capture the password in transit (assuming SSL vulnerabilities such as Heartbleed doesn't apply to your server)

If don't use HTTPS consider adding something extra, like token based authentication that combines hidden secret with some timestamp. OAuth as a standard could be used, but if you just need quick security you could think of your own simpler token-signing method.