John Melton's Weblog
Java, Security and Technology

Year Of Security for Java – Week 8 – HTTP Strict Transport Security

No Gravatar

What is it and why should I care?
HTTP Strict Transport Security (HSTS) is a new(ish) technology that allows an application to force browsers to only use SSL/TLS (HTTPS, not HTTP) when visiting their application. This occurs when the application sets an HSTS specific HTTP response header. Browsers that support HSTS recognize the response header and only communicate with that application over HTTPS for the specified time. Here are the basic steps of the flow:

Step 1: A user visits application, either over HTTP or HTTPS. For most users this will be HTTP as they often forget (or don’t know) to type in https://
Step 2: The application renders the response, including the HSTS response header that specifies the site should be loaded over HTTPS only for the next 90 days.
Step 3: Supporting browser will not issue a non-SSL request to that application for the next 90 days.

What should I do about it?
Set the header! This is another no-brainer. There are no backwards compatibility issues and it only enhances your security posture. By adding the header, you give your users greater security with very little effort on your part. Here’s a quick example of what setting the header might look like if you happen to code in Java.

HttpServletResponse ...;
response.setHeader("Strict-Transport-Security", "max-age=7776000; includeSubdomains");

The snippet above sets the amount of time that the browser should only use HTTPS when accessing the application (or any subdomains) to the next 90 days.

The max-age attribute is required and sets the number of seconds that only HTTPS should be used. This can be set to whatever you want. Setting this to 0 tells the browser to delete the existing policy and not require HTTPS.

The includeSubdomains attribute is optional. It does not take a value; its’ presence signifies that any sub-domains should abide by the same HSTS policy.

Expiration Reset
The time length (90 days in our example above) should be reset (overwritten) by the supporting browser every time the HSTS response header is received. What this means is that if you set the length to 90 days, and a person never goes more than 90 days without visiting your site, they’ll always be visiting over HTTPS since the 90 days starts over every time they visit. Just keep in mind that if you change the setting, all browsers that access your site (post-change) will get the update. If you set it to 90 days today and 10 tomorrow, the browser throws away the 90 days and replaces it with 10.

Click-Through Insecurity
The HSTS spec also recommends (though the current spec doesn’t seem to require) that the browser not send any data to the server if the channel is insecure for any reason (certificate issues, domain issues, etc.). This appears to be the route being taken by current browser implementers, which is the most secure option. This means that those warning pop-ups users often see over HTTPS connections (mixed content, expired cert) don’t appear any more and instead the user is simply shown an error.

Pre-loaded HSTS Lists
If you want to have even more assurance that your site is only ever visited over HTTPS, you can even request that your site be pre-loaded into a list of HSTS sites. This means the browser will require you to got that site over HTTPS on your very first visit! Paypal is one such well-known site that does this.

HSTS is a simple and effective control to let an application further protect its’ users by forcing them over HTTPS. If your site is (or at least should be) HTTPS only, then implementing HSTS can provide you and your users with enhanced assurance.


Technorati Tags: , , , , ,

Year Of Security for Java – Week 7 – Content Security Policy

No Gravatar

What is it and why should I care?
Content Security Policy (CSP) is a new(ish) technology put together by Mozilla that web apps can use as an additional layer of protection against Cross Site Scripting (XSS), which is the primary goal of the technology. A secondary goal is to protect against clickjacking.

XSS is quite a complex issue, as is evidenced by the recommendations in the OWASP prevention cheatsheets for XSS in general and DOM based XSS. CSP does several things to help app developers deal with XSS.

Whitelist Content Locations
One reason XSS is quite harmful is that the browsers implicitly trust the content received from the server, even if that content has been manipulated and is loading from an unintended location. This is where CSP comes in: CSP allows app developers to declare a whitelist of trusted locations for content. Browsers that understand CSP will then respect that list and only load content from there, and will ignore content that references locations outside the list.

