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

フロントエンドエンジニアのためのセキュリティ対策 ~XSS編~ / #frontkansai 2019

フロントエンドエンジニアのためのセキュリティ対策 ~XSS編~ / #frontkansai 2019

FRONTEND CONFERENCE 2019( https://2019.kfug.jp )でセキュリティ、主にXSSについて話をしました。
demo: https://shisama.dev/xss-test

# Technical Topics
- 3 types of XSS ( Reflected XSS, Stored XSS, DOM based XSS)
- XSS with React
- DOMPurify
- Content Security Policy
- Trusted Types

Masashi Hirano

November 02, 2019
Tweet

More Decks by Masashi Hirano

Other Decks in Programming

Transcript

  1. Frontend Conference 2019 #frontkansai
    Masashi Hirano @shisama_
    ϑϩϯτΤϯυΤϯδχΞͷͨΊͷ
    ηΩϡϦςΟରࡦ~XSSฤ~

    View Slide

  2. ฏ໺ ণ࢜ / Masashi Hirano
    @shisama_
    shisama
    Node.js Core Collaborator
    ؔ੢NodeֶԂOrganizer

    View Slide

  3. ͜Μͳਓʹௌ͍ͯ΄͍͠
    • ηΩϡϦςΟʹؔ৺͕͋Δํ
    • XSSʹֶ͍ͭͯͼ͍ͨํ(ॳதڃऀ)
    • WebΤϯδχΞ
    ಛʹϑϩϯτΤϯυΤϯδχΞ

    View Slide

  4. Agenda
    • WebͷηΩϡϦςΟಈ޲
    • ੬ऑੑ(XSS)ͷ࢓૊Έͱରࡦ
    • XSSͷجૅ
    • ରࡦ: จࣈྻͷΤεέʔϓ
    • ରࡦ: ϒϥ΢βͷػೳ(CSPɺTrusted Types)
    • ηΩϡϦςΟ΁ͷҙࣝ

    View Slide

  5. WebͷηΩϡϦςΟಈ޲

    View Slide

  6. https://www.ipa.go.jp/security/vuln/report/vuln2019q3.html

    View Slide

  7. https://www.ipa.go.jp/security/vuln/report/vuln2019q3.html
    ಧग़݅਺ (2019೥7݄ʙ9݄)

    View Slide

  8. https://www.ipa.go.jp/security/vuln/report/vuln2019q3.html
    ෼ྨ ݄ʙ݄ ಧग़ड෇։͔࢝Βͷྦྷܭ
    ιϑτ΢ΣΞ੡඼ ݅ ݅
    ΢ΣϒαΠτ ݅ ݅
    ߹ܭ ݅ ݅
    ಧग़݅਺ (2019೥7݄ʙ9݄)

    View Slide

  9. https://www.ipa.go.jp/security/vuln/report/vuln2019q3.html
    ෼ྨ ݄ʙ݄ ಧग़ड෇։͔࢝Βͷྦྷܭ
    ιϑτ΢ΣΞ੡඼ ݅ ݅
    ΢ΣϒαΠτ ݅ ݅
    ߹ܭ ݅ ݅
    8FC͕ιϑτ΢ΣΞʹ
    ൺ΂ͯഒҎ্ͷಧग़਺
    ಧग़݅਺ (2019೥7݄ʙ9݄)

    View Slide

  10. https://www.ipa.go.jp/security/vuln/report/vuln2019q3.html
    ΢ΣϒαΠτͷ੬ऑੑͷछྨผͷಧग़







    XSS
    (ΫϩεαΠτɾεΫϦϓςΟϯά)
    DNSͷઃఆෆඋ
    SQLΠϯδΣΫγϣϯ
    HTTPͷෆਖ਼ར༻
    σΟϨΫτϦɾτϥόʔαϧ
    ϑΝΠϧͷޡެ։
    ͦͷଞ

    View Slide

  11. https://www.youtube.com/watch?v=DDtM9caQ97I&t=633s

    View Slide

  12. https://www.hackerone.com/resources/top-10-vulnerabilities
    HackerOne 2018 Total Report

    View Slide

  13. https://blog.cybozu.io/entry/2019/06/20/160000
    Cybozu BugBounty 2018

    View Slide

  14. https://www.owasp.org/index.php/Japan
    " ΠϯδΣΫγϣϯ 42-ΠϯδΣΫγϣϯɺίϚϯυΠϯδΣΫγϣϯͳͲ
    " ೝূͷෆඋ Ϣʔβʔͷೝূ৘ใͷ࿙Ӯ
    " ػඍͳ৘ใͷ࿐ग़ ࡒ຿৘ใ΍ݸਓ৘ใͳͲ઄औɺվ͟Μ
    " 9.-֎෦ΤϯςΟςΟࢀর 99&
    ֎෦ΤϯςΟςΟʹΑΔϦϞʔτίʔυͷ࣮ߦͳͲ
    " ΞΫηε੍ޚͷෆඋ ଞͷϢʔβʔͷσʔλ΍ݖݶͷมߋ
    " ෆద੾ͳηΩϡϦςΟઃఆ ҆શͰͳ͍ઃఆʹΑΔ໰୊
    " ΫϩεαΠτεΫϦϓςΟϯά 944
    ϒϥ΢β্ͰͷεΫϦϓτ࣮ߦʹΑΔ৘ใ࿙͍͑ͳͲ
    " ҆શͰͳ͍σγϦΞϥΠθʔγϣϯ ϦϞʔτ͔Βͷίʔυ࣮ߦ
    " ط஌ͷ੬ऑੑͷ͋Δίϯϙʔωϯτͷ࢖༻ ੬ऑੑͷ͋ΔϥΠϒϥϦͳͲʹΑΔ߈ܸ΍ѱӨڹ
    " ෆे෼ͳϩΪϯάͱϞχλϦϯά ϞχλϦϯάͷෆඋʹΑΔ߈ܸݕ஌࿙Ε
    OWASP Top10 2017

    View Slide

  15. ͜͜·Ͱͷ·ͱΊ: WebͷηΩϡϦςΟಈ޲
    • ੬ऑੑͷଟ͕͘WebαΠτ͔Βൃੜ͢Δ΋ͷ
    • WebαΠτͷ੬ऑੑͰ࠷΋ଟ͍ͷ͸XSS
    • ಛʹॏେͳϦεΫ͕10ݸ͋Δ

    View Slide

  16. XSS

    View Slide

  17. XSSͷڴҖ
    • ίϯςϯπͷվ͟Μ
    • ηογϣϯϋΠδϟοΫ
    • ݸਓ৘ใ࿙Ӯ
    ※ҰྫͰ͢

    View Slide

  18. YouTubeͷඃ֐ࣄྫ
    • σϚͷϙοϓΞοϓදࣔɺଞαΠτ΁ͷϦμΠϨΫτͳͲ

    View Slide

  19. Twitterͷඃ֐ࣄྫ
    • ԕִϋΠδϟοΫʹΑΔϦπΠʔτ౤ߘ

    View Slide

  20. KADOKAWAͷඃ֐ࣄྫ
    • վ͟ΜʹΑΔϚϧ΢ΣΞ૊ΈࠐΈɺݸਓ৘ใ͕౪·ΕΔ

    View Slide

  21. 3छྨͷXSS
    • Reflected XSS
    • Stored XSS
    • DOM Based XSS

    View Slide

  22. ᶃ ߈ܸऀ͕༻ҙͨ͠ϖʔδʹΞΫηε
    Reflected XSS (൓ࣹܕXSS)
    ᶄ εΫϦϓτΛύϥϝʔλʹ
    ͯ͠ର৅αΠτʹભҠ
    alert("XSS") ?token=“”/>alert(“XSS")ᶅ εΫϦϓτ͕
    ຒΊࠐ·ΕͨHTML

    View Slide

  23. Reflected XSS (൓ࣹܕXSS)

    alert("XSS")
    ΫΤϦετϦϯάͷ஋Λͦͷ··HTMLʹ൓ө

    View Slide

  24. Reflected XSS (൓ࣹܕXSS)

    alert("XSS")
    ΫΤϦετϦϯάͷ஋Λͦͷ··HTMLʹ൓ө

    View Slide

  25. ᶃ ϑΥʔϜ͔ΒPOST
    ᶄ POST͞Εͨ
    ஋Λͦͷ··อଘ
    alert(“xss")
    alert(1)
    ᶅ ଞͷϢʔβʔ͕αΠτʹΞΫηε
    ᶆ DBͷ஋ΛHTMLʹ൓ө
    Stored XSS (஝ੵܕXSS)

    View Slide

  26. ᶃ ϑΥʔϜ͔ΒPOST
    ᶄ POST͞Εͨ
    ஋Λͦͷ··อଘ
    alert("XSS")
    alert(1)
    ᶅ ଞͷϢʔβʔ͕αΠτʹΞΫηε
    ᶆ DBͷ஋ΛHTMLʹ൓ө
    Stored XSS (஝ੵܕXSS)

    View Slide

  27. DOM Based XSS
    const hash = decodeURIComponent(location.hash.slice(1));
    document.querySelector('#result').innerHTML = hash;

    ϩέʔγϣϯϋογϡͷ஋Λ
    JavaScriptͰૠೖ

    View Slide

  28. DOM Based XSS
    const hash = decodeURIComponent(location.hash.slice(1));
    document.querySelector('#result').innerHTML = hash;

    ϩέʔγϣϯϋογϡͷ஋Λ
    JavaScriptͰૠೖ

    View Slide

  29. DOM Based XSS
    const hash = decodeURIComponent(location.hash.slice(1));
    document.querySelector('#result').innerHTML = hash;
    ιʔε (Source)
    γϯΫ (Sink)
    ୅දతͳSink
    - innerHTML
    - location.href
    - document.write
    - jQuery() ͳͲ
    ୅දతͳSource
    - location.hash
    - location.href
    - document.referrer
    - IndexedDB ͳͲ

    View Slide

  30. 3छྨͷXSS
    • Reflected XSS
    • Stored XSS
    • DOM Based XSS
    ࠷ऴతʹ͸ඃ֐ऀͷϒϥ΢β্Ͱ
    JavaScript͕࣮ߦ͞ΕΔ

    View Slide

  31. ओͳXSSͷରࡦ
    • ةݥͳจࣈྻͷΤεέʔϓɾ࡟আ
    • ϒϥ΢βͷػೳΛ࢖͏

    View Slide

  32. ओͳXSSͷରࡦ
    • ةݥͳจࣈྻͷΤεέʔϓɾ࡟আ
    • ϒϥ΢βͷػೳΛ࢖͏

    View Slide

  33. HTMLಛघจࣈͷΤεέʔϓॲཧ
    <br/>cookieHijack()<br/>
    <script>
    cookieHijack()
    </script>
    &
    <
    ม׵લ ม׵ޙ
    >


    &
    <
    >
    "
    '
    Τεέʔϓॲཧ

    View Slide

  34. ةݥͳจࣈྻͷ࡟আॲཧ

    ࡟আॲཧ

    View Slide

  35. จࣈྻͷΤεέʔϓɾ࡟আॲཧͷ࣮૷
    function sanitizer(str) {
    return str
    .replace(/&/g, "&")
    .replace(/.replace(/>/g, ">")
    .replace(/"/g, """)
    .replace(/'/g, "'")
    ...
    }

    View Slide

  36. จࣈྻͷΤεέʔϓɾ࡟আॲཧͷ࣮૷
    function sanitizer(str) {
    return str
    .replace(/&/g, "&")
    .replace(/.replace(/>/g, ">")
    .replace(/"/g, """)
    .replace(/'/g, "'")
    ...
    }
    ࣮૷͢Δ͕େม ςετ΋େม
    ࢓༷࿙Ε͍ͯͳ͍͔ෆ҆

    View Slide

  37. ݴޠػೳ΍OSSΛ࢖͏
    • ϓϩάϥϛϯάݴޠ΍ओཁͳϑϨʔϜϫʔΫʹ͸Τεέʔϓػೳ
    Λඋ͍͑ͯΔ
    • Τεέʔϓ༻ͷϥΠϒϥϦ΋ଟ਺ଘࡏ͠·͢

    View Slide

  38. https://reactjs.org/docs/introducing-jsx.html#jsx-prevents-injection-attacks

    View Slide

  39. const App = props => (

    alert(“xss")

    );
    React DOM escapes any values by default

    View Slide

  40. const App = props => (

    alert(“xss")

    );
    React DOM escapes any values by default
    944͸ى͖ͳ͍

    View Slide

  41. const App = (props) => (

    click me!

    );
    React DOM escapes any values by default

    View Slide

  42. const App = (props) => (

    click me!

    );
    React DOM escapes any values by default

    View Slide

  43. ReactͷXSS
    • javascript:εΩʔϜͳͲଐੑ஋͸Τεέʔϓ͞Εͳ͍
    • Ϣʔβʔ͕ೖྗͰ͖Ε͹XSS͸ൃੜ͢Δ





    {title}

    View Slide

  44. const Link = props => {
    const protocol = new URL(props.url).protocol;
    const safeUrl = /^https?:/.test(protocol) ? props.url : "";
    return {props.children};
    };
    const App = () => {
    const { url, title, onChangeUrl, onChangeTitle } = useInput();
    return (





    {title}

    );
    };

    View Slide

  45. const Link = props => {
    const protocol = new URL(props.url).protocol;
    const safeUrl = /^https?:/.test(protocol) ? props.url : "";
    return {props.children};
    };
    const App = () => {
    const { url, title, onChangeUrl, onChangeTitle } = useInput();
    return (





    {title}

    );
    };
    IUUQ·ͨ͸IUUQTϓϩτίϧͷΈڐՄ͢Δ͜ͱ
    ͰɺzKBWBTDSJQUz͔Β࢝·ΔจࣈྻΛແ֐Խ
    click me!

    View Slide

  46. https://github.com/facebook/react/pull/15047

    View Slide

  47. https://github.com/cure53/DOMPurify

    View Slide

  48. $ npm install dompurify
    npm

    CDN
    DOMPurify

    View Slide

  49. DOMPurify
    const untrustedStr = location.hash;
    //
    const trustedStr = DOMPurify.sanitize(untrustedHTML);
    $('#foo').innerHTML = trustedStr;
    //

    View Slide

  50. DOMPurify
    const untrustedStr = location.hash;
    //
    const trustedStr = DOMPurify.sanitize(untrustedHTML);
    $('#foo').innerHTML = trustedStr;
    //
    MPDBUJPOIBTIͷ஋͕
    ͦͷ··4JOL͞ΕͨΒ
    εΫϦϓτ͕࣮ߦ͞ΕΔ

    View Slide

  51. DOMPurify
    const untrustedStr = location.hash;
    //
    const trustedStr = DOMPurify.sanitize(untrustedHTML);
    $('#foo').innerHTML = trustedStr;
    //
    %0.1VSJGZTBOJUJ[FʹΑΓ
    ةݥͳจࣈྻ͚ͩআڈ͞ΕΔ

    View Slide

  52. https://developer.cybozu.io/hc/ja/articles/360001038846-DOMPurifyΛ࢖ͬͯ҆શʹDOMΛදࣔ͠Α͏-

    View Slide

  53. ओͳXSSͷରࡦ
    • ةݥͳจࣈྻͷΤεέʔϓɾ࡟আ
    • ϒϥ΢βͷػೳΛ࢖͏

    View Slide

  54. ϒϥ΢β͸༷ʑͳ੬ऑੑରࡦͷػೳΛඋ͍͑ͯΔ
    X-XSS-Protection
    HttpOnly
    SameSite
    Content Security Policy
    Referer
    Referrer-Policy
    XSS Auditor
    ※ܝࡌ͸Ұ෦
    Fetch Meta

    View Slide

  55. https://www.w3.org/TR/CSP2/

    View Slide

  56. https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy

    View Slide

  57. https://caniuse.com/#feat=mdn-http_headers_csp_content-security-policy

    View Slide

  58. ▼ Response Headers
    content-security-policy: script-src ‘self’ *.trusted.com
    σΟϨΫςΟϒ ιʔε
    • HTTPϨεϙϯεϔομʔʹ௥Ճ͢Δ
    • Ϧιʔεͷऔಘઌ΍εΫϦϓτͷ࣮ߦΛࢦఆͨ͠ιʔεͷΈʹ੍ݶͰ͖Δ
    • script-src ‘self’; img-src *.trusted.comͷ ͷΑ͏ʹෳ਺ઃఆ΋Մೳ
    script-src ‘self’; img-src *.trusted.com
    Content Security Policy

    View Slide


  59. Content Security Policy
    • HTMLͷλάͰࢦఆͰ͖ΔͷͰϑϩϯτΤϯυ͚ͩͰ΋࣮૷Մೳ
    • ΑΓઌʹઃఆ͞Εͨ஋ͷ্ॻ͖ෆՄ
    • ΑΓઌʹಡΈࠐ·ΕͨϦιʔε΍εΫϦϓτʹ͸ద༻Ͱ͖ͳ͍
    • Ͱ͸ઃఆͰ͖ͳ͍σΟϨΫςΟϒ͕͋Δ e.g. report-only

    View Slide

  60. ▼ Response Headers
    content-security-policy-report-only: script-src ‘self’ *.trusted.com
    report-uri /csp-report
    • ࣮ࡍͷCSPΛద༻ͤͣʹϨϙʔτ͚ͩૹΔ͜ͱ͕Մೳ
    • CSPͰڐՄ͞Ε͍ͯͳ͍৔߹ɺϨϙʔτΛPOST͢Δ
    • CSPͷຊ൪ಋೖલʹӨڹΛ֬ೝ͢Δ͜ͱ͕Մೳ
    • λάͰͷઃఆ͸ෆՄ
    Content-Security-Policy-Report-Only

    View Slide

  61. {
    "csp-report": {
    "document-uri": "http://example.com/index.html",
    "referrer": "",
    "blocked-uri": "http://invalid-cdn.com/js/react.js",
    "violated-directive": "script-src self *.trusted.com*",
    "original-policy": "script-src 'self' *.trusted.com; report-uri /csp-report/",
    "disposition": "report"
    }
    }
    Ϩϙʔτͷྫ

    View Slide

  62. content-security-policy: script-src ‘self’ *.trusted.com
    : εΫϦϓτͷ࣮ߦ੍ݶ
    : ڐՄ͢ΔιʔεΛࢦఆ
    Content Security Policyͷ஋ʹ͍ͭͯ
    script-src
    ‘self’ *.trusted.com
    Ωʔϫʔυ ϗετ

    View Slide

  63. σΟϨΫςΟϒ
    DPOOFDUTSD 9)3ɺ8FC4PDLFUͳͲͷ੍ݶ
    EFGBVMUTSD ଞͷϑΣονσΟϨΫςΟϒͷϑΥʔϧόοΫ
    JNHTSD ը૾ͷಡΈࠐΈઌΛ੍ݶ
    NFEJBTSD BVEJPWJEFPͷಡΈࠐΈઌΛ੍ݶ
    TDSJQUTSD εΫϦϓτͷ࣮ߦ৔ॴΛ੍ݶ
    TUZMFTSD ελΠϧͷద༻৔ॴΛ੍ݶ
    ୅දతͳσΟϨΫςΟϒ(ϑΣονͷҰ෦)

    View Slide

  64. content-security-policy: script-src ‘self’

    alert("XSS")

    ϗετͱϙʔτ͕ಉ͡εΫϦϓτͷΈڐՄ

    View Slide

  65. content-security-policy: script-src ‘self’

    alert("XSS")

    ϗετͱϙʔτ͕ಉ͡εΫϦϓτͷΈڐՄ
    ࢦఆ͞Εͨϗετͱҧ͏ͷͰېࢭ

    View Slide

  66. content-security-policy: script-src ‘self’

    alert("XSS")

    ϗετͱϙʔτ͕ಉ͡εΫϦϓτͷΈڐՄ


    ΠϯϥΠϯεΫϦϓτ͸ېࢭ

    View Slide

  67. content-security-policy: script-src ‘self’

    alert("XSS")

    ϗετͱϙʔτ͕ಉ͡εΫϦϓτͷΈڐՄ



    Πϕϯτଐੑ΍KBWBTDSJQUͳͲ΋ېࢭ

    View Slide

  68. content-security-policy: script-src ‘self’ ‘unsafe-inline’
    ΠϯϥΠϯεΫϦϓτͷڐՄ
    • ΠϯϥΠϯεΫϦϓτΛڐՄ͍ͨ͠৔߹
    • ໊લͷ௨Γunsafe(҆શͰ͸ͳ͍)

    View Slide

  69. https://www.w3.org/TR/CSP2/#source-list-valid-nonces
    CSP Lv.2 nonce

    View Slide

  70. content-security-policy: script-src ‘nonce-EDNnf03nceIOfn39fn3e9h3sdfa'
    alert("OK")
    alert(“NG")
    alert("NG")
    OPODFCBTFΤϯίʔυ஋

    View Slide

  71. content-security-policy: script-src ‘nonce-EDNnf03nceIOfn39fn3e9h3sdfa'
    alert("OK")
    alert(“NG")
    alert("NG")
    OPODFͷ஋͕Ұக͍ͯ͠ΔͷͰ࣮ߦΛڐՄ
    OPODFCBTFΤϯίʔυ஋

    View Slide

  72. content-security-policy: script-src ‘nonce-EDNnf03nceIOfn39fn3e9h3sdfa'
    alert("OK")
    alert(“NG")
    alert("NG")
    OPODF஋͕ෆҰக·ͨ͸ະࢦఆͳͷͰ࣮ߦΛېࢭ
    OPODFCBTFΤϯίʔυ஋

    View Slide

  73. content-security-policy: script-src ‘nonce-EDNnf03nceIOfn39fn3e9h3sdfa'
    alert("OK")
    • nonceͷ஋͸αʔόʔଆͰϦΫΤετ͝ͱʹมߋ͢Δ͜ͱ
    • ਪଌ͞Εͳ͍ϥϯμϜͳ஋ʹ͢Δ͜ͱ
    • scriptλάΛಈతʹੜ੒Ͱ͖ͳ͍
    nonceͷ஫ҙ఺

    View Slide

  74. content-security-policy: script-src ‘nonce-EDNnf03nceIOfn39fn3e9h3sdfa’ ‘strict-dynamic’
    <br/>const script = document.createElement('script');<br/>script.src = ‘/static/js/main.js’;<br/>document.head.appendChild(script);<br/>
    CSP Lv.3 strict-dynamic
    QBSTFSJOTFSUFEͰͳ͍TDSJQUͷಈతੜ੒͕Մೳ
    ※parser-inserted = HTMLύʔαʔ΍XMLύʔαʔʹΑͬͯૠೖ͞ΕΔ͜ͱ

    View Slide

  75. content-security-policy: script-src ‘nonce-EDNnf03nceIOfn39fn3e9h3sdfa’ ‘strict-dynamic’
    <br/>const script = document.createElement('script');<br/>script.textContent = location.hash.slice(1);<br/>document.head.appendChild(script);<br/>
    location.hashͷ஋ΛऔΔͱʁ

    View Slide

  76. content-security-policy: script-src ‘nonce-EDNnf03nceIOfn39fn3e9h3sdfa’ ‘strict-dynamic’
    <br/>const script = document.createElement('script');<br/>script.textContent = location.hash.slice(1);<br/>document.head.appendChild(script);<br/>
    location.hashͷ஋ΛऔΔͱʁ

    View Slide

  77. https://w3c.github.io/webappsec-trusted-types/dist/spec/

    View Slide

  78. Trusted Types
    URL String
    HTML String
    Script String
    Scritp URL
    TrustedURL
    TrustedHTML
    TrustedScript
    TrustedScriptURL
    TrustedTypes
    จࣈྻΛ҆શͳܕʹม׵ͯ͠ݕূ͢Δ

    View Slide

  79. content-security-policy: require-trusted-types-for ‘script’; trusted-types;
    script.textContent = location.hash.slice(1);
    document.head.appendChild(script);
    Trusted Types
    ҆શͳܕͰ͸ͳ͍ͷͰεΫϦϓτ͸࣮ߦ͞Εͳ͍

    View Slide

  80. content-security-policy: require-trusted-types-for ‘script’; trusted-types *;
    script-src ‘nonce-EDNnf03nceIOfn39fn3e9h3sdfa’ ‘strict-dynamic’
    <br/>const script = document.createElement('script');<br/>script.textContent = location.hash.slice(1);<br/>document.head.appendChild(script);<br/>

    View Slide

  81. content-security-policy: require-trusted-types-for ‘script’; trusted-types *;
    script-src ‘nonce-EDNnf03nceIOfn39fn3e9h3sdfa’ ‘strict-dynamic’
    <br/>const script = document.createElement('script');<br/>script.textContent = location.hash.slice(1);<br/>document.head.appendChild(script);<br/>
    944͸ى͖ͳ͍

    View Slide

  82. content-security-policy: require-trusted-types-for ‘script';
    trusted-types my-policy;
    const myPolicy = trustedTypes.createPolicy('my-policy', {
    createHTML: (s) => { return customSanitize(s) },
    createURL: (s) => { /* ΤεέʔϓॲཧͳͲ */ },
    createScript: (s) => { /* εΫϦϓτ಺༰ͷνΣοΫͳͲ */ },
    })
    Trusted Types Policy
    จࣈྻΛ҆શͳܕʹม׵͢ΔϙϦγʔΛੜ੒͢Δ

    View Slide

  83. Trusted Types Policy
    ϙϦγʔʹΑͬͯੜ੒͞Εͨܕ͸࣮ߦՄೳʹͳΔ
    const hash = decodeURIComponent(location.hash.slice(1));
    const trustedHtml = myPolicy.createHTML(hash)
    document.body.innerHTML = trustedHtml;
    content-security-policy: require-trusted-types-for ‘script’; trusted-types my-policy;

    View Slide

  84. const myPolicy = trustedTypes.createPolicy("my-policy", {
    createHTML: (s) => {
    return DOMPurify.sanitize(s);
    }
    });
    Trusted Types & DOMPurify
    const hash = decodeURIComponent(location.hash.slice(1));
    const trustedHtml = myPolicy.createHTML(hash)
    document.body.innerHTML = trustedHtml;


    View Slide

  85. https://github.com/w3c/webappsec-trusted-types/pull/205
    5SVTUFE5ZQFTUSVTUFE5ZQFTʹϦωʔϜ͞Εͨ

    View Slide

  86. https://www.chromestatus.com/feature/5650088592408576
    Chrome 83 ͔Β͸σϑΥϧτͰ༗ޮ

    View Slide

  87. chrome://flags/#enable-experimental-web-platform-features
    ΋͠$ISPNFҎԼΛ࢖͍ͬͯΔ৔߹

    View Slide

  88. src="https://w3c.github.io/webappsec-trusted-types/dist/es5/trustedtypes.build.js"
    data-csp="trusted-types my-policy“>
    <br/>trustedTypes.createPolicy('my-policy', ...);<br/>trustedTypes.createPolicy('unknown', ...); // throws<br/>document.body.innerHTML = 'foo'; // throws<br/>Trusted Types Polyfill<br/>npm<br/>CDN<br/>$ npm install trusted-types<br/>import {tt} from 'trusted-types'<br/>tt.createPolicy('my-policy', ...);<br/>

    View Slide

  89. • Demo Page: https://shisama.dev/xss-test/
    • GitHub: https://github.com/shisama/xss-test/
    • DOM Based XSS
    • CSP
    • Trusted Types
    ※devToolsͷconsoleΛ։͖ͳ͕Β֬ೝ͍ͯͩ͘͠͞

    View Slide

  90. https://github.com/facebook/react/pull/16157/

    View Slide

  91. ͜͜·Ͱͷ·ͱΊ: XSS
    • XSS͸ϒϥ΢βͰεΫϦϓτΛ࣮ߦ͢Δ߈ܸख๏
    • ೖྗ͞ΕͨจࣈྻͷΤεέʔϓͰରࡦՄೳ
    • ϒϥ΢βͷػೳͰରࡦՄೳ
    • CSP΍Trusted TypesͰΑΓ҆શʹXSSΛ๷͙͜ͱ͕Մೳ

    View Slide

  92. ηΩϡϦςΟ΁ͷҙࣝ

    View Slide

  93. https://www.amazon.co.jp/dp/4797393165

    View Slide

  94. https://www.amazon.co.jp/dp/4797393165
    “੬ऑੑͱ͸ɺʮѱ༻Ͱ͖Δόάʯ”
    ʰମܥతʹֶͿ ҆શͳWebΞϓϦέʔγϣϯͷ࡞Γํ ୈ̎൛ʱ ಙؙ ߒ (ஶ)

    View Slide

  95. ੬ऑੑ͸όάͰ͋Δͱ͍͏ҙࣝΛ࣋ͭ
    • ཁ݅ఆٛ΍࢓༷ࡦఆͰηΩϡϦςΟʹؔͯ͠FIX͢Δ
    • ػೳςετ͚ͩͰͳ͘ηΩϡϦςΟςετΛߦ͏
    • ੬ऑੑ(όά)͕ݟ͔ͭΕ͹؅ཧͯ͠༏ઌ౓Λ͚ͭΔ

    View Slide

  96. ୭͠΋͕
    ηΩϡϦςΟͷΤΩεύʔτͰ͸ͳ͍

    View Slide

  97. ͲͷΑ͏ʹ੬ऑੑΛ֬ೝ͢Ε͹Α͍͔

    View Slide

  98. https://www.ipa.go.jp/security/vuln/websecurity.html

    View Slide

  99. ʰ҆શͳ΢ΣϒαΠτͷ࡞ΓํʱνΣοΫϦετͰ͸͡ΊΔ

    View Slide

  100. • ֤੬ऑੑʹର͢Δʮࠜຊతղܾʯʮอݥతղܾʯ͕هࡌ͞Ε͍ͯΔ

    View Slide

  101. ҎԼͷ੬ऑੑ͕هࡌ͞Ε͍ͯΔ
    • ̍ʣ SQL ΠϯδΣΫγϣϯ
    • ̎ʣ OS ίϚϯυɾΠϯδΣΫγϣϯ
    • ̏ʣ ύε໊ύϥϝʔλͷະνΣοΫʗ
    σΟϨΫτϦɾτϥόʔαϧ
    • ̐ʣ ηογϣϯ؅ཧͷෆඋ
    • ̑ʣ ΫϩεαΠτɾεΫϦϓςΟϯά
    • ̒ʣ CSRFʢΫϩεαΠτɾϦΫΤετɾ
    ϑΥʔδΣϦʣ
    • ̓ʣ HTTP ϔομɾΠϯδΣΫγϣϯ
    • ̔ʣ ϝʔϧϔομɾΠϯδΣΫγϣ
    ϯ
    • ̕ʣ ΫϦοΫδϟοΩϯά
    • ̍̌ʣόοϑΝΦʔόʔϑϩʔ
    • ̍̍ʣΞΫηε੍ޚ΍ೝՄ੍ޚͷܽ

    View Slide

  102. ηΩϡϦςΟνΣοΫʹ࢖͑Δ΋ͷҰྫ
    • Ϧετ
    • ΢Σϒ݈߁਍அ࢓༷
    • OWASP Cheat Sheet Series
    • HTML5 Security Cheat Sheet
    • πʔϧ
    • OWASP ZAP
    • Vuls
    • VAddy

    View Slide

  103. جຊతͳ੬ऑੑͷ

    νΣοΫ΍ରࡦ͸Ͱ͖Δ

    View Slide

  104. όάΛະવʹ๷͗ɺ
    ൃݟͨ͠Β؅ཧ͠վम͠Α͏
    “੬ऑੑͱ͸ɺʮѱ༻Ͱ͖Δόάʯ”

    View Slide

  105. ·ͱΊ
    • ࠷΋ଟ͍੬ऑੑ͸XSS
    • XSSରࡦʹ͸จࣈྻΛΤεέʔϓ͢Δ
    • ϒϥ΢β͸CSPͳͲ੬ऑੑରࡦͷػೳΛඋ͍͑ͯΔ
    • ੬ऑੑ͸όάͱ͍͏ҙࣝΛ࣋ͭ͜ͱ

    View Slide

  106. ࢀߟ
    • ͦΖͦΖCSP Lv.2 nonce΍Ζ͏ - teppeis blog
    • Masato Kinugawa Security Blog: CVE-2018-5175: FirefoxͰCSPͷstrict-dynamic
    όΠύε
    • ҆શͳจࣈྻͰ͋ΔͱܕͰݕূ͢Δ Trusted Types ʹ͍ͭͯ - Jxck
    • Avoiding XSS in React is Still Hard - javascript-security - Medium
    • Securing Web Apps with Modern Platform Features (Google I/O ’19)

    View Slide

  107. Thanks.
    @shisama_
    shisama

    View Slide