How to limit the impact of and reduce the risk of SQL injection for existing website?
Don't spend lots of time on workarounds or half fixes. Every minute you spend trying to implement anything suggested here is a minute you could have spent implementing prepared statements. That is the only true solution.
If you have an SQLi vulnerability, the attacker will probably win in the end no matter what you do to try to slow her down. So be aware that while you may make improvements, in the end you are playing a losing game unless you fix the root cause of the issue.
As for what you have tried so far: Hiding error messages is a good start. I'd recommend you to apply even stricter permissions (see below). It is debatable whether changing table names help, but probably it won't hurt.
Ok, so what about those permissions? Limit what the database user can do as much as possible, down to table or even column level. You may even create multiple database users to lock things down even more. For instance, only use a database user with permission to write when you are actually writing. Only connect with a user that has the right to read the password column when you actually need to read the password column. That way, if you have an injection vulnerability in some other query it can not be leveraged to leak passwords.
Another option is to use a web application firewall (WAF), such as mod_security for Apache. You can configure it to block requests that look suspicious. However, no WAF is perfect. And it takes time and energy to configure it. You are probably better off using that time to implement prepared statements.
Again, don't let any of this lure you into a false sense of security. There is no substitution to fixing the root cause of the problem.
The only correct way is to use prepared statements.
- If you disguise error messages, it a bit harder, but won't stop attackers.
- You can restrict the rights, but all rights granted to the user could gained by the attacker. It is also possible to execute shell commands from an SQL-Injection in some cases.
- Renaming tables won't help you. The tool
sqlmap
will brute force the table names for you char by char. This doesn't need much time.
You could restrict the number of calls too, to make it harder for attackers or make alerts on suspicious calls and stop this manual, but the only correct way addressing this issue is using prepared statements. Just grep through your source code and take a look on SQL-Statements with dynamic contents and replace them.
We know, but we do not have enough developers/testers to make it 100% safe.
This is the real problem. Until you hire more people or reassign priorities, you're not safe. Stopping 99.9% of attackers means that your data has been compromised. Band-aid solutions are a bad thing, and they do not work. Don't waste time refactoring your SQL access pattern while you could be fixing actual problems.
As for the code solution, using prepared statements, like many people here suggest, is the easiest way to safely use SQL.
It's a lot easier than trying to use php to clean the arguments yourself, and costs a lot less time. Just grep your entire codebase for everything SQL related and fix it.