No Inline Scripts
Adding scripts inline to content is the way XSS is done, made possible because browsers have no way of telling whether the site actually sent that content, or if the attacker added the script to the site content. CSP prevents this entirely by forcing the separation of content and code (Great design!). This means that you have to move all your scripts to external files, which will require work for most apps, though it can be done (Twitter is one example of a high-profile site using CSP). The upside is in order for an attack to be successful with CSP, an attacker has to be able to:
Step 1) Inject a script tag at the head of your page.
Step 2) Make that script tag load from a trusted site within your whitelist.
Step 3) Control the referenced script at that trusted site.

This makes an XSS attack significantly more difficult.

Note: one common question here is what about event handling. CSP does still allow event handling through the onXXX handlers or the addEventListener mechanism.

No Code From Strings (eval dies)
Another welcome addition is the blacklisting of functions that create code from strings. This means that usage of the evil eval is out (along with a few others). Creating code from strings is a popular attack technique and is rather difficult to trace, so the removal of all these functions is actually quite helpful.

Another common question stemming from this is how to deal with JSON parsing. The right way to do this from a security perspective has always been to actually parse the JSON instead of eval it anyhow, and this functionality is still available, so nothing changes there.

Policy Violation Reporting
A rather cool feature of CSP is that you can configure your site to have a violation reporting handler, and then have that data available whether you run in report-only or in enforcing mode. In report only mode, you can get reports of locations in your site that will be prevented from execution when you enable CSP (a nice way to test). In enforcing mode, you can still get this data, but in production, you can also use this as a simple XSS detection mechanism (bad guy tried XSS and it didn’t run).

What should I do about it?

Well, you should use it! Actually, CSP doesn’t really seem to have a downside. It’s there to make your site safer, and even if a client’s browser doesn’t support it, it’s entirely backwards compatible, so your site won’t break for the client.

In general, I think the basic approach should be:
Step 1) Solve XSS through your standard security development practices (you should already be doing this)
Step 2) Learn about CSP – read the specs thoroughly
Step 3) Make the changes to your site and test and re-test (normal dev process)
Step 4) Run in report-only mode and monitor any violations to find areas you still need to fix. (could be avoided if you have a full functional test suite you can execute against your app in testing – good for you if you do!)
Step 5) After you’re confident your site is working properly, turn it on in enforcing mode.

As for how you actually implement it, you have 2 basic options: an HTTP header and a META tag. The header option is preferred, and an example is listed below.

Content-Security-Policy: default-src 'self'; 
    img-src *;
    object-src *;

The example above says the following:
Line 1: By default, only allow content from ‘self’ or the site represented by the current url.
Line 2: Allow images from anywhere.
Line 3: Allow objects from only the listed urls.
Line 4: Allow scripts from only the listed url.
Line 5: Use the listed url to report any violations of the specified policy.

CSP is a very interesting and useful new technology to help battle XSS. It’s definitely a useful tool to add to your arsenal.

Update (2/15/2012) Here’s an interesting post on using ModSecurity to add CSP to your site – a nice look for the administrators. (h/t @ryancbarnett)


Technorati Tags: , , , , , ,

Year Of Security for Java – Week 6 – CSRF Prevention in Java

No Gravatar

What is it and why should I care?
Cross Site Request Forgery (CSRF) is an attack wherein a victim is forced to execute unknown and/or undesired requests to a website at which he/she is currently authenticated. It exploits the fact that the “credentials” needed to perform a function on a website are generally loaded into a client-side cookie, which is transmitted automatically with every request. By exploiting this fact, an attacker can cause a victim to execute almost any request that isn’t protected against CSRF.

