Vaadin vulnerabilities

Sep 28, 2011

My review of Vaadin's security revealed these vulnerabilities, now fixed in Vaadin 6.6.7.

What is Vaadin? In their own words: Vaadin is a Java framework for building modern web applications. Its server-side architecture [and] security mechanisms to prevent eg. man-in-the-middle and cross-site scripting attacks [...] make Vaadin one of the most secure UI frameworks in existence.

Separator injection

In a Vaadin application, the server sends updates to the client using JSON, but the client uses a custom format to send updates to the server. This format uses exotic characters as a separator between records/variables. But, prior to Vaadin 6.6.7, there is no mechanism to escape those characters when they occur within the data. If an attacker can trick a client into sending his crafted data to the server, he can perform actions in the user interface on behalf of the victim.
In other words, the result is similar to that of cross site request forgery (CSRF).
If certain UI components, such as the rich text area (which allows a user to set arbitrary HTML) are used anywhere in the application, this also leads to cross site scripting (XSS).

There are multiple ways a client can be tricked into sending such data. For example a user could be tricked into copy-pasting a certain string. But there is also an automated way: if the application uses the URL fragment (with the UriFragmentUtility), the characters can be injected in there. Whether that last trick actually works depends on the browser. It works on Chrome but doesn't seem to work on Firefox, probably due to the way such characters are encoded.

More concretely, how does the format work? Suppose the user changes the text in a in a text field (with id PID1) to "test", and then presses a button (PID2; setting "state" to true). The client could then send the following (slightly simplified), were [xx] is the character with the given hexadecimal ascii value:

0a09a5e2-3190-4f16-a75b-284b98d221ce[1D]test[1F]PID1[1F]text[1F]s[1E]true[1F]PID2[1F]state[1F]b

1D is the burst separator, 1F the field separator, and 1E the record separator. The "s" means type string, and "b" type boolean. The first part is the anti-CSRF token.

If the text value instead of "test" would have been true[1F]PID3[1F]state[1F]b, then the server would interprete that as the user clicking on the button PID3. That can be done in the url fragment, with a url like this: http://vaadin-application/#true%1FPID3%1Fstate%1Fb.

This is Vaadin ticket 7669.

Classpath directory traversal

The Servlet in Vaadin takes care of the communication, but also serves static resources (html, javascript, css, images...). It looks for these resources in the "VAADIN" directory on the web application's classpath. Usually these resources would be found in a jar of the application, such as the Vaadin jar itself. But if the classpath also contains a directory (instead of only jars), also resources outside of the VAADIN directory can be retrieved using a simple /../ directory traversal. That allows an attacker to download the (byte)code of the application or configuration files (possibly containing passwords).

If this is exploitable in practice depends on how the application was packaged, and which servlet container is running it.

For example, creating a simple Vaadin application skeleton using the maven archetype with mvn archetype:generate -DarchetypeGroupId=com.vaadin -DarchetypeArtifactId=vaadin-archetype-clean -DarchetypeVersion=1.5.6 -DgroupId=tst -DartifactId=tst -Dversion=0 -Dpackaging=war and starting it with mvn package jetty:run, the main application class could be reached at the url /tst/VAADIN/../tst/MyVaadinApplication.class.

This is Vaadin ticket 7670.

Contributory XSS

There some places in the Vaadin framework that make it easy for a developer to introduce XSS problems. These are not directly exploitable by themselves, but in combination with other code can turn into vulnerabilities.

Exceptions on the server-side in handling updates from the client are often shown with an exclamation mark in a red circle next to the UI component that caused it; and hovering over that icon shows a tooltip with the exception stacktrace in it. HTML in that tooltip in the message of the exception (or its cause in the stacktrace) is not escaped.
For example, take a Vaadin application that shows a number in a text input field (without adding an explicit validator). If you paste HTML in that text field, parsing of that text to a number will fail with a NumberFormatException whose message includes the HTML text, that will then be shown unescaped.

I didn't find an automated way to exploit this that doesn't involve convincing a user to copy-paste some HTML. But this issue has the danger of turning another normal bug (that results in an otherwise harmless exception) into a security vulnerability.

This is Vaadin ticket 7671.

The src attribute of a number of UI components, which can contain a URL, is often handled without escaping. This seems to be the case for at least Embedded (when type is browser, i.e. an iframe), VWindow, VMenuBar, VFilterSelect, VView and Action. In an application where users are allowed to configure such a URL, which would then be used in such a component when shown to another user, this would be an exploitable XSS. That would be unusual, but not impossible; for example for the Embedded component, imagine a form where users can include an iframe in their posts.

This is Vaadin ticket 7672 (update: which they apparently didn't import into github).

Finally, in a slightly different category, there are strings that are shown intentionally as HTML without escaping, in places where it is not clearly documented in the Vaadin API. This is the case in the tooltip (description) of all components, caption of a Panel or a notification (as in Window.showNotification). If you use user-provided text in any of those, you must take care of escaping yourself. Future versions of Vaadin (starting from 6.7) will provide plain-text modes at least for some of these.

Conclusion

Vaadin is still a framework with a particularly good security architecture and counter-measures. But no program or framework is completely immune to security vulnerabilities. Vaadin's reaction to these vulnerabilities was quick and thorough.

Now it's time to update your Vaadin applications to a newer version!