Secure By Default Scripting

Last modified by Michael Hamann on 2025/01/09 11:41

 XWiki
 Requirements
 Idea
 
 
No

Description

Introduction

The proposal is to introduce new scripting macros in XWiki that follow a "secure by default" approach where injected values are escaped by default, similar to modern UI frameworks like React or Vue.js. This approach aims to prevent security vulnerabilities that can be easily introduced in XWiki due to the behavior of Velocity, which doesn't escape output values. The goal is to make it easier to write secure code without requiring much thought. This secure-by-default approach has been shown to greatly increase the security in similar contexts.

Requirements

  1. Support for both XWiki syntax and HTML with similar syntax: The new macros should support both XWiki syntax and HTML, with similar syntax for parameters. This will allow developers to use the same syntax for both, reducing the learning curve.
  2. Easy injection of attributes and content: The macro should allow to easily use a value stored in a variable as attribute value or content of any element of HTML or XWiki syntax.
  3. Support for wiki macros in HTML: A syntax like <xwiki-macro macro-name="translation" macro-parameter-key="some.translation"> should allow using XWiki macros in HTML content. This makes it easy to use XWiki macros in places where we currently use Velocity macros to create re-usable components. To avoid cluttering the macro namespace it would make sense to introduce macros that are only available on-demand (e.g., after using a special "use" macro with the document defining the macro as parameter).
  4. Support for the existing script context: The new macros should support the existing script context. The existing scripting API as well as variables (and macros?) defined, e.g., in Velocity should be accessible.
  5. Limited execution similar to Velocity: The new scripting language should not allow arbitrary code execution but should have restrictions similar to Velocity such that it can be allowed without programming right.
  6. (Optional) Syntax not executed by Velocity: The syntax for the new macros should not be executed by Velocity. This prevents accidental execution in an insecure way when the macro is used inside a Velocity macro.

Implementation

The proposed solution is to create two new scripting macros, one for HTML and one for XWiki syntax. These macros would parse HTML or XWiki syntax first, then evaluate the scripts in the parameters in an XDOM transformation on the macro content. This would eliminate the need for manual escaping.

The syntax should follow what similar projects like Thymeleaf use. Examples could be for HTML

<input type="text" name="userName" value="James Carrot" th:value="${user.name}" />

or for XWiki syntax

(% xw:id="user.id" xw:text="user.name" %)
= User Name =

In the second example, the value of xw:text would become the content of the heading, replacing "User Name". Similarly, this could also support parameters in macros and references. Alternatively, extra syntax could be supported in the content to directly inject content there.

The implementation would involve two main steps:

  1. Creating a new HTML parser: This parser would be used to parse the content of the new macro as HTML, resulting in an XDOM. This would also involve introducing new block(s) to represent HTML elements for which there are no dedicated blocks yet (either new dedicated blocks or a generic block).
  2. Applying a transformation on the XDOM (coming either from HTML or XWiki syntax): This transformation would execute scripts found in parameters starting, e.g., with xw:. Depending on the name, it would either replace them with new parameters without the prefix or execute special actions like
    1. for loops (duplicates blocks)
    2. if/elseif/else (removes blocks conditionally)
    3. content: parses the result as plain text and adds it as child blocks except for macros, where it would be added as a string. With a special prefix it should also be possible to treat the provided content as raw input for a specified syntax. Further, it should also be possible that the script for the content returns XDOM blocks that are then directly inserted as children.
    4. Special handling for macro blocks where parameters are directly converted to the parameter type (e.g., directly pass a list of strings to the parameters of the translation macro, a UIX could be passed as object to a future version of some UIX macro).

The result would be a regular XDOM that can be further transformed and then rendered into any output syntax.

Note that while it is possible to just integrate Thymeleaf, this, at least out of the box has some problems:

  1. No support for XWiki syntax
  2. No protection against calling dangerous methods on the returned objects as we have for Velocity
  3. No support for XWiki macros

It needs to be investigated if these limitations could be solved.

Related Projects

JSX is a different but related approach to combining HTML and JavaScript code.


 

Get Connected