Here is a simple image that shows a basic CSRF attack. The steps are:
Step 1. The victim is lured to visit an evil site (
Step 2. The victim’s browser loads the evil site, which contains a hidden image whose src points at an important transaction on
Step 3. The victim’s browser executes the transaction at, passing along the session cookie (general authn/z mechanism).
Step 4. The transaction occurs, and the victim is not aware until later, if at all.

What should I do about it?
Now that we know what CSRF is and why it is dangerous, let’s consider some possible solutions.

The classic solution to CSRF has been a per-session token (known as the synchronizer token design pattern). The basic flow is:
Step 1. User logs in and a randomized string (token) is placed in the user session
Step 2. On every form for a non-idempotent request (meaning essentially any request that changes server-side state – should be your HTTP POSTs), place the token in the form when it’s submitted.
Step 3. On the request handler for the non-idempotent request, validate that the submitted token matches the token stored in the session. If either is missing or they don’t match, do not process the transaction.

This solution has served pretty well for most situations over the years, but can be time-consuming to implement and often creates opportunities for forgetting validation on some requests.

The ESAPI project does have built in CSRF protection, but it is tied to the authentication scheme. Here is a writeup I previously did for ESAPI’s CSRF protection.

A very good option with solid protection is the OWASP CSRFGuard project. This library makes it relatively simple to include CSRF protection into your application by simply mapping a filter and updating a configuration file. This is certainly a resource worth checking out.

Stateless CSRF Protection
One more thing I’d like to point out is some interesting work John Wilander (@johnwilander) is doing in the area of stateless CSRF protection. In the case where you can’t or don’t want to maintain the user token in server-side session state, John proposes a seemingly novel solution. The proposal is to allow the client side to create a cookie with the CSRF token (which gets submitted on every request) and to include the token as a request parameter. Since an attacker can’t read both the cookie and request parameter, all the server side should have to do is validate that the token in the cookie and the request parameter match. This solution, to my knowledge, has not been widely reviewed or tested, but it is a great example of an elegant solution to a difficult problem. Only time will tell if this is the go-forward solution for stateless CSRF protection.

CSRF is a popular and dangerous attack, but with the protections described above, it is certainly manageable.

One last note here is that the token approach (classic or stateless) does break down when the site it is deployed on contains XSS (Cross Site Scripting) vulnerabilities. If an attacker can XSS your site, they can read the content and extract out the token you’re using, effectively nullifying the protection. The lesson is simple: fix those XSS bugs too!


Technorati Tags: , , , , ,

Year Of Security for Java – Week 5 – Clickjacking Prevention

No Gravatar

What is it and why do I care?
Clickjacking is a type of “web framing” or “UI redressing” attack. What that simply means in practice is that:

1. A user (victim) is shown an innocuous, but enticing web page (think watch online video)
2. Another web page (that generally does something important – think add friends on social network) is layered on top of the first page and set to be transparent
3. When the user thinks they are clicking on the web page they see (video), they are actually clicking on the higher layered (framed) page that is transparent

This attack is clever, and there are some interesting specifics in the actual execution of an attack (For more info, see the references), but here, I’m concerned with preventing the attack.

What should I do about it?

There is still no perfect answer on clickjacking, but things are getting better, especially as users upgrade to more modern browsers. The recommendation is two-fold:

1. Use the X-Frame-Options HTTP header
2. Include framebusting code

There is a future article in the series coming, I promise, on the X-Frame-Options HTTP header. All I’ll say for now is that this header is the more robust solution, but that it requires a relatively modern browser. Fortunately, folks are slowly moving towards more modern browsers, so the situation is improving.

As for the framebusting recommendation, it is breakable, but should still be done. It certainly raises the bar. There are many options for framebusting code, but the folks at Stanford put together a paper on framebusting where they evaluated the current code in the wild and showed ways to break it. They came up with their own proposed solution in the paper. I’ll omit the code here, but it’s at the top of page 11 of the pdf. The basic idea is to both:
a) use the stylesheet to disable display for the entire body of the page, and
b) use Javascript to either enable the display if not framed, or to bust out of the frame if framed.

This solution will probably (if it’s not already) be broken, but it appears to be the best we have today.

Clickjacking is unfortunately a less-than-clearcut issue to solve, but by combining a couple different approaches, you can resolve the issue with a fair amount of robustness.

Update 2/3/2012: The Stanford approach does not adequately support IE in all instances – here’s a post from August Detlefsen explaining the solution. (h/t Chris Schmidt)


Technorati Tags: , ,

Year Of Security for Java – Week 4 – Session Cookie HttpOnly Flag

No Gravatar

