ã³ã³ãã³ãã»ãã¥ãªãã£ããªã·ã¼ (CSP)
ã³ã³ãã³ãã»ãã¥ãªãã£ããªã·ã¼ (CSP) ã¯ãç¹å®ã®ç¨®é¡ã®ã»ãã¥ãªãã£è å¨ã®ãªã¹ã¯ã鲿¢ã¾ãã¯æå°éã«æããã®ã«å½¹ç«ã¤æ©è½ã§ããããã¯ãã¦ã§ããµã¤ããããã©ã¦ã¶ã¼ã¸ã®ä¸é£ã®æç¤ºã§æ§æããã¦ããããµã¤ããæ§æããã³ã¼ããå®è¡ã§ãããã¨ãå¶éããããã«ãã©ã¦ã¶ã¼ã«æç¤ºãã¾ãã
CSP ã®ä¸»ãªç¨éã¯ãææ¸ãèªã¿è¾¼ããã¨ã許å¯ãããªã½ã¼ã¹ãç¹ã« JavaScript ãªã½ã¼ã¹ãå¶å¾¡ãããã¨ã§ããããã¯ä¸»ã«ãæ»æè ã被害è ã®ãµã¤ãã«æªæã®ããã³ã¼ããæ³¨å ¥ããã¯ãã¹ãµã¤ãã¹ã¯ãªããã£ã³ã° (XSS) æ»æã«å¯¾ããé²å¾¡ã¨ãã¦ä½¿ç¨ããã¾ãã
CSP ã«ã¯ä»ã«ããã¯ãªãã¯ã¸ã£ããã³ã°ããã®é²å¾¡ãããµã¤ãã®ãã¼ã¸ã HTTPS çµç±ã§ç¢ºå®ã«èªã¿è¾¼ã¾ããããã«ãããªã©ã®ç®çãããã¾ãã
ãã®ã¬ã¤ãã§ã¯ã CSP ããã©ã¦ã¶ã¼ã«é ä¿¡ãããä»çµã¿ã¨ããã®æ¦è¦ãè¦ã¦ãããã¨ããå§ãã¾ãã
次ã«ãXSS ããä¿è·ããããã«èªã¿è¾¼ããªã½ã¼ã¹ãå¶å¾¡ããããã«ä½¿ç¨ããæ¹æ³ãããã¦ã¯ãªãã¯ã¸ã£ããã³ã°ããã®ä¿è·ãä¿è·ããã¦ããªããªã¯ã¨ã¹ãã®ã¢ããã°ã¬ã¼ããªã©ããã以å¤ã®ä½¿ç¨ä¾ã«ã¤ãã¦è¨è¿°ãã¾ããç°ãªã使ç¨ä¾éã«ä¾åé¢ä¿ã¯ãªããã¨ã«æ³¨æãã¦ãã ãããã¯ãªãã¯ã¸ã£ããã³ã°ããã®ä¿è·ã追å ããããã XSS ã®ç·©åã¯è¿½å ããããªãå ´åã¯ããã®ä½¿ç¨ä¾ã«å¯¾å¿ãããã£ã¬ã¯ãã£ãã追å ããã ãã§æ¸ã¿ã¾ãã
æå¾ã«ã CSP ãå±éããããã®æ¦ç¥ã¨ããã®ããã»ã¹ã容æã«ãããã¼ã«ã«ã¤ãã¦èª¬æãã¾ãã
CSP ã®æ¦è¦
CSP ã¯ã Content-Security-Policy ã¬ã¹ãã³ã¹ãããã¼ã§ãã©ã¦ã¶ã¼ã«é
ä¿¡ããå¿
è¦ãããã¾ããããã¯ãã¡ã¤ã³ææ¸ã ãã§ãªãããã¹ã¦ã®ãªã¯ã¨ã¹ãã«å¯¾ãããã¹ã¦ã®ã¬ã¹ãã³ã¹ã«è¨å®ããå¿
è¦ãããã¾ãã
ã¾ããææ¸ã® <meta> è¦ç´ ã® http-equiv 屿§ã使ç¨ãã¦æå®ãããã¨ãã§ãã¾ããããã¯ãéçãªã½ã¼ã¹ã®ã¿ãæã¤ã¯ã©ã¤ã¢ã³ãå´ã§ã¬ã³ããªã³ã°ãããåä¸ãã¼ã¸ã¢ããªãªã©ããµã¼ãã¼ã¤ã³ãã©ã¹ãã©ã¯ãã£ã«ä¾åãããã¨ãé¿ãããå ´åãªã©ã«ä¾¿å©ãªãªãã·ã§ã³ã§ãããã ãããã®ãªãã·ã§ã³ã¯ CSP ã®ãã¹ã¦ã®æ©è½ã«å¯¾å¿ãã¦ããããã§ã¯ããã¾ããã
ããªã·ã¼ã¯ãã»ãã³ãã³ã§åºåãããä¸é£ã®ããã£ã¬ã¯ãã£ããã¨ãã¦æå®ãã¾ããåãã£ã¬ã¯ãã£ãã¯ãã»ãã¥ãªãã£ããªã·ã¼ã®ç°ãªãå´é¢ãå¶å¾¡ãã¾ããåãã£ã¬ã¯ãã£ãã«ã¯ãååããã®å¾ã«ç©ºç½ããã®å¾ã«å¤ãç¶ãã¾ãããã£ã¬ã¯ãã£ãã«ãã£ã¦æ§æãç°ãªãå ´åãããã¾ãã
ä¾ãã°ã次㮠CSP ãèãã¦ã¿ã¾ãããã
Content-Security-Policy: default-src 'self'; img-src 'self' example.com
ãã㯠2 ã¤ã®ãã£ã¬ã¯ãã£ããè¨å®ãã¾ãã
default-srcãã£ã¬ã¯ãã£ãã'self'ã«è¨å®img-srcãã£ã¬ã¯ãã£ãã'self' example.comã«è¨å®
æåã®ãã£ã¬ã¯ãã£ã default-src ã¯ããããããå
·ä½çãªãã£ã¬ã¯ãã£ãã§ä»ã®ãªã½ã¼ã¹ã¿ã¤ãã«å¯¾ãã¦å¥ã®ããªã·ã¼ãè¨å®ããã¦ããªãéããææ¸ã¨åããªãªã¸ã³ãæã¤ãªã½ã¼ã¹ã®ã¿ãèªã¿è¾¼ããããã©ã¦ã¶ã¼ã«æç¤ºãã¾ãã 2 çªç®ã® img-src ã¯ãåããªãªã¸ã³ãæã¤ç»åãã¾ã㯠example.com ããæä¾ããã¦ããç»åãèªã¿è¾¼ããããã©ã¦ã¶ã¼ã«æç¤ºãã¾ãã
次ã®ç¯ã§ã¯ã CSP ã®ä¸»ãªæ©è½ã§ãããªã½ã¼ã¹ã®èªã¿è¾¼ã¿ãå¶å¾¡ããããã«å©ç¨ã§ãããã¼ã«ãè¦ã¦ããã¾ãã
ãªã½ã¼ã¹èªã¿è¾¼ã¿ã®å¶å¾¡
CSP ã使ç¨ãã¦ãææ¸ãèªã¿è¾¼ããã¨ã許å¯ããããªã½ã¼ã¹ãå¶å¾¡ãããã¨ãã§ãã¾ããããã¯ä¸»ã«ãã¯ãã¹ãµã¤ãã¹ã¯ãªããã£ã³ã° ï¼XSSï¼ æ»æããã®ä¿è·ã«ä½¿ç¨ããã¾ãã
ãã®ç¯ã§ã¯ããªã½ã¼ã¹ã®èªã¿è¾¼ã¿ãå¶å¾¡ãããã¨ã§ XSS ããä¿è·ããæ¹æ³ã«ã¤ãã¦æåã«èª¬æããæ¬¡ã« CSP ãæä¾ãããèªã¿è¾¼ããªã½ã¼ã¹ãå¶å¾¡ããããã®ãã¼ã«ã«ã¤ãã¦èª¬æãã¾ããæå¾ã«ãã峿 ¼ãª CSPãã¨å¼ã°ãããæ¨å¥¨ãããå ·ä½çãªæ¦ç¥ã«ã¤ãã¦è¨è¿°ãã¾ãã
XSS ã¨ãªã½ã¼ã¹èªã¿è¾¼ã¿
ã¯ãã¹ãµã¤ãã¹ã¯ãªããã£ã³ã° (XSS) æ»æã¨ã¯ãæ»æè ãã¿ã¼ã²ããã®ã¦ã§ããµã¤ãã®ã³ã³ããã¹ãã§èªåã®ã³ã¼ããå®è¡ã§ããæ»æã§ãããã®ã³ã¼ãã¯ãä¾ãã°ã次ã®ãããªãã¦ã§ããµã¤ãã®ã³ã¼ãèªä½ãã§ãããããããã¨ãå®è¡ãããã¨ãã§ãã¾ãã
- ãµã¤ãã«èªã¿è¾¼ã¾ãããã¼ã¸ã®ã³ã³ãã³ãã«ã¢ã¯ã»ã¹ã¾ãã¯å¤æ´ãã
- ãã¼ã«ã«ã¹ãã¬ã¼ã¸å ã®ã³ã³ãã³ãã«ã¢ã¯ã»ã¹ã¾ãã¯å¤æ´ãã
- ã¦ã¼ã¶ã¼ã®è³æ ¼æ å ±ã使ç¨ã㦠HTTP ãªã¯ã¨ã¹ããè¡ããã¦ã¼ã¶ã¼ãå½è£ ããããæ©å¯ãã¼ã¿ã«ã¢ã¯ã»ã¹ããããã
XSS æ»æã¯ãæ»æè ã使ããå¯è½æ§ã®ããå ¥å ï¼URL 弿°ãããã°æç¨¿ã®ã³ã¡ã³ããªã©ï¼ ãã¦ã§ããµã¤ããåãå ¥ãã¦ãããããµãã¿ã¤ã¸ã³ã°ããã«ãã¼ã¸ã«è¨è¼ããå ´åãã¤ã¾ã JavaScript ã¨ãã¦å®è¡ãããªããã¨ã確å®ã«ããªãå ´åã«å®ç¾å¯è½ã§ãã
ã¦ã§ããµã¤ãã¯ããã®ãã¼ã¸ã«å«ããåã«ãã®å ¥åããµãã¿ã¤ã¸ã³ã°ãããã¨ã§ã XSS ããèªèº«ãä¿è·ããå¿ è¦ãããã¾ãã CSP ã¯ããµãã¿ã¤ã¸ã³ã°ã失æããå ´åã§ãã¦ã§ããµã¤ããä¿è·ã§ãããè£å®çãªä¿è·æ©è½ãæä¾ãã¾ãã
ãµãã¿ã¤ã¸ã³ã°ã失æããå ´åãæ§ã ãªå½¢ã®æªæã®ããã³ã¼ããææ¸ã«æ³¨å ¥ãããå¯è½æ§ãããã¾ãã
-
æªæã®ãããªã½ã¼ã¹ã¸ãªã³ã¯ãã
<script>ã¿ã°html<script src="https://evil.example.com/hacker.js"></script> -
ã¤ã³ã©ã¤ã³ JavaScript ãå«ã
<script>ã¿ã°html<script> console.log("ããã¯ããã¾ããï¼"); </script> -
ã¤ã³ã©ã¤ã³ã¤ãã³ããã³ãã©ã¼
html<img onmouseover="console.log(`ããã¯ããã¾ããï¼`)" src="thumbnail.jpg" alt="" /> -
javascript:URLhtml<iframe src="javascript:console.log(`ããã¯ããã¾ããï¼`)"></iframe> -
å®å ¨ã§ã¯ãªã APIããã¨ãã°
eval()ãªã©ã®æåå弿°jseval("console.log(`ããã¯ããã¾ããï¼`)");
CSP ã¯ãããããã¹ã¦ã«å¯¾ããä¿è·ãæä¾ã§ãã¾ããCSP ã使ç¨ããã¨ã次ã®ãã¨ãå¯è½ã«ãªãã¾ãã
- JavaScript ãã¡ã¤ã«ããã³ãã®ä»ã®ãªã½ã¼ã¹ã®è¨±å¯ã½ã¼ã¹ãå®ç¾©ãã
https://evil.example.comããã®èªã¿è¾¼ã¿ã广çã«ãããã¯ãã¾ãã - ã¤ã³ã©ã¤ã³ã® script ã¿ã°ãç¡å¹ã«ãã¾ãã
- æ£ãããã³ã¹ã¾ãã¯ããã·ã¥ãè¨å®ããã¦ãã script ã¿ã°ã®ã¿è¨±å¯ãã¾ãã
- ã¤ã³ã©ã¤ã³ã¤ãã³ããã³ãã©ã¼ãç¡å¹ã«ãã¾ãã
javascript:URL ãç¡å¹ã«ãã¾ããeval()ãªã©ã®å±éºãª API ãç¡å¹ã«ãã¾ãã
次ã®ç¯ã§ã¯ããããã®ãã¨ãè¡ãããã« CSP ãæä¾ãããã¼ã«ã«ã¤ãã¦èª¬æãã¾ãã
ã¡ã¢: CSP ãè¨å®ãããã¨ã¯ãå ¥åã®ãµãã¿ã¤ãºã«ä»£ãããã®ã§ã¯ããã¾ãããã¦ã§ããµã¤ãã¯ãå ¥åããµãã¿ã¤ãºããCSP ãè¨å®ãã¦ãXSS ã«å¯¾ããå¤å±¤é²å¾¡ãæä¾ããå¿ è¦ãããã¾ãã
ãã§ãããã£ã¬ã¯ãã£ã
ãã§ãããã£ã¬ã¯ãã£ãã¯ãææ¸ãèªã¿è¾¼ããã¨ã許å¯ãããªã½ã¼ã¹ã®ç¹å®ã®ã«ãã´ãªã¼ï¼JavaScriptãCSS ã¹ã¿ã¤ã«ã·ã¼ããç»åããã©ã³ããªã©ï¼ãæå®ããããã«ä½¿ç¨ããã¾ãã
ãªã½ã¼ã¹ã®ç¨®é¡ã«ãã£ã¦ããã§ãããã£ã¬ã¯ãã£ãã¯ç°ãªãã¾ããä¾ã示ãã¾ãã
script-src㯠JavaScript ã«è¨±å¯ãããã½ã¼ã¹ãè¨å®ãã¾ããstyle-src㯠CSS ã¹ã¿ã¤ã«ã·ã¼ãã«è¨±å¯ãããã½ã¼ã¹ãè¨å®ãã¾ããimg-srcã¯ç»åã«è¨±å¯ãããã½ã¼ã¹ãè¨å®ãã¾ãã
ç¹å¥ãªãã§ãããã£ã¬ã¯ãã£ãã¨ã㦠default-src ãããã¾ããããã¯ããã£ã¬ã¯ãã£ããæç¤ºçã«æ²è¼ããã¦ããªããã¹ã¦ã®ãªã½ã¼ã¹ã®ä»£æ¿ããªã·ã¼ãè¨å®ãã¾ãã
ãã§ãããã£ã¬ã¯ãã£ãã®å®å ¨ãªã»ããã«ã¤ãã¦ã¯ããªãã¡ã¬ã³ã¹ææ¸ãåç §ãã¦ãã ããã
ããããã®ãã§ãããã£ã¬ã¯ãã£ãã¯ãåä¸ã®ãã¼ã¯ã¼ã 'none' ã¾ãã¯ã空éã§åºåããã 1 ã¤ä»¥ä¸ã®ãã½ã¼ã¹å¼ãã¨ãã¦æå®ãã¾ããè¤æ°ã®ã½ã¼ã¹å¼ãæ²è¼ããã¦ããå ´åãããããã®ã¡ã½ããããªã½ã¼ã¹ã許å¯ãã¦ããå ´åããã®ãªã½ã¼ã¹ã¯è¨±å¯ããã¾ãã
ä¾ãã°ãä¸è¨ã® CSP 㯠2 ã¤ã®ãã§ãããã£ã¬ã¯ãã£ããè¨å®ãã¦ãã¾ãã
default-srcã«ã¯ãåä¸ã®ã½ã¼ã¹å¼'self'ãæå®ããã¦ãã¾ããimg-srcã«ã¯ã2 ã¤ã®ã½ã¼ã¹å¼'self'ããã³example.comãæå®ããã¦ãã¾ãã
ããã¯æ¬¡ã®ãããªå¹æã«ãªãã¾ãã
- ç»åã¯ãææ¸ã¨åããªãªã¸ã³ã§ãããã
example.comããèªã¿è¾¼ã¾ãã¦ããå¿ è¦ãããã¾ãã - ãã以å¤ã®ãã¹ã¦ã®ãªã½ã¼ã¹ã¯ãææ¸ã¨åããªãªã¸ã³ã§ããå¿ è¦ãããã¾ãã
次ã®ããã¤ãã®ç¯ã§ã¯ãã½ã¼ã¹å¼ã使ç¨ãã¦ãªã½ã¼ã¹ã®èªã¿è¾¼ã¿ãå¶å¾¡ããããã¤ãã®æ¹æ³ã«ã¤ãã¦èª¬æãã¾ãããããã¯åå¥ã«èª¬æãã¦ãã¾ããããããã®å¼ã¯ä¸è¬çã«çµã¿åããããã¨ãã§ãã¾ããä¾ãã°ãåä¸ã®ãã§ãããã£ã¬ã¯ãã£ãã«ã¯ããã¹ãåã ãã§ãªããã³ã¹ãå«ãããã¨ãã§ãã¾ãã
ãªã½ã¼ã¹ã®ãããã¯
ãªã½ã¼ã¹åãå®å
¨ã«ãããã¯ããã«ã¯ããã¼ã¯ã¼ã 'none' ã使ç¨ãã¾ããä¾ãã°ã次ã®ãã£ã¬ã¯ãã£ãã¯ããã¹ã¦ã® <object> ããã³ <embed> ãªã½ã¼ã¹ããããã¯ãã¾ãã
Content-Security-Policy: object-src 'none'
'none' ã¯ãç¹å®ã®ãã£ã¬ã¯ãã£ãã§ã¯ä»ã®ã¡ã½ããã¨çµã¿åããããã¨ã¯ã§ãã¾ãããå®éã«ã¯ã'none' ã®æ¨ªã«ä»ã®ã½ã¼ã¹å¼ãæå®ããã¦ããå ´åããããã¯ç¡è¦ããã¾ãã
ãã³ã¹
nonce ã使ç¨ããæ¹æ³ãã <script> ããã³ <style> ã®ãªã½ã¼ã¹ã®èªã¿è¾¼ã¿ãå¶éããããã®æ¨å¥¨ãããæ¹æ³ã§ãã
ãã³ã¹ã使ç¨ããã¨ããµã¼ãã¼ã¯ HTTP ã¬ã¹ãã³ã¹ãã¨ã«ã©ã³ãã ãªå¤ãçæããããã script-src ããã³/ã¾ã㯠style-src ãã£ã¬ã¯ãã£ãã«è¨è¼ãã¾ãã
Content-Security-Policy:
script-src 'nonce-416d1177-4d12-4e3b-b7c9-f6c409789fb8'
ãµã¼ãã¼ã¯ããã®å¤ããææ¸å
ã«çµã¿è¾¼ãäºå®ã®ãã¹ã¦ã® <script> ããã³/ã¾ã㯠<style> ã¿ã°ã® nonce 屿§ã®å¤ã¨ãã¦è¨è¼ãã¾ãã
ãã©ã¦ã¶ã¼ã¯ 2 ã¤ã®å¤ãæ¯è¼ããããããä¸è´ããå ´åã«ã®ã¿ãªã½ã¼ã¹ãèªã¿è¾¼ã¿ã¾ãããã®ã¢ã¤ãã£ã¢ã¯ãæ»æè ããã¼ã¸ã« JavaScript ãæ¿å ¥ã§ããã¨ãã¦ããæ»æè ã¯ãµã¼ãã¼ã使ç¨ãããã³ã¹ãç¥ããªãããããã©ã¦ã¶ã¼ã¯ã¹ã¯ãªããã®å®è¡ãæå¦ããã¨ãããã®ã§ãã
ãã®ææ³ãæ©è½ããã«ã¯ãæ»æè ããã³ã¹ãæ¨æ¸¬ã§ããªããã¨ãå¿ è¦ã§ãã
å®éã«ã¯ãããã¯ããã³ã¹ã¯ãã¹ã¦ã® HTTP ã¬ã¹ãã³ã¹ã§ç°ãªã£ã¦ãããäºæ¸¬ä¸å¯è½ã§ãªããã°ãªããªãã¨ãããã¨ã§ãã
ããã¯ããµã¼ãã¼ã¯æ¯åæ°ãããã³ã¹ãæ¿å ¥ããªããã°ãªããªããããéç㪠HTML ãæä¾ã§ããªããã¨ãæå³ãã¾ããé常ããµã¼ãã¼ã¯ãã³ãã¬ã¼ãã¨ã³ã¸ã³ã使ç¨ãã¦ãã³ã¹ãæ¿å ¥ãã¾ãã
以ä¸ã¯ãããã示ã Express ã®ã³ã¼ãã®æç²ã§ãã
function content(nonce) {
return `
<script nonce="${nonce}" src="/main.js"></script>
<script nonce="${nonce}">console.log("hello!");</script>
<h1>Hello world</h1>
`;
}
app.get("/", (req, res) => {
const nonce = crypto.randomUUID();
res.setHeader("Content-Security-Policy", `script-src 'nonce-${nonce}'`);
res.send(content(nonce));
});
ãªã¯ã¨ã¹ããã¨ã«ããµã¼ãã¼ã¯æ°ãããã³ã¹ãçæããããã CSP ããã³è¿ãããææ¸å
ã® <script> ã¿ã°ã«æ¿å
¥ãã¾ãããµã¼ãã¼ã¯æ¬¡ã®ãã¨ãè¡ããã¨ã«æ³¨æãã¦ãã ããã
- ãªã¯ã¨ã¹ããã¨ã«æ°ãããã³ã¹ãçæãã¾ãã
- å¤é¨ã¹ã¯ãªããã¨ã¤ã³ã©ã¤ã³ã¹ã¯ãªããã®ä¸¡æ¹ã§ãã³ã¹ã使ç¨ãããã¨ãã§ãã¾ãã
- ææ¸å
ã®ãã¹ã¦ã®
<script>ã¿ã°ã«åããã³ã¹ã使ç¨ãã¾ãã
ãµã¼ãã¼ã¯ããã³ã¹ãæ¿å
¥ããããã«ä½ããã®ãã³ãã¬ã¼ãã使ç¨ãããã¹ã¦ã® <script> ã¿ã°ã«ãã³ã¹ãæ¿å
¥ããªããã¨ãéè¦ã§ããããããªãã¨ããµã¼ãã¼ããæ»æè
ã«ãã£ã¦æ¿å
¥ãããã¹ã¯ãªããã«èª¤ã£ã¦ãã³ã¹ãæ¿å
¥ãã¦ãã¾ãå¯è½æ§ãããã¾ãã
ãã³ã¹ã¯ãnonce 屿§ãæã¤è¦ç´ ãã¤ã¾ã <script> ããã³ <style> è¦ç´ ã«ã®ã¿ä½¿ç¨ã§ãããã¨ã«æ³¨æãã¦ãã ããã
ããã·ã¥
ãã§ãããã£ã¬ã¯ãã£ãã¯ããã®æ´åæ§ãä¿è¨¼ããããã«ãã¹ã¯ãªããã®ããã·ã¥ã使ç¨ãããã¨ãã§ãã¾ãããã®ã¡ã½ããã使ç¨ããã¨ããµã¼ãã¼ã¯æ¬¡ã®ããã«ãªãã¾ãã
- ããã·ã¥é¢æ° ï¼SHA-256ãSHA-384ãSHA-512 ã®ããããï¼ ã使ç¨ãã¦ãã¹ã¯ãªããã®ã³ã³ãã³ãã®ããã·ã¥ãè¨ç®ãã¾ãã
- çµæã® Base64 ã¨ã³ã³ã¼ãã使ãã¾ãã
- 使ç¨ããã¦ããããã·ã¥ã¢ã«ã´ãªãºã ï¼
sha256-ãsha384-ãsha512-ã®ããããï¼ ãèå¥ããæ¥é è¾ã追å ãã¾ãã
次ã«ããã®çµæããã£ã¬ã¯ãã£ãã«è¿½å ãã¾ãã
Content-Security-Policy: script-src 'sha256-cd9827ad...'
ãã©ã¦ã¶ã¼ãææ¸ãåä¿¡ããã¨ãã¹ã¯ãªãããããã·ã¥åãããã®çµæããããã¼ã®å¤ã¨æ¯è¼ããä¸è´ããå ´åã«ã®ã¿ã¹ã¯ãªãããèªã¿è¾¼ã¿ã¾ãã
ãã®ã¡ã½ãããæ©è½ããããã«ã¯ãå¤é¨ã¹ã¯ãªããã«ã integrity 屿§ãå«ã¾ãã¦ããå¿
è¦ãããã¾ãã
以ä¸ã¯ãããã示ã Express ã®ã³ã¼ãã®æç²ã§ãã
const hash1 = "sha256-ex2O7MWOzfczthhKm6azheryNVoERSFrPrdvxRtP8DI=";
const hash2 = "sha256-H/eahVJiG1zBXPQyXX0V6oaxkfiBdmanvfG9eZWSuEc=";
const csp = `script-src '${hash1}' '${hash2}'`;
const content = `
<script src="./main.js" integrity="${hash2}"></script>
<script>console.log("hello!");</script>
<h1>Hello world</h1>
`;
app.get("/", (req, res) => {
res.setHeader("Content-Security-Policy", csp);
res.send(content);
});
次ã®ç¹ã«æ³¨æãã¦ãã ããã
- ææ¸å ã®ãã¹ã¦ã®ã¹ã¯ãªããã«åå¥ã®ããã·ã¥ãè¨å®ãã¦ãã¾ãã
- å¤é¨ã¹ã¯ãªãã "main.js" ã«ã
integrity屿§ãè¨è¼ããåãå¤ãæå®ãã¦ãã¾ãã - ãã³ã¹ã使ç¨ããä¾ã¨ã¯ç°ãªããããã·ã¥ã¯å¤åããªããããCSP ã¨ã³ã³ãã³ãã¯ã©ã¡ããéçã§ãããã¨ãã§ãã¾ããããã«ãããããã·ã¥ãã¼ã¹ã®ããªã·ã¼ã¯ãã¯ã©ã¤ã¢ã³ãå´ã®ã¬ã³ããªã³ã°ã«ä¾åããéçãªãã¼ã¸ãã¦ã§ããµã¤ãã«ããé©ãããã®ã«ãªãã¾ãã
ã¹ãã¼ã ãã¼ã¹ã®ããªã·ã¼
ãã§ãããã£ã¬ã¯ãã£ãã¯ãhttps: ã®ãããªã¹ãã¼ã ããªã¹ããã¦ããã®ã¹ãã¼ã ã使ç¨ãã¦æä¾ããããªã½ã¼ã¹ã許å¯ãããã¨ãã§ãã¾ããä¾ãã°ãããã«ããããã¹ã¦ã®ãªã½ã¼ã¹ã®èªã¿è¾¼ã¿ã« HTTPS ãè¦æ±ããããªã·ã¼ãè¨å®ãããã¨ãã§ãã¾ãã
Content-Security-Policy: default-src https:
å ´æãã¼ã¹ã®ããªã·ã¼
ãã§ãããã£ã¬ã¯ãã£ãã¯ããªã½ã¼ã¹ã®å ´æã«åºã¥ãã¦ãªã½ã¼ã¹ã®èªã¿è¾¼ã¿ãå¶å¾¡ã§ãã¾ãã
ãã¼ã¯ã¼ã 'self' ã¯ãææ¸èªä½ã¨åããªãªã¸ã³ãæã¤ãªã½ã¼ã¹ã許å¯ãã¾ãã
Content-Security-Policy: img-src 'self'
ã¾ããã¯ã¤ã«ãã«ã¼ããå«ã 1 ã¤ä»¥ä¸ã®ãã¹ãåãæå®ãã¦ããããã®ãã¹ãããæä¾ããããªã½ã¼ã¹ã®ã¿ã許å¯ãããã¨ãã§ãã¾ããããã¯ãä¾ãã°ãä¿¡é ¼ã§ãã CDN ããã³ã³ãã³ããæä¾ããããã«ä½¿ç¨ãããã¨ãã§ãã¾ãã
Content-Security-Policy: img-src *.example.org
è¤æ°ã®å ´æãæå®ãããã¨ãã§ãã¾ããæ¬¡ã®ãã£ã¬ã¯ãã£ãã¯ãç¾å¨ã®ææ¸ã¨åãèµ·æºã®ç»åãã¾ã㯠"example.org" ã®ãµããã¡ã¤ã³ããæä¾ããã¦ããç»åãããã㯠"example.com" ããæä¾ããã¦ããç»åã®ã¿ã許å¯ãã¾ãã
Content-Security-Policy: img-src 'self' *.example.org example.com
ã¤ã³ã©ã¤ã³ JavaScript
CSP ã« default-src ã¾ã㯠script-src ãã£ã¬ã¯ãã£ããå«ã¾ãã¦ããå ´åããããæå¹ã«ãã追å ã®æªç½®ãè¬ããªãéããã¤ã³ã©ã¤ã³ JavaScript ã¯å®è¡ã§ãã¾ãããããã«ã¯ä»¥ä¸ãå«ã¾ãã¾ãã
-
ãã¼ã¸å ã®
<script>è¦ç´ å ã«å«ã¾ãã JavaScripthtml<script> console.log("ã¤ã³ã©ã¤ã³ã¹ã¯ãªããããããã«ã¡ã¯"); </script> -
ã¤ã³ã©ã¤ã³ã¤ãã³ããã³ãã©ã¼å±æ§ã§ã® JavaScript
html<img src="x" onerror="console.log('ã¤ã³ã©ã¤ã³ã¤ãã³ããã³ãã©ã¼ããããã«ã¡ã¯')" /> -
javascript:URL å ã® JavaScripthtml<a href="javascript:console.log('javascript: URL ããããã«ã¡ã¯')">ãããã¯ãªãã¯</a>
unsafe-inline ãã¼ã¯ã¼ãã使ç¨ããã¨ããã®å¶éã䏿¸ããããã¨ãã§ãã¾ããä¾ãã°ã次ã®ãã£ã¬ã¯ãã£ãã¯ããã¹ã¦ã®ãªã½ã¼ã¹ãåããªãªã¸ã³ã§ãããã¨ãè¦æ±ãã¾ãããã¤ã³ã©ã¤ã³ JavaScript ã¯è¨±å¯ãã¾ãã
Content-Security-Policy: default-src 'self' 'unsafe-inline'
è¦å:
'unsafe-inline' ã¯ãCSP ãä¿æããç®çã®å¤§åãç¡å¹ã«ãã¦ãã¾ããããéçºè
ã¯ä½¿ç¨ãé¿ãã¾ããããã¤ã³ã©ã¤ã³ JavaScript ã¯æãä¸è¬ç㪠XSS ãã¯ãã«ã® 1 ã¤ã§ãããCSP ã®æãåºæ¬çãªç®æ¨ã® 1 ã¤ã¯ããã®ç¡å¶éãªä½¿ç¨ãé²ããã¨ã§ãã
ã¤ã³ã©ã¤ã³ <script> è¦ç´ ã¯ãä¸è¨ã§è¨è¿°ããã¦ããããã«ããã³ã¹ã¾ãã¯ããã·ã¥ã«ãã£ã¦ä¿è·ããã¦ããå ´åã«ä½¿ç¨ã§ãã¾ãã
ãã£ã¬ã¯ãã£ãã«ãã³ã¹ã¾ãã¯ããã·ã¥å¼ãå«ã¾ãã¦ããå ´åãunsafe-inline ãã¼ã¯ã¼ãã¯ãã©ã¦ã¶ã¼ã«ãã£ã¦ç¡è¦ããã¾ãã
eval() ããã³åæ§ã® API
ã¤ã³ã©ã¤ã³ JavaScript ã¨åæ§ã«ãCSP ã« default-src ã¾ã㯠script-src ãã£ã¬ã¯ãã£ããå«ã¾ãã¦ããå ´åãeval() ããã³é¡ä¼¼ã® API ã¯å®è¡ã§ãã¾ãããããã«ã¯ãä»ã® API ã®ä¸ã§ãç¹ã«ä»¥ä¸ã®ãã®ãå«ã¾ãã¾ãã
-
eval()èªä½jseval('console.log("eval() ããããã«ã¡ã¯")'); -
Function()ã³ã³ã¹ãã©ã¯ã¿ã¼jsconst sum = new Function("a", "b", "return a + b"); -
setTimeout()ãsetInterval()ã®æåå弿°jssetTimeout("console.log('setTimeout ããããã«ã¡ã¯')", 1);
unsafe-eval ãã¼ã¯ã¼ãã使ç¨ãã¦ãã®åä½ã䏿¸ããããã¨ãã§ãã¾ãã unsafe-inline ã¨åæ§ããã®çç±ãåæ§ã§ããéçºè
㯠unsafe-eval ã使ç¨ãããã¨ã¯é¿ããã¹ãã§ãã
eval() ããã®ä»ã®ã¡ã½ããã®ä½¿ç¨ããã¹ã¦é¤å»ãããã¨ãå°é£ãªå ´åãããã¾ãããã®ãããªç¶æ³ã§ã¯ã ä¿¡é ¼å API ã使ç¨ãããã¨ã§ãå
¥åãå®ç¾©ãããããªã·ã¼ã«ç¢ºå®ã«é©åããããã«ãã¦ãå®å
¨æ§ãé«ãããã¨ãã§ãã¾ãã
ãã®å ´åãtrusted-types-evalãã¼ã¯ã¼ãã使ç¨ãã¦åä½ã䏿¸ããã¾ãããã
unsafe-inlineã¨ã¯ç°ãªããä¿¡é ¼åã対å¿ãã¦ããæå¹ã«ãªã£ã¦ãããã©ã¦ã¶ã¼ã§ã®ã¿åä½ã䏿¸ããã¾ããããã«ãããä¿¡é ¼åã«å¯¾å¿ãã¦ããªããã©ã¦ã¶ã¼ã§ã¯ã¡ã½ããããããã¯ãããã¾ã¾ã«ãªãã¾ãã
unsafe-inline ã¨ã¯ç°ãªããunsafe-eval ãã¼ã¯ã¼ãã¯ããã³ã¹å¼ã¾ãã¯ããã·ã¥å¼ãå«ã¾ãã¦ãããã£ã¬ã¯ãã£ãå
ã§ãåä½ãã¾ãã
峿 ¼ãª CSP
XSS 対çã¨ãã¦ã¹ã¯ãªããã®èªã¿è¾¼ã¿ãå¶å¾¡ããã«ã¯ã nonce- or hash- ãã¼ã¹ã®ãã§ãããã£ã¬ã¯ãã£ãã使ç¨ãããã¨ããå§ããã¾ããããã¯å³æ ¼ãª CSP ã¨å¼ã°ãã¾ãããã®ã¿ã¤ãã® CSP ã«ã¯ãå ´æãã¼ã¹ã® CSP ï¼é常ã¯ã許å¯ãªã¹ã CSPãã¨å¼ã°ãã¾ãï¼ ã«å¯¾ã㦠2 ã¤ã®å¤§ããªå©ç¹ãããã¾ãã
- CSP ã®è¨±å¯ãªã¹ãã¯æ£ããè¨å®ãããã¨ãé£ãããå¤ãã®å ´åãããªã·ã¼ã誤ã£ã¦å®å ¨ã§ãªããã¡ã¤ã³ããã¯ã¤ããªã¹ãã«ç»é²ãã¦ãã¾ããããXSS ã«å¯¾ãã广çãªä¿è·ãæä¾ã§ãã¾ããï¼CSP Is Dead, Long Live CSP! On the Insecurity of Whitelists and the Future of Content Security Policy ãåç §ãã¦ãã ããï¼ã
- CSP ã®è¨±å¯ãªã¹ãã¯é常ã«å¤§è¦æ¨¡ã«ãªããç¹ã«èªåã®å¶å¾¡ãåã°ãªãã¹ã¯ãªããã使ç¨ãã¦ããå ´åã¯ããã®ç®¡çãå°é£ã«ãªãå¯è½æ§ãããã¾ãã How I learned to stop worrying and love the Content Security Policy ã¨ããè¨äºã«ããã¨ã Google Analytics ãçµ±åããããã ãã«ãéçºè 㯠187 ä»¶ã® Google ãã¡ã¤ã³ã許å¯ãªã¹ãã«è¿½å ããããè¦æ±ããã¾ããã
ãã³ã¹ãã¼ã¹ã®å³æ ¼ãª CSP ã¯ã次ã®ããã«è¦ã¦ããã¾ãã
Content-Security-Policy:
script-src 'nonce-{RANDOM}';
object-src 'none';
base-uri 'none';
ãã® CSP ã§ã¯ã次ã®ãã¨ãè¡ãã¾ãã
- éã³ã¹ã使ç¨ãã¦ãèªã¿è¾¼ããã¨ã許å¯ãã JavaScript ãªã½ã¼ã¹ãå¶å¾¡ãã¾ãã
- ãã¹ã¦ã®ãªãã¸ã§ã¯ãã®åãè¾¼ã¿ããããã¯ãã¾ãã
- ãã¼ã¹ URI ãè¨å®ããããã®
<base>è¦ç´ ã®ä½¿ç¨ããã¹ã¦ãããã¯ãã¾ãã
ããã·ã¥ãã¼ã¹ã®å³æ ¼ãª CSP ãåæ§ã§ããããã³ã¹ã®ä»£ããã«ããã·ã¥ã使ç¨ãã¾ãã
Content-Security-Policy:
script-src 'sha256-{HASHED_SCRIPT}';
object-src 'none';
base-uri 'none';
ã³ã³ãã³ãèªä½ãå«ãã¬ã¹ãã³ã¹ãåçã«çæã§ããå ´åã¯ããã³ã¹ãã¼ã¹ã®ãã£ã¬ã¯ãã£ãã®æ¹ãã¡ã³ããã³ã¹ã容æã§ããããã§ãªãå ´åã¯ãããã·ã¥ãã¼ã¹ã®ãã£ã¬ã¯ãã£ãã使ç¨ããå¿ è¦ãããã¾ããããã·ã¥ãã¼ã¹ã®ãã£ã¬ã¯ãã£ãã®åé¡ç¹ã¯ãã¹ã¯ãªããã®å 容ã«å¤æ´ããã£ãå ´åã«ãããã·ã¥ãåè¨ç®ãã¦åé©ç¨ããå¿ è¦ããããã¨ã§ãã
strict-dynamic ãã¼ã¯ã¼ã
ä¸è¨ã®ããã«ã峿 ¼ãª CSP ã¯ãèªåã®å¶å¾¡ä¸ã«ã¯ãªãã¹ã¯ãªããã使ç¨ããå ´åãå®è£ ãå°é£ã§ãããµã¼ããã¼ãã£ã¼ã®ã¹ã¯ãªããã追å ã®ã¹ã¯ãªãããèªã¿è¾¼ãã ããã¤ã³ã©ã¤ã³ã¹ã¯ãªããã使ç¨ãããããã¨ããµã¼ããã¼ãã£ã¼ã®ã¹ã¯ãªããã¯ãã³ã¹ãããã·ã¥ã渡ããªããããããã¯å¤±æãã¾ãã
ãã®åé¡ã«å¯¾å¦ããããã«ãstrict-dynamic ãã¼ã¯ã¼ããæå®ããã¦ãã¾ããããã¯ãã§ãããã£ã¬ã¯ãã£ãã«å«ãããã¨ãã§ãããã¼ã¯ã¼ãã§ãã¹ã¯ãªããã«ãã³ã¹ã¾ãã¯ããã·ã¥ãæ·»ä»ããã¦ããå ´åããã®ã¹ã¯ãªããã¯ãããèªä½ã«ã¯ãã³ã¹ã¾ãã¯ããã·ã¥ãæããªãã¹ã¯ãªãããããã«èªã¿è¾¼ããã¨ã許å¯ãã广ãããã¾ããã¤ã¾ãããã³ã¹ã¾ãã¯ããã·ã¥ã«ãã£ã¦ã¹ã¯ãªããã«ç½®ãããä¿¡é ¼ã¯ãå
ã®ã¹ã¯ãªãããèªã¿è¾¼ãã¹ã¯ãªããï¼ããã³ããããèªã¿è¾¼ãã¹ã¯ãªããããã®ã¹ã¯ãªãããèªã¿è¾¼ãã¹ã¯ãªãããã¨ããããã«ï¼ã«æ¸¡ããã¾ãã
ä¾ãã°ã次ã®ãããªææ¸ãèãã¦ã¿ã¾ãããã
<html lang="ja">
<head>
<script
src="./main.js"
integrity="sha256-gEh1+8U9S1vkEuQSmmUMTZjyNSu5tIoECP4UXIEjMTk="></script>
</head>
<body>
<h1>ãã¼ã¸ã®ä¾</h1>
</body>
</html>
ããã«ã¯ãå¥ã®ã¹ã¯ãªãã "main2.js" ã使ãã¦è¿½å ããã¹ã¯ãªãã "main.js" ãå«ã¾ãã¾ãã
console.log("hello");
const scriptElement = document.createElement("script");
scriptElement.src = `main2.js`;
document.head.appendChild(scriptElement);
ç§ãã¡ã¯ã次ã®ãã㪠CSP ã使ç¨ãã¦ææ¸ãæä¾ãã¦ãã¾ãã
Content-Security-Policy:
script-src 'sha256-gEh1+8U9S1vkEuQSmmUMTZjyNSu5tIoECP4UXIEjMTk='
"main.js" ã¹ã¯ãªããã¯ããã®ããã·ã¥ã CSP ã®å¤ã¨ä¸è´ãããããèªã¿è¾¼ã¿ã許å¯ããã¾ãããããã "main2.js" ã®èªã¿è¾¼ã¿ã¯å¤±æãã¾ãã
CSP ã« 'strict-dynamic' ã追å ããã¨ã "main.js" 㯠"main2.js" ãèªã¿è¾¼ããã¨ã許å¯ããã¾ãã
Content-Security-Policy:
script-src 'sha256-gEh1+8U9S1vkEuQSmmUMTZjyNSu5tIoECP4UXIEjMTk='
'strict-dynamic'
ãã¼ã¯ã¼ã 'strict-dynamic' ã使ç¨ããã¨ãç¹ã«ã¦ã§ããµã¤ãããµã¼ããã¼ãã£ã®ã¹ã¯ãªããã使ç¨ãã¦ããå ´åã«ããã³ã¹ã¾ãã¯ããã·ã¥ãã¼ã¹ã® CSP ãç°¡åã«ä½æããã³ç¶æãããã¨ãã§ãã¾ãããã ãããã®ãã¼ã¯ã¼ãã使ç¨ããã¨ãCSP ã®ã»ãã¥ãªãã£ãä½ä¸ãã¾ãããªããªããè¨è¼ããã¹ã¯ãªããã XSS ã®æ½å¨çãªã½ã¼ã¹ã«åºã¥ã㦠<script> è¦ç´ ã使ããå ´åãCSP ã¯ããããä¿è·ããªãããã§ãã
ã¤ã³ã©ã¤ã³ JavaScript 㨠eval() ã®ãªãã¡ã¯ã¿ãªã³ã°
ä¸è¨ã§ãCSP ã§ã¯ã¤ã³ã©ã¤ã³ JavaScript ãæ¢å®ã§ç¦æ¢ããã¦ãããã¨ã説æãã¾ããããã³ã¹ã¾ãã¯ããã·ã¥ã使ç¨ããã¨ãéçºè
ã¯ã¤ã³ã©ã¤ã³ <script> ã¿ã°ã使ç¨ãããã¨ãã§ãã¾ãããã¤ã³ã©ã¤ã³ã¤ãã³ããã³ãã©ã¼ãjavascript: URLãeval() ã®ä½¿ç¨ãªã©ããã®ä»ã®ç¦æ¢ããã¦ãããã¿ã¼ã³ãé¤å»ããããã«ã³ã¼ãããªãã¡ã¯ã¿ãªã³ã°ããå¿
è¦ãããã¾ããä¾ãã°ãã¤ã³ã©ã¤ã³ã¤ãã³ããã³ãã©ã¼ã¯æ®éã addEventListener() ã®å¼ã³åºãã«ç½®ãæããã¹ãã§ãã
<p onclick="console.log('ã¤ã³ã©ã¤ã³ã¤ãã³ããã³ãã©ã¼ããããã«ã¡ã¯')">ãããã¯ãªãã¯</p>
<!-- served with the following CSP:
`script-src 'sha256-AjYfua7yQhrSlg807yyeaggxQ7rP9Lu0Odz7MZv8cL0='`
-->
<p id="hello">click me</p>
<script>
const hello = document.querySelector("#hello");
hello.addEventListener("click", () => {
console.log("Hello from an inline script");
});
</script>
ã¯ãªãã¯ã¸ã£ããã³ã°ããã®ä¿è·
frame-ancestors ãã£ã¬ã¯ãã£ãã使ç¨ããã¨ã <iframe> ãªã©ã®åãè¾¼ã¿é²è¦§ã³ã³ããã¹ãã§ããã®ææ¸ãåãè¾¼ããã¨ã許å¯ããææ¸ãå¶å¾¡ãããã¨ãã§ãã¾ãããã®æ»æã¯ãæ»æè
ãå¶å¾¡ãããµã¤ãã«ã¿ã¼ã²ãããµã¤ããåãè¾¼ããã¨ã«ä¾åãã¦ãããããã¯ãªãã¯ã¸ã£ããã³ã°æ»æã«å¯¾ãã广çãªä¿è·ææ®µã¨ãªãã¾ãã
frame-ancestors ã®æ§æã¯ããã§ãããã£ã¬ã¯ãã£ãã®æ§æã®ãµãã»ããã§ããåä¸ã®ãã¼ã¯ã¼ãå¤ 'none' ã¾ã㯠1 ã¤ä»¥ä¸ã®ã½ã¼ã¹å¼ãæå®ãããã¨ãã§ãã¾ãããã ãã使ç¨ã§ããã½ã¼ã¹å¼ã¯ãã¹ãã¼ã ããã¹ãåãã¾ã㯠'self' ãã¼ã¯ã¼ãå¤ã®ã¿ã§ãã
ãµã¤ãã«åãè¾¼ã¿æ©è½ãå¿
è¦ã§ãªãå ´åã¯ãframe-ancestors ã 'none' ã«è¨å®ãã¦ãã ããã
Content-Security-Policy: frame-ancestors 'none'
ãã®ãã£ã¬ã¯ãã£ãã¯ãX-Frame-Options ãããã¼ãããæè»ã«ç½®ãæãã¾ãã
ä¿è·ããã¦ããªããªã¯ã¨ã¹ãã®ã¢ããã°ã¬ã¼ã
ã¦ã§ãéçºè ã¯ããã¹ã¦ã®ã³ã³ãã³ãã HTTPS çµç±ã§æä¾ãããã¨ãå¼·ããå§ããã¾ãããµã¤ãã HTTPS ã«ã¢ããã°ã¬ã¼ãããéç¨ã§ããµã¤ã㯠HTTPS çµç±ã§ã¡ã¤ã³ææ¸ãæä¾ããªããããªã½ã¼ã¹ã¯ HTTP çµç±ã§æä¾ããå ´åãããã¾ããä¾ãã°ã次ã®ãããªãã¼ã¯ã¢ããã使ç¨ããå ´åã§ãã
<script src="http://example.org/my-cat.js"></script>
ããã¯æ··å¨ã³ã³ãã³ãã¨å¼ã°ããå®å ¨ã§ãªããªã½ã¼ã¹ãåå¨ããã¨ãHTTPS ã«ããä¿è·ãå¤§å¹ ã«å¼±ã¾ãã¾ãããã©ã¦ã¶ã¼ãå®è£ ããæ··å¨ã³ã³ãã³ãã¢ã«ã´ãªãºã ã§ã¯ãææ¸ã HTTPS çµç±ã§æä¾ããã¦ããå ´åãå®å ¨ã§ãªããªã½ã¼ã¹ã¯ãã¢ããã°ã¬ã¼ãå¯è½ãªã³ã³ãã³ããã¨ããããã¯å¯è½ãªã³ã³ãã³ããã«åé¡ããã¾ããã¢ããã°ã¬ã¼ãå¯è½ãªã³ã³ãã³ã㯠HTTPS ã«ã¢ããã°ã¬ã¼ãããããããã¯å¯è½ãªã³ã³ãã³ãã¯ãããã¯ããããã¼ã¸ãç ´æããå¯è½æ§ãããã¾ãã
æ··å¨ã³ã³ãã³ãã®ç©¶æ¥µã®è§£æ±ºçã¯ãéçºè ããã¹ã¦ã®ãªã½ã¼ã¹ã HTTPS çµç±ã§èªã¿è¾¼ããã¨ã§ãããããããµã¤ããå®éã«ãã¹ã¦ã®ã³ã³ãã³ãã HTTPS çµç±ã§æä¾ã§ããå ´åã§ããéçºè ããµã¤ãã§ä½¿ç¨ããã¦ãããªã½ã¼ã¹ãèªã¿è¾¼ããã¹ã¦ã® URL ãæ¸ãæãããã¨ã¯ãé常ã«å°é£ã§ããï¼ã¢ã¼ã«ã¤ããããã³ã³ãã³ãã«é¢ãã¦ã¯äºå®ä¸ä¸å¯è½ã§ããï¼å ´åãããã¾ãã
ãã®åé¡ã解決ããããã«ã upgrade-insecure-requests ãã£ã¬ã¯ãã£ããç¨æããã¦ãã¾ãããã®ãã£ã¬ã¯ãã£ãã«ã¯å¤ã¯æå®ãã¾ãããè¨å®ããã«ã¯ããã£ã¬ã¯ãã£ãåã ããå«ãã¾ãã
Content-Security-Policy: upgrade-insecure-requests
ãã®ãã£ã¬ã¯ãã£ããææ¸ã«è¨å®ããã¦ããå ´åããã©ã¦ã¶ã¼ã¯æ¬¡ã®å ´åã«ãHTTP URL ãèªåçã« HTTPS ã«ã¢ããã°ã¬ã¼ããã¾ãã
- ãªã½ã¼ã¹ ï¼ç»åãã¹ã¯ãªããããã©ã³ããªã©ï¼ ã®èªã¿è¾¼ã¿ãªã¯ã¨ã¹ã
- ææ¸ã¨åããªãªã¸ã³ã§ããããã²ã¼ã·ã§ã³ãªã¯ã¨ã¹ã ï¼ãªã³ã¯å ãªã©ï¼
- iframe ãªã©ã®ãã¹ããããé²è¦§ã³ã³ããã¹ãã§ã®ããã²ã¼ã·ã§ã³ãªã¯ã¨ã¹ã
- ãã©ã¼ã ã®éä¿¡
ãã ããã¿ã¼ã²ãããå¥ã®ãªãªã¸ã³ã§ããæä¸ä½ã®ããã²ã¼ã·ã§ã³ãªã¯ã¨ã¹ãã¯ã¢ããã°ã¬ã¼ãããã¾ããã
ä¾ãã°ãhttps://example.org ã®ææ¸ããupgrade-insecure-requests ãã£ã¬ã¯ãã£ããå«ã CSP ã§æä¾ããã¦ããããã®ææ¸ã«æ¬¡ã®ãããªãã¼ã¯ã¢ãããå«ã¾ãã¦ããã¨ãã¾ãã
<script src="http://example.org/my-cat.js"></script>
<script src="http://not-example.org/another-cat.js"></script>
ãã©ã¦ã¶ã¼ã¯ããããã®ãªã¯ã¨ã¹ããèªåçã« HTTPS ã«ã¢ããã°ã¬ã¼ããã¾ãã
ãã®ææ¸ã«ã次ã®ãããªé¨åãå«ã¾ãã¦ããã¨ãã¾ãã
<a href="http://example.org/more-cats">ãã£ã¨ãã³ãè¦ã¾ãããï¼</a>
<a href="http://not-example.org/even-more-cats">ä»ã®ãµã¤ãã§ãã£ã¨ãã³ãè¦ã¾ãããï¼</a>
ãã©ã¦ã¶ã¼ã¯ãæåã®ãªã³ã¯ã HTTPS ã«ã¢ããã°ã¬ã¼ããã¾ããã2 ã¤ç®ã®ãªã³ã¯ã¯å¥ã®ãªãªã¸ã³ã«ç§»åãããããã¢ããã°ã¬ã¼ããã¾ããã
ãã®ãã£ã¬ã¯ãã£ãã¯ããµã¤ãã¸ã®å¤é¨ãªã³ã¯ãã¢ããã°ã¬ã¼ãããªãããã Strict-Transport-Security ãããã¼ ï¼HSTS ã¨ãå¼ã°ããï¼ ã®ä»£ããã«ã¯ãªãã¾ããããµã¤ãã«ã¯ããã®ãã£ã¬ã¯ãã£ã㨠Strict-Transport-Security ãããã¼ãå«ããå¿
è¦ãããã¾ãã
ããªã·ã¼ã®ãã¹ã
æ¬çªç°å¢ã¸ã®é©ç¨ãã¹ã ã¼ãºã«è¡ããããCSP 㯠report-only ã¢ã¼ãã§åä½ããããã¨ãå¯è½ã§ãããã®ã¢ã¼ãã®å ´åãããªã·ã¼ã«ãããããã¯ã¯è¡ããããæå®ãã URI ã¸ããªã·ã¼éåã®å 容ãå ±åããã¾ããã¾ããæ°ããããªã·ã¼ãæ¬çªç°å¢ã«é©ç¨ããåã«è©¦é¨éç¨ããéã«ã report-only ã¢ã¼ãã¯å©ç¨ã§ãã¾ãã
ããªã·ã¼ã report-only ã¢ã¼ãã§åä½ãããã«ã¯ã以ä¸ã®ããã«ããªã·ã¼ã Content-Security-Policy-Report-Only HTTP ãããã¼ã«æå®ãã¾ãã
Content-Security-Policy-Report-Only: policy
åãã¬ã¹ãã³ã¹ä¸ã« Content-Security-Policy-Report-Only ãããã¼ã¨ Content-Security-Policy ãããã¼ãåå¨ããå ´åãã©ã¡ãã®ããªã·ã¼ãèæ
®ããã¾ãã
Content-Security-Policy ãããã¼ã«æå®ããããªã·ã¼ã«ã¤ãã¦ã¯ãããã¯ãè¡ãããContent-Security-Policy-Report-Only ãããã¼ã«æå®ããããªã·ã¼ã¯å ±åã®ã¿ãè¡ããã¾ãã
é常ã®ã³ã³ãã³ãã»ãã¥ãªãã£ããªã·ã¼ã¨ã¯ç°ãªããå ±åã®ã¿ã®ããªã·ã¼ã¯ <meta> è¦ç´ ã§ã¯é
ä¿¡ã§ããªããã¨ã«ã注æãã ããã
éåã®å ±å
CSP éåãå ±åããããã®æ¨å¥¨ãããæ¹æ³ã¯ãå ±å API ã使ç¨ããReporting-Endpoints ã§ã¨ã³ããã¤ã³ãã宣è¨ãããã®ãã¡ã® 1 ã¤ã CSP å ±å対象ã¨ãã¦æå®ãããã®ã§ãã Content-Security-Policy ãããã¼ã® report-to ãã£ã¬ã¯ãã£ãã使ç¨ãã¾ãã
è¦å:
CSP report-uri ãã£ã¬ã¯ãã£ãã使ç¨ãã¦ãCSP éåã¬ãã¼ãã®éä¿¡å
URL ãæå®ãããã¨ãã§ãã¾ãã
ãã®å ´åãPOST æä½ã«ãããå°ãç°ãªãå½¢å¼ã® JSON ã¬ãã¼ãã Content-Type ã application/csp-report ã¨ãã¦éä¿¡ããã¾ãã
ãã®æ¹æ³ã¯éæ¨å¥¨ã§ãããreport-to ããã¹ã¦ã®ãã©ã¦ã¶ã¼ã§å¯¾å¿ãããã¾ã§ã¯ã両æ¹ã宣è¨ãã¦ããå¿
è¦ãããã¾ãã
ãã®ææ³ã®è©³ç´°ã«ã¤ãã¦ã¯ãreport-uri ã®ãããã¯ãåç
§ãã¦ãã ããã
ãµã¼ãã¼ã¯ãHTTP ã® Reporting-Endpoints ã¬ã¹ãã³ã¹ãããã¼ã使ç¨ãã¦ãã¬ãã¼ãã®éä¿¡å
ã«é¢ããæ
å ±ãã¯ã©ã¤ã¢ã³ãã«éç¥ãããã¨ãã§ãã¾ãã
ãã®ãããã¼ã§ã¯ãã«ã³ãã§åºåããã 1 ã¤ä»¥ä¸ã®ã¨ã³ããã¤ã³ã URL ãå®ç¾©ãã¾ãã
ä¾ãã°ãã¬ãã¼ããåãå
¥ããååä»ãã¬ãã¼ãã¨ã³ããã¤ã³ã csp-endpoint ã https://example.com/csp-reports ã§å®ç¾©ããå ´åããµã¼ãã¼ã®ã¬ã¹ãã³ã¹ãããã¼ã¯æ¬¡ã®ããã«ãªãã¾ãã
Reporting-Endpoints: csp-endpoint="https://example.com/csp-reports"
ç°ãªã種é¡ã®ã¬ãã¼ããå¦çããè¤æ°ã®ã¨ã³ããã¤ã³ããè¨å®ãããå ´åã¯ã次ã®ããã«æå®ãã¾ãã
Reporting-Endpoints: csp-endpoint="https://example.com/csp-reports",
hpkp-endpoint="https://example.com/hpkp-reports"
Content-Security-Policy ãããã¼ã® report-to ãã£ã¬ã¯ãã£ãã使ç¨ãã¦ãç¹å®ã®å®ç¾©ããã¨ã³ããã¤ã³ããã¬ãã¼ãã«ä½¿ç¨ããããã«æå®ãããã¨ãã§ãã¾ããä¾ãã°ãCSP éåã®ã¬ãã¼ãã default-src ã§ https://example.com/csp-reports ã«éä¿¡ããããã«ããã«ã¯ã次ã®ä¾ã®ãããªã¬ã¹ãã³ã¹ãããã¼ãéä¿¡ãã¾ãã
Reporting-Endpoints: csp-endpoint="https://example.com/csp-reports"
Content-Security-Policy: default-src 'self'; report-to csp-endpoint
CSP éåãçºçããã¨ããã©ã¦ã¶ã¼ã¯ã¬ãã¼ãã JSON ãªãã¸ã§ã¯ãã¨ãã¦ãHTTP ã® POST æä½ã§ã Content-Type ã application/reports+json ã¨ãã¦éä¿¡ãã¾ãã
ã¬ãã¼ãã¯ãã·ãªã¢ã©ã¤ãºããã Report ãªãã¸ã§ã¯ãã®å½¢ã§ããããã®ä¸ã® type ããããã£ã®å¤ã "csp-violation" ã§ãbody ã®å¤ã¯ CSPViolationReportBody ãªãã¸ã§ã¯ããã·ãªã¢ã©ã¤ãºãããå½¢ã§ãã
ãããããªãã¸ã§ã¯ãã¯ã次ã®ããã«è¦ãã¾ãã
{
"age": 53531,
"body": {
"blockedURL": "inline",
"columnNumber": 39,
"disposition": "enforce",
"documentURL": "https://example.com/csp-report",
"effectiveDirective": "script-src-elem",
"lineNumber": 121,
"originalPolicy": "default-src 'self'; report-to csp-endpoint-name",
"referrer": "https://www.google.com/",
"sample": "console.log(\"lo\")",
"sourceFile": "https://example.com/csp-report",
"statusCode": 200
},
"type": "csp-violation",
"url": "https://example.com/csp-report",
"user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36"
}
ãµã¼ãã¼ããæå®ããã JSON å½¢å¼ã¨ã³ã³ãã³ãã¿ã¤ãã§ã¬ãã¼ããåä¿¡ããããè¨å®ããå¿ è¦ãããã¾ãã ãããã®ãªã¯ã¨ã¹ããå¦çãããµã¼ãã¼ã¯ããã¼ãºã«æé©ãªæ¹æ³ã§åä¿¡ããã¬ãã¼ããæ ¼ç´ãããå¦çããããããã¨ãã§ãã¾ãã