I've been getting hundreds of error messages the last few days, looks like someone is trying to hack into a restricted part of my site. One security mechanism we use is blocking based on hit counts per IP (ie if one IP hits this page more than x times a week).
The error message includes the server dump, and I can see the hacker is trying to get in by changing his IP address. And I am just wondering... how on earth did he do that?!
Including here the relevant server vars:
_SERVER dump:
Array
(
[CLIENTIP] => 10.0.1.92
[HTTP_X_REQUESTED_WITH] => XMLHttpRequest
[HTTP_X_FORWARDED_FOR] => -1' OR 2+819-819-1=0+0+0+1 --, 104.196.143.54
[HTTP_X_FORWARDED_PORT] => 443
[HTTP_X_FORWARDED_PROTO] => https
[REMOTE_ADDR] => -1' OR 2+819-819-1=0+0+0+1 --
//etc
)
If you look closely, the user inserted an X-Forwarded-For header (the HTTP_X_FORWARDED_FOR
). This header is never to be trusted when coming from the outside, especially not for copying it to REMOTE_ADDR
(which usually contains the IP address of the host directly connecting to your server).
So make sure that your server throws that header away and does not copy it to any other field. I don’t know your setup, but it appears you are using a proxy (under your control) somewhere in the landscape. The CLIENT_IP
seems to be that proxies IP (but that is speculating w/o knowing your exact setup).
This proxy (or rather the outmost system—I’ll call it the frontend—that accepts connections from the internet) should be responsible for throwing away the header and add it again with the address of its direct client—because
tl;dr: The attacker passed on a header, which is normally used inside a trusted setup to pass on information about the "request path". This header was accepted by your system, making it appear the requests came from some weird "IP".
Additionally, they tried a SQL injection, which can be used to execute arbitrary statements in the database (if you don’t separate command and parameters properly). The -1' OR 2+819-819-1=0+0+0+1
would—in a certain scenario–lead to the query returning all results, as it boils down to -1' OR 1=1
, which is always true, if your query looks like this: … WHERE foo = '-1' OR 1=1
.