What is it and why do I care?
Session cookies (or the cookie containing the JSESSIONID to Java folks) are the cookies used to perform session management for web applications. These cookies hold the reference to the session identifier for a given user, and the same identifier is maintained server-side along with any session scoped data related to that session id. Since cookies are transmitted on every request, this is the most common mechanism used for session management in web applications.

The HttpOnly flag is an additional flag that is used to prevent an XSS (Cross-Site Scripting) exploit from gaining access to the session cookie. Since gaining access to the session cookie, and subsequently hijacking the victim’s session, is one of the most common results of an XSS attack, the HttpOnly flag is a useful prevention mechanism.

HttpOnly Flag

What should I do about it?
The resolution here is quite simple. You must add the HttpOnly flag to your session cookie (and preferably all cookies).

Here’s an example of how a session cookie might look without the HttpOnly flag:

Cookie: jsessionid=AS348AF929FK219CKA9FK3B79870H;

And now, with the HttpOnly flag:

Cookie: jsessionid=AS348AF929FK219CKA9FK3B79870H; HttpOnly;

And, if you were following along from last week, with both the secure and HttpOnly flags:

Cookie: jsessionid=AS348AF929FK219CKA9FK3B79870H; HttpOnly; secure;

Not much to it. You can obviously manually do this, but if you’re working in a Servlet 3.0 or newer environment, there’s a simple configuration setting in the web.xml that takes care of this for you. You should add this snippet to your web.xml.


And, if you also use the secure flag, it looks like this:


As you can see, resolving this issue is quite simple. It should be on everyone’s TODO list.


Technorati Tags: , , ,

Year Of Security for Java – Introduction

No Gravatar

Year Of Security for Java

This will serve as the introduction for a new series that will have roughly 1 article per week for a year. This series will be different from my last series (OWASP Top Ten – Java) in that each article will be pretty short and focused. There are several motivations for this series:

1. Get some old topics written down
2. Research some new technologies
3. Write
4. Learn
5. Answer questions from Java friends

It’s the last one that serves as the primary motivation. In my work with Java developers, I understandably get asked a lot of questions about security. These are pretty far-ranging from the “what is this thing I heard about” to “how do I do this very specific thing correctly”. Developers are sharp, but have a lot they are held accountable for, of which security is only one. In this series, I hope to highlight some of the common issues the developers I work with ask me about frequently, as well as point out a few things they probably should be asking about, but don’t know to just yet.

If you have specific suggestions for articles you’d like to see, feel free to email me at domain_name at gmail dot com or on twitter (_jtmelton).

Hope you enjoy.

Technorati Tags: ,

Beware the HTTP path parameter

No Gravatar

Please forgive the title, but today’s topic is something to be wary of if you write (or use) any access control / authorization type code in web-based j2ee apps: HTTP URL path parameters. Many people are unfamiliar with them (as they are uncommon), but they are something you should be aware of. A nice simple description of url path parameters can be found here. Essentially path parameters are the bit of a url path that comes after a semi-colon (semi-colon is the most popular path parameter delimeter). So, here’s an example of 2 urls, each with an http path parameter:;jsessionid=OI24B9ASD7BSSD;/user/HomeServlet

We’ve all seen the first example probably many times where a jsessionid gets attached to our url. However, take a look at the second example. Pay very close attention to what is being presented here. This represents a request that is going to go to the administrative UpdateUserServlet, but with a path parameter of /user/HomeServlet. Now, what could be the problem here? Well, there actually turns out to be 2 different issues to deal with in most cases.

Issue 1 – The server product and version

The first issue to contend with is how your servlet container/app server product and version handles certain request APIs, as apparently different products and even versions deal with http path parameters in different ways. (I have not done the work to determine which servers and versions are affected, but you should do that in your own environment, as apparently even configuration changes can cause slightly differing behavior. These variations are caused by – read blamed on – a lack of clarity in the servlet spec regarding path parameters.)

This problem can be seen when using certain API calls from the HttpServletRequest object and seeing how those APIs handle path parameters. Two of the affected methods are getContextPath() and getServletPath(), where there are variations between whether or not these calls actually strip out any path parameters depending on server and version. Again, this testing is left as an exercise to the reader. We’ll see below what can happen when we make poor assumptions here.

