Slide 1

Slide 1 text

ϑϩϯτΤϯυ։ൃͷͨΊͷ ηΩϡϦςΟೖ໳ ฏ໺ ণ࢜ (@shisama_)

Slide 2

Slide 2 text

ฏ໺ ণ࢜ / Masashi Hirano Frontend Developer @shisama_ shisama Node.js Core Collaborator ࣾձਓେֶੜ@UoPeople

Slide 3

Slide 3 text

ʲએ఻ʳ2݄13೔ʹॻ੶Λग़൛͠·͢ʂ ੬ऑੑͷ࢓૊ΈͱରࡦΛίʔυ Λॻ͖ͳ͕Βֶ΂ΔϋϯζΦϯ ΋ܝࡌ͍ͯ͠·͢ʂ ࠓ೔͸ॻ੶͔Βൈਮͨ͠಺༰Λ ൃද͠·͢ɻ ϑϩϯτΤϯυ։ൃͷͨΊͷηΩϡϦςΟೖ໳

Slide 4

Slide 4 text

WebΞϓϦέʔγϣϯʹ͸ 
 ͲΜͳηΩϡϦςΟϦεΫ͕͋Δͷ͔

Slide 5

Slide 5 text

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

Slide 6

Slide 6 text

• ҉߸Խͷࣦഊ • ΞΫηε੍ޚͷෆඋ • ΠϯδΣΫγϣϯ • ੬ऑͰݹ͘ͳͬͨίϯϙʔωϯτ ࠓճ͓࿩͢ΔηΩϡϦςΟϦεΫ

Slide 7

Slide 7 text

• ҉߸Խͷࣦഊ ➡ ௨৴σʔλͷ҉߸Խ • ΞΫηε੍ޚͷෆඋ ➡ CORSΛ࢖ͬͨΞΫηε੍ޚ • ΠϯδΣΫγϣϯ ➡ XSSରࡦ • ੬ऑͰݹ͘ͳͬͨίϯϙʔωϯτ ➡ ੬ऑͳϥΠϒϥϦͷνΣοΫ ࠓճ͓࿩͢ΔηΩϡϦςΟϦεΫ

Slide 8

Slide 8 text

• ҉߸Խͷࣦഊ ➡ ௨৴σʔλͷ҉߸Խ • ΞΫηε੍ޚͷෆඋ ➡ CORSΛ࢖ͬͨΞΫηε੍ޚ • ΠϯδΣΫγϣϯ ➡ XSSରࡦ • ੬ऑͰݹ͘ͳͬͨίϯϙʔωϯτ ➡ ੬ऑͳϥΠϒϥϦͷνΣοΫ ࠓճ͓࿩͢ΔηΩϡϦςΟϦεΫ

Slide 9

Slide 9 text

Webϖʔδͷදࣔ͸ϒϥ΢βͱαʔόͷ௨৴͔Β͸͡·Δ HTML JS WebαΠτͷαʔό 
 site.example ଞͷWebαΠτ΍CDNͷαʔό JSON Ϣʔβ͕WebαΠτ΁ΞΫηε HTMLͳͲͷϦιʔεΛૹ৴ WebαΠτͱ͸ผͷαʔό΁ϦΫΤετ ϦιʔεΛૹ৴

Slide 10

Slide 10 text

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

Slide 11

Slide 11 text

HTTPͷऑ఺ • ௨৴σʔλͷ౪ௌ͕Մೳ • ௨৴૬ख͕ຊ෺͔Θ͔Βͳ͍ • ௨৴σʔλͷվ͟Μ

Slide 12

Slide 12 text

௨৴σʔλͷ౪ௌ • HTTPͷσʔλ͸҉߸Խ͞Ε͍ͯͳ͍ฏจͷ··ૹ৴͞ΕΔ • ௨৴్தͰ߈ܸऀ͕౪ௌ͢Δͱ 
 σʔλ͕ݟ͑ͯ͠·͏

Slide 13

Slide 13 text

௨৴૬ख͕ຊ෺͔Θ͔Βͳ͍ • ௨৴ઌͷαʔό͕ຊ෺͔Ͳ͏͔ূ໌Ͱ͖ͳ͍ • ِ෺ͷαʔό͕ຊ෺ʹͳΓ͢·͢͜ͱ͕Ͱ͖Δ • URLͰͷΈ௨৴૬खΛ 
 ಛఆ͢ΔͨΊɺِ෺͔ 
 Ͳ͏͔Θ͔Βͳ͍

Slide 14

Slide 14 text

