Skip to content

Latest commit

 

History

History
142 lines (91 loc) · 6.01 KB

template-security.md

File metadata and controls

142 lines (91 loc) · 6.01 KB
layout group subgroup title menu_title menu_order version github_link
default
fedg
C_Templates
Templates XSS security
Templates XSS security
5
2.2
frontend-dev-guide/templates/template-security.md

Security measures against XSS attacks

To prevent XSS issues Magento recommends the following rules for escaping output in templates:

  • If a method indicates that the content is escaped, do not escape: getTitleHtml(), getHtmlTitle() (the title is ready for the HTML output)

  • Type casting and php function count() don't need escaping (for example echo (int)$var, echo (bool)$var, echo count($var))

  • Output in single quotes doesn't need escaping (for example echo 'some text')

  • Output in double quotes without variables doesn't need escaping (for example echo "some text")

  • For all other cases, escape the data using specific escape functions.

The following code sample illustrates the XSS-safe output in templates:

{% highlight php %}

getTitleHtml() ?> getHtmlTitle() ?> escapeHtml($block->getTitle()) ?>

getId() ?>

getAnchorTextHtml() ? > {% endhighlight %}

Escape functions for templates

For the following output cases, use the specified function to generate XSS-safe output.

Case: JSON output\ Function: No function needed for JSON output.

{% highlight html %}

{% endhighlight %}

Case: String output that should not contain HTML\ Function: escapeHtml

You can pass in an optional array of allowed tags that will not be escaped.

If a tag is allowed, the following attributes will not be escaped: id, class, href, target, style and title. Any other attribute for that allowed tag will be escaped.

embed, iframe, video, source, object, audion, script and img tags will not be allowed regardless of the content of this array.

If your text contains special characters, they must be encoded as HTML entities, such as &lt; for < or &gt; for >.

{% highlight html %} escapeHtml($block->getLabel()) ?>

// Escaping translation

escapeHtml(__('Only registered users can write reviews. Please Sign in or create an account', $block->getLoginUrl(), $block->getCreateAccountUrl()), ['a']) ?>

{% endhighlight %}

Case: URL output\ Function: escapeUrl

{% highlight html %} Some Link

<script> var categoryUrl = 'escapeJs($block->escapeUrl($block->getCategoryUrl())) ?>'; </script>

{% endhighlight %}

Case: Strings inside JavaScript\ Function: In a JavaScript context, use the escapeJs function.

In cases where the JavaScript code outputs content onto the page, use the escapeUrl or the escapeHtml function where appropriate.

For example, when a URL output string is inside a JavaScript context, use both escapeJs and escapeUrl. If you insert the output string from inside a JavaScript context into the DOM, use both escapeJs and escapeHtml.

{% highlight javascript %} var fieldescapeJs($block->getFieldNamePostfix()) ?> = window.document.getElementById('my-element');

var categoryUrl = 'escapeJs($block->escapeUrl($block->getCategoryUrl())) ?>';

// Escaping content that will be inserted into DOM var string = escapeJs($block->escapeHtml(__('Only registered users can write reviews. Please Sign in or create an account', $block->getLoginUrl(), $block->getCreateAccountUrl()), ['a'])) ?> jQuery('#my-element').append(string);

// Here we are not inserting the translated string into the DOM, so it is ok if the string contains non-allowed tags or // JavaScript because it will be handled as a string. Do not use escapeHtml here, the browser will display quotes // and other symbols as HTML entities (', ", &, etc) alert('escapeJs(__('You are not authorized to perform this action.')) ?>'); {% endhighlight %}

Case: Strings inside HTML attributes\ Function: escapeHtmlAttr

{% highlight html %} Product Description

<?php echo $block->escapeHtmlAttr(__('A picture of the product in blue')) ?>

{% endhighlight %}

Static Test

To check your template for XSS vulnerabilities, you can use the static test XssPhtmlTemplateTest.php in dev\tests\static\testsuite\Magento\Test\Php\.

This static test finds all echo calls in PHTML-templates and determines if the output is properly escaped.

It covers the following cases:

  • /* @noEscape */ before output. Output doesn't require escaping. Test is green.

  • Methods which contain "html" in their names (for example echo $object->{suffix}Html{postfix}()). Data is ready for the HTML output. Test is green.

  • AbstractBlock methods escapeHtml, escapeHtmlAttr, escapeUrl, escapeJs are allowed. Test is green.

  • Type casting and php function count() are allowed (for example echo (int)$var, (bool)$var, count($var)). Test is green.

  • Output in single quotes (for example echo 'some text'). Test is green.

  • Output in double quotes without variables (for example echo "some text"). Test is green.

  • Other of previously mentioned. Output is not escaped. Test is red.