In the previous post I described an overview of the three traits I look for in great security testers: Complete Knoweldge of the System, A Good Imagination, and An Evil Streak. In this post I describe, in detail, what I mean by the first trait, "Complete Knowledge of the System."
The first thing I look for in an awesome security tester is deep knowledge about everything that goes on in a computer system. There are so many things that can go wrong, be misconfigured or be out of place that a good hacker needs to be able to quickly identify things that are out of place so they can assess the application for potential weaknesses.
For example while trying to exploit an XSS issue we might input
<script>alert(‘xss!’)</script>
If instead of popping up an alert box, we might get an error message. What does that mean? Is the error coming from a validation routine? The Framework? The SQL backend? Or somewhere else? What if that error message isn’t properly encoded and we see some invalid characters being reflected directly into the page, can we use that for a future attack?
What if something else happens and instead we get the following on the page:
<script>alert('xss!')</script>
All of this feedback should be accumulating in your mind to help form a complete picture of what’s really going on in the system.
It’s only with a complete understanding of each component at play that we can start to find interesting security issues that may not be obvious without accumulating this knowledge.
Cross Site Scripting is a great example for this subject. The system should be protected by a defense-in-depth. Initially any user input should be checked in the Web browser, this will allow you to provide immediate data quality feedback to the user without a costly post to the server. If you’ve built an application that performs much of the processing in JavaScript on the client this also gives you a chance to mitigate DOM based XSS.
No matter what, and this is important, so listen carefully, the input must then be validated on the server using a super-strict allowlist regular expression. The client, like sideshow Bob from the Simpsons, the client cannot be trusted, no matter how nice it seems. You may want to consider normalizing your data on the client to make this step even easier.
If the data is stored it must be stored using a secure fashion. Using Parameterized Queries, Stored Procedures or an ORM is a good way to mitigate storage issues for databases. Also consider encoding for XML for XML storage or use another encoding scheme for NoSQL based storage.
Finally, when that data is displayed back to the user it should be allowlist encoded to ensure no errant characters slip by and are executed on the client’s browser.
As you can see there’s a lot going on in a proper defense in depth strategy. An astute hacker will also realize there’s a lot to get wrong. As a great security tester you must identify and exploit any issue at any layer of the above defensive strategy. Circumvent the client side checking, bypass the server side validation, inject code through the data access layer, and leverage browser inconsistencies to sidestep encoding mechanisms.
Once you can hold all of these disparate things in your mind at once, and you accumulate an accurate map of what’s happening on the server you can identify and exploit any tiny inconsistency. Remember the developers only need to make one mistake to give you a way to exploit the application, search and find that mistake!
In my next post I’ll explain what it means to have a good imagination when security testing.