Upgrade to Pro — share decks privately, control downloads, hide ads and more …

JSHeroes '18 - XSS, CSRF, CSP, JWT, WTF? IDK ¯\_(ツ)_/¯

JSHeroes '18 - XSS, CSRF, CSP, JWT, WTF? IDK ¯\_(ツ)_/¯

Slides of my talk at JSHeroes 2018. More info at github.com/dkundel/intro-web-security

Dominik Kundel

April 19, 2018
Tweet

More Decks by Dominik Kundel

Other Decks in Programming

Transcript

  1. XSS, CSRF, CSP, JWT, WTF? IDK ¯\_( ツ)_/¯ Dominik Kundel

    - @dkundel Dominik Kundel | @dkundel | #jsheroes #websec #onesiejs
  2. XSS, CSRF, CSP, JWT, WTF? IDK ¯\_( ツ)_/¯ Dominik Kundel

    - @dkundel Dominik Kundel | @dkundel | #jsheroes #websec #onesiejs
  3. ⁇ XSS ⁇ ⁇ CSRF ⁇ ⁇ CSP ⁇ ⁇

    JWT ⁇ Dominik Kundel | @dkundel | #jsheroes #websec #onesiejs
  4. I THOUGHT OF EVERYTHING Only HTTPS powered by Let's Encrypt

    It even uses HSTS (HTTP Strict Transport Security) no mixed content Sanitized HTML No room for SQL injections Dominik Kundel | @dkundel | #jsheroes #websec #onesiejs
  5. NO REAL DATABASE NO REAL DATABASE INJECTIONS Dominik Kundel |

    @dkundel | #jsheroes #websec #onesiejs
  6. USE HttpOnly COOKIES // Make cookies HTTP only res.cookie('authToken', jwt,

    { httpOnly: true, signed: true, secure: true }); Dominik Kundel | @dkundel | #jsheroes #websec #onesiejs
  7. USE SAFE JWT IMPLEMENTATIONS const jwt = require('jsonwebtoken'); jwt.verify(token, secret,

    { algorithms: ['HS256'] }, (err, payload) => { if (err) { console.log('Invalid token!'); return; } console.log('Valid token!'); }); Dominik Kundel | @dkundel | #jsheroes #websec #onesiejs
  8. Don't be the next Equifax Stay up-to-date! Image: Michael Nagle/Bloomberg

    via Getty Images Dominik Kundel | @dkundel | #jsheroes #websec #onesiejs
  9. USE "noopener" <!-- Target page has access to window.opener -->

    <a href="http://example.com/" target="_blank">Dangerous Link</a> <!-- Target page does NOT have access to window.opener --> <a href="http://example.com" target="_blank" rel="noopener noreferrer">Saf e Link</a> Dominik Kundel | @dkundel | #jsheroes #websec #onesiejs
  10. USE CSRF TOKENS const csrf = require('csurf')({ cookie: true });

    app.get('/post', csrf, (req, res, next) => { // pass csrf to front-end via _csrf cookie or // req.csrfToken() in template }); app.post('/post', csrf, (req, res, next) => { // only valid if one of these is the same as the cookie: // req.body._csrf // req.query._csrf // req.headers['csrf-token'] // req.headers['xsrf-token'] // req.headers['x-csrf-token'] // req.headers['x-xsrf-token'] }); Dominik Kundel | @dkundel | #jsheroes #websec #onesiejs
  11. MYSPACE WORM Samy worm / JS.Spacehero worm Dominik Kundel |

    @dkundel | #jsheroes #websec #onesiejs
  12. TRICKS USED BY SAMY <!-- Use JavaScript in CSS and

    move code into HTML attribute --> <div id="mycode" expr="alert('hah!')" style="background:url('javascript:eval(document.all.mycode.expr)')" ></div> // avoid blacklisted words like innerHTML through string concat alert(eval('document.body.inne' + 'rHTML')); eval('xmlhttp.onread' + 'ystatechange = callback'); samy.pl/popular/tech.html Dominik Kundel | @dkundel | #jsheroes #websec #onesiejs
  13. OBSTRUSIVE JAVASCRIPT // Different ways to eval new Function(CODE)() //

    or setTimeout(CODE, 0) // or []["filter"]["constructor"]( CODE )() // or [][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[]) [+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]][([][(![]+[])[+[]]+([![]] +[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+ []+!+[]]+(!![]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+([![ ]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+ !+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[ ]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[]) [+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![] +[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+ (!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!! []+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+(!![ Dominik Kundel | @dkundel | #jsheroes #websec #onesiejs
  14. JSONP JSON with Padding <script> function gotPosts(data) { console.log(data); }

    </script> <script src="https://onesie.life/post?callback=gotPosts"></script> Dominik Kundel | @dkundel | #jsheroes #websec #onesiejs
  15. CSP EXAMPLE HEADER Content-Security-Policy: default-src 'self'; script-src 'nonce-NWo2+pmewRLPWqpsgv6J2w=='; style-src 'nonce-NWo2+pmewRLPWqpsgv6J2w==';

    object-src 'none'; img-src 'self' api.adorable.io; font-src 'self' fonts.gstatic.com; block-all-mixed-content; report-uri /csp-report; Dominik Kundel | @dkundel | #jsheroes #websec #onesiejs
  16. CSP IS NOT YOUR SECURITY STRATEGY! CSP is a Safety

    Net! Dominik Kundel | @dkundel | #jsheroes #websec #onesiejs
  17. OTHER THINGS TO LOOK OUT FOR Avoid clickjacking by disallowing

    framing using X-Frame-Options: deny Check out libraries like helmet for essential HTTP headers. Don't show versions of front-end libs or server Check for types of input(Can cause NoSQL injections) Dominik Kundel | @dkundel | #jsheroes #websec #onesiejs
  18. OTHER THINGS TO DO Consider Security Audits Stay up to

    date with versions (Greenkeeper) Use tools to detect security vulnerabilites (NSP, Snyk) Dominik Kundel | @dkundel | #jsheroes #websec #onesiejs