௨৴σʔλͷվ͟Μ • ௨৴σʔλͷ಺༰͕ਖ਼͍͔͠ݕূ͢Δ࢓૊Έ͕ͳ͍ • ͨͱ͑͹ɺϒϥ΢β͕ૹ৴ͨ͠σʔλͱαʔό͕ड৴ͨ͠σʔλ͕Ұ க͢Δ͔ݕূͰ͖ͳ͍ • ௨৴్தͰվ͟Μʢॻ͖׵͑ʣ 
 ͕͋ͬͯ΋ݕ஌Ͱ͖ͳ͍

Slide 15

Slide 15 text

HTTPSԽͰHTTPͷऑ఺ͷࠀ෰ • ௨৴σʔλͷ҉߸Խ • ௨৴૬खͷݕূ • վ͟ΜνΣοΫ

Slide 16

Slide 16 text

HTTP௨৴ͷલʹ҉߸Խ௨৴Λ 
 ཱ֬͢Δ

Slide 17

Slide 17 text

௨৴σʔλͷ҉߸Խ • TLSͱ͍͏ϓϩτίϧΛར༻ͯ͠௨৴Λ҉߸Խ͢Δ • ҉߸Խʹ͸ʮެ։伴҉߸ํࣜʯͱʮڞ௨伴҉߸ํࣜʯΛ༻͍Δ 
 ެ։伴҉߸ํࣜɿ҉߸伴ͷड͚౉͠͸؆୯͕ͩॲཧ͕஗͍ 
 ڞ௨伴҉߸ํࣜɿ҉߸伴ͷड͚౉͠͸೉͍͕͠ॲཧ͸଎͍

Slide 18

Slide 18 text

௨৴૬खͷݕূ • ిࢠূ໌ॻΛ࢖ͬͯ௨৴૬ख͕ຊ෺͔ݕূ͢Δ • ిࢠূ໌ॻ͸ೝূہʢCAʣ͕ൃߦͨ͠΋ͷΛ࢖͏ • ϒϥ΢βʹ͸͋Β͔͡Ίϧʔτূ໌ॻͱݺ͹ΕΔిࢠূ໌ॻ͕૊Έࠐ ·Ε͓ͯΓɺαʔό͔Βड͚औͬͨిࢠূ໌ॻͱরΒ͠߹Θͤͯূ໌ ॻ͕ຊ෺͔ݕূ͢Δ • ূ໌ॻِ͕෺ͩͬͨ৔߹ɺϒϥ΢β͸ܯࠂը໘Λදࣔ͢Δ

Slide 19

Slide 19 text

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

Slide 20

Slide 20 text

WebαΠτશମͷHTTPSԽʢৗ࣌SSLԽʣ͕ඞਢʹͳ͖͍ͬͯͯΔ • IABʢΠϯλʔωοτΞʔΩςΫνϟҕһձʣ͕ʮ৽͘͠ϓϩτίϧ Λઃܭ͢Δͱ͖͸҉߸ػೳΛඞਢʹ͢΂͖ʯͱओு • HTTP઀ଓͷ৔߹ɺϒϥ΢βͷURLόʔʹܯࠂ͕ 
 දࣔ͞ΕΔ • HTTPS઀ଓͷϖʔδͰ͔͠࢖͑ͳ͍API΋͋Δ 
 ྫɿPayment Request API

Slide 21

Slide 21 text

WebαΠτΛHTTPSԽͷͨΊʹ͢Δ͜ͱ • Mixed ContentΛमਖ਼͢Δ • HTTP→HTTPS΁ͷϦμΠϨΫτઃఆ • HSTSΛઃఆ͢Δ

Slide 22

Slide 22 text

Mixed Contentͷةݥੑ • 1ͭͷϖʔδ্ͰHTTPSͰ഑৴͞ΕͨϦιʔεͱHTTPͰ഑৴͞ΕͨϦ ιʔε͕ࠞࡏ͢Δ͜ͱΛMixed ContentͱݺͿ • HTML͕HTTPSʹ഑৴͞Ε͍ͯͯ΋αϒϦιʔεͷJavaScriptͳͲ͕ HTTPͰ഑৴͞Ε͍ͯΔͱɺ͔ͦ͜Β߈ܸ͞ΕΔՄೳੑ͕͋Δ • Chrome DevToolsͳͲΛ࢖͍ͳ͕ΒMixed ContentΛमਖ਼͠ͳ͚Ε͹ ͳΒͳ͍

Slide 23

Slide 23 text

No content

Slide 24

Slide 24 text

HTTP→HTTPS΁ͷϦμΠϨΫτઃఆ • http://͔Β͸͡·ΔURLͷϦϯΫ͕ଞͷWebαΠτʹషΒΕ͍ͯΔͳ Ͳͷࣄ৘͔ΒHTTP഑৴Λ΍ΊΔ͜ͱ͕Ͱ͖ͳ͍͜ͱ΋͋Δ • HTMLʹαϒϦιʔεͷURLΛϕλॻ͖͍ͯ͠ΔͳͲͷ৔߹ɺҰ౓ʹ मਖ਼͸೉͍͠ͷͰHTTP഑৴Λ࢒͓ͯ͘͠έʔε΋͋Δ • αʔόଆͰHTTPͷϦΫΤετΛ͢΂ͯHTTPS΁ϦμΠϨΫτ͢Δઃ ఆΛೖΕΔ

