Skip to main content

Code reviews rule: Visualforce Cross-Site Scripting (XSS)

Written by David Martin
Updated this week

Visualforce Cross-Site Scripting (XSS)

Why is this an issue?

Cross-Site Scripting (XSS) vulnerabilities occur when dynamic data is output in Visualforce pages without proper encoding. An attacker could inject malicious code that executes in the context of the user's browser session, potentially stealing session tokens or performing actions as the user.

Examples

Inside Script Tags

Incorrect code:

<apex:page controller="MyController">
<script>
var userName = '{!userName}';
console.log('Hello, ' + userName);
</script>
</apex:page>

If userName contains '; alert('XSS'); //, it would break out of the string and execute arbitrary JavaScript.

Correct code:

<apex:page controller="MyController">
<script>
var userName = '{!JSENCODE(userName)}';
console.log('Hello, ' + userName);
</script>
</apex:page>

Inside Style Tags

Incorrect code:

<apex:page controller="MyController">
<style>
.user-theme {
background-color: {!userColor};
}
</style>
</apex:page>

Correct code:

<apex:page controller="MyController">
<style>
.user-theme {
background-color: {!HTMLENCODE(userColor)};
}
</style>
</apex:page>

Inside Event Attributes

Incorrect code:

<apex:page controller="MyController">
<div onclick="handleClick('{!userInput}')">Click me</div>
</apex:page>

Correct code:

<apex:page controller="MyController">
<div onclick="handleClick('{!JSINHTMLENCODE(userInput)}')">Click me</div>
</apex:page>

With escape="false"

Incorrect code:

<apex:page controller="MyController">
<apex:outputText value="{!userInput}" escape="false"/>
</apex:page>

If userInput contains <script>alert('XSS')</script>, it would execute in the user's browser.

Correct code:

<apex:page controller="MyController">
<!-- Option 1: Keep escaping enabled (default) -->
<apex:outputText value="{!userInput}"/>

<!-- Option 2: If you need HTML formatting, encode user input -->
<apex:outputText value="{!HTMLENCODE(userInput)}" escape="false"/>
</apex:page>

How can I fix violations?

Use the appropriate encoding function based on context:

Context

Encoding Function

Inside <script> tags

JSENCODE()

Inside <style> tags

HTMLENCODE()

Inside event attributes (onclick, etc.)

JSINHTMLENCODE()

With escape="false"

HTMLENCODE() or remove escape="false"

When should I disable this rule?

You may want to dismiss this issue if:

  • The value is guaranteed to be safe (e.g. a numeric ID or Boolean from a trusted source)

  • You have validated and sanitized the input in the controller

  • The value comes from a picklist or other controlled source

  • The content is static

Resources

Did this answer your question?