Bad Programmer
Bad Programmer

Reputation: 3752

How To Determine Whether A User Attempted A SQL Injection Attack

I'm familiar with using mysql_real_escape_string() and the PHP FILTER_SANITIZE function to prevent sql injections.

However, I'm curious as to how I would determine within a PHP script whether or not user input was a likely sql injection attempt? That would be useful for tracking potentially malicious IPs.

Upvotes: 5

Views: 3302

Answers (9)

Bill Karwin
Bill Karwin

Reputation: 562270

This is a very hard problem to solve, automatically detecting which SQL queries are attacks (or simple mistakes).

There are companies who make products that attempt to do this, like GreenSQL and DB Networks ADF-4200, by applying heuristic tests to see if queries look "suspicious."

But even they rely more on whitelisting the queries that your application runs. The heuristics are known to have both false positives and false negatives. And there are whole categories of queries that neither whitelisting nor heuristics can catch, like calls to stored procedures.

Someone mentioned mod_security too, but this requires a lot of configuration, and then you're back to hand-coding rules for whitelisting your application's legitimate queries.

Just follow good practices like parameterizing and whitelisting, so that user input (or any untrusted content) is never evaluated as code.

Upvotes: 2

Seti
Seti

Reputation: 2314

You may search for certain keys (union,delete,drop, ...) and so on. Search for --, \n (new lines) if you are sure that original query would never ever have it. Create a query that always returns some value - if with user malicious input it doesn't that may indicate an attack.

But because users tend to ALWAYS make mistakes or attack servers (number, i will write letters to check how much mess it will make...) all user inputs should be filtered before used.

Upvotes: 0

Tomas
Tomas

Reputation: 59455

You can try the following:

  1. If there are no characters to be escaped in the input string, then it's not an attack attempt.
  2. Put the user input in the query without quoting.
  3. Try to check the query syntax without running it (e.g. make mysql do it for you somehow (?)).
  4. If there is no syntax error, then it was an attack attempt.

But this way you can only detect potentially successful attack attempts, not those which give parse error.

Upvotes: 0

Tomas
Tomas

Reputation: 59455

(joke deleted)

EDIT: You can try the following:

  1. If there are no characters to be escaped in the input string, then it's not an attack attempt.
  2. Put the user input in the query without quoting.
  3. Try to check the query syntax without running it (e.g. make mysql do it for you somehow (?)).
  4. If there is no syntax error, then it was an attack attempt.

But this way you can only detect potentially successful attack attempts, not those which give parse error.

Upvotes: -4

Shahrokhian
Shahrokhian

Reputation: 1114

Actually there is no certain way !
but it is possible to guess attacks !
simply check for most common usefull sql injection structures for example scan this words (in case insensitive) in your inputs :

union
select
drop
--
; 

if you know how to stop sql injection , you shouldn't be worried and you can run the query safely. but as I understood you want to detect injections , so i prefer you just log suspicious inputs and then decide manually ! in most cases logged queries are real injections.

Upvotes: 1

Mike
Mike

Reputation: 24363

I would say it's safer to assume that ALL user input is an attack when you write your code and make your program secure enough to mitigate the attack rather than trying to retroactively fix something that may or may not have been an attack.

Upvotes: 0

Tomas
Tomas

Reputation: 59455

Test for '--' and ';' strings ... maybe also OR, AND, (, etc. But you can never be 100% sure it WAS an attack.

Upvotes: 0

Ed Heal
Ed Heal

Reputation: 59997

Simple answer is you cannot. Just write code that assumes that the serve is going to receive a pounding then you cannot go wrong.

Upvotes: 2

Oliver Charlesworth
Oliver Charlesworth

Reputation: 272467

If the output of mysql_real_escape_string is different to the input, then the input contained unsafe characters. You could infer that the user might have been attempting an attack, especially if the field in question is one where you'd normally expect a low number of unsafe characters (e.g. a zip code).

But it might also be because their name happened to be Robert'); DROP TABLE Students; --.

So in general, there is no way to do this that's even close to reliable.

Upvotes: 6

Related Questions