Skip to the content.

Prevent Cross Script (XSS) vulnerability

  1. Reflexive XSS: Escape assigned variable on a Smarty templates
  2. Stored XSS from front to back
  3. Content Security Policies
  4. None secure svg files

XSS, or Cross-Site Scripting, is a type of web vulnerability where an attacker injects malicious scripts into web pages viewed by other users. These scripts can be executed in the context of the victim’s browser, allowing the attacker to steal sensitive information, perform actions on behalf of the victim, or otherwise compromise the security and integrity of the affected website.

It’s important for web developers and website owners to understand the dangers of XSS and implement proper security measures, such as input validation, output encoding, and other security best practices, to prevent XSS attacks and protect the security and privacy of their users. Regular security audits and testing can help identify and address XSS vulnerabilities in web applications.

IMPORTANT: There is no “perfect” protection against XSS, it is a polymorphic threat, which is constantly evolving. At any time, what was safe, becomes critically risky on an improbable dependency which adds an equally improbable event.

Reflexive XSS: Escape assigned variable on a Smarty templates

Reflected XSS, also known as non-persistent XSS, is a type of cross-site scripting vulnerability where an attacker injects malicious scripts into a website, and these scripts are then reflected back to users by the website’s server without proper sanitization. When a user visits the affected website and the malicious scripts are executed in their browser, it can lead to the execution of arbitrary code or other malicious activities.

Case <span>{$variable}</span>

The assign value of $variable can be: <script>alert(123);</script>.

In the front-office PrestaShop 1.7 and 8+ :

Filter smarty Render on source
{$variable nofilter} Exposed to a XSS: <script>alert(123)</script>
{$variable} &lt;script&gt;alert(123);&lt;/script&gt;
{$variable|escape:'quotes'} &lt;script&gt;alert(123);&lt;/script&gt;
{$variable|html_entity_decode} &lt;script&gt;alert(123);&lt;/script&gt;
{$variable|htmlspecialchars} &amp;lt;script&amp;gt;alert(123);&amp;lt;/script&amp;gt;
{$variable|htmlspecialchars_decode:3} &lt;script&gt;alert(123);&lt;/script&gt;
{$variable|strip_tags:false} alert(123);
{$variable|cleanHtml} ` `
{$variable|escape:'html'} &lt;script&gt;console.log(123);&lt;/script&gt;
{$variable|escape:'htmlall':'UTF-8'} &lt;script&gt;console.log(123);&lt;/script&gt;

In conclusion, escape a variable in a front template is not mandatory. Please note the behaviour is not the same with PrestaShop 1.6.

In the backoffice PrestaShop 1.7 and 8+ :

Filter smarty Render on source
{$variable nofilter} Exposed to a XSS: <script>alert(123)</script>
{$variable} Exposed to a XSS: <script>alert(123)</script>
{$variable|escape:'quotes'} Exposed to a XSS: <script>alert(123)</script>
{$variable|html_entity_decode} Exposed to a XSS: <script>alert(123)</script>
{$variable|htmlspecialchars_decode:3} Exposed to a XSS: <script>alert(123)</script>
{$variable|strip_tags:false} alert(123);
{$variable|cleanHtml} ` `
{$variable|htmlspecialchars} &lt;script&gt;alert(123);&lt;/script&gt;
{$variable|escape:'html'} &lt;script&gt;alert(123);&lt;/script&gt;
{$variable|escape:'htmlall':'UTF-8'} &lt;script&gt;alert(123);&lt;/script&gt;

In conclusion, escaping with |escape:'htmlall':'UTF-8' is mandatory to prevent XSS executions.

Case <span data-attribute="{$variable}">Test</span>

The assign value of $variable can be: " onmouseover="alert(123);.

In the front-office PrestaShop 1.7 and 8+ :

Filter smarty Render on source
{$variable nofilter} Exposed to a XSS: <span class="" data-attribute="" onmouseover="alert(123);">Test</span>
{$variable} &quot; onmouseover=&quot;alert(123)
{$variable|escape:'quotes'} &quot; onmouseover=&quot;alert(123)
{$variable|html_entity_decode} E&quot; onmouseover=&quot;alert(123)
{$variable|htmlspecialchars} &quot; onmouseover=&quot;alert(123)
{$variable|htmlspecialchars_decode:3} &quot; onmouseover=&quot;alert(123)
{$variable|strip_tags:false} &quot; onmouseover=&quot;alert(123)
{$variable|cleanHtml} ` `
{$variable|escape:'html'} &quot; onmouseover=&quot;alert(123)
{$variable|escape:'htmlall':'UTF-8'} &quot; onmouseover=&quot;alert(123)

