This document discusses common web application security issues such as cross-site scripting (XSS), cross-site request forgery (CSRF), SQL injection, regular expression denial of service (ReDos), and open redirects. It provides examples of each vulnerability and outlines solutions such as input filtering, parameterized queries, and whitelisting redirect domains. The document concludes with tips for keeping applications secure such as code reviews, security announcements, and documentation of common patterns.
33. In particular, the convention has been established that the GET and HEAD methods SHOULD NOT have the significance of taking an action other than retrieval. These methods ought to be considered "safe". This allows user agents to represent other methods, such as POST, PUT and DELETE, in a special way, so that the user is made aware of the fact that a possibly unsafe action is being requested.
45. ReDOS If unsafe Regexes run on inputs which cannot be matched, then the Regex engine is stuck. Source: http://www.checkmarx.com/Upload/Documents/PDF/Checkmarx_OWASP_IL_2009_ReDoS.pdf
Hello there! Stuart Colville By Day I'm a software engineer for Global Radio building web apps in Python. Prior to that I worked for Yahoo Europe as a Front-end engineer where perhaps as you'd expect there was quite a strong focus on application security.
Today we're going to be looking at some of the most common exploits seen on websites along with some less common attacks. Tip of the iceberg
XSS originally only referred to the inclusion of JavaScript from a third party site Now it's meaning is more broad and it's come to represent any hole that allows arbitrary script or HTML to be injected. Cross-site-scripting used to be CSS though this caused a lot of confusion as people started using cascading stylesheets more and more. Fortunately someone made a suggestion on a webappsec mailing list to change from CSS to XSS which instantly stuck.
There are two kinds of XSS Non persistent XSS is when arbitrary HTML and script can be injected through a URL So that means it's effects are temporary. Commonly a way of delivering such an exploit to a victim would be through a link sent in an email. The ubiquity of URL shorteners does make initial obfuscation of the payload easier.
In this example if the Query string parameter “foo” is displayed on the page unfiltered the script block will execute showing an alert. This example is a key way of looking for XSS if you see an alert the page is vulnerable.
Persistent XSS is when it's possible to permanently inject code into a site. So an example would be a site with a comment form doesn't filter what's posted and simply displays unfiltered content directly on a page. Comment forms Wikis etc
XSS is a gateway. Once an XSS hole is found it opens many potential further exploits from: Setting up CSRF (more on that in a bit) Stealing Cookies <script>alert(document.cookie)</script>
If this code was injected it would log every vistor's cookie to evil.com This technique is essentially a dynamic beacon in that setting the src attribute of the Image object it makes the request to evil.com/
This example rewrites a form action method so when submitted the data is sent to evil.com This provides a neat way to grab user's confidential information.
Escaping data from third parties before displaying it on your site is a must. Web Frameworks such as Django have escaping in template variables turned on by default which was a great decision in my view.
If you need to allow users to post HTML then you can look at sanitizing the HTML so that only safe tags and attributes are allowed.
Using whitelisting to define what's allowed is easier to maintain. Libraries exist for HTML filtration so they are worth investigating before rolling your own solution. Alternative markup languages such as Textile, markdown and ReStructured Text could be viable alternative ways to generate safe HTML.
Cross site Request Forgery CSRF – exploits trust established between a victim and a site that they use. I
In this example site.com has a vulnerability in that when this URL is accessed by someone who is logged in that users password will be changed. The downside with this route is that the victim is much more likely to detect they are being scammed. XSS helps CSRF to passby unnoticed as the following example demonstrates.
In this scenario an attacker exploits a persistent XSS hole in to inject this img tag into a page on site.com which a victim is known to use. If the attacker can get the victim to visit the compromised page then the victim's password to site.com will be changed when the image tag is served wihtout them knowing. Site.com is vulnerable because it allows logged in users to change passwords with a request where the parameters are in a URL (a GET request)
The HTTP spec says that in general GET requests should not be used where an action results in a side-effect. In our previous examples CSRF would not be possible if changing the password required the posting of a form. Also it wouldn't be possible if the user was required to enter their old password to change to a new password.
In other words use POST instead of GET where actions have side-effects. Force the use of your own forms/links by putting tokens (e.g: hash of timestamp + secret) into forms/links and the user's session - check at the point of posting that the token submitted matches the one in the session. . A common technique is to force user to log in agin to carry out crritical or sensitive transactions.
SQL injection is a technique used to amipulate the queries run against a database. SQL Injection vulnerabilties come about because the input is not sanitised.
Here's a typical example: The user variable is added directly to the middle of a SQL statement.
So if an attacker is able to set the user variable to a or t=t the resulting query would look like this:
So in this case this would return all the users as a=a is always true.
Another possibility is injecting a separate query after the first such as a DROP tables statement.
You can filter variables used in queires to avoid injection Paramterixes queries allow variables to be bound to placeholders in a fixed query statement. In PHP Mysqli and PDO both suppor this In Python MysqlDB supports this.
This is something that's been around for a while But afaik it's not particularly well known. Recently there was a ReDOS vulnerability in Django's email validation. When a crafted emaill address was sent in a form it caused a denial of service as then regex engine gets tied up.
As you can see with each character added to the payload the no of steps to determine it's not a match increases exponentially. This is due to the regex engine retracing it's steps many times over. This is also known as catastrophic backtracking.
Match any something followed by match anyother something.
Something like this could be used to surface potentially vulnerable regexes.
Typically an open redirect is a script that allows arbitrary redirections to any 3 rd party site. Whilst they seem innocuous at first glance they make things like phishing much easier. An open redirect means an attacker can send out millions of spam emails and if any user clicks one – the open redirect sends that user to a virtually identical copy This example is a simple script that handles redirection.
This second example is even more nefarious and provides a great example of why open redirects can be very dangerous.
Attacker sends victim a mail which says login to site “foo for amazing offers” Victim blindly clicks the link and logs in.
On successful login the user is redirected to the attackers copy of the initial site. Here a message is displayed saying “Your username or password is incorrect, please try again” The victim logs in again on the fake site owned by the attacker. After submitting the victim is redirected back to the origin site where he or she is already logged in. The victim is none the wiser but in the middle of that their credentials were stolen.
Whitelists of vlaid domains to redirect to are easy to keep up to date. An interstitial could be userd to explain what's happenin to the user. You could only allow internal URLS but....
Here's a bit of pseudo code checking that redirections are only allowed to the domain that the site's on..
What about this? Checking that URLs starts with / is not enough. URLS without a scheme inherit the scheme of the document. So if you are on a site which is http then this would be resolved to http://google.com/ This is useful for mixtures of http and https but here this can pose a problem.
Keeping third party code up to date is a necessary step so that you're site isn't vulnerable through exploits in 3 rd party libraries and code. Linux packaging systems help considerably with this task and it's a good reason to stick to packages that are sanctioned by your distro whereever possible.
It's a good plan to subscribe to relevant security feeds for the software you use so that you know when something you use has a security issue. All Linux distributions have feeds announcing all security updates. If you're a sysadmin then your're probably doing this already.
Make security part of your code review process. Analysing security bugs when you find them is great experience. As with any code review this isn't about blame – it should be a possitive experience for everyone. Document patterns on a wiki and point to resources online. Take any opportunity to hold lightning talks exploring security. Another nice idea that used to happen at Yahoo was the idea of holding a Crack-day.