Slide 25

Slide 25 text

HSTSΛઃఆ͢Δ • HSTSʢHTTP Strict Transport Securityʣ͸ϒϥ΢β͔Βૹ৴͢ΔϦΫ ΤετΛHTTPSʹڧ੍͢Δ͜ͱ͕Ͱ͖Δػೳ • Strict-Transport-SecurityϔομΛड͚औͬͨϒϥ΢β͸ͦͷWebαΠ τ΁ͷ࣍ճҎ߱ͷϦΫΤετ͸HTTPSͰߦ͏ • HSTSͷظݶΛઃఆ͢Δ 
 max-age͕ඞਢ

Slide 26

Slide 26 text

αϒυϝΠϯʹ΋HSTSΛઃఆ͢Δ • Strict-Transport-Security: 
 includeSubdomainsͰ 
 αϒυϝΠϯʹ΋HSTSΛ 
 ద༻ͤ͞Δ͜ͱ͕Մೳ

Slide 27

Slide 27 text

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

Slide 28

Slide 28 text

• ҉߸Խͷࣦഊ ➡ ௨৴σʔλͷ҉߸Խ • ΞΫηε੍ޚͷෆඋ ➡ CORSΛ࢖ͬͨΞΫηε੍ޚ • ΠϯδΣΫγϣϯ ➡ XSSରࡦ • ੬ऑͰݹ͘ͳͬͨίϯϙʔωϯτ ➡ ੬ऑͳϥΠϒϥϦͷνΣοΫ ࠓճ͓࿩͢ΔηΩϡϦςΟϦεΫ

Slide 29

Slide 29 text

֎෦͔ΒͷΞΫηεʹΑΔ໰୊ • ෳ਺ͷWebαΠτͷίϯςϯπΛ1ͭͷWebϖʔδͰར༻͢Δ͜ͱ͕ Մೳ • APIͷݺͼग़͠ɺiframeΛ࢖ͬͨίϯςϯπͷຒΊࠐΈɺը૾ͷऔ ಘ etc… • ͋ΒΏΔWebαΠτ͔Β੍ݶͳ͠ʹΞΫηεͰ͖Δঢ়ଶʹͳ͍ͬͯΔ ͱػີ৘ใͷ࿙͍͑΍վ͟ΜͳͲͷ߈ܸͷՄೳੑ͕͋Δ

Slide 30

Slide 30 text

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

Slide 31

Slide 31 text

Originͱ͍͏ڥք • ϒϥ΢β಺ʹ͸֎෦ͷΞΫηεΛ੍ݶ͢ΔOriginͱ͍͏ڥքઢ͕ઃ͚ ΒΕ͍ͯΔ • Origin͸εΩʔϜ+ϗετ໊+ϙʔτ൪߸ͷ૊Έ߹ΘͤΛࢦ͢

Slide 32

Slide 32 text

Originͱ͍͏ڥք • 2ͭͷURLͷOrigin͕ಉ͡৔߹ɺಉҰΦϦδϯʢSame OriginʣͱݺͿ • 2ͭͷURLͷOrigin͕ҟͳΔ৔߹ɺΫϩεΦϦδϯʢCross Origin)ͱ ݺͿ

Slide 33

Slide 33 text

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

Slide 34

Slide 34 text

Same Origin PolicyʹΑΔ੍ݶର৅ • JavaScriptʢfetchɺXHRʣΛ࢖ͬͨΫϩεΦϦδϯ΁ͷϦΫΤετ • JavaScriptΛ࢖ͬͨiframe಺ͷΫϩεΦϦδϯͷϖʔδ΁ͷΞΫηε • ΫϩεΦϦδϯͷը૾ΛಡΈࠐΜͩཁૉͷσʔλ΁ͷΞΫ ηε • Web Storage΍IndexedDBʹอଘ͞ΕͨΫϩεΦϦδϯͷσʔλ΁ͷ ΞΫηε

Slide 35

Slide 35 text

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

Slide 36

Slide 36 text

Cross Origin Resource SharingʢCORSʣ • CORSΛ࢖͑͹ɺΫϩεΦϦδϯؒͷϦΫΤετΛڐՄ͢Δ͜ͱͰ͖ Δ • JavaScriptʢfetchɺXHRʣΛ࢖ͬͨΫϩεΦϦδϯͱͷσʔλͷ΍Γ ͱΓ͕ՄೳʹͳΔ

Slide 37

Slide 37 text

CORSͷ࢓૊Έ • ΫϩεΦϦδϯͷαʔό΁ϦΫΤετࣗମ͸ૹ৴͞ΕͯɺϨεϙϯε ΋ฦͬͯ͘Δ • ϨεϙϯεͷCORSϔομʹΑͬͯαʔό͕ڐՄͨ͠ϦΫΤετͱ൑ அͨ͠Βɺϒϥ΢β͸ϨεϙϯεͷσʔλͷऔΓग़͠ΛڐՄ͢Δ

Slide 38

Slide 38 text

CORSͷ࢓૊Έ • αʔό͕ڐՄͨ͠Origin͔Ͳ͏͔൑ఆ͢ΔͨΊʹ 
 Access-Control-Allow-Originͱ͍͏ϨεϙϯεϔομΛར༻͢Δ 
 ྫ `Access-Control-Allow-Origin: https://site.example`

Slide 39

Slide 39 text

CORSͷ՝୊ • σʔλΛऔͬͯ͘Δ͚ͩͳΒ͜͜·Ͱͷઆ໌Ͱ໰୊ͳ͍ • σʔλΛߋ৽ɾ࡟আͳͲ෭࡞༻Λى͜͢ϦΫΤετͷ৔߹͸ɺϦΫΤ ετࣗମΛ๷͙ඞཁ͕͋Δ • ͨͱ͑͹σʔλΛ࡟আ͢ΔϦΫΤετ͕ૹ৴͞Εͯαʔό΁ಧ͘ͱ αʔό͸ϨεϙϯεΛฦ͢લʹσʔλΛ࡟আͯ͠͠·͏͔΋͠Εͳ͍ • Access-Control-Allow-OriginϔομͰ͸ɺϦΫΤετΛड͚औͬͨ αʔόͷಈ࡞·Ͱ͸੍ޚͰ͖ͳ͍

Slide 40

Slide 40 text

CORSͷ՝୊ ᶃ σʔλΛ࡟আ͢ΔϦΫΤετΛૹ৴ ᶅ Access-Control-Allow-OriginΛؚΉ 
 ϨεϙϯεΛૹ৴ ᶄ σʔλͷ࡟আॲཧΛ࣮ߦ ᶆ ϨεϙϯεΛഁغ Ϩεϙϯεσʔλ͸ഁغͰ͖ͯ΋ɺ σʔλͷ࡟আ͸ࢭΊΕ͍ͯͳ͍

Slide 41

Slide 41 text

CORSͷ࢓૊ΈʢϓϦϑϥΠτϦΫΤετʣ • ෭࡞༻Λى͜͢Α͏ͳϦΫΤετ͸ࣄલʹ໰୊ͳ͍͔֬ೝ͢Δ 
 ϓϦϑϥΠτϦΫΤετͱݺ͹ΕΔϦΫΤετ͕ૹ৴͞ΕΔ • ϓϦϑϥΠτϦΫΤετʹ͸OPTIONSͱ͍͏HTTPϝιου͕ར༻͞ Εɺ࣮ࡍͷσʔλͷߋ৽ɾ࡟আॲཧ͸͠ͳ͍ • ϨεϙϯεຊจʹσʔλΛؚΊͳ͍

Slide 42

Slide 42 text

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

Slide 43

Slide 43 text

ϓϦϑϥΠτϦΫΤετ͕ૹ৴͞ΕΔ৚݅ • GETɺHEADɺPOSTҎ֎ͷHTTPϝιου͕ར༻͞ΕΔͱ͖ • AcceptɺAccept-LanguageɺContent-LanguageɺContent-TypeҎ֎ ͷHTTPϔομ͕ૹ৴͞ΕΔͱ͖

Slide 44

Slide 44 text

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

Slide 45

Slide 45 text

No content

Slide 46

Slide 46 text

• ҉߸Խͷࣦഊ ➡ ௨৴σʔλͷ҉߸Խ • ΞΫηε੍ޚͷෆඋ ➡ CORSΛ࢖ͬͨΞΫηε੍ޚ • ΠϯδΣΫγϣϯ ➡ XSSରࡦ • ੬ऑͰݹ͘ͳͬͨίϯϙʔωϯτ ➡ ੬ऑͳϥΠϒϥϦͷνΣοΫ ࠓճ͓࿩͢ΔηΩϡϦςΟϦεΫ ଞʹ΋42-ΠϯδΣΫγϣϯͳͲ͕ ͋Δ͕ࠓ೔͸944͚ͩઆ໌͠·͢

Slide 47

Slide 47 text

XSSͱ͸ • ΫϩεαΠτεΫϦϓςΟϯάʢCross-Site Scriptingʣ • Webϖʔδ্ͷJavaScriptͷܽؕΛૂ͏߈ܸख๏ • ෆਖ਼ͳεΫϦϓτΛૠೖʢΠϯδΣΫγϣϯʣ࣮ͯ͠ߦ͢Δ͜ͱͰػ ີ৘ใͷ౪ΜͩΓɺϖʔδͷվ͟ΜΛߦͬͨΓ͢Δ • ଞͷ੬ऑੑʹൺ΂ͯใࠂ݅਺͕ଟ͍

