Security Architecture
Vaadin Flow is a server-side framework, in which all of your application state, business, and UI logic reside on the server. Unlike client-driven frameworks, a Flow application never exposes its internals to the browser, where vulnerabilities could be abused by an attacker.
Flow automates the communication between server and client through a single, secure endpoint. This endpoint has multiple built-in security features, which we describe in the following chapters.
The following is an example in which we fetch sensitive user data from the database. However, we do not expose anything on the client that is not required:
User clicks a button in the UI to edit their own data, such as their name.
This click is caught with framework JavaScript and translated into these two entities that are sent to the server:
the unique ID of the
Button
instance (previously assigned sequentially by the framework);what was done with the button, in this case a click, with associated mouse details (what type of click it was, and the associated cursor position).
The data is sent to the server using the single server endpoint. The application server uses standard Servlet Session methods to locate the correct user session, which is then given to Vaadin along with the request payload.
Vaadin double-checks the session info and checks that a
Button
with the given ID exists. If it does, the server-side click handler for the button is invoked and given the event details.The server-side code fetches the user details from storage. This data does not need to be filtered at this point, but the developer can choose to do this, if necessary.
The developer chooses which parts of the data to show the user by setting it as the content for any components.
For example:
nameTextField.setValue(user.getName())
After the handler code has executed, Vaadin does not store any reference to the fetched data. Any data that is not specifically set to be displayed is therefore discarded, such as user ID or hashed passwords or salts.
Only the user name string is sent to the client to be displayed, not the full user object. The client is not even aware that there is a user object on the server side.
After the user has modified the name, the new value is sent back to the server. On the server, the developer can load the user object again, set the new name, and store the object.
As the example shows, the developer can safely handle confidential data in their code, even when dealing with UI code. The framework only stores data that the developer gives it explicitly. Only data that should be visible on the client is actually sent there.
Application State
In a Vaadin Flow application, the server is always aware of your application’s state. This means that, like client-side applications, the server is aware of what is currently visible on the end user’s screen. Hence, Vaadin denies actions to components that are not currently visible on the screen, or those that have been disabled on the server.
For instance, if the developer sets a component to be disabled, this effect is set on both the server and the client. On the client, an attacker can circumvent this, since attackers have full control over anything in the browser. However, the server will block any attempt to interact with the component and a warning is printed to the server logs.
Button button = new Button("Click me for effect!");
button.setEnabled(false);
button.addClickListener(e -> {
// If the Button is disabled, this listener will not run,
// even if an attacker enables the button client side.
});
Data Validation
In a Vaadin application, the data binding API supports data validation on the server, which cannot be bypassed by client-side attacks. Vaadin components do support client-side validation to increase the responsiveness of the application, but the developer should be aware that these should be used purely for convenience, since they are easily circumvented in the browser.
As with other web applications, all data coming from the client should always be validated once it reaches the server. It is not safe to rely only on client-side validation. Vaadin provides a set of pre-created server-side validators for this purpose. In addition, the developer is free to use any Java API for validating the data, including connecting to external services. Vaadin also has a built-in integration with Java’s Bean Validation (JSR 303) standard.
Data coming from a data store (such as a database) and inserted as HTML into DOM elements (for example, setting innerHTML
for elements or using HTML mode in component captions) should also be escaped.
Please see the chapter on XSS for more information.
Web Services
No public Web Services are necessary in Vaadin applications. All communication in Vaadin goes through a single HTTP request handler used for RPC requests using the standard Servlet Java API. With Vaadin, you never open up your business logic as Web Services and thus there are fewer attack entry points to your Vaadin application.
SSL and HTTPS
Vaadin always recommends developers to set up secure server endpoints and run all communication exclusively under HTTPS. Vaadin works out of the box with HTTPS, and there is nothing for the developer to configure in their application code. Please refer to the documentation of your servlet container for details on how to set up HTTPS on your server.
D23C116F-2ABD-425F-A604-7F2F69A52616