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

フロントエンド開発のためのセキュリティ入門

 フロントエンド開発のためのセキュリティ入門

Developers Summit 2023 10-A-4 「フロントエンド開発のためのセキュリティ入門」の発表資料です。
https://event.shoeisha.jp/devsumi/20230209/session/4176/

「HTTPS化」「CORS」「XSS」「脆弱なライブラリのチェック」について説明しています。

Masashi Hirano

February 10, 2023
Tweet

More Decks by Masashi Hirano

Other Decks in Programming

Transcript

  1. ϑϩϯτΤϯυ։ൃͷͨΊͷ


    ηΩϡϦςΟೖ໳
    ฏ໺ ণ࢜ (@shisama_)

    View Slide

  2. ฏ໺ ণ࢜ / Masashi Hirano
    Frontend Developer


    @shisama_


    shisama


    Node.js Core Collaborator


    ࣾձਓେֶੜ@UoPeople


    View Slide

  3. ʲએ఻ʳ2݄13೔ʹॻ੶Λग़൛͠·͢ʂ
    ੬ऑੑͷ࢓૊ΈͱରࡦΛίʔυ
    Λॻ͖ͳ͕Βֶ΂ΔϋϯζΦϯ
    ΋ܝࡌ͍ͯ͠·͢ʂ


    ࠓ೔͸ॻ੶͔Βൈਮͨ͠಺༰Λ
    ൃද͠·͢ɻ
    ϑϩϯτΤϯυ։ൃͷͨΊͷηΩϡϦςΟೖ໳

    View Slide

  4. WebΞϓϦέʔγϣϯʹ͸

    ͲΜͳηΩϡϦςΟϦεΫ͕͋Δͷ͔

    View Slide

  5. WebΞϓϦέʔγϣϯͰൃੜ͢ΔηΩϡϦςΟϦεΫ
    08"415PQ
    " ΞΫηε੍ޚͷෆඋ
    " ҉߸Խͷࣦഊ
    " ΠϯδΣΫγϣϯ
    " ҆શ͕֬ೝ͞Εͳ͍ෆ҆ͳઃܭ
    " ηΩϡϦςΟͷઃఆϛε
    " ੬ऑͰݹ͘ͳͬͨίϯϙʔωϯτ
    " ࣝผͱೝূͷࣦഊ
    " ιϑτ΢ΣΞͱσʔλͷ੔߹ੑͷෆ۩߹
    " ηΩϡϦςΟϩάͱϞχλϦϯάͷࣦഊ
    " αʔόʔαΠυϦΫΤετϑΥʔδΣϦ

    View Slide

  6. • ҉߸Խͷࣦഊ


    • ΞΫηε੍ޚͷෆඋ


    • ΠϯδΣΫγϣϯ


    • ੬ऑͰݹ͘ͳͬͨίϯϙʔωϯτ
    ࠓճ͓࿩͢ΔηΩϡϦςΟϦεΫ

    View Slide

  7. • ҉߸Խͷࣦഊ ➡ ௨৴σʔλͷ҉߸Խ


    • ΞΫηε੍ޚͷෆඋ ➡ CORSΛ࢖ͬͨΞΫηε੍ޚ


    • ΠϯδΣΫγϣϯ ➡ XSSରࡦ


    • ੬ऑͰݹ͘ͳͬͨίϯϙʔωϯτ ➡ ੬ऑͳϥΠϒϥϦͷνΣοΫ
    ࠓճ͓࿩͢ΔηΩϡϦςΟϦεΫ

    View Slide

  8. • ҉߸Խͷࣦഊ ➡ ௨৴σʔλͷ҉߸Խ


    • ΞΫηε੍ޚͷෆඋ ➡ CORSΛ࢖ͬͨΞΫηε੍ޚ


    • ΠϯδΣΫγϣϯ ➡ XSSରࡦ


    • ੬ऑͰݹ͘ͳͬͨίϯϙʔωϯτ ➡ ੬ऑͳϥΠϒϥϦͷνΣοΫ
    ࠓճ͓࿩͢ΔηΩϡϦςΟϦεΫ

    View Slide

  9. Webϖʔδͷදࣔ͸ϒϥ΢βͱαʔόͷ௨৴͔Β͸͡·Δ
    HTML
    JS
    WebαΠτͷαʔό

    site.example
    ଞͷWebαΠτ΍CDNͷαʔό
    JSON
    Ϣʔβ͕WebαΠτ΁ΞΫηε
    HTMLͳͲͷϦιʔεΛૹ৴
    WebαΠτͱ͸ผͷαʔό΁ϦΫΤετ
    ϦιʔεΛૹ৴

    View Slide

  10. Webϖʔδͷදࣔ͸ϒϥ΢βͱαʔόͷ௨৴͔Β͸͡·Δ
    HTML
    JS
    WebαΠτͷαʔό

    site.example
    ଞͷWebαΠτ΍CDNͷαʔό
    JSON
    Ϣʔβ͕WebαΠτ΁ΞΫηε
    HTMLͳͲͷϦιʔεΛૹ৴
    WebαΠτͱ͸ผͷαʔό΁ϦΫΤετ
    ϦιʔεΛૹ৴
    ௨৴ʹ͸)551ͱ͍͏ϓϩτίϧ
    ͕࢖ΘΕ͍ͯΔ
    ௨৴్தͰ߈ܸΛ͞ΕΔͱɺϒϥ΢β
    ΍αʔόͰରࡦ͍͍ͯͯ͠΋ແҙຯ

    View Slide

  11. HTTPͷऑ఺
    • ௨৴σʔλͷ౪ௌ͕Մೳ


    • ௨৴૬ख͕ຊ෺͔Θ͔Βͳ͍


    • ௨৴σʔλͷվ͟Μ

    View Slide

  12. ௨৴σʔλͷ౪ௌ
    • HTTPͷσʔλ͸҉߸Խ͞Ε͍ͯͳ͍ฏจͷ··ૹ৴͞ΕΔ


    • ௨৴్தͰ߈ܸऀ͕౪ௌ͢Δͱ

    σʔλ͕ݟ͑ͯ͠·͏

    View Slide

  13. ௨৴૬ख͕ຊ෺͔Θ͔Βͳ͍
    • ௨৴ઌͷαʔό͕ຊ෺͔Ͳ͏͔ূ໌Ͱ͖ͳ͍


    • ِ෺ͷαʔό͕ຊ෺ʹͳΓ͢·͢͜ͱ͕Ͱ͖Δ


    • URLͰͷΈ௨৴૬खΛ

    ಛఆ͢ΔͨΊɺِ෺͔

    Ͳ͏͔Θ͔Βͳ͍

    View Slide

  14. ௨৴σʔλͷվ͟Μ
    • ௨৴σʔλͷ಺༰͕ਖ਼͍͔͠ݕূ͢Δ࢓૊Έ͕ͳ͍


    • ͨͱ͑͹ɺϒϥ΢β͕ૹ৴ͨ͠σʔλͱαʔό͕ड৴ͨ͠σʔλ͕Ұ
    க͢Δ͔ݕূͰ͖ͳ͍


    • ௨৴్தͰվ͟Μʢॻ͖׵͑ʣ

    ͕͋ͬͯ΋ݕ஌Ͱ͖ͳ͍

    View Slide

  15. HTTPSԽͰHTTPͷऑ఺ͷࠀ෰
    • ௨৴σʔλͷ҉߸Խ


    • ௨৴૬खͷݕূ


    • վ͟ΜνΣοΫ

    View Slide

  16. HTTP௨৴ͷલʹ҉߸Խ௨৴Λ

    ཱ֬͢Δ

    View Slide

  17. ௨৴σʔλͷ҉߸Խ
    • TLSͱ͍͏ϓϩτίϧΛར༻ͯ͠௨৴Λ҉߸Խ͢Δ


    • ҉߸Խʹ͸ʮެ։伴҉߸ํࣜʯͱʮڞ௨伴҉߸ํࣜʯΛ༻͍Δ

    ެ։伴҉߸ํࣜɿ҉߸伴ͷड͚౉͠͸؆୯͕ͩॲཧ͕஗͍

    ڞ௨伴҉߸ํࣜɿ҉߸伴ͷड͚౉͠͸೉͍͕͠ॲཧ͸଎͍

    View Slide

  18. ௨৴૬खͷݕূ
    • ిࢠূ໌ॻΛ࢖ͬͯ௨৴૬ख͕ຊ෺͔ݕূ͢Δ


    • ిࢠূ໌ॻ͸ೝূہʢCAʣ͕ൃߦͨ͠΋ͷΛ࢖͏


    • ϒϥ΢βʹ͸͋Β͔͡Ίϧʔτূ໌ॻͱݺ͹ΕΔిࢠূ໌ॻ͕૊Έࠐ
    ·Ε͓ͯΓɺαʔό͔Βड͚औͬͨిࢠূ໌ॻͱরΒ͠߹Θͤͯূ໌
    ॻ͕ຊ෺͔ݕূ͢Δ


    • ূ໌ॻِ͕෺ͩͬͨ৔߹ɺϒϥ΢β͸ܯࠂը໘Λදࣔ͢Δ

    View Slide

  19. վ͟ΜνΣοΫ
    • ҉߸௨৴ͷͨΊʹૹ৴ͨ͠҉߸伴΍ిࢠূ໌ॻʹվ͟Μ͕ͳ͍͔
    νΣοΫ͢Δ


    • ΋͠҉߸伴΍ిࢠূ໌ॻʹվ͟Μ͕͋Ε͹ɺͦͷޙͷHTTP௨৴͸҆
    શͰ͸ͳ͍ͨΊ௨৴Λऴྃ͢Δ

    View Slide

  20. WebαΠτશମͷHTTPSԽʢৗ࣌SSLԽʣ͕ඞਢʹͳ͖͍ͬͯͯΔ
    • IABʢΠϯλʔωοτΞʔΩςΫνϟҕһձʣ͕ʮ৽͘͠ϓϩτίϧ
    Λઃܭ͢Δͱ͖͸҉߸ػೳΛඞਢʹ͢΂͖ʯͱओு


    • HTTP઀ଓͷ৔߹ɺϒϥ΢βͷURLόʔʹܯࠂ͕

    දࣔ͞ΕΔ


    • HTTPS઀ଓͷϖʔδͰ͔͠࢖͑ͳ͍API΋͋Δ

    ྫɿPayment Request API

    View Slide

  21. WebαΠτΛHTTPSԽͷͨΊʹ͢Δ͜ͱ
    • Mixed ContentΛमਖ਼͢Δ


    • HTTP→HTTPS΁ͷϦμΠϨΫτઃఆ


    • HSTSΛઃఆ͢Δ

    View Slide

  22. Mixed Contentͷةݥੑ
    • 1ͭͷϖʔδ্ͰHTTPSͰ഑৴͞ΕͨϦιʔεͱHTTPͰ഑৴͞ΕͨϦ
    ιʔε͕ࠞࡏ͢Δ͜ͱΛMixed ContentͱݺͿ


    • HTML͕HTTPSʹ഑৴͞Ε͍ͯͯ΋αϒϦιʔεͷJavaScriptͳͲ͕
    HTTPͰ഑৴͞Ε͍ͯΔͱɺ͔ͦ͜Β߈ܸ͞ΕΔՄೳੑ͕͋Δ


    • Chrome DevToolsͳͲΛ࢖͍ͳ͕ΒMixed ContentΛमਖ਼͠ͳ͚Ε͹
    ͳΒͳ͍

    View Slide

  23. View Slide

  24. HTTP→HTTPS΁ͷϦμΠϨΫτઃఆ
    • http://͔Β͸͡·ΔURLͷϦϯΫ͕ଞͷWebαΠτʹషΒΕ͍ͯΔͳ
    Ͳͷࣄ৘͔ΒHTTP഑৴Λ΍ΊΔ͜ͱ͕Ͱ͖ͳ͍͜ͱ΋͋Δ


    • HTMLʹαϒϦιʔεͷURLΛϕλॻ͖͍ͯ͠ΔͳͲͷ৔߹ɺҰ౓ʹ
    मਖ਼͸೉͍͠ͷͰHTTP഑৴Λ࢒͓ͯ͘͠έʔε΋͋Δ


    • αʔόଆͰHTTPͷϦΫΤετΛ͢΂ͯHTTPS΁ϦμΠϨΫτ͢Δઃ
    ఆΛೖΕΔ

    View Slide

  25. HSTSΛઃఆ͢Δ
    • HSTSʢHTTP Strict Transport Securityʣ͸ϒϥ΢β͔Βૹ৴͢ΔϦΫ
    ΤετΛHTTPSʹڧ੍͢Δ͜ͱ͕Ͱ͖Δػೳ


    • Strict-Transport-SecurityϔομΛड͚औͬͨϒϥ΢β͸ͦͷWebαΠ
    τ΁ͷ࣍ճҎ߱ͷϦΫΤετ͸HTTPSͰߦ͏


    • HSTSͷظݶΛઃఆ͢Δ

    max-age͕ඞਢ

    View Slide

  26. αϒυϝΠϯʹ΋HSTSΛઃఆ͢Δ
    • Strict-Transport-Security:

    includeSubdomainsͰ

    αϒυϝΠϯʹ΋HSTSΛ

    ద༻ͤ͞Δ͜ͱ͕Մೳ

    View Slide

  27. PreloadΛ࢖͑͹ॳճ͔ΒHTTPSΛڧ੍Ͱ͖Δ

    View Slide

  28. • ҉߸Խͷࣦഊ ➡ ௨৴σʔλͷ҉߸Խ


    • ΞΫηε੍ޚͷෆඋ ➡ CORSΛ࢖ͬͨΞΫηε੍ޚ


    • ΠϯδΣΫγϣϯ ➡ XSSରࡦ


    • ੬ऑͰݹ͘ͳͬͨίϯϙʔωϯτ ➡ ੬ऑͳϥΠϒϥϦͷνΣοΫ
    ࠓճ͓࿩͢ΔηΩϡϦςΟϦεΫ

    View Slide

  29. ֎෦͔ΒͷΞΫηεʹΑΔ໰୊
    • ෳ਺ͷWebαΠτͷίϯςϯπΛ1ͭͷWebϖʔδͰར༻͢Δ͜ͱ͕
    Մೳ


    • APIͷݺͼग़͠ɺiframeΛ࢖ͬͨίϯςϯπͷຒΊࠐΈɺը૾ͷऔ
    ಘ etc…


    • ͋ΒΏΔWebαΠτ͔Β੍ݶͳ͠ʹΞΫηεͰ͖Δঢ়ଶʹͳ͍ͬͯΔ
    ͱػີ৘ใͷ࿙͍͑΍վ͟ΜͳͲͷ߈ܸͷՄೳੑ͕͋Δ

    View Slide

  30. ֎෦͔ΒͷΞΫηεʹΑΔ໰୊

    View Slide

  31. Originͱ͍͏ڥք
    • ϒϥ΢β಺ʹ͸֎෦ͷΞΫηεΛ੍ݶ͢ΔOriginͱ͍͏ڥքઢ͕ઃ͚
    ΒΕ͍ͯΔ


    • Origin͸εΩʔϜ+ϗετ໊+ϙʔτ൪߸ͷ૊Έ߹ΘͤΛࢦ͢

    View Slide

  32. Originͱ͍͏ڥք
    • 2ͭͷURLͷOrigin͕ಉ͡৔߹ɺಉҰΦϦδϯʢSame OriginʣͱݺͿ


    • 2ͭͷURLͷOrigin͕ҟͳΔ৔߹ɺΫϩεΦϦδϯʢCross Origin)ͱ
    ݺͿ

    View Slide

  33. Same Origin Policy(ಉҰΦϦδϯϙϦγʔɺSOP)
    • ϒϥ΢β͸Ұ෦ͷσʔλͷ΍ΓऔΓΛSame Origin͚ͩʹ੍ݶ͍ͯ͠
    Δɻͬ͘͟Γݴ͏ͱ͜Ε͕Same Origin Policy

    View Slide

  34. Same Origin PolicyʹΑΔ੍ݶର৅
    • JavaScriptʢfetchɺXHRʣΛ࢖ͬͨΫϩεΦϦδϯ΁ͷϦΫΤετ


    • JavaScriptΛ࢖ͬͨiframe಺ͷΫϩεΦϦδϯͷϖʔδ΁ͷΞΫηε


    • ΫϩεΦϦδϯͷը૾ΛಡΈࠐΜͩཁૉͷσʔλ΁ͷΞΫ
    ηε


    • Web Storage΍IndexedDBʹอଘ͞ΕͨΫϩεΦϦδϯͷσʔλ΁ͷ
    ΞΫηε

    View Slide

  35. • ͨͱ͑͹ɺfetchؔ਺Λ࢖ͬͯΫϩεΦϦδϯ΁ϦΫΤετΛૹ৴͢
    Ε͹͜ͷΑ͏ͳΤϥʔ͕ൃੜ͢Δ
    JavaScriptʢfetchɺXHRʣΛ࢖ͬͨ

    ΫϩεΦϦδϯ΁ͷϦΫΤετ

    View Slide

  36. Cross Origin Resource SharingʢCORSʣ
    • CORSΛ࢖͑͹ɺΫϩεΦϦδϯؒͷϦΫΤετΛڐՄ͢Δ͜ͱͰ͖
    Δ


    • JavaScriptʢfetchɺXHRʣΛ࢖ͬͨΫϩεΦϦδϯͱͷσʔλͷ΍Γ
    ͱΓ͕ՄೳʹͳΔ

    View Slide

  37. CORSͷ࢓૊Έ
    • ΫϩεΦϦδϯͷαʔό΁ϦΫΤετࣗମ͸ૹ৴͞ΕͯɺϨεϙϯε
    ΋ฦͬͯ͘Δ


    • ϨεϙϯεͷCORSϔομʹΑͬͯαʔό͕ڐՄͨ͠ϦΫΤετͱ൑
    அͨ͠Βɺϒϥ΢β͸ϨεϙϯεͷσʔλͷऔΓग़͠ΛڐՄ͢Δ

    View Slide

  38. CORSͷ࢓૊Έ
    • αʔό͕ڐՄͨ͠Origin͔Ͳ͏͔൑ఆ͢ΔͨΊʹ

    Access-Control-Allow-Originͱ͍͏ϨεϙϯεϔομΛར༻͢Δ

    ྫ `Access-Control-Allow-Origin: https://site.example`

    View Slide

  39. CORSͷ՝୊
    • σʔλΛऔͬͯ͘Δ͚ͩͳΒ͜͜·Ͱͷઆ໌Ͱ໰୊ͳ͍


    • σʔλΛߋ৽ɾ࡟আͳͲ෭࡞༻Λى͜͢ϦΫΤετͷ৔߹͸ɺϦΫΤ
    ετࣗମΛ๷͙ඞཁ͕͋Δ


    • ͨͱ͑͹σʔλΛ࡟আ͢ΔϦΫΤετ͕ૹ৴͞Εͯαʔό΁ಧ͘ͱ
    αʔό͸ϨεϙϯεΛฦ͢લʹσʔλΛ࡟আͯ͠͠·͏͔΋͠Εͳ͍


    • Access-Control-Allow-OriginϔομͰ͸ɺϦΫΤετΛड͚औͬͨ
    αʔόͷಈ࡞·Ͱ͸੍ޚͰ͖ͳ͍

    View Slide

  40. CORSͷ՝୊
    ᶃ σʔλΛ࡟আ͢ΔϦΫΤετΛૹ৴
    ᶅ Access-Control-Allow-OriginΛؚΉ

    ϨεϙϯεΛૹ৴
    ᶄ σʔλͷ࡟আॲཧΛ࣮ߦ
    ᶆ ϨεϙϯεΛഁغ
    Ϩεϙϯεσʔλ͸ഁغͰ͖ͯ΋ɺ
    σʔλͷ࡟আ͸ࢭΊΕ͍ͯͳ͍

    View Slide

  41. CORSͷ࢓૊ΈʢϓϦϑϥΠτϦΫΤετʣ
    • ෭࡞༻Λى͜͢Α͏ͳϦΫΤετ͸ࣄલʹ໰୊ͳ͍͔֬ೝ͢Δ

    ϓϦϑϥΠτϦΫΤετͱݺ͹ΕΔϦΫΤετ͕ૹ৴͞ΕΔ


    • ϓϦϑϥΠτϦΫΤετʹ͸OPTIONSͱ͍͏HTTPϝιου͕ར༻͞
    Εɺ࣮ࡍͷσʔλͷߋ৽ɾ࡟আॲཧ͸͠ͳ͍


    • ϨεϙϯεຊจʹσʔλΛؚΊͳ͍

    View Slide

  42. CORSͷ࢓૊ΈʢϓϦϑϥΠτϦΫΤετʣ

    View Slide

  43. ϓϦϑϥΠτϦΫΤετ͕ૹ৴͞ΕΔ৚݅
    • GETɺHEADɺPOSTҎ֎ͷHTTPϝιου͕ར༻͞ΕΔͱ͖


    • AcceptɺAccept-LanguageɺContent-LanguageɺContent-TypeҎ֎
    ͷHTTPϔομ͕ૹ৴͞ΕΔͱ͖

    View Slide

  44. ϓϦϑϥΠτϦΫΤετͰૹ৴͞ΕΔϔομ

    View Slide

  45. View Slide

  46. • ҉߸Խͷࣦഊ ➡ ௨৴σʔλͷ҉߸Խ


    • ΞΫηε੍ޚͷෆඋ ➡ CORSΛ࢖ͬͨΞΫηε੍ޚ


    • ΠϯδΣΫγϣϯ ➡ XSSରࡦ


    • ੬ऑͰݹ͘ͳͬͨίϯϙʔωϯτ ➡ ੬ऑͳϥΠϒϥϦͷνΣοΫ
    ࠓճ͓࿩͢ΔηΩϡϦςΟϦεΫ
    ଞʹ΋42-ΠϯδΣΫγϣϯͳͲ͕
    ͋Δ͕ࠓ೔͸944͚ͩઆ໌͠·͢

    View Slide

  47. XSSͱ͸
    • ΫϩεαΠτεΫϦϓςΟϯάʢCross-Site Scriptingʣ


    • Webϖʔδ্ͷJavaScriptͷܽؕΛૂ͏߈ܸख๏


    • ෆਖ਼ͳεΫϦϓτΛૠೖʢΠϯδΣΫγϣϯʣ࣮ͯ͠ߦ͢Δ͜ͱͰػ
    ີ৘ใͷ౪ΜͩΓɺϖʔδͷվ͟ΜΛߦͬͨΓ͢Δ


    • ଞͷ੬ऑੑʹൺ΂ͯใࠂ݅਺͕ଟ͍

    View Slide

  48. XSSͷڴҖ
    • ػີ৘ใͷ࿙͍͑


    • ِ৘ใͷදࣔ


    • ҙਤ͠ͳ͍ૢ࡞ͷ࣮ߦ


    • ηογϣϯ৘ใୣऔʹΑΔɺͳΓ͢·͠


    • ِͷೖྗϑΥʔϜදࣔʹΑΔϑΟογϯά

    View Slide

  49. XSSͷڴҖ
    • YouTube΍TwitterͳͲେ͖ͳαʔϏε΋ඃ֐Λड͚ͨ͜ͱ͕͋Δ

    View Slide

  50. 3छྨͷXSS
    • ൓ࣹܕXSSʢRe
    fl
    ected XSS)


    • ஝ੵܕXSSʢStored XSSʣ


    • DOM-based XSS

    View Slide

  51. ൓ࣹܕXSS (Re
    fl
    ected XSS)
    ᶃ ߈ܸऀ͕༻ҙͨ͠ϖʔδʹΞΫηε
    ᶄ εΫϦϓτΛύϥϝʔλʹ


    ͯ͠ର৅αΠτʹભҠ
    alert("XSS") ?token=“”/>alert(“XSS")ᶅ εΫϦϓτ͕

    ຒΊࠐ·ΕͨHTML

    View Slide

  52. ൓ࣹܕXSSͷಛ௃
    • αʔό಺ͰϨεϙϯεͷHTMLΛ૊ΈཱͯΔͱ͖ʹϦΫΤετʹؚ·
    ΕͨXSSͷίʔυΛͦͷ··HTML΁൓өͯ͠͠·͏


    • ϦΫΤετ಺ʹෆਖ਼εΫϦϓτؚ͕·Ε͍ͯΔͱ͖ͷΈʹൃੜ͢Δ


    • ෆਖ਼ͳεΫϦϓτΛؚΉϦΫΤετΛૹ৴ͨ͠Ϣʔβʔ͚͕ͩඃ֐Λ
    ड͚Δ

    View Slide

  53. ஝ੵܕXSS (Stored XSS)
    ᶃ ϑΥʔϜ͔ΒPOST
    ᶄ POST͞Εͨ


    ஋Λͦͷ··อଘ
    alert(“xss")
    alert(1)
    ᶅ ଞͷϢʔβʔ͕αΠτʹΞΫηε
    ᶆ DBͷ஋ΛHTMLʹ൓ө

    View Slide

  54. ஝ੵܕXSSͷಛ௃
    • αʔό΁ૹ৴͞Εͨෆਖ਼εΫϦϓτΛσʔλϕʔεͳͲʹอଘͯ͠͠
    ·͍ӬଓతʹXSSͷةݥ͕͋Δ


    • σʔλϕʔεͷ಺༰͕൓ө͞ΕΔશͯͷϢʔβʔ͕ඃ֐Λड͚Δ


    • σʔλϕʔε͔Βෆਖ਼εΫϦϓτΛؚΉσʔλΛ࡟আ͢ΔͳͲରॲ͠
    ͳ͍ݶΓɺඃ֐͸ࢭ·Βͳ͍

    View Slide

  55. DOM-based XSS
    const hash = decodeURIComponent(location.hash.slice(1));


    document.querySelector('#result').innerHTML = hash;

    ϩέʔγϣϯϋογϡͷ஋Λ


    JavaScriptͰૠೖ

    View Slide

  56. DOM-based XSSͷಛ௃
    • ϒϥ΢β্ͷJavaScriptΛ࢖ͬͨDOMૢ࡞͕ݪҼͰൃੜ͢Δ


    • ଞͷ2ͭͱҧ͍ϑϩϯτΤϯυͷίʔυͷෆඋʹΑͬͯൃੜ͢Δ


    • αʔόΛհͣ͞ʹ߈ܸ͕੒ཱ͢ΔͨΊɺ߈ܸͷݕ஌΍ϩάऔಘ͕೉͠
    ͍


    • ϑϩϯτΤϯυͷJavaScript͸DevTools͔ΒݟΔ͜ͱ͕ग़དྷΔͨΊɺ
    ߈ܸऀ͸੬ऑੑΛൃݟ͠΍͍͢

    View Slide

  57. 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

  58. ୅දతͳXSSରࡦ
    • จࣈྻͷΤεέʔϓ


    • ReactɺVueɺAngularͳͲͷϑϨʔϜϫʔΫΛ࢖͏


    • javascript:εΩʔϜͷURLΛຒΊࠐ·ͳ͍


    • DOMPurifyͳͲͷϥΠϒϥϦ΍Sanitizer APIΛ࢖ͬͯةݥͳจࣈྻΛ
    আڈ͢Δ


    • Content Security Policy

    View Slide

  59. จࣈྻͷΤεέʔϓ
    <br/><br/><br/>cookieHijack()<br/><br/><br/>


    <script>


    cookieHijack()


    </script>


    &
    <
    ม׵લ ม׵ޙ
    >


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

    View Slide

  60. ReactͳͲͷϑϨʔϜϫʔΫΛ࢖͏
    • ReactɺVueɺAngularɺSvelteͳͲͷ༗໊ͳϥΠϒϥϦ/ϑϨʔϜϫʔΫ͸ΤεέʔϓॲཧΛ
    ࣗಈͰ΍ͬͯ͘ΕΔ


    • ։ൃऀ͸ΤεέʔϓॲཧΛ͢Δඞཁ͸ͳ͍


    • ͨͩ͠ɺҰ෦ͷAPIΛ࢖͏͜ͱͰXSS͸ൃੜ͢Δ͜ͱ͕͋Γ·͢


    • dangerouslySetInnerHTML͸innerHTMLͱಉ͘͡จࣈྻΛͦͷ··HTMLͱͯ͠ೝࣝ͢Δ
    ʢReactʣ


    • ޙड़ͷjavascript:εΩʔϜʹΑΔXSSʹ͸ରԠ͍ͯ͠ͳ͍ʢReactʣ


    • ίϯιʔϧʹܯࠂ͸ग़Δ

    View Slide

  61. javascript:εΩʔϜͷURLΛຒΊࠐ·ͳ͍
    • ͨͱ͑͹ɺϦϯΫͷURLΛೖྗͰ͖ΔϑΥʔϜ͕͋ͬͨͱ͢Δ


    • ϑΥʔϜʹhttps://example.comͱೖྗͨ͠Βhttps://example.com
    ΁ͷϦϯΫ͕ੜ੒͞ΕΔͱ͢Δ















    {title}



    ೚ҙͷ63-ΛઃఆՄೳͱ͢Δ

    View Slide

  62. javascript:εΩʔϜͷURLΛຒΊࠐ·ͳ͍
    • ϑΥʔϜʹjavascript:alert(“xss”)ͱೖྗ͞ΕΔͱɺΫϦοΫͨ͠ͱ͖
    ʹalert(“xss”)͕࣮ߦ͞ΕΔϦϯΫ͕Ͱ͖ͯ͠·͏
    const App = (props) => (

















    click me!


    KBWBTDSJQUεΩʔϜΛ࢖͑͹೚ҙͷ
    εΫϦϓτΛૠೖͰ͖Δ

    View Slide

  63. javascript:εΩʔϜͷURLΛຒΊࠐ·ͳ͍
    const Link = props => {


    const protocol = new URL(props.url).protocol;


    const safeUrl = /^https?:/.test(protocol) ? props.url : "";


    return {props.children};


    };


    const App = (props) => {


    return (





    {title}





    );


    };
    IUUQ·ͨ͸IUUQT͔Β͸͡·Δ63-͚ͩΛ
    ઃఆ͢ΔΑ͏ʹϑΟϧλϦϯά͢Δ

    View Slide

  64. DOMPurifyΛ࢖ͬͨةݥͳจࣈྻͷআڈ
    • DOMPurify͸OSSͷϥΠϒϥϦ


    • npm΍CDN͔Βμ΢ϯϩʔυͯ͠࢖͏͜ͱ͕Ͱ͖Δ


    • จࣈྻ͔ΒXSSΛى͜͢ةݥͳจࣈྻΛ࡟আͯ͘͠ΕΔ
    const untrustedStr = location.hash;


    //


    const trustedStr = DOMPurify.sanitize(untrustedStr);


    $('#foo').innerHTML = trustedStr;


    //

    View Slide

  65. Sanitizer APIΛ࢖ͬͨةݥͳจࣈྻͷআڈ
    • ϒϥ΢βʹ૊Έࠐ·Ε͍ͯΔAPI


    • Ͱ͖Δ͜ͱ͸DOMPurifyͱࣅ͍ͯͯةݥͳจࣈྻΛআڈ͢Δ
    const untrustedStr = location.hash;


    //

    const sanitizer = new Sanitizer(untrustedStr);


    const target = document.getElementById(untrustedStr);


    target.setHTML(untrustedStr, { sanitizer });


    //

    View Slide

  66. Content Security Policy (CSP)
    • ڐՄ͞Ε͍ͯͳ͍JavaScriptͷ࣮ߦ΍ϦιʔεͷಡΈࠐΈͳͲΛϒ
    ϩοΫ͢Δϒϥ΢βͷػೳ


    • Content-Security-Policyͱ͍͏ϨεϙϯεϔομʹΑͬͯԿΛͲ͏ϒ
    ϩοΫ͢Δͷ͔ઃఆ͢Δ͜ͱ͕Մೳ

    View Slide

  67. View Slide

  68. Content Security Policyͷ࢖༻ํ๏
    • HTTPϨεϙϯεϔομʔʹ௥Ճ͢Δ


    • Ϧιʔεͷऔಘઌ΍εΫϦϓτͷ࣮ߦΛࢦఆͨ͠ιʔεͷΈʹ੍ݶͰ͖Δ


    • script-src ‘self’; img-src *.trusted.comͷ ͷΑ͏ʹෳ਺ઃఆ΋Մೳ
    ▼ Response Headers


    content-security-policy: script-src ‘self’ *.trusted.com
    σΟϨΫςΟϒ ιʔε
    script-src ‘self’; img-src *.trusted.com

    View Slide

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

    View Slide

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

    View Slide

  71. ͔ΒCSPΛ༗ޮʹͰ͖Δ
    • HTMLͷλάͰࢦఆͰ͖ΔͷͰϑϩϯτΤϯυ͚ͩͰ΋࣮૷Մೳ


    • ΑΓઌʹઃఆ͞Εͨ஋ͷ্ॻ͖ෆՄ


    • ΑΓઌʹಡΈࠐ·ΕͨϦιʔε΍εΫϦϓτʹ͸ద༻Ͱ͖ͳ͍


    • Ͱ͸ઃఆͰ͖ͳ͍σΟϨΫςΟϒ͕͋Δ e.g. report-only

    View Slide

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

    alert("XSS")

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

    View Slide

  73. CSPͷྫ
    content-security-policy: script-src ‘self’

    alert("XSS")

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

    View Slide

  74. CSPͷྫ
    content-security-policy: script-src ‘self’

    alert("XSS")

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


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

    View Slide

  75. CSPͷྫ
    content-security-policy: script-src ‘self’

    alert("XSS")

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



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

    View Slide

  76. CSPͷ՝୊
    • CSP͕ద༻͞Ε͍ͯΔϖʔδͰ͸ΠϯϥΠϯεΫϦϓτ͸ېࢭ͞ΕΔ


    • unsafe-inlineΩʔϫʔυΛ࢖͑͹ΠϯϥΠϯεΫϦϓτΛڐՄͰ͖Δ
    ͕ɺXSSʹΑΓຒΊࠐ·ΕͨΠϯϥΠϯεΫϦϓτ·Ͱ࣮ߦͯ͠͠·
    ͏Մೳੑ͕͋Γ໊લͷͱ͓Γ҆શͰ͸ͳ͍ʢunsafe-inlineʣ


    • ϗετ໊ͷࢦఆ͸ᷖճ͕ՄೳͰ͋Δ※

    ※ https://research.google/pubs/pub45542/

    View Slide

  77. Strict CSP
    • ҆શʹΠϯϥΠϯεΫϦϓτΛ࣮ߦͰ͖Δnonce·ͨ͸hashΛϕʔε
    ͱͨ͠Strict CSPͱ͍͏ઃఆ͕GoogleʹΑͬͯਪ঑͞Ε͍ͯΔ
    Content-Security-Policy:


    script-src 'nonce-tXCHNF14TxHbBvCj3G0WmQ==' 'strict-dynamic'
    https: 'unsafe-inline';


    object-src 'none';


    base-uri 'none';


    View Slide

  78. content-security-policy: script-src ‘nonce-EDNnf03nceIOfn39fn3e9h3sdfa'


    alert("OK")
    alert(“NG")
    alert("NG")
    OPODFCBTFΤϯίʔυ஋

    View Slide

  79. content-security-policy: script-src ‘nonce-EDNnf03nceIOfn39fn3e9h3sdfa'


    alert("OK")
    alert(“NG")
    alert("NG")
    OPODFͷ஋͕Ұக͍ͯ͠ΔͷͰ࣮ߦΛڐՄ
    OPODFCBTFΤϯίʔυ஋

    View Slide

  80. content-security-policy: script-src ‘nonce-EDNnf03nceIOfn39fn3e9h3sdfa'


    alert("OK")
    alert(“NG")
    alert("NG")
    OPODF஋͕ෆҰக·ͨ͸ະࢦఆͳͷͰ࣮ߦΛېࢭ
    OPODFCBTFΤϯίʔυ஋

    View Slide

  81. nonceͷ஫ҙ఺
    • nonceͷ஋͸αʔόʔଆͰϦΫΤετ͝ͱʹมߋ͢Δ͜ͱ


    • ਪଌ͞Εͳ͍ϥϯμϜͳ஋ʹ͢Δ͜ͱ


    • scriptλάΛಈతʹੜ੒Ͱ͖ͳ͍
    content-security-policy: script-src ‘nonce-EDNnf03nceIOfn39fn3e9h3sdfa'


    alert("OK")

    View Slide

  82. strict-dynamic
    content-security-policy: script-src ‘nonce-EDNnf03nceIOfn39fn3e9h3sdfa’ ‘strict-dynamic’


    <br/><br/><br/>const script = document.createElement('script');<br/><br/><br/>script.src = ‘/static/js/main.js’;<br/><br/><br/>document.head.appendChild(script);<br/><br/><br/>
    QBSTFSJOTFSUFEͰͳ͍TDSJQUͷಈతੜ੒͕Մೳ

    JOOFS)5.-ͳͲγϯΫʹͳΔؔ਺͸ېࢭ͞Ε͍ͯΔ
    ※parser-inserted = HTMLύʔαʔ΍XMLύʔαʔʹΑͬͯૠೖ͞ΕΔ͜ͱ

    View Slide

  83. CSPͷReport-OnlyϞʔυ
    • ࣮ࡍͷCSPΛద༻ͤͣʹϨϙʔτ͚ͩૹΔ͜ͱ͕Մೳ


    • CSPͰڐՄ͞Ε͍ͯͳ͍৔߹ɺϨϙʔτΛPOST͢Δ


    • CSPͷຊ൪ಋೖલʹӨڹΛ֬ೝ͢Δ͜ͱ͕Մೳ


    • λάͰͷઃఆ͸ෆՄ
    ▼ Response Headers


    content-security-policy-report-only: script-src ‘self’ *.trusted.com


    report-uri /csp-report


    View Slide

  84. Ϩϙʔτͷྫ
    {


    "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

  85. XSSରࡦͰॏཁͳ͜ͱ
    • XSSରࡦʹ͸༗໊ͳϥΠϒϥϦ΍ϑϨʔϜϫʔΫΛ࢖͍·͠ΐ͏


    • CSP͸XSSରࡦʹ͸ڧྗͳखஈ͚ͩͲɺ్தͰಋೖ͢Δͷ͸೉͍͠


    • αʔϏεͷϦϦʔεલʹಋೖ͠ɺे෼ʹݕূ͠·͠ΐ͏


    • ӡ༻தͷWebΞϓϦέʔγϣϯ͸Report-OnlyϞʔυͰӨڹൣғΛ
    े෼ʹ֬ೝ͔ͯ͠ΒCSPΛ༗ޮʹ͍͖ͯ͠·͠ΐ͏

    View Slide

  86. • ҉߸Խͷࣦഊ ➡ ௨৴σʔλͷ҉߸Խ


    • ΞΫηε੍ޚͷෆඋ ➡ CORSΛ࢖ͬͨΞΫηε੍ޚ


    • ΠϯδΣΫγϣϯ ➡ XSSରࡦ


    • ੬ऑͰݹ͘ͳͬͨίϯϙʔωϯτ ➡ ੬ऑͳϥΠϒϥϦͷνΣοΫ
    ࠓճ͓࿩͢ΔηΩϡϦςΟϦεΫ

    View Slide

  87. JavaScriptͷϥΠϒϥϦࣄ৘
    • Node.js / npmͷొ৔ʹΑΓJavaScriptͷϥΠϒϥϦ͕രൃతʹ
    ૿͑ͨ


    • Node.js΍ϑϩϯτΤϯυͳͲJSͷ։ൃͰ͸ଟ͘ͷϥΠϒϥϦ͕
    ࢖ΘΕ͍ͯΔ

    View Slide

  88. http://www.modulecounts.com/
    npmʹొ࿥͞Ε͍ͯΔϥΠϒϥϦ͕
    ѹ౗తͳ਺ʹͳ͍ͬͯΔ

    View Slide

  89. http://www.modulecounts.com/
    npmʹొ࿥͞Ε͍ͯΔϥΠϒϥϦ͕
    ѹ౗తͳ਺ʹͳ͍ͬͯΔ
    ਺͕ଟ͍෼ɺ
    ੬ऑੑͷ͋ΔϥΠϒϥϦ΋ଟ͍

    View Slide

  90. JavaScriptϥΠϒϥϦͷ੬ऑੑࣄ৘
    • ਓؾϥΠϒϥϦʹѱҙͷ͋Δίʔυ͕ૠೖ͞ΕΔࣄ݅


    • ESLint (JavaScriptͷ࠷΋ϙϐϡϥʔͳ੩తղੳπʔϧ)ʹѱҙ
    ͷ͋Δίʔυ͕ૠೖ͞Ε͍ͯͨ(2018೥7݄)


    • 1िؒʹ200ສDLͷϥΠϒϥϦevent-streamʹԾ૝௨՟΢Υ
    Ϩοτ͔Β҉߸伴Λ౪Έग़͢ػೳ͕ૠೖ͞ΕΔ(2018೥11݄)

    View Slide

  91. JavaScriptϥΠϒϥϦͷ੬ऑੑࣄ৘
    • ੈքͷτοϓ75,000ͷWebαΠτ(Alexaௐ΂)ͷ্Ґ37%͕Կ͔͠
    Βͷ੬ऑੑͷ͋ΔJSϥΠϒϥϦΛ࢖༻


    • ϊʔεΠʔελϯେֶͷݚڀνʔϜʹΑΔௐࠪ݁Ռ(2017೥)


    • ݹ͍ϥΠϒϥϦΛ࢖༻͍ͯ͠Δ


    • ޿ࠂ΍τϥοΩϯάɺιʔγϟϧϝσΟΞͷ΢ΟδΣοτʹຒΊ
    ࠐ·Ε͍ͯΔ͜ͱ͕ଟ͍

    View Slide

  92. ੬ऑͳϥΠϒϥϦͷ࢖༻Λ๷͙ରࡦ
    • npm auditίϚϯυΛ࢖ͬͨ੬ऑੑ਍அ


    • DependabotɺSnykɺyamoryͳͲΛ࢖ͬͨ੬ऑੑ਍அ

    View Slide

  93. npm auditΛ࢖͏
    • npmʹඪ४Ͱ૊Έࠐ·Ε͍ͯΔίϚϯυπʔϧ


    • ར༻͍ͯ͠Δnpmύοέʔδͷ੬ऑੑΛ਍அͯ͘͠ΕΔ


    • npm installΛ͢Δͱ͖ʹࣗಈͰ࣮ߦ͞ΕΔ


    • CIͰ࣮ߦ͢Ε͹ࣗಈͰ੬ऑੑͷ͋ΔϥΠϒϥϦͷར༻Λ๷͙͜ͱ͕Ͱ͖Δ


    • npm audit
    fi
    xίϚϯυͰ੬ऑͳϥΠϒϥϦͷΞοϓσʔτΛҰׅͰߦ͏͜ͱ
    ͕Ͱ͖Δ

    View Slide

  94. ੬ऑੑͷ͋ΔϥΠϒϥϦ΍πʔϧΛݕ஌͢Δ
    • ར༻͍ͯ͠ΔϥΠϒϥϦ΍πʔϧͷ੬ऑੑΛݕ஌͢Δ࢓૊ΈΛ੔
    ͑·͠ΐ͏


    • GitHubͷDependabotɺSnykɺyamoryͳͲ༷ʑͳαʔϏε͕ଘ
    ࡏ͢Δ


    • ͲͷαʔϏε΋ಠࣗͷػೳ΍੬ऑੑσʔλϕʔεͳͲΛ͍࣋ͬͯ
    Δ

    View Slide

  95. DependabotΛ࢖͏
    • GitHubʹඪ४ͰඋΘ͍ͬͯΔ੬ऑੑ਍அαʔϏε


    • ੬ऑੑͷ͋ΔϥΠϒϥϦΛΞοϓσʔτ͢ΔϓϧϦΫΤετΛࣗ
    ಈͰ࡞੒


    • ੬ऑੑͷ͋ΔϥΠϒϥϦ΍πʔϧΛҰཡͰ֬ೝͰ͖Δ


    • ϦϙδτϦͷઃఆը໘͔Β؆୯ʹ༗ޮʹͰ͖Δ

    View Slide

  96. ੬ऑͳϥΠϒϥϦΛݟ͚ͭΔͱɺ


    Dependabot͕ڭ͑ͯ͘ΕΔ

    View Slide

  97. Dependabot͕ϓϧϦΫΤετΛ࡞
    ੒ͯ͘͠ΕΔ

    View Slide

  98. ·ͱΊ
    • ͍·͙͢HTTPSԽ͠Α͏


    • CORSΛཧղͯ͠ద੾ʹΫϩεΦϦδϯͷΞΫηεΛ੍ޚ͠Α͏


    • XSSରࡦ͸ϥΠϒϥϦ΍ϑϨʔϜϫʔΫɺCSPΛ࢖͓͏


    • ϥΠϒϥϦʹ੬ऑੑ͕ͳ͍͔֬ೝ͢ΔͨΊͷ࢓૊ΈΛ੔͑Α͏

    View Slide

  99. ࠷ޙ·Ͱ͝ࢹௌ͍͖ͨͩ


    ͋Γ͕ͱ͏͍͟͝·ͨ͠

    View Slide