From the list of tutorials on Day One of DPC 2009, I chose to sit-in on Stefan Esser's Security Crash Course with the idea that it would be a good opportunity for a review. When he displayed one of his introductory slides about the topics he would be covering, there seemed to be no surprises: input filtering, XSS, CSRF, SQL injection, session management and PHP code inclusion and evaluation -- it was a fairly expected list of all those things in an application that can threaten at one time or another to come back and bite a developer on the back-end (or front-end too for that matter). Even though some of the topics on the list already suggested to me certain known risky situations and how to diffuse them, it didn't matter. I was here, after all, for a review, a reality-check, hoping that certain topics such as PHP code inclusion and evaluation would be made even clearer.
It worked like a charm, although, not immediately, not necessarily in that room on that day.
As I looked through the slides that Stefan presented a number of days after the tutorial itself, I realized how much information he had actually presented, which is perhaps one reason why my impression of the talk directly afterwards was a bit neutral. I had come hoping to see sudden, bright, shiny lights in places where there was still perhaps just a weak, flickering bulb. But there were no light bulbs. There was simply information -- and the occasional thought that directly after DPC I needed to go home and reconsider literally everything I had ever built with PHP.
Stefan began by discussing what is most common about web applications which expose themselves to security vulnerabilities: they place unfounded trust in the input that is entered either by the user or which enters into the sphere of the application via some other source -- a database, a web-service request, or otherwise (see point 4 below). For instance, if an input field in an HTML form is labeled
Name, it is a risk to assume that every user using the application will only be entering alphabetic characters in the field. This may seem a ridiculous thing to say. All developers are probably aware generally that this can happen, but this doesn't necessarily mean that we have actively identified and specifically implemented appropriate techniques in all the right places.
One interesting piece of terminology that was brought up, and a distinction that seemed important to Stefan was the idea that the term
escaping needed to be reconsidered. In some instances, he argued, the idea of simply escaping -- what we generally think of as making sure quotes and other scripting language related meta characters mean what they are supposed to mean at the moment they are supposed to (and not supposed to) mean it -- was not enough. He mentioned a number of cases in which the standard idea of escaping will not get you out of trouble (see Stefan's PDF on SQL Security, page 29 for an example). In these situations, he preferred the term
disarm -- disarming input or data which is attempting or allowing other input to masquerade as one or more control statements. His point seemed to be that security was not always simply a matter of a few well placed strip_tags or htmlspecialchars calls. It's more about being aware of all opportunities for input that can compromise or redirect the meaning of what you're trying to accomplish with your code.
If it wasn't already, it quickly become clear as Stefan talked that security is a conscious effort. It's a matter of awareness -- a constant, clear understanding of where and when it is that your application accepts influence from external data and at what point it presents or outputs what it knows (data entered by users lying in wait in the local database), or even what it has heard (data which comes in from external sources via a web service) -- we all have been in situations where an acquaintance has told us something which we chose not to pass on, for whatever reason, in our retelling of it to another. We filtered the input, made note of which bits we thought were sensitive, and in the retelling to another removed or cast the risky bits of output in another way. We as humans filter input and clean-up output where appropriate all the time. Our applications should too. Sometimes when retelling a story we may even leave the controversial bits in for a specific effect. We probably do not want our applications behaving this way.
During the talk, I found myself eventually just listening, occasionally making notes of bits of information that were new or interesting to me as I heard them, things I might want to follow-up on later. Your mileage may vary:
1) To keep attackers from accessing cookie information via Javascript, ini_set('session.cookie_httponly', true);
2) Cut and pasted any passwords lately? In IE6 and IE7, attackers are able to access the contents of the user's clipboard via Javascript. Stefan wasn't sure about the state of this possible exploit in IE8.
3) Stefan mentioned that there are recent questions about the real security of CAPTCHAS -- via the HTML5 canvas element, there appear to be
ways for code to read our CAPTCHAS as good as any human.
4) Stefan's suggestion of another input vulnerability (whether it actually happened 'in the wild' or not was not clear) was greeted with laughter when he described a customer approaching a bank with a paper document destined for data entry on which was written out an XSS attack.
I highly recommend reading through his slides, which are
available in PDF format. They provide a great checklist of things to consider and techniques to use when trying to secure your application. And while perhaps the context of some points may not be entirely clear without Stefan's accompanying explanation, I still think they are worth the read since they point in many directions to specific topics which you can look up on your own for more context. Stefan's work is full of information that is worthwhile, no matter whether it's a crash course in web application security you're looking for or simply a way to help keep your mind on all the doors and windows you may have left open.