In the backoffice PrestaShop 1.7 and 8+ :

Filter smarty Render on source
{$variable nofilter} Exposed to a XSS: <span class="" data-attribute="" onmouseover="alert(123);">Test</span>
{$variable} Exposed to a XSS: <span class="" data-attribute="" onmouseover="alert(123);">Test</span>
{$variable|escape:'quotes'} Exposed to a XSS: <span class="" data-attribute="" onmouseover="alert(123);">Test</span>
{$variable|html_entity_decode} Exposed to a XSS: <span class="" data-attribute="" onmouseover="alert(123);">Test</span>
{$variable|htmlspecialchars_decode:3} Exposed to a XSS: <span class="" data-attribute="" onmouseover="alert(123);">Test</span>
{$variable|strip_tags:false} Exposed to a XSS: <span class="" data-attribute="" onmouseover="alert(123);">Test</span>
{$variable|cleanHtml} ` `
{$variable|htmlspecialchars} &quot; onmouseover=&quot;alert(123)
{$variable|escape:'html'} &quot; onmouseover=&quot;alert(123)
{$variable|escape:'htmlall':'UTF-8'} &quot; onmouseover=&quot;alert(123)

In conclusion, escaping with |escape:'htmlall':'UTF-8' is mandatory to prevent XSS executions.

Please note that:

In a twig template :

DO:


<p>{{$comment.content|e}}</p>

Stored XSS from front to back

Stored XSS, also known as persistent XSS or Type 2 XSS, is a type of cross-site scripting vulnerability where an attacker injects malicious scripts into a website, and these scripts are stored on the server-side and then retrieved and executed by other users when they visit the affected website. Unlike reflexive XSS, which involves immediate reflection of the malicious script back to the user, stored XSS allows the malicious script to be persisted on the server and can affect multiple users over an extended period of time.

The PrestaShop weakness come from a frontoffice form, stored in database and executed in the backoffice. This kind of XSS are dangerous because an attacker can inject a malicious javascript that create a new employee or import a malware as a module.

To prevent this kind of vulnerability, you need escape properly your template as seen previously, but you need also validate your data to avoid to store XSS on your database.

First, we recommand to create an object model and use save(), add() and update() method this object model instead of creating INSERT UPDATE or REPLACE sql request to manage your data.

// MyModuleObjectModel
 public  static  $definition = [
     'table' => 'mymoduletable',
     'primary' => 'id_mymoduletable',
     'fields' => [
         'id_customer' => [
             'type' => self::TYPE_INT, 
             'validate' => 'isUnsignedInt', 
             'required' => true, 
             'size' => 10,
         ],
         'content' => [
             'type' => self::TYPE_HTML, 
             'validate' => 'isCleanHtml',
             'required' => false,
             'size' => 128,
         ],
     ],
 ];

List of PrestaShop validations for previous malicious pattern :

Validate <script>alert(123)</script> Return
Validate::isName() false
Validate::isMailName false
Validate::isMessage false
Validate::isAddress false
Validate::isGenericName false
Validate::isCleanHtml false
Validate::isPasswd true
Validate::isPlaintextPassword true
Validate::isHashedPassword false
Validate::isUrl false
Validate::isUrlOrEmpty false
Validate::isString true
Validate::isAnything true
Validate::isLabel false
Validate::isTabName false
Validate::isVoucherDescription false
Validate::isMailSubject false
Validate::isPhpDateFormat false
Validate " onmouseover="alert(123); Return
Validate::isName false
Validate::isMailName false
Validate::isMessage true
Validate::isAddress false
Validate::isGenericName false
Validate::isCleanHtml false
Validate::isPasswd true
Validate::isPlaintextPassword true
Validate::isHashedPassword false
Validate::isUrl false
Validate::isUrlOrEmpty false
Validate::isString true
Validate::isLabel true
Validate::isTabName true
Validate::isVoucherDescription true
Validate::isMailSubject true
Validate::isPhpDateFormat true

In conclusion, avoid isString isAnything isLabel isMessage

We recommand for data comming from front office to use isCleanHtml. This forbid all html tags and suspicious html attributes.

Content Security Policies

Content-Security-Policy (CSP) is an HTTP response header that browsers use to enhance the security of the page. The Content-Security-Policy header allows you to restrict which resources (such as JavaScript, CSS, Images, etc.) can be loaded, and the URLs that they can be loaded from.

It’s recommanded to apply on PrestaShop websites CSP.

You can read CSP

None secure svg files

SVG files can contain javascript that can be executed if you load with your browser the SVG.




go left Prevent sensitive data disclosure go back go up Prevent logical weakness go right