âã¯ãªãã¯ã¸ã£ããã³ã°â æ»æã¯ã訪åè ã®ä»£ããã«ã æªæã®ãããã¼ã¸ã â被害ãåãããµã¤ãâ ä¸ã§ã¯ãªãã¯ãããã¨ãå¯è½ã¨ãããã®ã§ãã
Twitter, Facebook, Paypal ããã®ä»ãå«ãå¤ãã®ãµã¤ãã¯ãã®æ¹æ³ã§ãããã³ã°ããã¾ããããã¡ãããä»ã¯å¯¾å¦æ¸ã¿ã§ãã
èãæ¹
ãã®èãæ¹ã¯ã¨ã¦ãåç´ã§ãã
ããã¯ãFacebookã§è¡ãããã¯ãªãã¯ã¸ã£ããã³ã°ã§ã:
- 訪åè ãæªæã®ãããã¼ã¸ã«èªãåºããã¾ããæ¹æ³ã¯ããã§ã¯é¢ä¿ããã¾ããã
- ãã®ãã¼ã¸ã¯ç¡å®³ã«è¦ãããªã³ã¯ãæã£ã¦ãã¾ã(âä»ãããéæã¡ã«ãªãâ ã âãããã¯ãªãã¯ãã¦ãã ãããã¨ã¦ãé¢ç½ããâ ãªã©)ã
- ãã®ãªã³ã¯ã®ä¸ã«ãä¾ãã° âãããâ ãã¿ã³ããã®ãªã³ã¯ã®çä¸ã«ããããã«ãæªæã®ãããã¼ã¸ã facebook.com ã®
srcãå©ç¨ããéæãª<iframe>ãé ç½®ãã¾ããé常ããã¯ãz-indexã§è¡ããã¾ãã - ãªã³ã¯ãã¯ãªãã¯ãããã¨ããã¨ããå®éã«ã¯è¨ªåè ã¯ãã®ãã¿ã³ãã¯ãªãã¯ãããã¨ã«ãªãã¾ãã
ãã¢
æªæã®ãããã¼ã¸ãã©ã®ããã«è¦ãããã®ãã¢ã§ããããæç½ã«ããããã«ã <iframe> ã¯åéæã«ãã¦ãã¾ã(å®éã«ã¯ãæªæã®ãããã¼ã¸ã¯å®å
¨ã«éæã§ã)ã:
<style>
iframe { /* 被害ãµã¤ã ããã® iframe */
width: 400px;
height: 100px;
position: absolute;
top:0; left:-20px;
opacity: 0.5; /* å®éã«ã¯ opacity:0 ã§ã */
z-index: 1;
}
</style>
<div>Click to get rich now:</div>
<!-- 被害ãµã¤ãã® url -->
<iframe src="/clickjacking/facebook.html"></iframe>
<button>Click here!</button>
<div>...And you're cool (I'm a cool hacker actually)!</div>
æ»æã®å®å ¨ããã¢ããã¡ãã§ã:
<!DOCTYPE HTML>
<html>
<body style="margin:10px;padding:10px">
<input type="button" onclick="alert('Like pressed on facebook.html!')" value="I LIKE IT !">
</body>
</html><!doctype html>
<html>
<head>
<meta charset="UTF-8">
</head>
<body>
<style>
iframe {
width: 400px;
height: 100px;
position: absolute;
top: 5px;
left: -14px;
opacity: 0.5;
z-index: 1;
}
</style>
<div>Click to get rich now:</div>
<!-- The url from the victim site -->
<iframe src="facebook.html"></iframe>
<button>Click here!</button>
<div>...And you're cool (I'm a cool hacker actually)!</div>
</body>
</html>ããã§ã¯ åéæãª <iframe src="facebook.html"> ãããããã®ä¾ã§ã¯ãâClick here!â ã¨è¨ããã¿ã³ã®ä¸ã«ããã®ãåããã¾ãããã¿ã³ãã¯ãªãã¯ããã¨ãå®éã«ã¯ iframe ãã¯ãªãã¯ãã¾ãããiframe ã¯éæãªãããã¦ã¼ã¶ã«ã¯è¦ãã¾ããã
çµæã訪åè ã Facebook ã§èªè¨¼æ¸ã¿ã®å ´å (é常㯠âãã°ã¤ã³æ å ±ãè¦ãã¦ããâ ãæå¹)ãâãããâ ãããã¾ããTwitter ã§ã¯ âãã©ãã¼â ãã¿ã³ããããã¾ããã
次ã¯ãåãä¾ã§ãããç¾å®ã«ããè¿ãã <iframe> ã opacity:0 ã®å ´åã§ã:
<!DOCTYPE HTML>
<html>
<body style="margin:10px;padding:10px">
<input type="button" onclick="alert('Like pressed on facebook.html!')" value="I LIKE IT !">
</body>
</html><!doctype html>
<html>
<head>
<meta charset="UTF-8">
</head>
<body>
<style>
iframe {
width: 400px;
height: 100px;
position: absolute;
top: 5px;
left: -14px;
opacity: 0;
z-index: 1;
}
</style>
<div>Click to get rich now:</div>
<!-- The url from the victim site -->
<iframe src="facebook.html"></iframe>
<button>Click here!</button>
<div>...And you're cool (I'm a cool hacker actually)!</div>
</body>
</html>æ»æããããã«å¿
è¦ãªãã¨ã¯ããã¿ã³ããªã³ã¯ã®çä¸ã«ããããã<iframe> ãæªæã®ãããã¼ã¸ã«é
ç½®ãããã¨ã ãã§ããããã¯é常 CSS ã§å¯è½ã§ãã
ãã®æ»æã¯ãã¦ã¹æä½ã«ã®ã¿å½±é¿ãã¾ãã
æè¡çã«ã¯ããããããã³ã°ããããã¹ããã£ã¼ã«ããããå ´åãããã¹ããã£ã¼ã«ããéãªãããã« iframe ãé ç½®ãããã¨ã¯ã§ãã¾ãããªã®ã§ã訪åè ããã¼ã¸ã«è¡¨ç¤ºããã¦ããå ¥åãã£ã¼ã«ãã«ãã©ã¼ã«ã¹ãå½ã¦ããã¨ããã¨ããå®éã«ã¯ iframe å ã®å ¥åãã£ã¼ã«ãã«ãã©ã¼ã«ã¹ãã¾ãã
ãããããã®å¾åé¡ãããã¾ããiframe ã¯è¦ããªãããã訪åè ã®å ¥åãããã®ã¯ç»é¢ä¸ã«è¦ãã¾ããã
ç»é¢ä¸ã«å ¥åããæåã表示ãããªãå ´åãé常ã¯å ¥åãããã¾ãã
ä¼çµ±çãªé²å¾¡ç(å¼±ã)
æãå¤ãé²å¾¡çã¯ããã¬ã¼ã å ã§ãã¼ã¸ãéããã¨ãç¦æ¢ãã JavaScript ã§ã(ãããã âãã¬ã¼ã ãã¹ãã£ã³ã°(framebusting)â)ã
ãã®ããã«ãªãã¾ã:
if (top != window) {
top.location = window.location;
}
ã¤ã¾ã: window ããããã«ãªããã¨ãããã£ãå ´åãèªèº«ãèªåçã«ãããã«ãã¾ãã
ãã ããããããã¯ããæ¹æ³ã¯ãããããããããä¿¡é ¼ã§ããé²å¾¡çã§ã¯ããã¾ãããããã¤ãåãä¸ãã¾ãããã
ãããããã²ã¼ã·ã§ã³ããããã¯ãã
beforeunload ã¤ãã³ãã§ãtop.location ã夿´ãããã¨ã«ããå¼ãèµ·ããããé·ç§»ããããã¯ãããã¨ãã§ãã¾ãã
ããããã¼ã¸(ããã«ã¼ã«å±ãã)ã¯ããã«ãã³ãã©ãã»ããããiframe ã top.location ã夿´ãããã¨ããã¨ã訪åè
ã¯ãããå»ãããããå°ããã¡ãã»ã¼ã¸ãåãåãã¾ãã
ãã®ããã«:
window.onbeforeunload = function() {
window.onbeforeunload = null;
return "Want to leave without learning all the secrets (he-he)?";
};
ã»ã¨ãã©ã®å ´åã訪åè
ã¯å¦å®çãªåç(ãã¼ã¸ãå»ããªã)ã§ãããããªããªããå½¼ãã¯iframe ã®åå¨ã¯ç¥ãããè¦ããã®ã¯ããããã¼ã¸ã ãã§ãããããå»ãçç±ããªãã¨æãããã§ãããã®ãããtop.location ãå¤ããã¾ãã!
åä½:
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
</head>
<body>
<div>Changes top.location to javascript.info</div>
<script>
top.location = 'https://javascript.info';
</script>
</body>
</html><!doctype html>
<html>
<head>
<meta charset="UTF-8">
<style>
iframe {
width: 400px;
height: 100px;
position: absolute;
top: 0;
left: -20px;
opacity: 0;
z-index: 1;
}
</style>
<script>
function attack() {
window.onbeforeunload = function() {
window.onbeforeunload = null;
return "Want to leave without learning all the secrets (he-he)?";
};
document.body.insertAdjacentHTML('beforeend', '<iframe src="iframe.html">');
}
</script>
</head>
<body>
<p>After a click on the button the visitor gets a "strange" question about whether he wants to leave.</p>
<p>Probably he would respond "No", and the iframe protection is hacked.</p>
<button onclick="attack()">Add a "protected" iframe</button>
</body>
</html>Sandbox 屿§
sandbox 屿§ã«ãã£ã¦å¶éããããã¨ã®1ã¤ã«ãããã²ã¼ã·ã§ã³ãããã¾ãããµã³ãããã¯ã¹åããã iframe ã¯ãtop.location ã夿´ããªãå ´åãããã¾ãã
ã¤ã¾ããsandbox="allow-scripts allow-forms" ãæã¤ iframe ã追å ãã¾ããããã¯å¶éãç·©åããã¹ã¯ãªããå®è¡ã¨ãã©ã¼ã éä¿¡ã許å¯ãã¾ããããããtop.location ã®å¤æ´ãç¦æ¢ããããããallow-top-navigation ã¯çç¥ãã¾ãã
ããããã®ã³ã¼ãã§ã:
<iframe sandbox="allow-scripts allow-forms" src="facebook.html"></iframe>
ãã®åç´ãªé²å¾¡ãåé¿ããæ¹æ³ã¯ä»ã«ãããã¾ãã
X-Frame-Options
ãµã¼ããµã¤ãã®ããã X-Frame-Options ã¯ããã¬ã¼ã å
ã«ãã¼ã¸ã表示ãããã¨ã許å¯ã¾ãã¯ç¦æ¢ãããã¨ãã§ãã¾ãã
ãã㯠ãµã¼ããã éãããªããã°ãªãã¾ããã<meta> ã¿ã°ã®ä¸ã§ãããè¦ã¤ãã¦ãããã©ã¦ã¶ã¯ç¡è¦ãã¾ãããããã£ã¦ã<meta http-equiv="X-Frame-Options"...> ã¯ä½ããã¾ããã
ãã®ãããã«ã¯3ã¤ã®å¤ãããã¾ã:
DENY- 決ãã¦ãã¬ã¼ã å ã«ãã¼ã¸ã表示ãã¾ããã
SAMEORIGIN- 親ã®ããã¥ã¡ã³ããåããªãªã¸ã³ããæ¥ã¦ããå ´åããã¬ã¼ã ã®å å´ã許å¯ãã¾ãã
ALLOW-FROM domain- 親ã®ããã¥ã¡ã³ããæå®ããããã¡ã¤ã³ããã®ãã®ã§ããå ´åããã¬ã¼ã ã®å å´ã許å¯ãã¾ãã
ä¾ãã°ãTwitter 㯠X-Frame-Options: SAMEORIGIN ã使ã£ã¦ãã¾ãã
åä½ç¢ºèª:
<iframe src="https://twitter.com"></iframe>
å©ç¨ãã¦ãããã©ã¦ã¶ã«ãã£ã¦ãä¸ã® iframe ã¯ç©ºãã¾ãã¯ãã©ã¦ã¶ããã®ãã¼ã¸ããã®æ¹æ³ã§ã¯ç§»åãããã¨ã許å¯ããªããã¨ãè¦åãããã®ã«ãªãã¾ãã
æ©è½æ§ãç¡å¹ã«ãã¦è¡¨ç¤ºãã
X-Frame-Options ãããã«ã¯å¯ä½ç¨ãããã¾ããä»ã®ãµã¤ãã§ã¯ããã¨ãæ£å½ãªçç±ããã£ãã¨ãã¦ãããã¼ã¸ããã¬ã¼ã å
ã«è¡¨ç¤ºãããã¨ã¯ã§ãã¾ããã
ãã®ãããä»ã®è§£æ±ºçãããã¾ããä¾ãã°ããã¹ã¦ã®ã¯ãªãã¯ã鮿ãããããheight: 100%; width: 100%; ãæã¤ <div> ã§ãã¼ã¸ã âè¦ãâ ãã¨ãã§ãã¾ããwindow == top ã¾ãã¯ãä¿è·ã®å¿
è¦ããªãã¨å¤æããå ´åã«ã¯ã <div> ã¯æ¶ããããã«ãã¾ãã
ãã®ãããªãã®ã§ã:
<style>
#protector {
height: 100%;
width: 100%;
position: absolute;
left: 0;
top: 0;
z-index: 99999999;
}
</style>
<div id="protector">
<a href="/" target="_blank">Go to the site</a>
</div>
<script>
// ãããã®ã¦ã£ã³ãã¦ãç°ãªããªãªã¸ã³ããã®ãã®ã§ããã°ã¨ã©ã¼ã«ãªãã¾ã
// ããã§ã¯ OK ã§ã
if (top.document.domain == document.domain) {
protector.remove();
}
</script>
ãã¢:
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<style>
#protector {
height: 100%;
width: 100%;
position: absolute;
left: 0;
top: 0;
z-index: 99999999;
}
</style>
</head>
<body>
<div id="protector">
<a href="/" target="_blank">Go to the site</a>
</div>
<script>
if (top.document.domain == document.domain) {
protector.remove();
}
</script>
This text is always visible.
But if the page was open inside a document from another domain, the div over it would prevent any actions.
<button onclick="alert(1)">Click wouldn't work in that case</button>
</body>
</html><!doctype html>
<html>
<head>
<meta charset="UTF-8">
</head>
<body>
<iframe src="iframe.html"></iframe>
</body>
</html>ãµããª
ã¯ãªãã¯ã¸ã£ããã³ã°ã¯ãã¦ã¼ã¶ãä½ãèµ·ãã¦ãããç¥ããã«ãâé¨ãã¦â æªæã®ãããµã¤ãä¸ã§ã¯ãªãã¯ããããæ¹æ³ã§ããéè¦ãªã¯ãªãã¯ã«ããæä½ãããå ´åãããã¯å±éºã§ãã
ããã«ã¼ã¯èªèº«ã®æªæã®ãããã¼ã¸ã¸ã®ãªã³ã¯ãã¡ãã»ã¼ã¸ã§æç¨¿ããããä»ã®ææ®µã使ã£ã¦è¨ªåè ãèªåã®ãã¼ã¸ã«èªå°ãã¾ããããã«ã¯æ§ã ãªããªã¨ã¼ã·ã§ã³ãããã¾ãã
ãã観ç¹ããè¨ãã°ãæ»æã¯ âæ·±ãâ ã¯ããã¾ãããããã«ã¼ãè¡ã£ã¦ããã®ã¯ã·ã³ã°ã«ã¯ãªãã¯ã®åå/横åãã ãã§ããããããå¥ã®è¦³ç¹ã§è¨ãã°ãããã«ã¼ãã¯ãªãã¯ã®å¾ã«å¥ã®å¶å¾¡/æä½ç»é¢ã表示ããããã¨ãç¥ã£ã¦ããå ´åãç¡ç¾ãªã¡ãã»ã¼ã¸ã使ç¨ãã¦ãåæ§ã«ã¦ã¼ã¶ã«ããããã¯ãªãã¯ããããã¨ãã§ãã¾ãã
ãã®æ»æã¯é常ã«å±éºã§ãããªããªããæã ãUIãè¨è¨ããã¨ããé常ã¯ããã«ã¼ã訪åè ã®ä»£ããã«ã¯ãªãã¯ãããã¨ã¯äºæããªãããã§ãããã®ãããã¾ã£ããäºæ³å¤ã®å ´æã§èå¼±æ§ãè¦ã¤ããå¯è½æ§ãããã¾ãã
- ãã¬ã¼ã ã®å
å´ã«è¡¨ç¤ºããããã¨ãæå³ãã¦ããªããã¼ã¸(ã¾ãã¯Webãµã¤ãå
¨ä½)ã«ã¯
X-Frame-Options: SAMEORIGINãå©ç¨ãããã¨ãæ¨å¥¨ãã¾ãã - ãã¼ã¸ã iframe ã§è¡¨ç¤ºãããã¨ã許å¯ãããããå®å
¨ãç¶æãããå ´åã«ã¯ãè¦ã
<div>ã使ç¨ãã¦ãã ããã
ã³ã¡ã³ã
<code>ã¿ã°ã使ã£ã¦ãã ãããè¤æ°è¡ã®å ´åã¯<pre>ãã10è¡ãè¶ ããå ´åã«ã¯ãµã³ãããã¯ã¹ã使ã£ã¦ãã ãã(plnkr, JSBin, codepenâ¦)ã