Issue 2 – Your code

Here is where the actual problem really shows up … when we actually use these APIs. One of the most common uses is for writing access control / authorization code. Many access control frameworks or internal codebases use a url mapping concept of some kind. They vary widely in how they are implemented, but a simple example might be: anything with “/admin/” in the path requires the admin role, or anything that ends in “UpdateServlet” requires the manager role. Let’s use the “ends with” example and walk through some code.

String uri = request.getRequestURI();	//note getRequestURI will always return the full path with path parameters but not request parameters
if (uri.endsWith("UpdateServlet")) {
    //require the manager role here
} else {
    //just require standard user role

This is a very trivial piece of code, but will be similar in spirit to what is in lots of access control code in j2ee apps. Here the developer was expecting the user to send a request that looked like

when they were trying to get to the update servlet. But what happens if the user sends a request like;/app/UserReadServlet

HERE’S THE PROBLEM! Now the app code has checked the URI, and sees that it ends with ReadServlet and not UpdateServlet, so it only requires the standard user role, and the access control check passes. But the app server/container sees that the ACTUAL request is going to UserUpdateServlet, and allows the user to go there. Now we have a access control bypass issue! The user has been able to circumvent your “protection”.

DOH! Ok, now what …?

Fixing the problem

There are several ways you could address this issue, and each option varies in difficulty and correctness.
1. You could whitelist all of your allowed requests and compare them to pre-determined acceptable urls, but that might get cumbersome with a very large app.
2. You can perform some cleansing (stripping) of the url path parameters, but that can be an issue if your app server allows various path parameter delimeters.
3. You can also compare from the start of the URI or path instead of checking the end. This might be similar to the whitelist option
4. Another option that should definitely be used is to check your app server/container (on every upgrade as well) to see what it’s actual behavior is regarding path parameters).
5. Another option might be to perform your access control check at the beginning of a request handling piece of code, like a servlet, or action. That way, you know that’s the code actually being executed, so it’s the url you should be verifying. This has the problem of a lack of centralized control however.

There are certainly more options here, and you know what will work in your code, but hopefully the options above help as a starting point. Hopefully you found this information helpful and are able to update your projects to fix the issue if it exists.


Much of my research for this article came from an important bug in the Spring Security (formerly Acegi) project that was caused by this path parameter issue (bug found by Ed Schaller). More information can be found at the following 2 urls.

Special Author Note

This topic was first shared with me by Abraham Kang. He both introduced me to this issue and reviewed this article for me. Thanks Abraham!

Technorati Tags: , , ,

Application Intrusion Detection with OWASP AppSensor

No Gravatar


This article is a basic introduction to AppSensor, an OWASP project that’s been gaining a lot of traction recently. It’s a fairly simple concept, and one that I think (and hope) will be implemented in lots of applications in the near future. If you’d rather watch a video about AppSensor, here is a good one from Michael Coates, the project lead. Alternatively, here is a very quick video of a demo of AppSensor. So, let’s get started …

What is AppSensor and why should I care?

AppSensor is an implementation of an idea called application layer intrusion detection. The concept is very simple. While we have controls like intrusion detection at the network layer and web application firewalls at the web layer to detect attacks, these tools work outside the application where they are missing some context. We don’t currently have a good paradigm to represent attack detection and possible response inside an application, unless you completely roll your own. There is actually an implementation of this concept in ESAPI, (see the IntrusionDetector interface) and AppSensor’s implementation can be used as a drop-in replacement for the default handler provided by ESAPI, but more on that later. For now, let’s talk about why you need AppSensor.

So, you do good threat modeling, good security architecture, design, coding, code reviews, white/black box security scans, etc. … great, but you still have security holes. It’s a fact of life that today’s complex applications, and the heavily constrained timelines under which they are built, lead to security holes. If you have an application of any decent size, you are almost assuredly vulnerable to something. You should absolutely continue good secure development practices – these are crucial – but we need more.

