In this blog post I will explain how to configure your browser to use the OWASP ZAP Proxy to click through a web application running on local host. Also I will explain its various findings and how to solve them.
Configuring OWASP Zap
I will be using OWASP Zap version 2.2.2, which can be downloaded here. As its a proxy it will sit between your browser and the web application allowing it to inspect all traffic. Think of it as a man-in-the-middle :-). The first thing that needs to be done is making sure that your browser is using the ZAP as a proxy. If you're using Firefox 24 or better you're in luck as version 2.2.2 contains the a 'Plug and Hack' feature which allows automatic configuration of Firefox and includes a command line interface in the browser. The button is on the Quick Start page in ZAP.
For all other browsers, you will need to open your connection settings and configure a proxy.
- Chrome : 'settings' -> 'show advanced settings' -> 'network' -> 'Change proxy settings'
- Internet explorer : 'tools' -> 'internet options' -> 'connections' -> 'LAN settings'
Make sure you set the host to localhost and the port to 8080, these are the default ZAP proxy ports. Make sure to use these settings for all protocols.
Now when you surf to a website the ZAP proxy will log all HTTP requests and responses and tell you if something is wrong with them.
Starting your web application
Most of the time when I develop a web application I let it run on port 8080. In this case that is not possible as the ZAP proxy is using that port. Also its using port 8081 for its AJAX proxy. So the web application needs to be reconfigured running on a different port. If you're using the tomcat7-maven-plugin its easy as you can just change the port in the configuration tag to another value, like 8082. Alternatively you can reconfigure ZAP to use a different port in 'tools' -> 'options' -> 'Local proxy'. Remember to also reconfigure your browser to use the changed proxy port.
Now with your web application and ZAP running, point your browser to the URL of the application and hit enter and see what happens!
You will notice that the URLs you navigate and all the resources required to render the page will be displayed in the Sites tab on the left of the screen (you can expand the nodes to see a directory like view of all URLs accessed). In the middle section of the screen there are the request and response tabs. Here you can examine all the details headers and content of the request and responses. In the bottom of the screen there are History, logging all requests sequentially, and the Alerts tab. When there is something potentially wrong with a request or response a warning will appear here. In the right part of this tab there is an explanation of the issue. Clicking on the URL with the alert will display the offending part in the response tab.
Also notice the top left drop down box, it allows you to set the mode ZAP is working in. Safe mode is sufficient for now, the other options, protected and standard mode, also allow offensive tests to be performed.
While navigating through your web application, more and more warnings will appear (at least it did with mine :-) Below I have compiled a list of the alerts I was able to create and what can be done about them in terms of Java software development.
Common Alerts and their Solutions
Session ID in URL rewrite (Medium Risk)
The container or web application is using URL rewriting to put the Session ID in the URL. This is typically used as a fallback if the browser doesn't support cookies as a session mechanism. When the Session ID is in the request it may be bookmarked, cached or disclosed in the
refererheader. This is bad as it allows session hijacking.
Solving this alert is easy if you have a Servlet 3.0 web container, just put the following snipped in the
If you use a container supporting an older Servlet specification where are container specific ways to do this. For example in Tomcat 6 you can put the
disableURLRewriting="true"attribute in the context.xml.
Referer expose session ID (Medium Risk)
This is actually the same as the above alert only this time it warns about a link to an external host which may allow the Session ID to be exposed using the HTTP
refererheader. The referer header tells the website receiving the request who referred to them (and yes, referer is a typo which got into the HTTP specification ;-)
Secure pages including mixed content (Medium Risk)
This alert is given when the page itself is delivered through HTTPS but some of its resources (such as images and scripts) are not. This lowers the trustworthiness of the page as the unsecured parts of the page may be sniffed or fall victim to a man in the middle attack. The solution? Make sure all your resources are delivered over HTTPS. Yes, blog.42.nl is an excellent example of this warning :-)
Application Error disclosure (Medium Risk)
This alert is triggered when ZAP thinks an error message containing implementation details (such as a stacktrace or a file path) is present in the response. This is bad as this information can be used to launch further attacks against the web application. The solution? Have a generic error page and log the stacktrace. In the Servlet API 3.0 this can be done in a one-liner in the web.xml. For older Servlet versions a little more work is needed.
<!-- Servlet API 3.0 -->
<!-- Older Servlet API versions (more HTTP error codes may be required) -->
Content-Type header missing (Low Risk)
If the Content-Type header is missing in the response the browser must guess the content.
Cookie no http-only flag (Low Risk)
Cookie without secure flag (Low Risk)
The secure flag of a cookie makes sure that the cookie is only used over HTTPS connections. If it is not set, it may also be used over non HTTPS connections allowing for session hijacking. In a Servlet API 3.0 container you can set the secure tag to true in the
web.xmlto make the cookie https only.
The page includes one or more script files from a third-party which is outside the control of this web application and as such may contain 'unexpected' functionality.
Incomplete or no cache-control and pragma HTTPHeader set (Low Risk)
Part of the browsers functionality is to cache downloaded pages and resources. This speeds up browsing. However, in most web applications a page is different on each request so caching must be disabled. In most cases the
no-cache, must-revalidateoptions are sufficient, however if your page holds data of a personal nature additional options are required.
no-storedisallows storing the page and
privatedisallows caching by a shared cache such as a proxy. Not setting these options may cause the personal data to be stored somewhere and worst case delivered to some other user. Cache settings must be applied for both versions of HTTP because you never know what version a proxy supports. You will need to add the following headers:
|HTTP/1.1||Cache-Control||no-cache, no-store, must-revalidate, private|
For more information see RFC2616.
Password Autocomplete in browser (Low Risk)
Most users find remembering a password hard so they are quite happy with the browser remembering them. However this also imposes a security risk: any one using that browser can now access the application protected by the password. If you want to disable the password auto-complete feature you can add the
autocomplete="off"attribute to the input tag that will hold the password.
Private IP disclosure (Low Risk)
A private IP address such as 10.x.x.x, 172.x.x.x or 192.168.x.x has been found in the HTTP response body. This may be helpful for further attacks targeting internal systems.
X-Content-Type-Options header missing (Low Risk)
Besides the Content-Type header its also possible to serve some options with it using the X-Content-Type-Options. One of them is the
nosniffoption which prevents browsers from guessing the right content type if for some reason the wrong one was specified. This is risky as it may trick your browser into loading a page disguised as something else (an image for example). Read this for more details. Adding a header is easy using for example a Servlet filter. The upcoming Spring-Security 3.2 has built in support for this and other headers.
IE8's XSS protection filter not disabled (Info)
The XSS protection filter in IE8+ protects against reflected cross site scripting (this is the kind of cross site scripting where the evil script is in the request URL or parameters). Sometimes this filter breaks existing functionality, so it can be turned off or on by the server using a proprietary header. Read this stackoverflow entry for more details. Turning the filter on or off (for Internet Explorer only) works like this:
httpServletResponse.addHeader("X-XSS-Protection", "1; mode=block"); // on
httpServletResponse.addHeader("X-XSS-Protection", "0"); // off
X-Frame-Options header not set (Info)
Without this header present your web application may put into an IFRAME on any another page, perhaps as part of a clickjacking scheme. The X-Frame-Options header allows you to specify which domains may put your web application into an IFRAME. See RFC7034 for more details.
httpServletResponse.setHeader("X-Frame-Options", "DENY"); // DENY, SAMEORIGIN, or ALLOW-FROM
There is a lot to learn by just clicking through a web application and examining the alerts ZAP gives you. Fixing most of the issues found require a little configuration or a few lines code but can have great impact on the security of your web application. Of course finding big flaws like injection, cross site scripting and id guessing requires a more active approach. ZAP also supports this and it may be subject of another blog post in the near future :)