3

I've noticed that the way we escape data in templates is changing as part of 2.2

Escape functions for templates

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

The upcoming release of Magento 2.2 will deprecate these functions.

Please check back on this page after the 2.2 release for updated documentation on new escape functions.

But I can't find any info on how this will work in 2.2.

My question is, how will escaping output in templates work in 2.2? Or how does it currently work in 2.2 if you're reading this after 2.2 has been released.

Link to XSS on the dev docs

Ben Crook
  • 15,685
  • 3
  • 52
  • 104

1 Answers1

4

This docs could be changed, check latest version Template Security - Magento 2.2

Stay tuned — We'll roll out more 2.2 documentation updates in the coming weeks.


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:

 <?php echo $block->getTitleHtml() ?>
 <?php echo $block->getHtmlTitle() ?>
 <?php echo $block->escapeHtml($block->getTitle()) ?>
 <h1><?php echo (int)$block->getId() ?></h1>
 <?php echo count($var); ?>
 <?php echo 'some text' ?>
 <?php echo "some text" ?>
 <a href="<?php echo $block->escapeUrl($block->getUrl()) ?>"><?php echo $block->getAnchorTextHtml() ?></a>

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.

 <!-- In this example $postData is a JSON string -->
 <button class="action" data-post='<?php /* @noEscape */ echo $postData ?>' />

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 >.

<span class="label"><?php echo $block->escapeHtml($block->getLabel()) ?></span>

// Escaping translation
<div id='my-element'><?php echo $block->escapeHtml(__('Only registered users can write reviews. Please <a href="%1">Sign in</a> or <a href="%2">create an account</a>', $block->getLoginUrl(), $block->getCreateAccountUrl()), ['a']) ?></div>

Case: URL output

Function: escapeUrl

<a href="<?php echo $block->escapeUrl($block->getCategoryUrl()) ?>">Some Link</a>
<script>
  var categoryUrl = '<?php echo $block->escapeJs($block->escapeUrl($block->getCategoryUrl())) ?>';
</script>

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.

Case: Strings inside HTML attributes

Function: escapeHtmlAttr

<span class="<?php echo $block->escapeHtmlAttr($block->getSpanClass()) ?>">Product Description</span>
<input name="field" value="<?php echo $block->escapeHtmlAttr($block->getFieldValue()) ?>" />

<!--  Escaping translation inside attributes -->
<img src="product-blue.jpg" alt="<?php echo $block->escapeHtmlAttr(__('A picture of the product in blue')) ?>" />

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.

Mateusz Lerczak
  • 173
  • 2
  • 13
  • Yeah but the functions are still being used there, if they are deprecated then surely they shouldn't be using them in the example. So I presume the 2.2 docs haven't been updated fully yet. – Ben Crook Aug 30 '17 at 11:37
  • 1
    You are right @BenCrook, they are still upgrading docs. But I think they don't remove it after publish on 2.2 docs. Stay tuned — We'll roll out more 2.2 documentation updates in the coming weeks. – Mateusz Lerczak Aug 30 '17 at 11:40
  • Thanks, I'll see what is announced with 2.2 and mark your answer as correct if it is right when 2.2 is released. – Ben Crook Aug 30 '17 at 12:28