Availability | Confluence 4.0 or later |
Starting from Confluence 4.0, the Anti-XSS protection for plugins is enabled by default, but in rare cases, when this configuration change breaks an existing plugin, plugin authors might need to take action to ensure that their plugin still works.
Anti-XSS is a safeguard placed on Velocity template files that automatically HTML encodes inserted variables, therefore protecting against potential cross-site scripting vulnerabilities. It was introduced in Confluence 2.9, then enabled by default in Confluence 3.0 for core Confluence, and then enforced for Confluence core and plugins in Confluence 4.0. It does not apply to any other HTML output generated by plugins. For more information, read the Anti-XSS documentation.
Cross-site scripting is a real and dangerous security problem with many web applications. Anti-XSS protects against many potential sources of XSS vulnerabilities. Opting in to Anti-XSS protection requires very little effort and results in a safer plugin.
Starting from Confluence 4.0, Anti-XSS applies to Confluence plugins by default.
There are three mechanisms to mark that your Velocity template should have Anti-XSS protection applied to it:
.html.vm
suffix (i.e. mypage.html.vm
).html
directory (that is, /templates/html/mypage.vm
).#htmlSafe()
somewhere in the template.If you do any (or any combination) of the items mentioned, any variable substitution performed in your Velocity template will be always HTML-encoded under the rules described in the Anti-XSS documentation.
The enforced HTML encoding may cause some plugins to stop functioning correctly. The symptoms include the following:
Starting from Confluence 4.0, HTML encoding is on for plugins by default.
We'd recommend that as much of your HTML markup is contained in actual Velocity templates. However, some templates acquire HTML markup via method calls and property access to Java objects in the Velocity context, and very often the result is written directly to the output of the template. In this situation, we need to inform the Velocity renderer that these values are intended to contain HTML and should not be encoded when written.
There are a few ways to accomplish this.
HtmlSafe
method annotationFor values retrieved by calling methods or accessing properties of objects in the context, it is possible to inform
the Velocity system that these values are safe to be written without encoding. Achieve this by annotating the method
(whether a property getter or not) with the HtmlSafe
annotation.
Here is an example of an annotated Java class.
1 2import com.atlassian.velocity.htmlsafe.HtmlSafe; public class MyContextClass { @HtmlSafe public String myMarkupReturningMethod() { return "<b>This method returns marked up text!</b>"; } public String myMethodWithAnXssExploit() { return "<script>alert('owned');</script>"; } }
This is the example of using an instance of this class in a template.
1 2<ol> <li>$objectOfMyContextClass.myMarkupReturningMethod() <li>$objectOfMyContextClass.myMethodWithAnXssExploit() </ol>
This is the result when Anti-XSS is disabled.
1 2<ol> <li><b>This method returns marked up text!</b> <li><script>alert('owned');</script> </ol>
This is the result when Anti-XSS is enabled.
1 2 3 4 5<ol> <li><b>This method returns marked up text!</b> <li><script>alert('owned');</script> </ol>
Retrofitting this type of behavior into an existing significant codebase with an extensive plugin catalog is very difficult.
We'd like to make this new behavior fit in as well as possible with the existing body of work. For this reason,
certain methods are automatically deemed as HtmlSafe
:
render
or getRender
.Html
.This strategy fits in with the observation that many of the existing methods that return HTML were named according to this convention.
A few often used methods are known to return HTML by contract. These methods are therefore also treated as HtmlSafe
by default.
com.atlassian.confluence.util.HtmlUtil#htmlEncode
This means that any uses of these methods will behave identically whether the Anti-XSS mode is engaged.
To cater for cases where HTML strings are built entirely in a Velocity template and then rendered, you can avoid
the auto encoder by using a Html
suffix for the reference name.
This is the template.
1 2#set ($someHtml = "<p>This is a paragraph</p>") #set ($some = $someHtml) <ul> <li>$someHtml <li>$some </ul>
This is the output.
1 2 3 4 5<ul> <li><p>This is a paragraph</p> <li><p>This is a paragraph</p> </ul>
The Velocity template reference $body
also avoids automatic encoding. Many templates use this convention to include
whole slabs of HTML sourced from other rendering mechanisms. This exclusion is very likely to be removed in the future,
so it is strongly recommended that all such references are changed to make use of the standard Html
suffix as described previously.
Disable Anti-XSS
directive in a Velocity templateAdd the following Velocity directive to your template:
1 2#disableAntiXss()
This will prevent variables in your template from being HTML encoded automatically.
To ensure that your HTML markup will function correctly, follow these guidelines on working with the Anti-XSS feature:
HtmlSafe
. Before using, methods that return HTML markup that cannot be contained in
templates, such as data sourced from user input or other remote retrieval, need to be marked as HtmlSafe
or assigned to
a Velocity reference ending in the string Html
. Consider using the HtmlFragment
class for a richer, HtmlSafe
description of the data that you return. The fewer sources of HtmlSafe
data are used, the better the security of the system is.$body
reference encoding exclusion. To keep the system as
consistent as possible, change usages of $body
in templates that include HTML fragments to use either a Html
suffix or the HtmlFragment
class.Developers interested in advanced details and use-cases should consult the Advanced HTML encoding documentation.
As much as we'd love to make the new HTML encoding system transparent to use, there are a few things that you need to watch out for.
With Velocity configuration of Confluence, you can use reference interpolation in any strings you construct in a Velocity template.
1 2#set ($myVar = "<p>Here is a paragraph</p>") #set ($myHtml = "$myVar <p>A second paragraph</p>") Here it is: $myHtml
1 2Here it is: <p>Here is a paragraph</p> <p>A second paragraph</p>
As can be seen from the example, automatic HTML encoding will occur when references are interpolated inside strings in the same manner as when they are written to the template output. At present, there is no way to treat this case specially and you will need to make sure that any data used as part of interpolation is treated correctly by the encoder.
Occasionally, you might have some code in your velocity template that makes a call back to some Java logic. To make sure that the value is protected by the Anti-XSS mechanism, you must have the string evaluated within the Velocity template. If not, you will pass a reference into the Java code that will not be protected.
You should write the Velocity template like this:
1 2$object.doSomething("$action.getValue()")
The quotes around the $action.getValue()
call mean that Velocity will evaluate it before passing it into object.doSomething()
,
and it will have a chance to be automatically encoded before being passed to the Java method.
Templates rendered from a Struts Velocity result can access values on the Struts action stack as if they are entries in
the Velocity context. If these values are sourced from getter methods on the current action, the automatic encoding
system cannot detect whether the getter method has been marked as HtmlSafe
. In this situation, the value will be
automatically encoded when rendered, regardless of any annotation or method naming convention used by the source of the value.
To fix this, you can do one of the following:
HtmlSafe
reference naming convention (for example, assigning the action context value to a
context variable ending with Html
before rendering).$action
reference.Some Java code may use the Velocity context as a data passing mechanism to collect information from a template after it is rendered.
1 2public class DataHolder { @HtmlSafe public String getHtml() { return "<strong>My html</strong>"; } }
myTemplate
1 2#set ($result = data.getHtml()) ...
1 2Template myTemplate = getTemplate(); Context myContext = new VelocityContext(); myContext.put("data", new DataHolder()); renderTemplate(myTemplate, myContext); String message = (String) myContext.get("result");
The previous Java code will fail with a ClassCastException
at runtime because the reference $result
will not
be an instance of String
but an instance of BoxedValue
due to the way that Confluence Velocity runtime handles
HtmlSafe
values in the Velocity context. If there is demand, type compatibility can be restored using a transparent
unboxing context layer, but in general, this mechanism of information passing is discouraged. Context values that
are not set from HtmlSafe
sources are not affected in this situation.
For this mode of behavior, there are two parts of the system:
You may notice that the #htmlSafe()
velocity directive (which causes a template to opt in to Anti-XSS protection)
has the opposite meaning to the @HTMLSafe
Java annotation (which causes a Java method to opt out of Anti-XSS protection).
We regret this confusing naming and hope to fix it in a future release. We will, however, ensure that #htmlSafe()
continues to work.
Rate this page: