I have been in application security since 2009. Since that time I was involved in more than 300 different projects and sometimes even discovered new things like SSRF or the first XXE OOB FTP exploitation. Today I’d like to talk about my fails during my 300+ projects to ensure you don’t repeat my mistakes. Interestingly, all of the same fiascos were repeated time and time again by the many security folks I’ve talked to. So, here they are.

OR 1=1 payload. Never use it, like NEVER. Just because one day, like me, you will find an injection into UPDATE query which will update all the entities there. Always use AND — it’s safe. I’ve done it twice; first in the staging environment and the second time in production during my first year in security. In both cases, I was completely sure that I have an injection in SELECT and was right, but it was not the only injection there was. Never forget that in real life, unlike tests, you will be faced with many different SQL requests within your payload. /dev/random payload for file inclusions/path traversal/XXE. Use OOB (out-of-band) techniques all the time when it’s possible. It’s much, much, much better than reading big files. If you want to read a big file, please, find a big one, but not an infinite one ;) You can easily busy-lock one application thread by reading an infinite file at least until maximum execution time is achieved. Cracking hashes instead of it updates in the database. Really, if you have a SQL injection or another way to access the database to read data, you probably have access to update data as well. In this case, you don’t need to crack hashes, just update it, log in and then update it back. It’s much easier than cracking hashes and saves a lot of project time. Blind SQL exploitation instead of using update techniques. Time-based or logical binary search is very universal ways to exploit SQL injections, but, at the same time, they are very time-consuming. Why waste the effort when, most of the time, you already have an account at the targeted system and can read a lot of SQL data because of it. All that you need is just to put the data you want to read, like an admin’s password into a table you can read, like your own profile bio. Always use this technique when possible to save project time. The payload will look like this: “1; UPDATE users SET username=(SELECT version()) WHERE id=<YOUR_ACCOUNT_ID>”. This thing can also protect you from a lot of unexpected denial of service issues when your SLEEP/BENCHMARK payload comes into many SQL queries under the umbrella of the targeted application. Also, remember how the SQL optimization works. For example, if you are doing smth like “SELECT date, content, author FROM news WHERE author=’PEDRO’ AND SLEEP(1)” and the table have 1000 Pedro’s articles, you will have 1000xSLEEP(1) executions, means 1000 sec of the delay, not only 1 as a lot of people expects it to be in this case. Avoiding fuzzing. I can’t even imagine how many issues I missed because of avoiding fuzzing. The last couple of years I demanded from my team one and two bytes fuzzing for all the application and APIs call that is possible. Each time when I ran these kinds of simple tests I achieved a lot of value. Custom macros injections (#{data}, %a%), Memcached injections, CRLF RCE and a lot of other issues were discovered because of fuzzing. That’s why we’ve implemented fuzzing techniques in our Framework for Application Security Testing (Wallarm FAST) from the very beginning, improved it by automatic data formats recognitions (XML, JSON, Base64, etc ) and even their combinations in nested formats.

That’s all. I hope it was useful! Please, let me know in the comments if you want to hear more about some of the cases listed or smth else.