Archief ‘Web’ categorie
Door: Jan-Kees van Andel, 27 February 2010
I like the maven-jetty-plugin. If I download an Open Source project, I usually first look for this baby, because it allows me to quickly run the code in a tested environment. This saves me from a lot of configuration, which would otherwise cause me to lose interest. This often doesn’t take long…
Also, you can completely configure the server in your POM, centralizing configuration and making it thus easy to store server settings in version control. Also, the mvn-jetty-plugin benefits from your existing Maven project configuration, like dependencyManagement.
Some of my buddies at Apache even use the maven-jetty-plugin on a daily basis for their real work. I never got this far, mostly because I’m more familiar with Tomcat, but also because I didn’t really see it as a mature development tool. However, today I decided to give it a chance.
The first attempt
So, I created a simple webapp in my favorite IDE: IntelliJ IDEA and added a Maven2 POM to enable Maven2 support. All well so far.
This was the initial version of my POM:
All was fine, my test app was running, but I needed to enable Unified EL to test MyFaces BeanValidator.
Adding UEL libraries
So, I added a dependency to the UEL API and Impl in my POM, but there was an issue. Every web container already provides the old Expression Language in the jsp-api.jar. So I’m not allowed to package my own EL libraries.
However, I’m quite stubborn, so I tried anyway:
So, let’s give it a try:
mvn jetty:run-exploded
(MyFaces 2.0 requires exploded deployment in Jetty).
Result? BOOOM!
The fix, replacing libraries
The error is completely appropriate. You’re just not allowed to package your own version of the servlet libraries. That’s the job of the servlet container. Failing to do so will result in the error shown above.
So we need to fix this issue by somehow replacing the Jetty libraries or at least changing the way Jetty loads its jsp-api.jar. This is no trivial task however, since jetty is initialized by Maven and doesn’t have a fixed directory structure on disk.
So we need to have some way in Maven to configure the Jetty libraries.
First, Jetty doesn’t have an endorsed mechanism, so that’s a no-go.
But the fix is actually quite easy, just pass some dependencies into the jetty plugin in the POM.
The final POM looks like this:
As you can see, Maven takes care of the heavy lifting. You only need to specify your dependencies and they will override any dependencies with the same groupId, artifactId and type.
So, now I don’t have any reason not to use mvn-jetty-run to test my code!
Happy coding!
Gepost in Algemeen, JavaServer Faces, Maven | Geen reacties »
Door: Jan-Kees van Andel, 31 January 2010
If you have (just like me) been following the Web Beans and Contexts and Dependency Injection (CDI) work, you might be thinking (also just like I did): “That CDI is heavily over-engineered”. My “moment of clarity” was a year ago, at DeVoxx 2008.
It was a talk by Pete Muir of JBoss. He was showing a really simple use case and tried to implement it using CDI. The talk was really technology driven and I hated it. Why? Because it wasn’t an improvement compared with the existing technologies. He wrote an application, containing several interfaces, classes (this is not bad) and custom annotations. If the goal was to show some kind of geniosity, it was a good talk. But if the goal was to show how this new technology would make our lives better… then sorry, he failed miserably.
More than a year further, there have been a lot of movements on the CDI front. And, as an Apache MyFaces developer, I’m of course very interested how to use CDI in a JSF 2.0 application. And as an Apache fanboy, I of course prefer Apache software, in this case MyFaces with OpenWebBeans and OpenJPA.
Configuration
Since OpenWebBeans is still under development, you need to do some additional steps to get it to work.
The following POM should get you up and running quickly in Tomcat:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.apache.myfaces</groupId>
<artifactId>myfaces-example-ebanking</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<dependencies>
<!-- Compile dependencies -->
<dependency>
<groupId>org.apache.myfaces.core</groupId>
<artifactId>myfaces-api</artifactId>
<version>${myfaces-version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.apache.myfaces.core</groupId>
<artifactId>myfaces-impl</artifactId>
<version>${myfaces-version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.apache.openjpa</groupId>
<artifactId>openjpa-all</artifactId>
<version>${openjpa-version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>commons-digester</groupId>
<artifactId>commons-digester</artifactId>
<version>2.0</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.apache.openwebbeans</groupId>
<artifactId>openwebbeans-impl</artifactId>
<version>${openwebbeans.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.apache.openwebbeans</groupId>
<artifactId>openwebbeans-jsf</artifactId>
<version>${openwebbeans.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.apache.geronimo.specs</groupId>
<artifactId>geronimo-interceptor_1.1_spec</artifactId>
<version>1.0.0-EA1-SNAPSHOT</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>jsr250-api</artifactId>
<version>1.0</version>
<scope>compile</scope>
</dependency>
<!-- Test dependencies -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
<version>${junit-version}</version>
</dependency>
</dependencies>
<repositories>
<repository>
<id>Apache MyFaces beta</id>
<name>Apache MyFaces beta</name>
<url>http://people.apache.org/~lu4242/myfaces200beta</url>
</repository>
</repositories>
<properties>
<myfaces-version>2.0.0-beta</myfaces-version>
<openwebbeans.version>1.0.0-SNAPSHOT</openwebbeans.version>
<openjpa-version>2.0.0-M3</openjpa-version>
<junit-version>4.7</junit-version>
</properties>
</project>
Note some of the additional dependencies required to run in Tomcat, as opposed to a full blown appserver.
Also, at the moment you need to build OpenWebBeans from source manually. The geronimo-interceptor_1.1_spec dependency will be downloaded to your local Maven repository on a “mvn install”. OpenJPA is not needed for this simple use case, but I use it in my project.
Code
And then, the real code:
public class WebUtils {
private static volatile String basePath;
@Produces @Named public String getBasePath() {
if (basePath == null) {
basePath = FacesContext.getCurrentInstance().getExternalContext().getRequestContextPath();
}
return basePath;
}
}
This class contains a so-called Producer Method. As the name suggests, it produces stuff. In this case, it produces a String with Dependent scope. This means the method will be invoked every time the variable is needed. EL expressions or injection are the most common cases for this.
I’m caching the return value, though it’s not necessary, since getting the context path is pretty cheap.
The view could look like this (snippet):
...
<link href="#{basePath}/style/default.css" rel="stylesheet" type="text/css" />
...
Another implementation could put the variable into the Application scope, like this:
public class WebUtils {
@Produces @Named @ApplicationScoped public String getBasePath() {
return FacesContext.getCurrentInstance().getExternalContext().getRequestContextPath();
}
}
As easy it might seem, the approaches shown above require some responsibility from the programmer though. With producer methods, it becomes really easy to mess things up. After all, you’re effectively creating globals. Tool support may help you here though. For example, the Dependency Analyzer in IntelliJ IDEA 9.0.1 already contains pretty decent support for JSF 2.0 and CDI. And, knowing the reputation of the JetBrains folks, I’m sure they come up with even more fancy stuff.
A more classic implementation
A more classic implementation could look like the following:
@Named
@ApplicationScoped
public class WebBean {
private static volatile String basePath;
public String getBasePath() {
if (basePath == null) {
basePath = FacesContext.getCurrentInstance().getExternalContext().getRequestContextPath();
}
return basePath;
}
}
I’m not using producer methods anymore. The WebBean is now a CDI-managed bean.
The client code becomes slightly more verbose, but who cares? I’ll put the client code in a generic template anyway!:
...
<link href="#{webBean.basePath}/style/default.css" rel="stylesheet" type="text/css" />
...
Wrapping up
I haven’t even showed the complete tip of the iceberg. CDI offers several ways to write code and we’ve yet to find out the (anti) patterns.
I would like to point you to the OpenWebBeans documentation for more info, but unfortunately this is still under development. The good news is that JBoss Weld already has extensive documentation.
Gepost in Java EE, JavaServer Faces | Geen reacties »
Door: Jan-Kees van Andel, 24 January 2010
JSF 2.0 adds a lot of interesting features. Andy Schwartz provides an extensive overview on his blog.
On this blog, I’d like to elaborate a bit further on the interesting features JSF 2.0 has to offer.
JSF 2.0: System Events
JSF 2.0 comes with a useful feature, called System events. System events are predefined events that are published at predefined points in the lifecycle.
System events are either global or component system events.
Global system events
An example of a global system event is PostConstructApplicationEvent, which is published when all configuration is done. It can be seen as a JSF replacement for ServletContextListener.
Listener registration is done by invoking Application.subscribeToEvent(Class<? extends SystemEvent> type, SystemEventListener listener).
Component system events
Component system events only apply to the component to which the listener is attached.
An example of a component system event is PreRenderComponentEvent. This event is published to the appropriate component when it’s about to be rendered.
Listener registration is done by invoking UIComponent.subscribeToEvent(Class<? extends SystemEvent> type, ComponentSystemEventListener listener).
<f:event /> tag
The JSF 2.0 spec also defines the <f:event /> tag, which needs to be nested inside a component tag in the web page. This tag is used to make listener registration easier. Just nest the tag inside a component tag in your Facelet, specify the event to listen to and specify a MethodExpression to your listener method and everything works.
An example
Below is an example of an e-banking login page. It uses a challenge-response authentication mechanism, so it generates a “random” challenge when the page is loaded. Because users can navigate to the login page directly (GET-request), we can’t rely on an action method to be invoked first, so let’s fix this using system events.
First, a bit of history
I’ve always hated to write “the first” page in JSF. Since JSF short circuits the lifecycle in the case of a GET request, you don’t really have an appropriate hook for page initialization, making it difficult to create a dynamic landing page.
One could write “lazy getters”:
public class MyBackingBean {
private List accounts;
public List getAccounts() { // Yuck
if (accounts == null) {
// Do some expensive database query
accounts = doSomeWork();
}
return accounts;
}
}
It’s quite obvious this is extremely nasty. You don’t know when the getter is invoked (EL triggers the invocation), and that if-null check is also ugly. Btw. getters with logic are ugly anyway…
JSF 1.2 offered a slightly more elegant option with @PostConstruct:
public class MyBackingBean {
private List accounts;
@PostConstruct
public void init() {
accounts = doSomeWork();
}
public List getAccounts() { // Still not good
return accounts;
}
}
This is a bit better, but still not very good. The exact point of invocation within the lifecycle is still not obvious. But at least we now know the init() method won’t be invoked multiple times.
There are other ways to tackle this issue, for example, using a PhaseListener, or using a framework like Seam, but that has issues of its own.
Back to the event example
Below is a snippet of my login page.
<h:form>
<dl>
<dt><h:outputLabel value="Customer ID" for="customerId" /></dt>
<dd><h:inputText id="customerId" value="#{loginBean.customerId}" required="true" /></dd>
<dt><h:outputLabel value="Challenge" for="challenge" /></dt>
<dd><h:outputText id="challenge" value="#{loginBean.challenge}">
<f:event name="preRenderComponent" listener="#{loginBean.generateChallenge}" />
</h:outputText></dd>
<dt><h:outputLabel value="Response (always 123456)" for="response" /></dt>
<dd><h:inputSecret id="response" value="#{loginBean.response}" required="true" /></dd>
<dt> </dt>
<dd><h:commandButton value="Login" action="#{loginBean.loginUsingTokenGenerator}" /></dd>
</dl>
</h:form>
As you can see, the above snippet contains the challenge response login form. Line 7 is the interesting one. It registers a PreRenderComponentEvent listener method on the LoginBean.
The LoginBean is shown next (snippet…).
@Named
@SessionScoped
public class LoginBean implements Serializable {
private Integer customerId;
private Integer challenge;
private Integer response;
private @Inject LoginService loginService;
private Customer customer;
// Getters and setters
public void generateChallenge(ComponentSystemEvent event) throws AbortProcessingException {
this.challenge = loginService.generateChallenge();
}
public String loginUsingTokenGenerator() {
customer = loginService.loginUsingTokenGenerator(customerId, challenge, response);
if (customer == null) {
FacesContext.getCurrentInstance().addMessage(null,
new FacesMessage(
"Username and/or password is incorrect or your account has been disabled"));
return null;
} else {
return "/pages/homepage.xhtml?faces-redirect=true";
}
}
}
Don’t mind the annotations, they come from CDI (JSR-330 a.k.a. Contexts and Dependency Injection). The only thing to remember from these is that this class is a Session scoped managed bean which gets a LoginService injected. Note that I would also prefer ViewScoped, instead of SessionScoped.
Also, don’t mind the return values in loginUsingTokenGenerator. This is also a new feature in JSF 2.0, called Implicit Navigation.
Note the generateChallenge() method. The throws clause is not mandatory. The argument type must be ComponentSystemEvent though.
Wrapping up
As you can see, System events and the <f:event /> tag provide a convenient way to hook in custom logic on a per-component basis.
And, because we’re back to normal OO programming, instead of getter hacking, unit testing the LoginBean is easy as pie!
Pretty neat huh?!
Gepost in JavaServer Faces | 1 reactie »
Door: Jan-Kees van Andel, 7 September 2009
In the previous blog, I’ve shown you a tip of the CSRF iceberg and a simple prevention mechanism. In this blog, I’ll elaborate a bit more on the implementation of a successful CSRF prevention mechanism.
Ad-hoc token per form implementation
As stated, the solution is simple, just include a hidden field in every form, store the same value in the session and compare the two when the form is submitted.
Although working, this fix has some disadvantages.
- First, security is not turned-on by default. Every developer needs to be aware of the concept of CSRF and may not forget it when adding new forms. This also applies to developers that have to maintain the website in the future. They may not even know CSRF in the first place and just remove ‘that silly token’ from the form.
- Second, it’s probably not the most elegant solution from a Separation of Concerns perspective. Now, every form needs to be aware of security and you need to perform a check in your side controller logic.
So let’s elaborate on some more mature solutions.
What are the variables?
Like always in computer science, there is no single, one-size-fits-all, perfect solution. It always depends on the context. Well, let’s give it a bit of context!
-
Token freshness
How often is a new token generated? In other words, what’s the time-to-live of a token?
-
Token quality
How random should the token be? What algorithm should you use?
-
Token storage
You’ll need to store the token in two places to compare them. First, the HTML where your forms and links reside. And somewhere else…
-
Back buttons and bookmarking
How to deal with users pressing the back button and seeing a cached web page which they submit? How to deal with bookmarks? Also, you can have Single Sign On, paving the way for deep linking into your system without re-authentication.
-
Ajax
When using Ajax, many server side requests may occur before a full page refresh happens (if any). What to do with token management?
-
Punishment
What to do with hack attempts? Do you log an error and short-circuit the server side processing? Or do you log the user off?
-
Logging
How do you log the event? What kind of information do you include in the logging?
As you can see, there are many variables and all of them may impact your implementation. Most of them even influences each other. In the next section, I’ll discuss all of them in isolation.
Token freshness
This is a major one. A choice needs to be made here. Do you generate one token when the user logs in or do you re-generate a new token each time an action is made?
While re-generating a new token with every request may be very secure, it’s not the most practical solution in reality. In practice, it doesn’t even add that much security, because the Same Origin Policy takes care of the integrity of the token. I also wouldn’t worry about brute force attacks for the token, since the user will probably be logged off long before the attacker guesses right. But when we throw back buttons, Ajax, double-clicking users, etc. into the mix, changing the token during a session has serious disadvantages.
So, unless you have really really really weak token (which will never happen unless you pick an integer between 0 and 1), I would generate the token once (@login) and reuse that value.
Token quality
First of all, we’re not talking about high end encryption stuff here. The only use of the token is turning the URL into a “random” URL. So simple tokens will do.
Important to note is that the attacker will probably never see any token, unless he logs into the system (the token is only used for secure pages). So we need something between an incremental counter and some heavy duty 1024 bit encryption.
I would say, keep it simple. Just use a Random generator or a simple AES key, if it makes your security department happy. When using something like AES, remember to encode it using Base64. It only needs to be one way encryption, since you can compare the encrypted values.
This is a simple AES token generator which also encodes the token using Base64 so it can be used in the HTML.
import java.util.Random;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import org.apache.commons.codec.binary.Base64;
public class IntegrityTokenGenerator {
public static void main(String[] args) {
IntegrityTokenGenerator integrityTokenGenerator = new IntegrityTokenGenerator();
System.out.println(integrityTokenGenerator.generateToken());
System.out.println(integrityTokenGenerator.generateToken());
System.out.println(integrityTokenGenerator.generateToken());
}
private static final String ENC_TYPE = "AES";
private final SecretKey key;
private final Cipher cipher;
private final Random random;
public IntegrityTokenGenerator() {
try {
KeyGenerator keyGen = KeyGenerator.getInstance(ENC_TYPE);
key = keyGen.generateKey();
cipher = Cipher.getInstance(ENC_TYPE);
cipher.init(Cipher.ENCRYPT_MODE, key);
random = new Random();
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("Error generating integrity token");
}
}
public String generateToken() {
try {
String tokenString = "" + System.nanoTime() + "" + random.nextInt();
byte[] tokenBytes = tokenString.getBytes("UTF-8");
byte[] encoded = cipher.doFinal(tokenBytes);
return new String(Base64.encodeBase64(encoded));
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("Error generating integrity token");
}
}
}
I used AES in this example, but you can use anything, like Blowfish. Performance is not an issue, because of the small token length. I’m talking about less than milliseconds. Also, encryption strength is not very important, because you only need a simple token. Remember to base64 encode binary tokens into plain text.
Also be sure to use a random value each time when you generate a token. This way, the token sequence becomes less predictable. To make it a bit more secure, include some personal data in the token, like a customer ID. The combination of data make the key even less likely to guess. Don’t put any confidential data in the token. It doesn’t add any security and only increases the risk of information leakage.
And make sure not to throw too specific exceptions. Just log them and throw a general exception. Details may never end up in the wrong hands!
One more note about the snippet. A big advantage of this approach is that you don’t have any key management. Keys may leak and key management puts another burden on the system administrators. This implementation generates a key once (when the class is instantiated) and reuses it. Java takes care of the details.
Token storage
There are many ways to keep track of the current token for the currently logged in user, but the HttpSession and Cookies are the most common. Cookies decrease the amount of state your server must manage, but for some reason, developers think cookies are unsafe.
When used for storing CSRF prevention tokens, cookies can be safe. Why? Because an attacker cannot see the contents of the cookies. It’s the browser that appends the cookies to an HTTP request, but the attacker cannot see them. A mechanism like HttpOnly makes cookies more secure, because it prevents scripts to access them. But storing security tokens on the client is inherently unsafe and is probably the prime reason not to use cookies to store the tokens. You CAN do it, but you must be very careful AND rely on the browser to do the right thing. For example, Firefox ignores HttpOnly, causing cookies to be quite unsafe.
But why not store the token in an HttpSession attribute? Generate it once, put it in the session and then compare this token with the submitted token. It has a little bit of overhead, but that will probably be nothing compared with the rest of the session data.
I prefer the HttpSession over cookies by a mile length. With session attributes, I don’t have to think about token confidentiality and with cookies I do. Easy choice.
Back buttons and bookmarking
For some reason, clients want us to build systems in web browsers that are not specifically designed for such a purpose. But it’s a fact of life, so we need to deal with it. Browsers have back/forward buttons, refresh buttons and bookmarks and allow users to navigate freely by using the address bar. If you want your users to be able to use these features, here are some notes.
Only check the CSRF prevention token on state changing actions. Users often don’t bookmark actions, but they bookmark pages. When you only check the CSRF token when the form is submitted, the user can use a bookmark to navigate to the form. The server then renders a token into the form. The user submits the form and it works. You just need to give the server a chance to render a form before the user triggers an action. Using post-redirect-get makes it even more robust, because it prevents users to bookmark the POST request.
Also, don’t re-generate tokens with each request. When you want to support back buttons, you’ll have to be aware of the possibility that the rendered page may be a cached (stale) page which contains an outdated token. So, use the same token for the duration of the session.
You might also want to consider storing the token per user in a persistent store, so that when the same user navigates to the site (after a time of inactivity, maybe days or weeks) he gets the same token, thus fixing possible bookmarking problems.
If you implement your own home brewn CSRF prevention mechanism you can redirect the user to a proper page when the integrity token is absent or invalid. This way, the user doesn’t see some strange error but a proper page instead.
Ajax
When securing your website, you also need to secure your Ajax actions. After all, an Ajax request is just the same (from the server perspective) as another request. So you need to include CSRF tokens in the Ajax requests as well.
Luckily, with most JavaScript libraries, this is easy, since they provide a generic abstraction for Ajax requests and often provide a way to append generic parameters to a request.
The implementation is really easy, just render the CSRF token to a script variable and append it to all requests, like shown below.
var globalIntegrityToken = '<%=(String)session.getAttribute("integrityToken")%>';
Yeah I know that scriptlets are ugly, but I don’t care in this example. You can use EL or whatever you like.
Appending the token to the URL is easy, for example using JQuery:
$.ajax({
type: 'POST',
url: '/changeEmail.do',
data: {
newEmail: $('emailaddress').val(),
integrityToken: globalIntegrityToken
}
});
Again, reusing the same token for a longer period of time makes your job a lot easier. Otherwise, if you re-generate the token per request, you need a way to update all tokens that exist in the DOM when the request is completed. This has performance impact on the client and makes the code a lot more complex. You’ll have to make sure you update all tokens, which include:
- The global variable, which is easy to update in a generic way
- All hidden fields that contain a token. If you can easily find the fields, this should also be easy
- Any tokens in querystrings. This may be a bigger challenge and you may end up using regular expressions to parse and replace the querystrings
So, when you reuse the same token for the duration of the session (or longer) Ajax will probably not be difficult.
Punishment
What do you do when you see someone fiddling with the CSRF prevention token? First of all, don’t proceed with the action the user invokes. But do you log the user off?
If you can, I would suggest making a switch to turn the logoff mechanism on and off. Turning it off makes it easier to test, but you need to turn it on in production. If you’re afraid that you (or the sysadmin) forgets to turn the mechanism on, you can skip this switch.
Just be sure your prevention mechanism doesn’t give false positives, because users will be very annoyed if they are logged off often.
Logging the user off has some other benefit. If there is a hacker messing around with your website, users will get logged off very often and complaints will come in often at your help desk. This way, you have the opportunity to detect hackers. If you let the user proceed working without notification, you will never know that something happened. Unless your sysadmins proactively scan the log files, but unfortunately I don’t see sysadmins do these kind of things very often…
Logging
How do you log the event? I would suggest creating a separate security log file so that sysadmins can react to hack attempts. It’s also useful as a proof in a lawsuit. I would log as much as possible. You can think about:
- Date/time of course and also the timezone.
- The entire HTTP request, with cookies, referrer, user agent, etc.
- The source IP address. However it may be spoofed or a proxy, at least you can see that there is a difference with the “real” user’s IP.
- The invoked action, along with it’s parameters.
- Any server side state, specific to your system.
It might be a good idea to also log the first two items when the user authenticates so you can compare the two values.
To summarize
In most cases, you’ll want to use a static CSRF prevention token for the duration of the session. It makes Ajax implementations easier and gives browser features like back buttons and bookmarks a more natural behavior. When you do, implementing a working CSRF prevention mechanism may not be a big issue anymore.
The other variables don’t have this much impact, but be sure to pick a good combination, because some variable combinations may harm each other.
Gepost in Architectuur, Security, Web | Geen reacties »
Door: Jan-Kees van Andel, 31 August 2009
What is it?
Cross site request forgery (CSRF) is a type of attack, made to a web application by another web application, running in another tab or window in the same browser on the same computer. The server cannot see the difference between legitimate and malicious requests, since all HTTP requests look the same. Thus, the server (obviously) assumes a legitimate request. This gives the hacker the opportunity to impersonate the user and execute commands without the user knowing it. Or more abstract, CSRF may violate integrity.
The attack is caused by three things.
- First, the fact that most websites completely rely on a session cookie to represent the user.
- Second, because browsers allow websites to invoke certain cross domain requests.
- And third, the browser appends all cookies that belong to a domain to every request to that domain.
Example
For example, you have a social networking site where you can add friends to your network. Let’s say everyone has a link on his/her personal page that can be used to add that person to your “friends” list.
The link may look like this:
<a href="/addfriend.do?userid=12345">Add friend</a>
The application uses the HttpSession (or JAAS Subject or whatever. The attack is not specific to Java) to determine the currently logged in user and its userId. The userId of the new friend is taken from the querystring. Both are combined and the relation is created. This mechanism trusts the integrity of the session, which is not a bad thing on itself.
So far so good…
Attacking the example website
But the above example has one major flaw. It assumes that a session safely represents the user and bases security checks on this assumption. For some reason, people think that the session is “safe”, just because it exists on the server. But there is one big issue with sessions. The server determines which session belongs to a certain user by a sessionId, which is stored in a cookie in the user’s browser (URL rewriting is also possible, but not common). From the server point of view, this cookie IS the user. So, when someone accesses the cookie value, this person is automatically authenticated. But that’s not the issue here. That would be a case of session hijacking (or session fixation). You can migitate the risk of session hijacking using common security mechanisms, like SSL, and by ensuring that only proper input is accepted. But we’re talking about CSRF here.
CSRF is possible, because all cookies that belong to a certain domain are sent with each request to that domain, regardless from what domain the request is invoked, even when that web page is running in a different tab or window. SSL doesn’t help you here. If a call is made using HTTPS, the cookies are still appended to the request and a valid HTTPS request is executed.
Note: The details of cookie sharing differ per browser. For example, in Internet Explorer, when you use CTRL+N to open a new window, cookies (and thus sessions) are shared between the window and its “parent”, but when a new process is created (e.g. from the Start Menu or Quick Launch), the two act as two separate browsers and cookies are not shared. This distinction is often not visible to (or known by) the end user. But there are more issues, like the annoying IE8-I-share-cookies-between-tabs-”feature”.
What can an attacker do with this knowledge? Consider the example above. If the social networking site permits HTML content on your personal page, the attacker can first create an account and then put the following HTML snippet on his personal page.
<img src="/addfriend.do?userid=[ATTACKER_USER_ID]" />
The browser sees this image tag and tries to load the image, effectively invoking the following HTTP request to the specified URL. It doesn’t matter that the URL doesn’t point to a real image, the processing on the server is being done anyway. The request is invoked from the victim’s browser, so the victim’s cookies are appended to the request.
Now, everyone who visits the attacker’s personal page becomes a friend of the attacker.
With a bit more effort, the attacker can do almost anything with the entire social networking site. SAMY is an example of an attack on MySpace which used XSS and CSRF techniques to do its thing.
Almost all major websites (like GMail) have had CSRF leaks and many major websites still have.
How about POST?
The previous example uses an image to trigger an HTTP GET request. So you might think that POST is safer. Well, opposed to what many people claim, POST is not much safer than GET (from a networking perspective they are the same). Where we use an image to trigger a GET request, we can just as easily use a (hidden) form to trigger a POST request, as shown in the next snippet:
<form id="myForm" action="/addFriend.do" method="post">
<input type="hidden" name="userid" value="[ATTACKER_USER_ID]" />
</form>
<script type="text/javascript">
document.getElementById("myForm").submit();
</script>
Cross Site?
The risk of CSRF may be small or big. In the above example, the attack concentrated on the same website.
This is a case of a “Stored CSRF Vulnerability” (from www.isecpartners.com/documents/XSRF_Paper.pdf), which means that the attacker uses a security hole in the application itself to invoke the HTTP methods. The attacker uses techniques like XSS as an “enabler” for their CSRF attack. This kind of attack is completely the responsibility of the website. They just need to prevent the user to enter any HTML.
But CSRF also works cross domain. In that case, we talk about “Reflected CSRF” (also from www.isecpartners.com/documents/XSRF_Paper.pdf). In this case, your website itself may be perfectly safe (meaning it doesn’t accept HTML snippets like in the example) but an attacker may still invoke HTTP requests to your site using a different site, like a forum, blog, email, IM or whatever. Effectively this means your website can be the victim of the leak in another website. Luckily, this method often fails, since the user must be logged in on the targeted site and visit the malicious other site at the same time. How often this happens depends on the type of website. I’m sure most people don’t visit many dangerous websites when doing electronic banking, but it’s not uncommon to do this when logged in on webmail, especially since these kind of websites often provide features like Single Sign On or long sessions.
But doesn’t the browser prevent this behavior?!?!?! Nope, as I’ll indicate in the following section.
Same Origin Policy
First implemented in Netscape Navigator 2.0, the Same Origin Policy is one of the main security mechanisms in modern browsers. Basically, it allows scripts that are located on the same domain to interact, while preventing interaction between scripts that are on different domains. With interaction, I mean accessing properties, invoking methods and other scripting mechanisms.
The Same Origin Policy is invoked when one of the following actions happens.
- Requesting URLs with XMLHttpRequest (XHR)
- Accessing frames and iframes
- Accessing documents
- Accessing cookies
- Accessing browser windows
The list above is not complete, but contains the major actions that are validated against the Same Origin Policy.
This means that for example, it’s not allowed to invoke cross domain XHR requests. That’s good. It adds a serious layer of security and in most cases, you won’t need cross domain XHR requests.
But the Same Origin Policy doesn’t apply to everything. For example, it’s still possible to reference images, scripts and style sheets from different domains. It’s also possible to submit forms across domains.
I’m talking about domains a lot, let’s see what I mean with a domain, using the following listing. It shows how some example URL’s relate to the following web page: http://www.domain.com/pages/homepage.html. It also shows whether the Same Origin Policy allows document retrieval, and if not, why.
| Other URL |
Allowed |
Reason |
| http://www.domain.com/otherDirectory/page.html |
Allowed |
Different directory is allowed |
| https://www.domain.com/page.html |
Not allowed |
Different protocol |
| http://sub.domain.com/page.html |
Not allowed |
Different subdomain |
| http://www.domain.com:8080/page.html |
Not allowed |
Different port |
So a different domain can also mean: different protocol, different port or different subdomain.
Also, be warned that there are several ways around the Same Origin Policy. For example using the Flash cross-domain.xml file. Flickr was vulnerable to this, as written here.
To summarize, the Same Origin Policy provides quite a lot of safety, but not enough to completely prevent CSRF attacks. It does provide a helping hand, as I will show in the last part.
For a more detailed discussion of the Same Origin Policy, see:
https://developer.mozilla.org/En/Same_origin_policy_for_JavaScript and
http://taossa.com/index.php/2007/02/08/same-origin-policy/ and
http://taossa.com/index.php/2007/02/17/same-origin-proposal/
HTTPOnly cookie flag
As some may know, HTTPOnly is a cookie flag that is respected by most major browsers. Some browsers only added HTTPOnly support recently, like Firefox, which only has HTTPOnly support since version 3. Some browsers, like IE, already supported the flag for ages.
It is included in the Set-Cookie Http response header, as follows:
Set-Cookie: =[; =]
[; expires=][; domain=]
[; path=][; secure][; HTTPOnly]
It is appended to the Set-Cookie value in just the same way as the Secure flag, which prevents the cookie to be sent across insecure connections (non-HTTPS).
Basically, marking a cookie as HTTPOnly, prevents any scripts to access it. HTTPOnly cookies are only accessible by the browser to include it in the requests made to the server. It is not accessible by any JavaScript (the document.cookie property).
For more information, see the OWASP HTTPOnly documentation.
Btw. The Java Servlet specification only added HttpOnly support in version 3.0, so it’s not final at the time of writing!
Fixes
The solution is actually quite simple. Just use unguessable URLs in your website. You can achieve this by including a random token in the querystring/POSTdata of “important” requests. It’s not necessary to include it in requests that don’t change any state on the server, only state modifying requests need to have the token.
Why not include it in simple GET requests? Simple, because they don’t change anything and the hacker has no way to read the information that has been sent back to the browser, because of the Same Origin Policy. As indicated before, the Same Origin Policy prevents any scripts to read content from a remote page. Using XHR is also not possible, since the Same Origin Policy prevents cross domain requests using XHR. So, thanks to the Same Origin Policy, confidentiality is ensured. But to ensure integrity, some steps need to be taken by the developer.
For integrity, you need to implement a mechanism like the following: When you render an HTML form, be sure to include a hidden field with a random integrity token. You’ll also need to put this token into the session. When the form is submitted, you’ll need to compare the submitted token with the token in the session. If they are not the same, trigger an error or log the user off. Whatever you do, don’t let the request continue executing!
Also, don’t forget to include an integrity token in state-changing GET requests and Ajax calls and check appropriately!
There are a lot of variables in a successful CSRF prevention mechanism. In the next blog, I’ll give you some guidelines so you can pick the right ones for your website.
Gepost in Architectuur, Security, Web | 4 reacties »
Door: Jan-Kees van Andel, 23 August 2009
For some reason, when talking about web site/application performance, people think about the server side, like optimizing database queries and tuning connection pools. Yeah, of course, it’s important to tune the server side. But what people often don’t realize is that there’s lots to gain on the client side as well.
For the people that haven’t done so already, download Firefox with the Firebug plugin. You can activate Firebug using the F12 keyword.
Firebug has a really useful “Net” tab (which must be activated because it has quite an overhead. You can use this tab for debugging (inspecting headers and stuff), but it also gives you a good indication of your performance.
To give you an example, below is a screenshot of java.sun.com.

Analyzing the problem
What can a developer learn from this output?
-
First, you can see that the server side part is quite fast. It only takes 220ms to write the entire page to the client (the first bar). They could maybe optimize a bit by flushing earlier, to have better network utilization, but this is probably the consequence of an architectural choice (I assume they’re using an MVC style approach like Struts, where you would first gather all data and then forward to a JSP page). It wouldn’t even be a big win, since the server side performance is only a small part of the total performance.
-
Second, we can see a lot of activity is happening after the initial page request. By using the handy Firebug filters, I can easily see that 3 CSS style sheets, 17 JavaScripts and 38 images are fetched. This sums up to a total page load time of almost 4 seconds. In fact, there are so many requests that they don’t even fit on my screen.
-
A third lesson we can learn from this output is that almost all requests are made sequentially. I’ve made a simple calculation. The total amount of data downloaded is 137KB and it took around 4 seconds. That’s around 35KB/s!!! As an indication, I normally download (large files) with a megabyte per second. How about bad network utilization!
-
Fourth, there are some moments where no resources are downloaded at all. This is because downloaded resources have to be parsed, executed, rendered or whatever. This also hurts parallelism. After all, the computations required to do something with a resource don’t involve network I/O, so it would be nice if the browser started downloading the next file. This would be way more efficient. Fixing this issue is not trivial in most cases, so I’m not gonna talk about it here. Steve Souders has blogged about it extensively.
Http connections in your browser
Before trying to fix the problem (which I’m not going to do, since it’s not my website), we need to know some things about how web browsers handle requests.
An important thing to know is that browsers only use a certain amount of connections in parallel to the same web server. With web server, I mean the same IP address. So if multiple domain names resolve to the same IP address I’m talking about the same web server. This is in accordance with the HTTP 1.1 protocol, which states that a single web browser instance should only use 2 connections per web server. Below is a table with some popular browsers and their default parallel connection counts, using HTTP 1.1. (when using HTTP 1.0, the numbers may differ)
Browser # of Connections
Internet Explorer <8 2
Internet Explorer >=8 6
Firefox <3 2
Firefox >=3 6
Safari 4
References:
http://support.microsoft.com/?scid=kb%3Ben-us%3B282402&x=8&y=8
http://blogs.zdnet.com/Burnette/?p=565
http://www.stevesouders.com/blog/2008/03/20/roundup-on-parallel-connections/
You can change the settings of your browser. For example, when using Firefox, you can use about:config to increase the amount of parallel connections. But since most visitors of your website won’t change this setting and just use a mainstream browser, you can’t rely on this setting. On my current project (online ebanking, so the end user are “normal” people, not whizkids), we have to support browsers back to IE6. This means we have to perform well in browsers that use only 2 parallel connections per web server. Also, statistics indicate that people who use old browsers often are not on high bandwith connections (or are on a corporate network).
So… we had to do some work to enhance user experience.
To wrap up: The issue is simply that too many resources are loaded. It shows up in the chatty waterfall chart.
The solution
With a bit of background knowledge, we can start looking at the solution. We need a way to increase the average download speed/decrease the loading times. As shown in the image, you can see that several small files is not very efficient, so let’s start combining them. This saves some overhead, because we have to download less files. Also, as a nice side effect, compression techniques like GZIP are more efficient on large files.
But are issues, because we developers like to create maintainable code in separate small files. And working with large project teams and version control systems is often a mess when you have large files that everyone is editing concurrently.
Luckily, the solution is easy. Just aggregate all files into one big file. On my project, I’ve used Yahoo’s YUICompressor which not only aggregates, but also minifies the scripts and stylesheets. http://developer.yahoo.com/yui/compressor/
Since we use Apache Maven 2 as our build tool, I’ve integrated compression into our build using a Maven plugin which invokes YUICompressor. I’ve used http://alchim.sourceforge.net/yuicompressor-maven-plugin/
Using the default settings, the plugin only minifies the files. The minified files get the “-min” suffix.
Below is an example of a Maven 2 configuration where the listed files are minified and aggregated into one big “all.js” file. The normal files are still present, but I’ll get into that later.
<project>
<build>
<plugins>
<plugin>
<groupId>net.sf.alchim</groupId>
<artifactId>yuicompressor-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>compress</goal>
</goals>
</execution>
</executions>
<configuration>
<nosuffix>true</nosuffix>
<aggregations>
<aggregation>
<insertNewLine>true</insertNewLine>
<output>${project.build.directory}/${project.build.finalName}/js/all.js</output>
<includes>
<include>${project.build.directory}/${project.build.finalName}/js/jquery.js</include>
<include>${project.build.directory}/${project.build.finalName}/js/util.js</include>
<include>${project.build.directory}/${project.build.finalName}/js/defs.js</include>
<include>${project.build.directory}/${project.build.finalName}/js/ajax.js</include>
<include>${project.build.directory}/${project.build.finalName}/js/handlers.js</include>
</includes>
</aggregation>
</aggregations>
</configuration>
</plugin>
</plugins>
</build>
</project>
As you can see, I’ve explicitly specified the files to include. You can also use wildcards. I prefer this way because now I’m 100% sure of the ordering in the final aggregation. With wildcards, on the other hand, a simple refactoring (like renaming a file) could silently break the application @runtime. By being explicit, I get an error telling me that a file is missing.
CSS can also be aggregated and minified. And I must say, YUICompressor is really impressive. For example, it doesn’t just remove all comments, but determines per occurrence if it needs to be removed. For example, if you have a Safari Commented Backslash Hack v2 (http://perishablepress.com/press/2006/08/27/css-hack-dumpster/), it will not be removed, since that would break your CSS.
Below is an example where both the JS and CSS files are aggregated into two files: “all.js” and “all.css”.
<plugin>
<groupId>net.sf.alchim</groupId>
<artifactId>yuicompressor-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>compress</goal>
</goals>
</execution>
</executions>
<configuration>
<nosuffix>true</nosuffix>
<aggregations>
<aggregation>
<insertNewLine>true</insertNewLine>
<output>${project.build.directory}/${project.build.finalName}/js/all.js</output>
<includes>
<include>${project.build.directory}/${project.build.finalName}/js/jquery.js</include>
<include>${project.build.directory}/${project.build.finalName}/js/util.js</include>
<include>${project.build.directory}/${project.build.finalName}/js/defs.js</include>
<include>${project.build.directory}/${project.build.finalName}/js/ajax.js</include>
<include>${project.build.directory}/${project.build.finalName}/js/handlers.js</include>
</includes>
</aggregation>
<aggregation>
<insertNewLine>true</insertNewLine>
<output>${project.build.directory}/${project.build.finalName}/css/all.css</output>
<includes>
<include>${project.build.directory}/${project.build.finalName}/css/global.css</include>
<include>${project.build.directory}/${project.build.finalName}/css/main.css</include>
<include>${project.build.directory}/${project.build.finalName}/css/buttons.css</include>
<include>${project.build.directory}/${project.build.finalName}/css/menu.css</include>
<include>${project.build.directory}/${project.build.finalName}/css/components.css</include>
</includes>
</aggregation>
</aggregations>
</configuration>
</plugin>
What about images?
Images can be aggregated too, but this is way more difficult than with scripts. You’ll have to use image sprites, but this first involves creating a sprite (you can do this with online tools if you want), but then the difficulties start, since you need some CSS tricks to “select” the image from the sprite using offsets. This is a real pixel-pain-in-the-ass, but you’ll also enter the realm of cross browser issues here.
This page is a good starting point, but beware, depending on your situation, things may become difficult.
See: http://www.alistapart.com/articles/sprites.
On the other hand, you can of course begin small. For example, creating several sprites for buttons (with hovers and sliding doors you can turn 4 images into 1), boxes and logos. Every improvement is welcome.
Conclusion
Aggregation can greatly improve the performance of your website. On my project, I’ve decreased load times (with an empty cache) from 7 seconds to less than 3 seconds, using only aggregation and script/CSS compression. Using GZIP, caching and some other tweaks, I’m currently even lower. I’m still planning to implement the image sprites.
The moral of this blog is that there is more than the server side and you have to remember, it’s the end user who experiences your application. End users really hate hickups, long load times and web pages that build up in strange ways. They will be annoyed and maybe even lose their trust in the integrity of the application. And when this happens, you’re in deep shit.
Also, remember. Performance tuning differs from other disciplines, like security. With security, there are no (or at least little) compromises. But on the other hand, you can (and should) be happy with every performance improvement as the only valid performance measurement is the happyness of the end user.
Notes
- I didn’t remove the original files, since I want to be able to switch @runtime between aggregated files and the originals. This greatly simplifies debugging, especially in production.
- Check performance in all browsers. As indicated, browsers have different default values for several settings and different characteristics.
- Client side performance is often easy to test. You don’t need heavy load, like you would when doing server side performance testing. You can start with your development machine and a simple testing server is often good enough for a more thorough test.
Gepost in Architectuur, Web | Geen reacties »
Door: Jan-Kees van Andel, 25 June 2009
On my current project (online e-banking application for a medium/large scale bank), we needed to add Cross Site Scripting (XSS) protection afterwards. Well, actually, we had a working XSS protection mechanism in place, but the security auditors pointed out the implementation had flaws. But we’ll get to that later.
Cross Site Scripting?
First, let me explain what Cross Site Scripting (XSS) is. XSS is a hack where malicious code (JavaScript/HTML) is injected into a trusted site. With trusted, I mean the user trusts the site, which is usually the case with e-banking websites. At least, I hope so.
A simple example is a web site which contains a search box, like the following.
<form action="/search.do" method="GET">
<input type="text" name="searchString" value="Enter something here" />
<input type="submit" value="Search" />
</form>
When the user submits the form, a request is made to the following URL: /search.do?searchString=[THE_USER_INPUT]
The application responds with a page, containing the results, including a summary of the search criteria, and also the search form, prefilled with the search string the user entered, like here.
<!-- Some HTML -->
<form action="search.jsp" method="GET">
<input type="text" name="searchString" value="${param.searchString}" />
<input type="submit" value="Search" />
</form>
<table id="results">
<!-- The search results -->
</table>
<!-- The rest of the site -->
So far, so good, right?
No, wrong!!!
Suppose a hacker enters the following value into the searchString box:
"/><script>alert("hello")</script><p id="
You’ll see an alert box with the message: “Hello”. You have injected a script into your web page.
But why would anyone hack his own browser session? That’s not the danger here. The danger is that a hacker can create an URL, like
http://www.yoursite.com/search.do?searchString="/><script>alert("hello")</script><p id="
and send it to other people.
When they click on it, the script gets executed in their browser.
Of course, an alert window is harmless, but what if I inject some DOM scripting to create a form where the user must enter his or her credentials for the attacked site? Or an image to automatically trigger a “Button click” (this is actually a case of Cross Site Request Forgery)? With such a leak, I can do almost anything on your page, without you knowing.
Let’s see what happens when the login page of your bank is vulnerable to XSS. Phishing becomes easy as stepping on kittens!
As you’re probably now aware of, XSS is a great “enabler” for all kind of other hacks. And the fun part is, hackers can spot XSS flaws easily and often using automatic tools. Not scared yet? In that case, I hope you’re not working on the website where I perform my electronic payments! You should be scared for these kind of leaks.
Countermeasures
In theory, it is very easy to protect your website against XSS. Just escape all variables, according to the escaping rules that apply for the markup/script language you are about to put the variables in. Apache Commons Lang has a utility for this purpose: the class StringEscapeUtils with its method escapeHtml and some others. escapeHtml is probably the method you’ll need most, since most variables are outputted in HTML tags.
Why is this fix enough? Well, just test it out with the example above. We modify the JSP to escape the input before rendering it to the client, as shown below.
<%
String param = request.getParameter("searchString");
if (param == null) param = "";
String escaped = org.apache.commons.lang.StringEscapeUtils.escapeHtml(param);
%>
<form action="search.jsp" method="GET">
<input type="text" name="searchString" value="<%=escaped%>"/>
<input type="submit" value="Search"/>
</form>
The difference is that I added an escaping routine here. Nothing fancy, except that the “obvious” happens. The user input is shown on the screen in exactly the same way the user has entered it.
You see, no validation or black-/whitelists are needed, which is great, since you don’t want to bother users with security.
Some caveats, which become quite annoying later on.
- Timing is essential with regards to escaping. You cannot do it on your input parameters, since you’ll then end up with HTML encoded texts in your backend systems (that was the flaw I was talking about in the introduction). You also don’t want to be bothered with HTML encoding in your Java business logic, so input filtering is not the way to go. You definitely need to filter on the output, just before you render your page back to the client.
- You may not escape a variable twice, since the user ends up with HTML codes in his/her UI. When escaping > twice, it first becomes > and after the second pass, it becomes >, which is not only wrong with regards to usability, it also opens up some interesting new security holes.
- When you persist user input unencoded, which you should, you also need to escape all variables that come from there before rendering the web page. Essentially, you just need to escape every variable that is inserted into the web page, since it may (directly or indirectly) be manipulated by a malicious user.
Implementation
So, we need a way to escape all user input just before it is rendered. What are the options?
-
Custom JSP function
Probably the easiest way to escape special characters is by implementing a JSP custom function, like the JSF “outputText” component:
<h:outputText escape="true" value="<script>" />
. This one is easy to implement. It’s just a burden to edit all 200 JSP files (and the same amount of JSP Tag files) in our project and add the function at all places where a variable is used. The second issue is that you also need to be sure you don’t escape a variable twice, since that results in strange output and, ironically, new security holes. This is especially the case with tag attributes. Do you escape in the tag or in the calling code? You’ll need a strategy there. Finally, and probably most importantly, this solution will probably become a maintenance nightmare. JSPs are cluttered with these custom functions and future maintainers may never forget one when making changes. Something more generic would be nice.
-
ELResolver?
ELResolvers are added to JSP with version 2.1. We use Tomcat 6, so that’s great. However, the ELResolver mechanism differs greatly from, for example, the JSF VariableResolver mechanism. VariableResolvers are implemented using decoration, which makes them very useful to intercept all variable access and modify the responses. ELResolvers are implemented as a CoR and the implementation makes it impossible to create a custom filtering mechanism for all variables. It is also not the right place for this kind of logic. Why? Imagine a JSP Tag file. In the calling JSP file, you use EL to pass an argument to the tag and in the JSP Tag file, you use EL to put the argument in the HTML. With an ELResolver solution, variables get escaped twice. Not good.
-
Tomcat hooks, AOP, Javassist?
There are other ways to hook into the JSP/Servlet lifecycle. Containers provide vendor specific hooks to hook into the lifecycle, but unfortunately, no Tomcat hooks to help us here. But we’re not defeated yet! We can use AOP or a bytecode library to enhance some core Tomcat classes. Of course, we’re entering the black magic room here, but if it works… Unfortunately, these are also no real options. We can for example intercept all calls that go into the EL runtime by proxying all EL calls, but this has almost all of the issues as a custom ELResolver. Darn!
-
Servlet Filter?
But what’s wrong with a plain old Servlet Filter which escapes HTML special tags afterwards? The issue with a Servlet Filter is that it can’t possibly see the difference between legitimate and injected markup. The Filter Either escapes all markup (including your own) or nothing (which renders it useless). After the JSP has been executed, you’ll end up with HTML. If there is an XSS attack, you are simply too late when you use a Servlet Filter. So, it has to do with timing. Let’s step back.
-
Object graph XSS filtering!
There are two issues with most solutions presented.
- Timing: The solution is too early or too late, making it useless or wrong.
- no. executions: The solution has the risk of escaping the variable more than once, making it wrong and unsafe.
So, what’s the best point in the request processing lifecycle to do the escaping? It turns out that just before the JSP is executed is the ideal moment. It’s ideal, because you’re not too early, so you won’t notice anything in your Java code. It’s also ideal, since you have full control over execution, making it easier to execute once and only once.
Object graph XSS filtering
The graph walker sounds like a solution, however, it’s a difficult one to implement.
The reason is the flexibility of our MVC framework. It’s allowed to pass arbitrary object graphs to the JSP. This is an issue, since you can’t just iterate over all attributes and escape them. For example, some attributes may be collections, maps or domain objects, containing possibly unsafe strings.
So we need an object walker. What features should it have?
- Cycle detection, to prevent infinite loops.
- Ability to modify arbitrary objects, either using reflection (POJO’s) or API (Collections).
Implementation sources
A hack and slash implementation of this solution is attached. What do you guys think of it? Does it look like a workable solution?
Ps. I’m aware of the fact that I haven’t implemented any pattern or followed any best practice. It’s just a simple PoC.
Click here to download the ObjectWalker sources
Gepost in Architectuur, Security, Web | 4 reacties »
Door: Roy van Rijn, 5 June 2009

You’ve probably heard people talking before about ‘cloud computing’.
But what exacly is this cloud computing you might ask?
To figure this out I decided to create my own Google App Engine project and find out about cloud computing along the way.
Wikipedia states that cloud computing is:
“Cloud computing is a style of computing in which dynamically scalable and often virtualized resources are provided as a service over the Internet. Users need not have knowledge of, expertise in, or control over the technology infrastructure in the “cloud” that supports them”
So, cloud computing doesn’t only have a vague name, the description isn’t very helpful either. But the key ingredients are “scalable” and “virtualized” and “as a service”. And you don’t have control over the infrastructure…
Lets take a look at Google App Engine. It was released in April 2008 as a platform for developing (Python)cloud applications. App Engine hosts these applications virtually on many machines, the programs are distributed and scaled across a vast amount of servers. And now, since the beginning of this year Google App Engine also supports Java!
The concept is simple, you get to build an application, preferably using Google’s App Engine-eclipse-plugin. And the JRE you build on is a slightly stripped-down version to make it usable on a cloud, like a sandbox.
Because you don’t know on what kind of servers your application will run on, or on how many servers, Google has decided you can’t do the following:
- Start threads
- Go to the Filesystem, no I/O
- Open sockets directly, but you can open connections through HTTP/HTTPS
- Make calls to System (like exit();, gc(); etc)
And there is more. Because of these restrictions you can’t access a database! So you can’t use something like Hibernate and some Oracle/MySQL/Postgress machine. To still be able to save/persist objects Google has teamed up with Datanucleus. Using JDO or (a stripped down version of) JPA you can persist and retrieve objects on the cloud.
With this in mind I started making my own application. And the frameworks I wanted to use are:
- Wicket (Web Framework)
- Spring IOC
- Spring ORM (for transaction management, using annotations)
- JPA (instead of the default JDO)
The first problems I encountered was getting Wicket to load. Because of the sandbox-restrictions there are a couple of things you can’t do. For example, Wicket can’t save temporary data to disk (what it normally does). And there are problems with Wicket being in ‘development-mode’ where is wants to start Threads to poll for changed resources.
A good overview on what it takes to get Wicket working is explained here:
http://www.danwalmsley.com/2009/04/08/apache-wicket-on-google-app-engine-for-java/
Next up was installing and running Spring. This was relatively easy at first. The core Spring code ran pretty much as expected. I added the JARs to my project and added this to the web.xml:
<!-- Spring -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationcontext-*.xml</param-value>
</context-param>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<listener>
<listener-class>
org.springframework.web.context.request.RequestContextListener
</listener-class>
</listener>
As you can see, I load up multiple XML files. I decided to go with the all-out-annotations method using Spring ORM. This proved to be pretty challenging…
With these annotations you are able to do the following in the code:
@Repository("loginDao")
@Transactional
public class LoginDaoImpl implements LoginDao {
@PersistenceContext
private EntityManager entityManager;
... (and more)
As you can see I’m using Spring to inject my EntityManager into the DAO. But you can’t just load the entity manager in Google App Engine, you need a specific piece of configuration. I used the following XML:
<bean id="data.emf"
class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">
<property name="persistenceUnitName" value="transactions-optional" />
</bean>
<bean class="org.springframework.orm.jpa.JpaTemplate">
<property name="entityManagerFactory" ref="data.emf" />
</bean>
<bean id="transactionManager"
class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="data.emf" />
</bean>
To tell Spring to scan for these annotations you need to add the following lines in your applicationcontext:
<context:annotation-config />
<context:component-scan base-package="nl.redcode.*" />
And now the problems start… The first problem is that Google App Engine doesn’t support all core classes. When loading these annotations Spring will load its PersistenceAnnotationBeanPostProcessor. But it contains the following piece of code:
try {
return (EntityManagerFactory) lookup(jndiName, EntityManagerFactory.class);
}
catch (NamingException ex) {
throw new IllegalStateException("Could not obtain
EntityManagerFactory [" + jndiName + "]from JNDI", ex);
}
And the Exception we get is:
org.springframework.beans.factory.BeanCreationException: Error creating
bean with name
'org.springframework.context.annotation.internalPersistenceAnnotationProcessor':
Initialization of bean failed; nested exception is
java.lang.NoClassDefFoundError: javax/naming/NamingException
at
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:480)
at
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory$1.run(AbstractAutowireCapableBeanFactory.java:409)
at java.security.AccessController.doPrivileged(Native Method)
at
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:380)
at
org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:264)
at
...etc
And when I looked at the white-list it was clear, NamingException isn’t part of the sandbox Google App Engine uses. So I started to google how to solve this. The first thing I encoutered was somebody who added the following lines to his/her applicationContext:
<bean id="org.springframework.context.annotation.internalPersistenceAnnotationProcessor"
class="java.lang.String" />
This piece of code, when executed before the annotation-scan, loads a String in the Spring Container under the name “internalPersistenceAnnotationProcessor”. This causes Spring to ignore its own instantiation of the PersistenceAnnotationBeanPostProcessor and we don’t get the Exception anymore.
But this causes some more damage we don’t want in the application. Before my Dao’s received a valid EntityManager, but they are Null now…!
So I took the code of the original Spring PersistenceAnnotationBeanPostProcessor and replaced all the instances of NamingException with just Exception. This removed the dependency to NamingException. I called this new bean “AppEngineJPAPostProcessor”. This is how I configured it in the applicationContext:
<bean id="org.springframework.context.annotation.internalPersistenceAnnotationProcessor"
class="nl.redcode.springhack.AppEngineJPAPostProcessor" />
The EntityManager(Factory) is now created, it gets injected into the DAO’s, they have transactions using annotations and everybody is happy!
When I got a little further in my project I decided to deploy my application to the cloud and test it online. Deploying your application to App Engine is very simple, just push the “Deploy” button in the Eclipse plugin and you only need to enter your credentials and a version-number of your release!
But then the old BeanPostProcessor bit me in the back again. On the server I got the following Exception when deploying:
java.lang.SecurityException: Unable to get members for class org.springframework.jndi.JndiLocatorSupport
at com.google.apphosting.runtime.security.shared.intercept.java.lang.Class_$10.run(Class_.java:357)
at com.google.apphosting.runtime.security.shared.intercept.java.lang.Class_$10.run(Class_.java:347)
at java.security.AccessController.doPrivileged(Native Method)
at com.google.apphosting.runtime.security.shared.intercept.java.lang.Class_.getMembers(Class_.java:347)
at com.google.apphosting.runtime.security.shared.intercept.java.lang.Class_.getDeclaredMethods(Class_.java:174)
at org.springframework.util.ReflectionUtils.doWithMethods(ReflectionUtils.java:460)
at org.springframework.util.ReflectionUtils.doWithMethods(ReflectionUtils.java:443)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.findAutowiringMetadata(AutowiredAnnotationBeanPostProcessor.java:299)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessMergedBeanDefinition(AutowiredAnnotationBeanPostProcessor.java:179)
It seems the runtime is a bit more strict then the development server Google App Engine uses. For some reason it doesn’t like the JndiLocatorSupport. This is excepted because Google App Engine, due to the nature of the cloud, prohibits the use of JNDI.
Soon I found the problem, the only reference to JndiLocatorSupport is my own BeanPostProcessor:
/**
* Rewritten for use in Google AppEngine
*
* @author Roy van Rijn
*/
public class AppEngineJPAPostProcessor extends JndiLocatorSupport implements
InstantiationAwareBeanPostProcessor, BeanFactoryAware {
private Map persistenceUnits;
...
When I removed the ‘extends’ part there were two pieces of code that stopped working, they both look like this:
try {
return (EntityManagerFactory) lookup(jndiName, EntityManagerFactory.class);
}
It seems this PostProcessor always does a JNDI lookup to find the correct EntityManager! But we can’t do this if we don’t have access to the JndiLocatorSupport methods anymore. So I decided to hack a little bit in this code, my solution was to load the EntityManagerFactory and EntityManager from the Spring container:
try {
return ((JpaTransactionManager)beanFactory
.getBean("transactionManager"))
.getEntityManagerFactory();
/* return (EntityManagerFactory) lookup(jndiName,
EntityManagerFactory.class);*/
} catch (Exception ex) {
...
This solved all the problems and with the changes to the BeanPostProcessor I’m now able to use all the Spring annotations, for persistency and transactions, in Google AppEngine.
I’m now still in the middle of developing my application on Google App Engine, but it seems that Google App Engine works like a charm. The problem is, most frameworks can’t really cope with the sandbox out-of-the-box. But with (some) minor patches and tweaking most frameworks will run using Google App Engine. The only major problem I’m having (which can’t be solved) is Datanucleus. I chose to use JPA because it is much richer and has more features then JDO, but Datanucleus hasn’t implemented much of these features yet.
For example, I had the following annotation on a field: @Column(unique=true)
Datanucleus threw “java.lang.UnsupportedOperationException: No support for uniqueness
constraints“.
Also, I created a query with this: “username = :username OR emailAddress = :emailAddress”
But Datanucleus doesn’t support the operator “OR”.
Other things DataNucleus can’t currently do:
- Many-to-many relationships
- Joins in a query (WHAT??)
- Aggregation queries (group by, having, sum, avg, max, min)
- Polymorphic queries. You cannot perform a query of a class to get instances of a subclass. Each class is represented by a separate entity kind in the datastore.
So, we’ve seen what a cloud is, what Google App Engine is, and I explained some tweaks/patches needed to get Wicket and Spring working.
Why use Google App Engine? It is free (up to some CPU/mail/data limits) and your project runs on a cloud, and thus is very scalable. You don’t have to worry about the environment or server. Your application will scale when its needed and everything is pre-installed and ready to run.
But be prepared for difficult classloading issues and missing classes. You just can’t expect all frameworks to be working out-of-the-box with the sandbox-limitations. Also don’t expect much support with persisting, the JPA-support is very minimal and won’t let you do much more then persisting and retrieving single objects.
Enough blogging, now its time for me again to tinker on my application, maybe I’ll tell about it here in the future!
Gepost in Middleware, Spring, Web | 8 reacties »
Door: Stephan Oudmaijer, 20 April 2009
Oracle en Sun hebben een akkoord bereikt over de overname van Sun door Oracle. Lange tijd leek het erop dat IBM een van de belangrijkste kanshebber was om Sun over te nemen. Echter konden IBM en Sun het niet eens worden over de voorwaarden waaronder de deal door zou gaan en de prijs per aandeel. Oracle betaalt de aandeelhouders van Sun $9.50 per aandeel, hetgeen neerkomt op een deal van $7.4 billion dollar. Dat is $0.10 per aandeel meer dan IBM bereid was om neer te tellen.
De overname van Sun door Oracle levert wel een aantal interessante vraagstukken op, wat gaat Oracle bijvoorbeeld doen met Java? Op dit moment is er nogal wat onenigheid over het Java Community Proces (JCP), het standardisatie proces voor Java. Velen hopen dat Oracle de JCP nu echt open zal maken. Anderen zeggen dat er geen sprake van een inspraak proces is. Aan de andere kant, misschien is het wel niet in het belang van Oracle om Java nog opener te maken om het zodoende concurrent IBM lastiger te maken?
Verder zijn er nog NetBeans en GlassFish? Aangezien Oracle BEA heeft overgenomen, bekend van o.a. de applicatie server WebLogic, is er bij Oracle een overschot aan applicatie servers ontstaan. Zelfde geldt voor ontwikkelomgeving NetBeans vs JDeveloper, zullen beide naast elkaar blijven bestaan of worden ze samengevoegd?
Daarnaast is Oracle plotsklaps eigenaar geworden van MySQL, door velen gezien als het open source alternatief voor Oracle. Moeten we ons nu gaan verdiepen in PostgreSQL?
Voor het orginele persbericht zie: http://www.oracle.com/corporate/press/2009_april/018363.htm
Gepost in Algemeen, Web | 1 reactie »
Door: Vincent Hartsteen, 17 April 2009
Most developers would answer this question the same way that Bob the Builder would when asked if he can fix it. “Yes I can” would be the reply. And I’m sure that Bob can. Why? Because Bob does his building based on a blueprint that tells him exactly what to build and what to use for building it.
In construction the architect is responsible for producing the blueprint. The architect talks to the customer in order to get a list of requirements for the building. For instance is the building used as an office-space or is it used as a family-home. Should it be a single or multi story building and how many rooms should it have. And of course the amount of money the customer is willing to spend. Geared with the list of requirements the architect uses his design skills and his technical knowledge to make a first sketch of the building. The architect discusses this sketch with his team of electrical, mechanical and structural engineers to find out if it feasible from a technical point-of-view. For instance is the construction mechanically strong enough, are the selected materials useable, etcetera. This should all result in a blueprint for a building that meets the customer’s requirements, is usable with respect to the needs of the customer and is aesthetically pleasing. Finally the constructionworkers take the blueprint and start building the construction.
In software development some similar process takes place. In short the information analist and the customer discuss about the requirements for the system. What functionality should the system offer, what is the expected load etcetera. The information analist works in close cooperation with the software architect. The software architect is responsible for making the technical decisions (which frameworks to use, what platform, how many nodes, etc.) such that the non-functional requirements (scalability, extensibility, manageability, etc.) can be met. The UML-artifacts created by the information analist and the software architect (e.g. use-case model, software architecture document, use-case realizations, etc.) are input for the developers.
One major difference between the blueprint for the construction workers and the UML-artifacts for the developers is that the blueprint has usability embedded. The architect has knowledge about how to make a construction usable to its users. When there is a requirement that a house must have 2 bathrooms the architect knows that to make them usable he could place one on the groundfloor and the other on the first floor. He could have fulfilled the requirement by putting both bathrooms on the attic but that would not have made them very useable. Very often a developers gets a requirement which basically comes down to: “the application must have a web-interface or a GUI and it should be user-friendly”. That’s it. So now it is up to the developers to figure out what “user-friendly” is.
Most developers have a technical mindset and find it hard to step into the role of the end-user. It is the end-user that decides if the application is user-friendly. He does so when the application supports the end-user to do his job without problems. So in order to design a user-friendly interface it must be clear what the application is used for and how it is used. Very often user-friendlyness is misconceived as “protect the end-user from making mistakes”. If end-users use the application every now and then to do some work it can be valid to pop-up a confirmation dialog. Expert users that use the application on a regular basis get annoyed by such dialogs.
There are currently lots of tools/frameworks that allow developers to build goodlooking user-interfaces: JavaFX, Flex, SAF, JSF, Wicket, and the list goes on. But goodlooking is not the same as user-friendly. With the tooling mentioned before we could build a very nice 3D, animated, gradient color dialog box that is very annoying (remember the Office paperclip?). So basically we have the tools to create cool and goodlooking user-interfaces but most of us lack the knowledge of how to build usable ones.
My point is that there should be a role in the softwaredevelopment team, just like a information analist or a software architect, that is responsible for designing the interaction with the end-user. Just like the architect in construction. I haven’t come across a person with such a role in the many projects I’ve worked on over the past years. Until that time it is up to us developers to design user-interfaces and for that we need to broaden our horizon and try to place ourselves on the end-user seat.
A few years ago I read “About Face. The Essentials of User Interface Design” (first edition) written by Alan Cooper which got me interested on this subject (3rd edition is the most recent version). The book describes the problems that occur when developers start designing user-interfaces and give advice on how to improve on that, all illustrated with entertaining examples. If you get into the situation where you as a developer are responsible for the design of the user-interface this book might help you do a better job.
Vincent Hartsteen
N.B.: Currently I’m reading “The Inmates are running the Asylum”, also by Alan Cooper. This book describes the role of “interaction designers”. I’ll write my findings when I’ve finished the book.
Gepost in Algemeen, Architectuur, Boeken, Web | 2 reacties »
| |