Thursday, September 16, 2010

Fun with firewalls

One of the applications I've been working on uses Spring Webflow and, at a few crucial points in the application, renders data into a JavaScript dialog. Spring offers a JavaScript library to help with handling AJAX requests, including support for handling redirect-on-POST inside aforementioned JavaScript dialogs.

So, in one particular case, you would click on a button, an asynchronous request would be made to enter a new view-state in Webflow and, after redirecting, the content of the response would get rendered in a JavaScript pop-up.

Eventually, one or two of our customers complained about this button not working. This was puzzling since it didn't affect the vast majority of our customers. Screenshots from the customers' machines showed no errors or gave any clue as to what was broken. We had a hunch it might have something to do with security settings but had no way to verify that or reproduce the behaviour on our end. For the time being we just gave up, as we were already considering doing away with the pop-up anyway.

A few weeks later I was digging through Spring's JavaScript code for some other reason and noticed how the asynchronous redirecting is handled. Since sending a HTTP redirect status would mean that the browser would redirect the complete window, Spring checks for Ajax requests and in case it finds one, puts a special header into the response and answers with a normal 200 status. Spring's JavaScript then checks for that special header and, if it thinks the response should be rendered in a pop-up, follows the redirect by making another Ajax request and displays the response in the pop-up. It's pretty clever and gives a lot of flexibility.

Out of curiosity I wanted to know what would happen if that special header didn't make it to the browser. I fired up Fiddler and replaced our server's response with a version with Spring's headers removed. I clicked on the button and - nothing happened! I was pretty happy that I figured out a way to reproduce the problem but I still wasn't sure this was actually the cause. Because why would anyone want to filter HTTP headers?

To be certain, I changed the JavaScript to show a descriptive error message to the user in case the headers went missing. This wouldn't actually fix the functionality but at least the user would get some feedback on clicking the button. The code eventually found its way onto our servers and a few months later we had a customer mail in a screenshot of the new error message. And with a little back and forth with their IT person we found out that it was indeed the firewall of the customer filtering out headers. Eventually they changed their settings so that they could use our application without problems.

Which really only leaves the question of 'Why?' It's understandable that non-IT companies with a small IT staff just rely on the default settings of whatever firewall package they bought. But as a developer of said firewall, what security do I gain by filtering response headers? I can see how filtering specific request headers makes sense at least in obscuring the internal network to the outside. But what harm could possibly come in a response header that couldn't otherwise also come via one of the white-listed headers or just plain via the response body?

Oh, well. There's a ticket in the SWF JIRA and it might be worth a look if you're using Webflow.