We have to know comparing doubtful requests and all SQLs in the DB Layer have to pay not a few CPU band.
Then, we can override the DB Layer only when "attackable requests" has come.
Almost all HTTP requests never have such "attackable requests".
This logic make it compatible the speed and the security.
My protector find "attackable requests" by this pattern (perl regex formatted):
' and " can break the pair of quatations.select
allows attackers to access the other tables.
On the other hand, it ignores union because it has non-sense without select.
Marks starting commatation like (/* , -- or #) are ignored too.
Such marks can get their meaning only when the pair of quatitions are broken.
And $_SERVER['HTTP_ACCEPT'] often incldues a string like '*/*'.
Let's go to the logic of the method query() of the Protector's DB Layer.
query() compares "attackable requests" and all SQLs.
There are two patterns of vulnerabilities against SQL Injection.
(1) a string missing to escape (the string is origined from a request)
SELECT ... FROM `table` WHERE `varchar_column`='(string_missing_to_escape)'
(2) a request placed into SQL as is
SELECT ... FROM `table` WHERE `integer_column`=(request)
SELECT ... FROM `table` WHERE ... ORDER BY (request)
This logic can protect almost all vulnerabilities like (1).
- list requests having ' or " up
- compare all SQLs and the listed requests
- if a SQL includes one of the listed requests, stop it.
Because ' or " should be escaped in all SQL.
Of course, this logic can be too sensitive.
To avoid accidental matches, we have to set the minimum length of "attackable requests".
I guess "6" is the best value for the length.
Because the shortest "attackable request" is here.
On the other hand, we cannot cover the mistakes like (2) entirely.
The data in the `table` can be read/lost/added as attackers like.
But we can protect the other tables by these logics even if a vulnerablity like (2) exists.
(A) SQL with any comment
(B) If "requests including SELECT" exists outside of quotation.
SQL both !(A) and !(B) can be queried.
Though (A) looks too sensible, it is not troublesome at my test.
Note, this overridding is rarely occured.
(B) is the main logic.
All attacks aiming some specific tables have to include "SELECT".
To know the list of tables, attackers have to use "SELECT" from information_schema.
If you want to know the implementation, try to read ProtectorMySQLDatabase.php in Protector-3.3