Let’s consider those folks that actually end up breaking into our apps. It turns out that attackers vary in how good they are. Some are better than others; some are phenomenal, though the bar has continually been lowered due to automated tools. However, any attacker, bad, good or great, almost always has to try several things in order to successfully break into your app (for many classes of vulnerabilities). If they get in on the first try, they’re either lucky, or your app is so insecure, there’s not much that can help it. So, what if we could differentiate the bad guys before they actually get in? That’s the idea of AppSensor. Let’s assume that it takes an attacker 20 tries to find a field he can manipulate to get an XSS bug, but you can detect that he’s trying to find an XSS bug in 5 tries. Now, we have the advantage – we’ve determined he’s a bad guy, and can respond before a successful attack occurs.

The AppSensor project represents both the concept and implementation of an application layer intrusion detection system. First, a little info (and a few references) about the conceptual pieces. There are 3 basic concepts in AppSensor:
1. Detection
2. Evaluation
3. Response

Detection is the process of actually recognizing that an attacker is performing an attack. This involves adding code (which we’ll show a sample of below) to points that are deemed valid “detection points”. These are points in the code where we know the expected reasonable path(s) a user should be performing, and have a way to detect the user has varied from the path. Consider the case where a user submits a GET request when the form is setup for a POST. That should NEVER happen in a normal circumstance unless the user is doing some modification. A collection of these detection points has been created by the team in order to help you get started in determining reasonable locations to check for attacks.

Evaluation is the process of evaluating all the actual attack detections across the system for all users and determining when it is appropriate to trigger certain response actions. This is, for lack of a better term, the “engine” of the system, and is really behind-the-scenes code for anyone who wants to implement AppSensor. The interface to this would be the threshold setup (shown below)

Response is the activity of actually responding when it is determined an attack has actually occurred. A collection of these response actions has been created by the team in order to help you get started in determining reasonable responses for attacks.

These are the basic components of the system, but in order to really understand the system, feel free to read the book. This was a mammoth effort to document this concept, and as open source projects go, is some of the best documentation available.

How do I use it?

My key part in the project has been from the development side. For a quick “getting started” version of using AppSensor that has some good information (I wrote it :)), see the developer guide. Here I’ll show the few basic steps to getting going. I’m going to show the setup here as if you’re using OWASP ESAPI in your project. This is by no means required, but since there is already the concept of intrusion detection, it makes life a bit simpler. Also, since ESAPI is a set of distinct controls, you can use some and not others. So, here are the steps:

1. Replace default ESAPI intrusion detector with AppSensor intrusion detector.


2. Add threshold configuration. There is an file (see dev guide for details) that you can use to configure thresholds for when an attack is considered to “trigger” a response. Here’s an example configuration for a threshold.

# number of intrusions in a specified segment of time that constitutes the upper threshold - once crossed, it's considered an "attack"
# segment of time (in seconds)
# list of actions you want executed in the specified order as the threshold for this intrusion is met - ie. log the first time, logout the user the second time, etc.
# some integer - duration of time to disable
# some measure of time, currently supported are s,m,h,d (second, minute, hour, day)
# some integer - duration of time to disable
# some measure of time, currently supported are s,m,h,d (second, minute, hour, day)

3. Add detection points into your code. This is the hardest actual work – it requires finding those places in your codebase where you can check for an attack. This example shows an instance where we’ve decided that 404 requests could be considered an attack. In this case, a single request or even a handful might be legitimate, but dozens or more probably point to a scanner of some type looking for vulnerable code.

//This example snippet might be placed on a jsp that handles HTTP 404 errors.  
//When the page is accessed, this code notifies AppSensor that an invalid page request was made.
//Notice that the exception is created, not thrown

new AppSensorException("ACE3", "Invalid request", "Attacker is requesting a non-existent (404) page (" + requestedURI + ")");


So, that’s it – pretty simple. AppSensor is another tool in the toolbelt for the security developer/practitioner. It is an idea that can be implemented in an application fairly easily and with great effect. It has the power to detect and prevent an attack before it is successful, and has the key advantage of context within an application, allowing us to respond to the user that performed the attack.

That’s it for now. I may post more detailed information about AppSensor as the project progresses. For now, feel free to comment here and let me know what you think.


