aboutsummaryrefslogtreecommitdiffstats
path: root/documentation/advanced/advanced-security.asciidoc
blob: e04a3bc06779064e022ea3a8fe4a4b67caeb2b1b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
---
title: Common Security Issues
order: 8
layout: page
---

[[advanced.security]]
= Common Security Issues

[[advanced.security.sanitizing]]
== Sanitizing User Input to Prevent Cross-Site Scripting

You can put raw HTML content in many components, such as the [classname]#Label#
and [classname]#CustomLayout#, as well as in tooltips and notifications. In such
cases, you should make sure that if the content has any possibility to come from
user input, you must make sure that the content is safe before displaying it.
Otherwise, a malicious user can easily make a
link:http://en.wikipedia.org/wiki/Cross-site_scripting[cross-site scripting
attack] by injecting offensive JavaScript code in such components. See other
sources for more information about cross-site scripting.

Offensive code can easily be injected with [literal]#++<script>++# markup or in
tag attributes as events, such as [parameter]#onLoad#.

// TODO Consider an example, Alice, Bob, etc.

Cross-site scripting vulnerabilities are browser dependent, depending on the
situations in which different browsers execute scripting markup.

Therefore, if the content created by one user is shown to other users, the
content must be sanitized. There is no generic way to sanitize user input, as
different applications can allow different kinds of input. Pruning (X)HTML tags
out is somewhat simple, but some applications may need to allow (X)HTML content.
It is therefore the responsibility of the application to sanitize the input.

Character encoding can make sanitization more difficult, as offensive tags can
be encoded so that they are not recognized by a sanitizer. This can be done, for
example, with HTML character entities and with variable-width encodings such as
UTF-8 or various CJK encodings, by abusing multiple representations of a
character. Most trivially, you could input [literal]#++<++# and [literal]#++>++#
with [literal]#++&lt;++# and [literal]#++&gt;++#, respectively. The input could
also be malformed and the sanitizer must be able to interpret it exactly as the
browser would, and different browsers can interpret malformed HTML and
variable-width character encodings differently.

