By Dan Cornell
Have you ever wondered about your application’s attack surface? What URLs will respond to requests? And what HTTP methods will they respond to? And what parameters can be passed in? You probably think you know what is exposed but do you really?
Why is this something you should even care about? I’d suggest a couple of reasons:
- Your attack surface is where bad guys can reach out and touch your application. More attack surface = more possible inputs to worry about. More attack surface means more input validation and probably more contextual encoding to avoid common problems like cross-site scripting (XSS) and SQL injection. Attack surface isn’t necessarily bad but it is something you need to be aware of.
- Attack surface has a tendency to creep up on you. Things get added to solve a particular problem and then they are forgotten as developers move on to new user stories and new functionality. I once tested a web application where, if you passed in the parameter “d” to any page in the application, it would delete the order referenced by that parameter value. The “d” parameter never showed up in any HTML rendered by the (non-administrative) pages in the application, but the functionality had been cut and pasted into every single page regardless. So if a bad guy got lucky and tried to send in a “d” parameter…
Knowing where you are exposed lets you better understand what your application looks like to potential adversaries and is essential if you want to do thorough security testing. The question is – what can you do to enumerate potential attack points?
We are currently finishing up the first phase of some research funded by the US Department of Homeland Security (DHS) under their Small Business Innovation Research (SBIR) program to develop Hybrid Analysis Mapping (HAM) capabilities for software assurance. You can read more about the scope of this research and some of the coverage it has received so far. The object of the research is to map the results of static application scanners (like Fortify SCA) to the results of dynamic application scanners (like IBM Rational AppScan). We’ve been pretty successful at that and we’re including that in future versions of ThreadFix. In addition, an interesting – and unanticipated – result of this work is that we created a utility that can do a lightweight scan of an application’s source code and dump out an enumeration of the application’s attack surface.
The functionality is packaged in the endpoints.jar utility available for download from the ThreadFix Google Code download page. The command-line tool has a simple syntax:
java –jar endpoints.jar <PATH_TO_APP_BASE>
The endpoint enumerator takes a look at the application base and tries to determine the language and framework that is in use. Once the framework has been determined, the tool develops an analysis model with the following information:
- Relative URL in the application that should respond to requests
- HTTP methods for each URL
- Parameters each URL might access during page execution
It then dumps out a listing to STDOUT where you can review it, parse it, or do whatever you like. This can provide a great start for manual penetration testing activities by highlighting potentially interesting information.
So how does this work for Java applications using JSP? Calculating the relative URLs for JSP is pretty simple. Basically we just need to find the common code root and the relative URLs are extrapolated from there. JSP makes it pretty simple. (Spring and other frameworks make it far less simple and we will post more about that later.) To determine the HTTP methods we currently just assume that JSPs will respond to GET and POST methods. (Making this more comprehensive will require a bit more analysis which we currently do for the Spring framework) Finally, determining the parameters that a JSP page will use requires some simple static analysis where we track down calls to request.getParameter(key). If “key” is a String literal, then that is the parameter name. If “key” is a String variable then we do some data flow parsing to see if we can trace the variable back to its value. It isn’t perfect but it works reasonably well.
Let’s take a look at the output of the tool when it is run against the Bodgeit Store. Bodgeit is an intentionally-flawed application written in Java using JSPs that is intended as a training tool for penetration testers. Running the command:
java –jar endpoints.jar ~/git/bodgeit
results in the output:
[POST, GET],/advanced.jsp,[q, debug]
[POST, GET],/basket.jsp,[update, productid, quantity, debug]
[POST, GET],/contact.jsp,[anticsrf, debug, comments]
[POST, GET],/login.jsp,[username, debug, password]
[POST, GET],/password.jsp,[password1, password2]
[POST, GET],/product.jsp,[typeid, prodid, debug]
[POST, GET],/register.jsp,[password1, username, password2, debug]
[POST, GET],/search.jsp,[q, debug]
Most of this is pretty basic and shouldn’t be terribly surprising. However, the “debug” parameter that appears in a number of pages is a cause for some further inspection. Also, that “admin.jsp” page might not be something that everyone should have access to. These are exactly the kinds of thing that get placed into applications, and then find their way into production to cause trouble down the road. Keeping an ongoing eye on your application’s attack surface can help you catch things like this early – before they make their way into production and before they result in problems.
So what’s missing? We’ve hit the major points, but there are some limitations:
- This only deals with web applications right now. We might look at doing things with mobile applications (you can find some rudimentary analysis like this in our Smart Phones Dumb Apps scripts for security testing mobile applications but that has not yet been integrated into the Hybrid Analysis Mapping technology).
- The support is very language and framework dependent. Right now, we have support for Java/JSP and Java/Spring and we’re working on others. Also the code is all open source and we’re structuring it so that it is easy for folks to get involved and add support for their favorite languages and frameworks. If you’re interested in helping, just drop me a line on Twitter or via email.
- The attack surface model is limited. In the future, we’re looking at adding support for cookies and other HTTP headers as well as other input points such as environment variables, command-line arguments, inbound (but non-HTTP) network traffic, and so on. For right now though, URLs and their GET and POST parameters provide a solid starting point.
This is an area where other folks have done work as well. For more information, check out:
- Paolo Perego’s work parsing web.xml to identify servlet URLs for pentests
- Dinis Cruz’s work with the O2 Spring MVC Viewer
So – take some time and think about your application’s attack surface. What might be lurking about that you haven’t thought about in a while? Run the endpoints.jar utility through its paces and feel free to post any bugs or feature requests to our issue tracker. Bad guys are undoubtedly thinking about your application’s attack surface. Shouldn’t you be thinking about it as well?
Contact us to talk about ways you can get the most our of your application testing efforts.
dan _at_ denimgroup.com