I should briefly mention the other members of the core team: Michael Coates is the project lead, and Colin Watson is another key member of the team.


AppSensor Project Page
AppSensor Book
AppSensor Developer Guide

Technorati Tags: , , , , , , ,

Preventing Log Forging in Java

No Gravatar

This article will provide a quick overview of log forging and discuss a couple simple solutions to prevent it.

First, what is log forging?

Logging is one of the most common things that an application does. Logging is a very generic term that can mean lots of different things, from debug style logging for the developer, up to and including functioning as the system audit log. The 3 most common logging mechanisms I see in real world use are:
1. System output (System.out.println)
2. 3rd party logging library (log4j, commons logging, slf4j, etc.)
3. DB Logging

System output
System output is a functional mechanism, but tends to provide spotty information at times, since developers often don’t log everything they should in order for the log to be functional. A simple example of this is that essentially all logging should include a timestamp and at least the logged in user if applicable, but System.out logging often doesn’t include these 2 basic pieces of information.

3rd party logging library
The 3rd party logging libraries are the workhorses of the java logging world. They are probably the most used option and for good reason. The popular frameworks provide very simple configuration, offer all the basic features (and even some advanced features), and can be setup to log the same “meta-information” for each log entry (such as timestamp, username, etc.).

DB Logging
Most often DB logging is used for log/audit data that needs to be maintained for a reasonable amount of time. If there is auditing going on for the application, a DB is a popular choice since the audit records can actually reference the data it is about using the relational DB mechanisms already built into the DB product. Also when logging to a DB, there is usually a reasonable amount of data that is stored. This is likely due to the fact that someone sat down and thought out what data should be stored, and created the DB schema to store that info – that way the standard for what data needs to be logged is perfectly clear to the developer.

Now that we’ve talked about a few basic types of logging, let’s see what log forging is. Let’s consider this bit of code.

String previousPage = request.getParameter("prev");"Previous page from request was: " + previousPage);

This simple bit of code just writes a request parameter to the log. Pretty simple. Let’s consider two scenarios here. If the user is using the application as intended, something like the following might be sent in – “prev=viewCart”, telling the app the page the user was coming from was a view shopping cart page. This would result in the following being written in the log.

[2010-10-21 18:45:15] [bill] Previous page from request was: viewCart

Now what would happen if an attacker instead decided to modify the request parameter and instead entered “prev=viewCart\r\n[2010-10-21 18:45:15] [steve] Account successfully created” as the request parameter? (Note the data I entered above is not actually URL encoded for clarity, but would be in a real example) Now the log will look like the following:

[2010-10-21 18:45:15] [bill] Previous page from request was: viewCart
[2010-10-21 18:45:15] [steve] Account successfully created

Now the attacker has been able to create a forged entry in the application log which reduces the value of the logs, and frustrates any forensic type activities. This is the essence of log forging.

So how do I prevent it?

There are various options to prevent log forging. I’ll discuss just a few and my opinions of them.

1. Validate all input that could be put in the log file. This would involve doing strict whitelist validation to make sure that characters that pose issues in logs are not available to the attacker. This option, in my opinion, would be the least likely to work. The truth is that you’d have to validate lots of data, and if it failed validation, it wouldn’t get logged. That data could be valuable debugging information or even audit data. This is my least favorite option, and I’ve only actually seen it once in practice.

2. Log to a database. Essentially logging to a database does prevent log forging since carriage return / newline mean nothing in that context, but it introduces another possible exploit: SQL Injection. For information about how to prevent SQL Injection properly, please see: The OWASP Top Ten and ESAPI – Part 2 – Injection Flaws. This is an ok option if you need to use a database for auditing, but I wouldn’t use it for standard logging. If you do use it, be sure to use a proper SQL Injection prevention mechanism.

3. Encode all output. This is a simple and elegant solution, and my personal favorite. There’s not that much to it – just encode those characters you need to in order to prevent log forging, and everything else get’s logged the same. You can develop a simple wrapper around your favorite logging utility in order to do the log forging prevention work, and use the logging utility for all it’s other features. Luckily the good people who built ESAPI already did this for you. They have a logging component built into ESAPI that contains this log forging protection. An example for wrapping the popular Log4j library is here. Here is a snippet of code that shows their encoding in action.

// ensure no CRLF injection into logs for forging records
String clean = message.replace( '\n', '_' ).replace( '\r', '_' );
if ( ESAPI.securityConfiguration().getLogEncodingRequired() ) {
    clean = ESAPI.encoder().encodeForHTML(message);
    if (!message.equals(clean)) {
        clean += " (Encoded)";

As you can see, the class simply replaces all carriage returns and line feeds with underscores, then, if configuration dictates, HTML encodes the message. If the original message to be logged is different from the encoded version, a simple ” (Encoded)” string is tacked onto the end of the log entry to denote that it required encoding of some type.

Other notes

Another possibility when writing data to a log that may or may not be true in your environment is XSS. Though it doesn’t sound clear at first, consider this possibility. You log all of your data to a flat file, then your team, an auditor, system admin, or anyone comes along and opens your log file in a fancy web based log viewer. If XSS attacks are stored in the log, then the log viewer would then be susceptible to XSS. The best solution, in my opinion, would be to ensure your log viewer is protected from XSS. I feel that when you output data to a particular location, you should protect against the attacks specific to that location, ie log output should protect against log forging. However, it is helpful to be aware of issues like this to understand the full situation. Also note in the ESAPI code above, HTML output encoding is performed, and could help prevent this situation as well.


So, as you can see, log forging is an issue that affects pretty much every J2EE application out there. It’s fairly simple to understand and fairly simple to solve. Hope this helps. Let me know if you found it useful, or if you have dealt with log forging differently.

Technorati Tags: , , , , , ,

The OWASP Top Ten and ESAPI – Final Summary

No Gravatar

Ok, well now we’ve been through all the issues listed in the 2007 version of the Top Ten. The new 2010 version is very similar with a couple discrepancies. I may follow up on those couple of issues at a later time. Hopefully you’ve seen through all the articles in this series that ESAPI (specifically the Java version was used) was built to deal with quite a few real security issues that developers face today. This series has shown that ESAPI can be used in almost every instance to either partially or completely remediate a specific issue, and to do it properly. The ESAPI community is thriving, and good things are coming out frequently. New implementations of some controls are showing up. New people are joining. New issues are being tackled. Get involved with this community and make it better. Use the outstanding controls this group has kindly given away, and offer some of your own.

Hopefully this series has been helpful to you in moving closer to secure J2EE development by exposing you to ESAPI and all it has to offer. I’ll be moving on to different topics in the future. Hope you enjoyed this one!

As a reference, all the articles from the series are listed below for easy access.
Part 0: The OWASP Top Ten and ESAPI
Part 1: The OWASP Top Ten and ESAPI – Part 1 – Cross Site Scripting (XSS)
Part 2: The OWASP Top Ten and ESAPI – Part 2 – Injection Flaws
Part 3: The OWASP Top Ten and ESAPI – Part 3 – Malicious File Execution
Part 4: The OWASP Top Ten and ESAPI – Part 4 – Insecure Direct Object Reference
Part 5: The OWASP Top Ten and ESAPI – Part 5 – Cross Site Request Forgery (CSRF)
Part 6: The OWASP Top Ten and ESAPI – Part 6 – Information Leakage and Improper Error Handling
Part 7: The OWASP Top Ten and ESAPI – Part 7 – Broken Authentication and Session Management
Part 8: The OWASP Top Ten and ESAPI – Part 8 – Insecure Cryptographic Storage
Part 9: The OWASP Top Ten and ESAPI – Part 9 – Insecure Communications
Part 10: The OWASP Top Ten and ESAPI – Part 10 – Failure to Restrict URL Access

As a final note, I’d like to make a special request. If you have any requests for something you’d like to see here, an article on a specific topic involving J2EE web security, feel free to comment here or send me an email. My direct contact info is listed on the About page.

Technorati Tags: , , , ,

← Previous PageNext Page →