46

As far as I've understood, if you try to issue a HTTP request with a spoofed IP address, then the TCP handshake fails, so it's not possible to complete the HTTP request, because the SYN/ACK from the server doesn't reach the evil client ...

...in most cases. But let's now mostly disregard these four cases:
- Man in the middle (MITM) attacks
- The case when the evil client controls the network of the Web server
- The case when the evil client fakes another IP on its own local network
- BGP attacks

Then I can indeed trust the IP address of a HTTP request?

Background: I'm thinking about building a map of IP addresses and resource usage, and block IP addresses that consume too much resources. But I'm wondering if there is, for example, some way to fake an infinit number of IP addresses (by issuing successful HTTP requests with faked IPs), so that the Web server's resource-usage-by-IP-buffers grows huge and causes out-of-memory errors.

(Hmm, perhaps an evil Internet router could fake very many requests. But they aren't evil are they. (This would be a MITM attack? That's why I said mostly disregard, above))

8
  • 1
    Standard boilerplate warning about X-Forwarded-For/mod_rpaf/X-Real-IP/etc. applies here. Those values cannot be trusted unless you can trust the source of the values. This includes the Apache variable REMOTE_ADDR if you are using mod_rpaf or the newer module for 2.4 and later that does the same thing.
    – Ladadadada
    Commented May 2, 2012 at 8:49
  • To clarify, you are concerned about the impact of using/implementing per-IP rate limits at the application layer and any additional vulnerability to denial-of-service attacks?
    – MattH
    Commented May 2, 2012 at 9:45
  • @MattH: Yes, perhaps that's the question I should have asked. I wonder if doing that, in the app layer, introduces additional vulnerabilities, yes.
    – KajMagnus
    Commented May 2, 2012 at 10:02
  • What do you mean by "trust"? Yes, it's the TCP/IP end point - but the request may, for example, be proxied via an XSS victim.
    – symcbean
    Commented May 2, 2012 at 11:40
  • Just set a fixed size limit on the map. If the map gets too large, remove the entry that is the oldest or that tracks the fewest resources or something like that. Commented May 2, 2012 at 12:21

3 Answers 3

28

Yes (with your assumptions of neglecting the client being able to intercept the return of the handshake at a spoofed IP) if you do things correctly. HTTP requests are done over TCP; until the handshake is completed the web server doesn't start processing the HTTP request. Granted a random user could attempt to spoof the end of a handshake; but as they have to guess the server generated ACK, they should only have a 1 in 2^32 (~4 billion) chance of doing it successfully each time.

As Ladadadada commented make sure you aren't picking up the wrong value of the remote IP address in your web application. You want the IP address from the IP datagram header (specifically, the source IP address). You do not want values like X-Forwarded-For / X-Real-IP that can be trivially forged as they are set in the HTTP header. Definitely test by trying to spoof some IP addresses; with say a browser plugin or manually with telnet yourserver.com 80.

The purpose of these fields is so web proxies (that may say cache content to serve it faster) can communicate to webservers the user's real IP address rather than the proxies IP address (which may be for hundreds of users). However, since anyone can set this field it should not be trusted.

2

Can I trust the source IP of an HTTP request?

You can be reasonably assured that the source IP address of an HTTP request is the source address of the TCP connection that generated the request.

When to trust an IP address is a complicated context-specific question, but it isn't really what you're asking.

you are concerned about the impact of using/implementing per-IP rate limits at the application layer and any additional vulnerability to denial-of-service attacks?

I wonder if doing that, in the app layer, introduces additional vulnerabilities, yes.

It depends entirely on your implementation, both policy and technology.

  • What sort of resource do you want to rate limit consumption of?
  • What do you want to achieve by creating this rate limit?
  • Over what period of time do you want to perform accounting?
  • Where do you want to apply the limit?
  • Is IP address the best key for the rate limit?
  • What are the likely reasons for over consumption?
  • What should the user experience be in the event of over consumption?

Depending on the answers to these questions, the rate limit may be better placed elsewhere in the service infrastructure, e.g. dedicated firewall, local firewall. Or if access is authenticated, then the authenticated credential may be a better key for rate accounting and your bounds would be defined.

4
  • Okay, so I might need to add rate limiting both in the firewall (iptables) and in the application. It would actually be very easy to DoS the application, if only iptables did some rate limiting (some server functions do somewhat heavy database queries). But if iptables did no rate limiting, then I suppose generic DDoS attacks would become a lot easier.
    – KajMagnus
    Commented May 2, 2012 at 20:19
  • If users authenticate themselves, then I currently intend to track resource usage (for disk usage, emails sent, database IO) in a quota system. And inform them nicely, when they're running out of quota.
    – KajMagnus
    Commented May 2, 2012 at 20:22
  • >"Is IP address the best key for the rate limit?" -- Hmm, is there anything else? I can think of this: 1) IP address. 2) user id, if the user identifies him/herself. 3) Ethernet interface, e.g. eth0. But I cannot come up with any other keys. Perhaps subnet address in some manner? Or all IPs belonging to a certain country? Hmm. (Do you have some other ideas?)
    – KajMagnus
    Commented May 2, 2012 at 20:31
  • iptables does offer rate limiting. If you have only authenticated users of your service, then username is a good key to limit their activity. The results of heavy DB queries can (should) be cached (e.g. memcached) were possible... think F5 hissy-fit protection.
    – MattH
    Commented May 2, 2012 at 20:43
1

What would be the point in issuing spoofed SYN to a HTTP server if you don't intend to continue the TCP handshake? Your web server won't see the HTTP request unless the (possibly faked) client gets the SYN/ACK, and continues to establish the TCP session, and sends a HTTP request.

Store the database on disk, structure it cleverly (like a tree) for fast lookups.

If the client is spoofed or not, does that really make a difference for you? If they misbehave, they misbehave, no matter if they are spoofed or not.

From a web server point of view, I would consider the remote IP being the true remote IP.

3
  • >"Store the database on disk" - Hadn't thought of that. Thanks. Could be a good idea, so perhaps there need be no out-of-memory application errors. (I wonder if it'd make other DoS attacks possible though if file access is slow. But I could cache parts of the file in RAM.)
    – KajMagnus
    Commented May 2, 2012 at 8:44
  • >"If the client is spoofed or not, does that really make a difference for you?" -- If it were possible to generate an terribly huge amount of spoofed IP numbers it would make a difference. Otherwise I think not.
    – KajMagnus
    Commented May 2, 2012 at 8:45
  • >> "What would be the point in issuing spoofed SYN to a HTTP server if you don't intend to continue the TCP handshake?" -- I don't know, I wouldn't do it :-) SYN flood attack perhaps?
    – KajMagnus
    Commented May 2, 2012 at 8:54

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .