# Content Security Policy

CSP (Content Security Policy) has been introduced in WEM 4.2, enhancing the security of your WEM and web applications in general. However, CSP restricts certain common web features, requiring us to implement them differently to ensure they function correctly in a CSP-compliant environment. Below are some common cases that need to be updated for compatibility with CSP.

In Portal-Settings you can change the CSP Setting - choose between minimal and automatic.

* **Minimal**\
  This option is the standard for existing portals, which allows for inline custom javascripts, html attributes and CSS-styling using the Script Blocks or Custom HTML in your pages, as well as Widgets that also have inline custom scripts, attributes and styling. \
  What happens when you keep minimal: on every request the Content-Security-Policy header is just set to `default-src https: data: 'unsafe-eval' 'unsafe-inline'`.
* **Automatic**\
  This option is available for portals running on WEM Kubernetes Runtimes version 4.2 and newer. It provides an automatic higher level of Content Security, to help prevent various types of attacks, such as Cross-Site Scripting (XSS) and data injection attacks.\
  What happens when you activate Automatic: on every request, the server generates [nonces](https://content-security-policy.com/nonce/) and sends the Content-Security-Policy headers combining the settings from DevOps Portal, CSP-directives in the selected Design Template, nonce-based rules for scripts and styles, and any other CSP contributions, like from widgets (that can have their own specific CSP-related settings).

{% hint style="danger" %}
**BEWARE**: changing from minimal to automatic may change and even break your application if you have parts that are not CSP Compliant. Make sure to read our information (see links below) and make sure your pages have no custom inline scripts, html attributes or CSS-styling or other unsafe elements or links to external contents that may not be CSP-compliant. Make sure to properly check and test all parts of your application with the Automatic setting in Staging before publishing this option to Live!
{% endhint %}

{% hint style="info" %}
Other CSP-related information:

[Content Security Policy](/platform/wemreference/content-security-policy.md) reference, explaining specific WEM parts affected.\
[3. General](/platform/tutorials/building-widgets/basics/3-general.md#content-security-policy) in Widgets.\
[CSP](/platform/wemreference/wmt/reference/csp.md) in WMT - Design Templates.

[General CSP Quick Reference Guide](https://content-security-policy.com/nonce/)&#x20;
{% endhint %}

#### Startup Scripts, Script Modules, etc.

Fortunately, script blocks such as `startupscript`, `submitscript`, `unloadscript`, and `scriptmodule` do not require any modifications, as they are already trusted. However, a few unsafe functions and classes should not be used, as they can allow malicious code to be executed. We will discuss these cases below.

#### The Nonce Attribute

The nonce attribute is used in HTML to enhance security by preventing certain types of attacks, such as Cross-Site Scripting (XSS). It helps control which **scripts** and **styles** are allowed to run on a webpage, thereby improving the overall security posture of web applications. When a `<script>` or `<style>` tag includes a `nonce`, it indicates that the content is trusted and can be executed or applied. Implementing this in WEM is straightforward; simply add the `nonce` attribute and use the `CspNonce` magic constant as follows:

```html
<script nonce="<?attr CspNonce ?>"> console.log("Hello"); </script>
<style nonce="<?attr CspNonce ?>"> .my-cool-element { border-radius: 5px; } </style>
```

#### Inline Scripts

Inline scripts, such as JavaScript within an `onclick` attribute, must now be placed inside a trusted `<script>` block. This block should either be annotated with a `nonce` or run within a `startupscript`.

Previously, you might have written something like this:

```html
<button onclick="handler1()">Button 1</button>
<button onclick="handler2()">Button 2</button>
```

This is no longer allowed. Instead, the handlers should be defined in a JavaScript code block, as shown below:

```html
<button id="<?attr OutputId() ?>-btn1">Button 1</button>
<button id="<?attr OutputId() ?>-btn2">Button 2</button>
<? startupscript ?>
    document
        .getElementById(<?js OutputId() ?> + "-btn1")
        .addEventListener("click", () => handler1());

    document
        .getElementById(<?js OutputId() ?> + "-btn2")
        .addEventListener("click", () => handler2());
<? end ?>
```

#### JavaScript in Href

Another case that is considered an inline script, and is mostly used in design templates, is the use of JavaScript in the `href` attribute of an `<a>` tag. This is often used in conjunction with an `onclick` event to prevent navigation, as shown below:

```html
<a href="javascript:void(0)" onclick="navigateToHome()">Home</a>
```

This is an interesting scenario because using `href` styles the `<a>` element with a blue underline, similar to a normal link. If we remove the `href` attribute, this styling is lost. Depending on the situation, this may or may not be an issue. However, if we want to maintain the styling, what are our options?

We cannot simply set `href=""` because that will refresh the page, which is not our intention since we want to execute `navigateToHome()`. We could use `href="#"`, but this would cause the viewport to scroll to the top, which may not always be desirable. What about using `href="#0"`? In this case, if no `<a name="0">` exists, the viewport will not scroll. Unfortunately, the downside is that `#0` will be appended to the URL in the address bar, resulting in a URL like `https://website.com/#0`.

Another approach is to handle this with styling. Since we need to change the way we handle the `onclick` event, we can implement it as follows:

```html
<a id="home-button">Home</a>
<? startupscript ?>
    const linkEl = document.getElementById("home-button");
    linkEl.addEventListener("click", () => navigateToHome());
    linkEl.style.color = "linktext";
    linkEl.style.cursor = "pointer";
    linkEl.style.textDecoration = "underline linktext";
<? end ?>
```

Please select the option that best fits your situation.

#### Inline Styles

A similar restriction applies to inline styles. Styles defined within a `style` attribute are no longer permitted. Instead, styles should be added via an external CSS resource, a `<style>` block, or a trusted `<script>`.

For example, the style on this `<div>` will be ignored:

```html
<div style="color: tomato">Text 1</div>
<div style="color: lightgoldenrodyellow">Text 2</div>
```

If you have access to the design template, you can create a new CSS selector and use that class name:

```css
.color-tomato {
    color: tomato;
}

.color-lightgoldenrodyellow {
    color: lightgoldenrodyellow;
}
```

Then, in HTML:

```html
<div class="color-tomato">Text 1</div>
<div class="color-lightgoldenrodyellow">Text 2</div>
```

If you are dealing with a static HTML element and there is no alternative to using the `style` attribute, we recommend adding a `<style>` block with a `nonce`, along with an `id` attribute using `OutputId()` like this:

```html
<div id="<?attr OutputId() ?>-txt1">Text 1</div>
<div id="<?attr OutputId() ?>-txt2">Text 2</div>
<style nonce="<?attr CspNonce ?>">
    #<?= OutputId() ?>-txt1  {
        color: tomato;
    }
    #<?= OutputId() ?>-txt2 {
        color: lightgoldenrodyellow;
    }
</style>
```

Depending on the situation, you can also apply styles using JavaScript:

```html
<div id="<?attr OutputId() ?>-txt1">Text 1</div>
<div id="<?attr OutputId() ?>-txt2">Text 2</div>
<? startupscript ?>
    document
        .getElementById(<?js OutputId() ?> + "-txt1")
        .style.color = "tomato";

    document
        .getElementById(<?js OutputId() ?> + "-txt2")
        .style.color = "lightgoldenrodyellow";
<? end ?>
```

A keen observer will notice that we used two buttons or divs as examples of how to handle these cases when we have multiple elements. If you only need to update the code for a single HTML element, you can simply use `<?attr OutputId() ?>` instead of an identifier like `<?attr OutputId() ?>-btn1`.

Please note that there are multiple ways to address these styling issues, and depending on the situation, you may need to consider alternatives. However, one approach can be somewhat misleading, and it is as follows:

```html
<div class="example" id="<?attr OutputId() ?>">Text</div>
<? startupscript ?>
    const exampleElement = document.getElementBy(<?js OutputId() ?>);
    
    // This will result in a CSP violation.
    exampleElement.setAttribute("style", "background: tomato; color: white;");

    // However this works.
    exampleElement.style.cssText = "background: tomato; color: white;";
<? end ?>
```

#### Script Evaluation

In JavaScript, script evaluation refers to the process of executing a string as JavaScript code. This practice poses significant security risks, especially when the string contains user input. For this reason, script evaluation is disallowed under CSP.

The following code examples are no longer permitted:

```javascript
// The use of eval is evil.
const userInput = "console.log('Hi mom, I can hack!'); 2 + 2";
const result = eval(userInput);

// This will not function.
const add = new Function("a", "b", "return a + b");

// Using setTimeout() or setInterval() with a string as the first argument is not allowed.
setTimeout("console.log('Bad stuff');", 100);
```

By avoiding script evaluation and adhering to CSP guidelines, you can significantly enhance the security of your web applications.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.wem.io/platform/wemreference/content-security-policy.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