Slide 48

Slide 48 text

XSSͷڴҖ • ػີ৘ใͷ࿙͍͑ • ِ৘ใͷදࣔ • ҙਤ͠ͳ͍ૢ࡞ͷ࣮ߦ • ηογϣϯ৘ใୣऔʹΑΔɺͳΓ͢·͠ • ِͷೖྗϑΥʔϜදࣔʹΑΔϑΟογϯά

Slide 49

Slide 49 text

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

Slide 50

Slide 50 text

3छྨͷXSS • ൓ࣹܕXSSʢRe fl ected XSS) • ஝ੵܕXSSʢStored XSSʣ • DOM-based XSS

Slide 51

Slide 51 text

൓ࣹܕXSS (Re fl ected XSS) ᶃ ߈ܸऀ͕༻ҙͨ͠ϖʔδʹΞΫηε ᶄ εΫϦϓτΛύϥϝʔλʹ ͯ͠ର৅αΠτʹભҠ alert("XSS") ?token=“”/>alert(“XSS")

Slide 52

Slide 52 text

൓ࣹܕXSSͷಛ௃ • αʔό಺ͰϨεϙϯεͷHTMLΛ૊ΈཱͯΔͱ͖ʹϦΫΤετʹؚ· ΕͨXSSͷίʔυΛͦͷ··HTML΁൓өͯ͠͠·͏ • ϦΫΤετ಺ʹෆਖ਼εΫϦϓτؚ͕·Ε͍ͯΔͱ͖ͷΈʹൃੜ͢Δ • ෆਖ਼ͳεΫϦϓτΛؚΉϦΫΤετΛૹ৴ͨ͠Ϣʔβʔ͚͕ͩඃ֐Λ ड͚Δ

Slide 53

Slide 53 text

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

    Slide 54

    Slide 54 text

    ஝ੵܕXSSͷಛ௃ • αʔό΁ૹ৴͞Εͨෆਖ਼εΫϦϓτΛσʔλϕʔεͳͲʹอଘͯ͠͠ ·͍ӬଓతʹXSSͷةݥ͕͋Δ • σʔλϕʔεͷ಺༰͕൓ө͞ΕΔશͯͷϢʔβʔ͕ඃ֐Λड͚Δ • σʔλϕʔε͔Βෆਖ਼εΫϦϓτΛؚΉσʔλΛ࡟আ͢ΔͳͲରॲ͠ ͳ͍ݶΓɺඃ֐͸ࢭ·Βͳ͍

    Slide 55

    Slide 55 text

    DOM-based XSS const hash = decodeURIComponent(location.hash.slice(1)); document.querySelector('#result').innerHTML = hash; ϩέʔγϣϯϋογϡͷ஋Λ JavaScriptͰૠೖ

    Slide 56

    Slide 56 text

    DOM-based XSSͷಛ௃ • ϒϥ΢β্ͷJavaScriptΛ࢖ͬͨDOMૢ࡞͕ݪҼͰൃੜ͢Δ • ଞͷ2ͭͱҧ͍ϑϩϯτΤϯυͷίʔυͷෆඋʹΑͬͯൃੜ͢Δ • αʔόΛհͣ͞ʹ߈ܸ͕੒ཱ͢ΔͨΊɺ߈ܸͷݕ஌΍ϩάऔಘ͕೉͠ ͍ • ϑϩϯτΤϯυͷJavaScript͸DevTools͔ΒݟΔ͜ͱ͕ग़དྷΔͨΊɺ ߈ܸऀ͸੬ऑੑΛൃݟ͠΍͍͢

    Slide 57

    Slide 57 text

    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 ͳͲ

    Slide 58

    Slide 58 text

    ୅දతͳXSSରࡦ • จࣈྻͷΤεέʔϓ • ReactɺVueɺAngularͳͲͷϑϨʔϜϫʔΫΛ࢖͏ • javascript:εΩʔϜͷURLΛຒΊࠐ·ͳ͍ • DOMPurifyͳͲͷϥΠϒϥϦ΍Sanitizer APIΛ࢖ͬͯةݥͳจࣈྻΛ আڈ͢Δ • Content Security Policy

    Slide 59

    Slide 59 text

    จࣈྻͷΤεέʔϓ cookieHijack() <script> cookieHijack() </script> & < ม׵લ ม׵ޙ > “ ‘ & < > " ' Τεέʔϓॲཧ

    Slide 60

    Slide 60 text

    ReactͳͲͷϑϨʔϜϫʔΫΛ࢖͏ • ReactɺVueɺAngularɺSvelteͳͲͷ༗໊ͳϥΠϒϥϦ/ϑϨʔϜϫʔΫ͸ΤεέʔϓॲཧΛ ࣗಈͰ΍ͬͯ͘ΕΔ • ։ൃऀ͸ΤεέʔϓॲཧΛ͢Δඞཁ͸ͳ͍ • ͨͩ͠ɺҰ෦ͷAPIΛ࢖͏͜ͱͰXSS͸ൃੜ͢Δ͜ͱ͕͋Γ·͢ • dangerouslySetInnerHTML͸innerHTMLͱಉ͘͡จࣈྻΛͦͷ··HTMLͱͯ͠ೝࣝ͢Δ ʢReactʣ • ޙड़ͷjavascript:εΩʔϜʹΑΔXSSʹ͸ରԠ͍ͯ͠ͳ͍ʢReactʣ • ίϯιʔϧʹܯࠂ͸ग़Δ

    Slide 61

    Slide 61 text

    javascript:εΩʔϜͷURLΛຒΊࠐ·ͳ͍ • ͨͱ͑͹ɺϦϯΫͷURLΛೖྗͰ͖ΔϑΥʔϜ͕͋ͬͨͱ͢Δ • ϑΥʔϜʹhttps://example.comͱೖྗͨ͠Βhttps://example.com ΁ͷϦϯΫ͕ੜ੒͞ΕΔͱ͢Δ ೚ҙͷ63-ΛઃఆՄೳͱ͢Δ

    Slide 62

    Slide 62 text

    javascript:εΩʔϜͷURLΛຒΊࠐ·ͳ͍ • ϑΥʔϜʹjavascript:alert(“xss”)ͱೖྗ͞ΕΔͱɺΫϦοΫͨ͠ͱ͖ ʹalert(“xss”)͕࣮ߦ͞ΕΔϦϯΫ͕Ͱ͖ͯ͠·͏ const App = (props) => (
    click me! KBWBTDSJQUεΩʔϜΛ࢖͑͹೚ҙͷ εΫϦϓτΛૠೖͰ͖Δ

    Slide 63

    Slide 63 text

    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-͚ͩΛ ઃఆ͢ΔΑ͏ʹϑΟϧλϦϯά͢Δ

    Slide 64

    Slide 64 text

    DOMPurifyΛ࢖ͬͨةݥͳจࣈྻͷআڈ • DOMPurify͸OSSͷϥΠϒϥϦ • npm΍CDN͔Βμ΢ϯϩʔυͯ͠࢖͏͜ͱ͕Ͱ͖Δ • จࣈྻ͔ΒXSSΛى͜͢ةݥͳจࣈྻΛ࡟আͯ͘͠ΕΔ const untrustedStr = location.hash; // const trustedStr = DOMPurify.sanitize(untrustedStr); $('#foo').innerHTML = trustedStr; //

    Slide 65

    Slide 65 text

    Sanitizer APIΛ࢖ͬͨةݥͳจࣈྻͷআڈ • ϒϥ΢βʹ૊Έࠐ·Ε͍ͯΔAPI • Ͱ͖Δ͜ͱ͸DOMPurifyͱࣅ͍ͯͯةݥͳจࣈྻΛআڈ͢Δ const untrustedStr = location.hash; // 
 const sanitizer = new Sanitizer(untrustedStr); const target = document.getElementById(untrustedStr); target.setHTML(untrustedStr, { sanitizer }); //

    Slide 66

    Slide 66 text

    Content Security Policy (CSP) • ڐՄ͞Ε͍ͯͳ͍JavaScriptͷ࣮ߦ΍ϦιʔεͷಡΈࠐΈͳͲΛϒ ϩοΫ͢Δϒϥ΢βͷػೳ • Content-Security-Policyͱ͍͏ϨεϙϯεϔομʹΑͬͯԿΛͲ͏ϒ ϩοΫ͢Δͷ͔ઃఆ͢Δ͜ͱ͕Մೳ

    Slide 67

    Slide 67 text

    No content

    Slide 68

    Slide 68 text

    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

    Slide 69

    Slide 69 text

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

    Slide 70

    Slide 70 text

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

    Slide 71

    Slide 71 text

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

    Slide 72

    Slide 72 text

    content-security-policy: script-src ‘self’ alert("XSS") ϗετͱϙʔτ͕ಉ͡εΫϦϓτͷΈڐՄ CSPͷྫ

    Slide 73

    Slide 73 text

    CSPͷྫ content-security-policy: script-src ‘self’ alert("XSS") ϗετͱϙʔτ͕ಉ͡εΫϦϓτͷΈڐՄ ࢦఆ͞Εͨϗετͱҧ͏ͷͰېࢭ ❌

    Slide 74

    Slide 74 text

    CSPͷྫ content-security-policy: script-src ‘self’ alert("XSS") ϗετͱϙʔτ͕ಉ͡εΫϦϓτͷΈڐՄ ❌ ❌ ΠϯϥΠϯεΫϦϓτ͸ېࢭ

    Slide 75

    Slide 75 text

    CSPͷྫ content-security-policy: script-src ‘self’ alert("XSS") ϗετͱϙʔτ͕ಉ͡εΫϦϓτͷΈڐՄ ❌ ❌ ❌ Πϕϯτଐੑ΍KBWBTDSJQUͳͲ΋ېࢭ

    Slide 76

    Slide 76 text

    CSPͷ՝୊ • CSP͕ద༻͞Ε͍ͯΔϖʔδͰ͸ΠϯϥΠϯεΫϦϓτ͸ېࢭ͞ΕΔ • unsafe-inlineΩʔϫʔυΛ࢖͑͹ΠϯϥΠϯεΫϦϓτΛڐՄͰ͖Δ ͕ɺXSSʹΑΓຒΊࠐ·ΕͨΠϯϥΠϯεΫϦϓτ·Ͱ࣮ߦͯ͠͠· ͏Մೳੑ͕͋Γ໊લͷͱ͓Γ҆શͰ͸ͳ͍ʢunsafe-inlineʣ • ϗετ໊ͷࢦఆ͸ᷖճ͕ՄೳͰ͋Δ※ 
 ※ https://research.google/pubs/pub45542/

    Slide 77

    Slide 77 text

    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';

    Slide 78

    Slide 78 text

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

    Slide 79

    Slide 79 text

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

    Slide 80

    Slide 80 text

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

    Slide 81

    Slide 81 text

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

    Slide 82

    Slide 82 text

    strict-dynamic content-security-policy: script-src ‘nonce-EDNnf03nceIOfn39fn3e9h3sdfa’ ‘strict-dynamic’ const script = document.createElement('script'); script.src = ‘/static/js/main.js’; document.head.appendChild(script); QBSTFSJOTFSUFEͰͳ͍TDSJQUͷಈతੜ੒͕Մೳ 
 JOOFS)5.-ͳͲγϯΫʹͳΔؔ਺͸ېࢭ͞Ε͍ͯΔ ※parser-inserted = HTMLύʔαʔ΍XMLύʔαʔʹΑͬͯૠೖ͞ΕΔ͜ͱ

    Slide 83

    Slide 83 text

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

    Slide 84

    Slide 84 text

    Ϩϙʔτͷྫ { "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" } }

    Slide 85

    Slide 85 text

    XSSରࡦͰॏཁͳ͜ͱ • XSSରࡦʹ͸༗໊ͳϥΠϒϥϦ΍ϑϨʔϜϫʔΫΛ࢖͍·͠ΐ͏ • CSP͸XSSରࡦʹ͸ڧྗͳखஈ͚ͩͲɺ్தͰಋೖ͢Δͷ͸೉͍͠ • αʔϏεͷϦϦʔεલʹಋೖ͠ɺे෼ʹݕূ͠·͠ΐ͏ • ӡ༻தͷWebΞϓϦέʔγϣϯ͸Report-OnlyϞʔυͰӨڹൣғΛ े෼ʹ֬ೝ͔ͯ͠ΒCSPΛ༗ޮʹ͍͖ͯ͠·͠ΐ͏

    Slide 86

    Slide 86 text

    • ҉߸Խͷࣦഊ ➡ ௨৴σʔλͷ҉߸Խ • ΞΫηε੍ޚͷෆඋ ➡ CORSΛ࢖ͬͨΞΫηε੍ޚ • ΠϯδΣΫγϣϯ ➡ XSSରࡦ • ੬ऑͰݹ͘ͳͬͨίϯϙʔωϯτ ➡ ੬ऑͳϥΠϒϥϦͷνΣοΫ ࠓճ͓࿩͢ΔηΩϡϦςΟϦεΫ

    Slide 87

    Slide 87 text

    JavaScriptͷϥΠϒϥϦࣄ৘ • Node.js / npmͷొ৔ʹΑΓJavaScriptͷϥΠϒϥϦ͕രൃతʹ ૿͑ͨ • Node.js΍ϑϩϯτΤϯυͳͲJSͷ։ൃͰ͸ଟ͘ͷϥΠϒϥϦ͕ ࢖ΘΕ͍ͯΔ

    Slide 88

    Slide 88 text

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

    Slide 89

    Slide 89 text

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

    Slide 90

    Slide 90 text

    JavaScriptϥΠϒϥϦͷ੬ऑੑࣄ৘ • ਓؾϥΠϒϥϦʹѱҙͷ͋Δίʔυ͕ૠೖ͞ΕΔࣄ݅ • ESLint (JavaScriptͷ࠷΋ϙϐϡϥʔͳ੩తղੳπʔϧ)ʹѱҙ ͷ͋Δίʔυ͕ૠೖ͞Ε͍ͯͨ(2018೥7݄) • 1िؒʹ200ສDLͷϥΠϒϥϦevent-streamʹԾ૝௨՟΢Υ Ϩοτ͔Β҉߸伴Λ౪Έग़͢ػೳ͕ૠೖ͞ΕΔ(2018೥11݄)

    Slide 91

    Slide 91 text

    JavaScriptϥΠϒϥϦͷ੬ऑੑࣄ৘ • ੈքͷτοϓ75,000ͷWebαΠτ(Alexaௐ΂)ͷ্Ґ37%͕Կ͔͠ Βͷ੬ऑੑͷ͋ΔJSϥΠϒϥϦΛ࢖༻ • ϊʔεΠʔελϯେֶͷݚڀνʔϜʹΑΔௐࠪ݁Ռ(2017೥) • ݹ͍ϥΠϒϥϦΛ࢖༻͍ͯ͠Δ • ޿ࠂ΍τϥοΩϯάɺιʔγϟϧϝσΟΞͷ΢ΟδΣοτʹຒΊ ࠐ·Ε͍ͯΔ͜ͱ͕ଟ͍

    Slide 92

    Slide 92 text

    ੬ऑͳϥΠϒϥϦͷ࢖༻Λ๷͙ରࡦ • npm auditίϚϯυΛ࢖ͬͨ੬ऑੑ਍அ • DependabotɺSnykɺyamoryͳͲΛ࢖ͬͨ੬ऑੑ਍அ

    Slide 93

    Slide 93 text

    npm auditΛ࢖͏ • npmʹඪ४Ͱ૊Έࠐ·Ε͍ͯΔίϚϯυπʔϧ • ར༻͍ͯ͠Δnpmύοέʔδͷ੬ऑੑΛ਍அͯ͘͠ΕΔ • npm installΛ͢Δͱ͖ʹࣗಈͰ࣮ߦ͞ΕΔ • CIͰ࣮ߦ͢Ε͹ࣗಈͰ੬ऑੑͷ͋ΔϥΠϒϥϦͷར༻Λ๷͙͜ͱ͕Ͱ͖Δ • npm audit fi xίϚϯυͰ੬ऑͳϥΠϒϥϦͷΞοϓσʔτΛҰׅͰߦ͏͜ͱ ͕Ͱ͖Δ

    Slide 94

    Slide 94 text

    ੬ऑੑͷ͋ΔϥΠϒϥϦ΍πʔϧΛݕ஌͢Δ • ར༻͍ͯ͠ΔϥΠϒϥϦ΍πʔϧͷ੬ऑੑΛݕ஌͢Δ࢓૊ΈΛ੔ ͑·͠ΐ͏ • GitHubͷDependabotɺSnykɺyamoryͳͲ༷ʑͳαʔϏε͕ଘ ࡏ͢Δ • ͲͷαʔϏε΋ಠࣗͷػೳ΍੬ऑੑσʔλϕʔεͳͲΛ͍࣋ͬͯ Δ

    Slide 95

    Slide 95 text

    DependabotΛ࢖͏ • GitHubʹඪ४ͰඋΘ͍ͬͯΔ੬ऑੑ਍அαʔϏε • ੬ऑੑͷ͋ΔϥΠϒϥϦΛΞοϓσʔτ͢ΔϓϧϦΫΤετΛࣗ ಈͰ࡞੒ • ੬ऑੑͷ͋ΔϥΠϒϥϦ΍πʔϧΛҰཡͰ֬ೝͰ͖Δ • ϦϙδτϦͷઃఆը໘͔Β؆୯ʹ༗ޮʹͰ͖Δ

    Slide 96

    Slide 96 text

    ੬ऑͳϥΠϒϥϦΛݟ͚ͭΔͱɺ Dependabot͕ڭ͑ͯ͘ΕΔ

    Slide 97

    Slide 97 text

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

    Slide 98

    Slide 98 text

    ·ͱΊ • ͍·͙͢HTTPSԽ͠Α͏ • CORSΛཧղͯ͠ద੾ʹΫϩεΦϦδϯͷΞΫηεΛ੍ޚ͠Α͏ • XSSରࡦ͸ϥΠϒϥϦ΍ϑϨʔϜϫʔΫɺCSPΛ࢖͓͏ • ϥΠϒϥϦʹ੬ऑੑ͕ͳ͍͔֬ೝ͢ΔͨΊͷ࢓૊ΈΛ੔͑Α͏

    Slide 99

    Slide 99 text

    ࠷ޙ·Ͱ͝ࢹௌ͍͖ͨͩ ͋Γ͕ͱ͏͍͟͝·ͨ͠