Notice that the problem applies also to user input from a
[classname]#RichTextArea# is transmitted as HTML from the browser to server-side
and is not sanitized. As the entire purpose of the [classname]#RichTextArea#
component is to allow input of formatted text, you can not just remove all HTML
tags. Also many attributes, such as [parameter]#style#, should pass through the
sanitization.
f0f0 } /* Literal.String.Char */ .highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */ .highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */ .highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */ .highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */ .highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */ .highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */ .highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */ .highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */ .highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */ .highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */ .highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */ .highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */ .highlight .vc { color: #336699 } /* Name.Variable.Class */ .highlight .vg { color: #dd7700 } /* Name.Variable.Global */ .highlight .vi { color: #3333bb } /* Name.Variable.Instance */ .highlight .vm { color: #336699 } /* Name.Variable.Magic */ .highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */
---
title: Compiling a Client-Side Module
order: 4
layout: page
---

[[clientside.compiling]]
= Compiling a Client-Side Module

A client-side module, either a Vaadin widget set or a pure client-side module, needs to be compiled to JavaScript using the Vaadin Client Compiler.

Widget set compilation is most often needed when using add-ons.
In that case, the widget sets from different add-ons are compiled into an _application widget set_, as described in <<dummy/../../../framework/addons/addons-overview.asciidoc#addons.overview, "Using Vaadin Add-ons">>.

When doing client-side development, you need to compile the widget set every time you modify the client-side code.

[[clientside.compiling.overview]]
== Vaadin Compiler Overview

The Vaadin Client Compiler compiles Java to JavaScript.
It is provided as the executable [filename]#vaadin-client-compiler# JAR.
// You can run it with the [literal]#++-jar++# parameter for the Java runtime.
It requires the [filename]#vaadin-client# JAR, which contains the [classname]#DefaultWidgetSet#, Vaadin client-side framework.

The compiler compiles a _client module_, which can either be a pure client-side module or a Vaadin widget set, that is, the Vaadin Client-Side Engine that includes the widgets used in the application.
The client module is defined with a module descriptor, which was described in <<clientside-module#clientside.module, "Client-Side Module Descriptor">>.
The module descriptor for application widget sets is automatically generated.

While you can compile client modules individually, in Vaadin applications you normally combine them in one application widget set.
The application widget set includes any add-on and custom widgets.
The compiler scans the class path for any widget sets to include in the application widget set.

=== Compilation Result

The compiler writes the compilation result to a target folder that will include the compiled JavaScript with any static resources included in the module.

[[clientside.compiling.maven]]
== Compiling in Maven Projects

The Vaadin Maven Plugin, which is enabled in all Vaadin archetypes, makes Maven to automatically compile the widget set when necessary.

ifdef::web[]
=== Plugin Configuration

[source,xml]
----
<plugin>
  <groupId>com.vaadin</groupId>
  <artifactId>vaadin-maven-plugin</artifactId>
  <version>${vaadin.plugin.version}</version>

  <configuration>
    <extraJvmArgs>-Xmx512M -Xss1024k</extraJvmArgs>
    <webappDirectory>${basedir}/target/classes/VAADIN/widgetsets</webappDirectory>
    <draftCompile>false</draftCompile>
    <compileReport>false</compileReport>
    <style>OBF</style>
    <strict>true</strict>
  </configuration>

  <executions>
    <execution>
      <goals>
        <goal>update-theme</goal>
        <goal>update-widgetset</goal>
        <goal>compile</goal>
        <goal>compile-theme</goal>
      </goals>
    </execution>
  </executions>
</plugin>
----
endif::web[]

[[clientside.compiling.maven.modes]]
=== Compilation Modes

The Vaadin Maven Plugin can compile widget sets either locally or online by using a cloud service.
The online compilation requires that all the widget sets are available in certain public Maven repositories.
As this is not the case when developing custom widgets, you must use the `local` mode.

Local compilation is the default mode, so you only need to enable it if you have changed the mode to use the online service.

See <<DUMMY/../../addons/addons-maven#addons.maven.modes, "Widget Set Modes">> for more information.

[[clientside.compiling.maven.compiling]]
=== Compiling

You can explicitly compile the widget set with the [literal]#vaadin:compile# goal.

On command-line:

[subs="normal"]
----
[prompt]#$# [command]#mvn# [parameter]#vaadin:compile#
----

If there is no widget set defined, but you have add-on dependencies that need a
custom widget set, the Vaadin Maven plugin will automatically generate a widget set definition for you.

[[clientside.compiling.eclipse]]
== Compiling in Eclipse

When you have the Vaadin Plugin installed in Eclipse, you can simply click the *Compile Vaadin Widgetset* button in the toolbar.

.Widget set compilation button in Eclipse
image::img/widgetset-compiling-toolbar.png[width=50%, scaledwidth=60%]

It will compile the widget set it finds from the project.
If the project has multiple widget sets, such as one for custom widgets and another one for the project, you need to select the module descriptor of the widget set to compile before clicking the button.

Compiling with the Vaadin Plugin for Eclipse currently requires that the module descriptor has suffix [filename]#Widgetset.gwt.xml#, although you can use it to compile also other client-side modules than widget sets.

The result is written under [filename]#WebContent/VAADIN/widgetsets# folder.

ifdef::web[]
[[clientside.compiling.ant]]
== Compiling with Ant

Consider the following configuration:

[source, xml, subs="normal"]
----
<target name="configure">
    <!-- Where project source files are located -->
    <property name="sources" value="[replaceable]#src#" />

    <!-- Path to root of web application folder -->
    <property name="webroot" value="[replaceable]#WebContent#" />

    <!-- Compilation work directory -->
    <property name="workdir" value="[replaceable]#build/work#"/>
</target>
----

The script assumes the Eclipse project layout with [filename]#WebContent# folder.

The `compile-widgetset` target invokes the Vaadin Compiler to compile the widget set.
The class path includes source folder in case there are custom widgets, compiled server-side classes, and the dependencies resolved with Ivy.

[source, xml]
----
<target name="compile-widgetset" depends="init,resolve">
    <java classname="com.google.gwt.dev.Compiler"
          failonerror="yes" fork="yes">
        <arg value="-war" />
        <arg value="${webroot}/VAADIN/widgetsets" />
        <arg value="${widgetset}" />
        <arg value="-logLevel"/>
        <arg value="INFO"/>
        <!-- <arg value="-strict"/> -->
        <jvmarg value="-Xmx1024M"/>
        <jvmarg value="-Xss512M"/>
        <jvmarg value="-Djava.awt.headless=true"/>

        <classpath>
            <!-- Location of source code -->
            <pathelement path="${sources}" />

            <!-- Compiled server-side classes -->
            <pathelement path="${workdir}/WEB-INF/classes" />

            <!-- Dependencies retrieved with Ivy -->
            <path refid="ivy.deps.widgetset"/>
        </classpath>
        <sysproperty key="vFailIfNotSerializable" value="${failifnotserializable}" />
    </java>

    <!-- Cleanup -->
    <delete dir="${webroot}/VAADIN/gwt-unitCache"/>
    <delete dir="${webroot}/VAADIN/widgetsets/WEB-INF"/>
</target>
----

You can copy the example build script to your project and, once configured, run it with Ant.
You may need to do some configuration in the build targets, such as to exclude or include source or target paths.
endif::web[]