daemon-sec-cheatsheet

The cheatsheet vault for operators: AD, enumeration, exploitation, priv-esc, web, DFIR
git clone https://git.daemon-sec.xyz/daemon-sec-cheatsheet.git
Log | Files | Refs | README | LICENSE

reverse-tab-nabbing.md (4616B)


      1 ---
      2 title: "Reverse Tab Nabbing"
      3 section: "Web Pentesting"
      4 sectionSlug: "pentesting-web"
      5 sourcePath: "src/pentesting-web/reverse-tab-nabbing.md"
      6 sourceUrl: "https://github.com/HackTricks-wiki/hacktricks/blob/188de82beb54e70956b2952367a0af91d26758b8/src/pentesting-web/reverse-tab-nabbing.md"
      7 sha: "188de82beb54e70956b2952367a0af91d26758b8"
      8 isIndex: false
      9 modified: true
     10 license: "CC-BY-NC-4.0"
     11 ---
     12 
     13 # Reverse Tab Nabbing
     14 
     15 ## Description
     16 
     17 If an attacker controls the `href` of a link opened with `target="_blank"` and the new page receives an opener reference, the attacker-controlled page can navigate the original tab through `window.opener`. Explicit `rel="opener"` requests that relationship. Current HTML behavior gives `_blank` links implicit `noopener` in modern browsers, but older browsers, embedded webviews, `window.open()` calls, or explicit `opener` can still expose it.<sup>[[1]](#references)</sup><sup>[[3]](#references)</sup>
     18 
     19 A regular way to abuse this behaviour would be to **change the location of the original web** via `window.opener.location = https://attacker.com/victim.html` to a web controlled by the attacker that **looks like the original one**, so it can **imitate** the **login** **form** of the original website and ask for credentials to the user.
     20 
     21 Cross-origin policy does not give the malicious page arbitrary DOM or JavaScript access to the opener. It exposes only the limited cross-origin `WindowProxy` surface, whose most important tabnabbing capability is navigation of the opener.<sup>[[3]](#references)</sup>
     22 
     23 ## Overview
     24 
     25 ### With back link
     26 
     27 Link between parent and child pages when prevention attribute is not used:
     28 
     29 ![https://owasp.org/www-community/assets/images/TABNABBING_OVERVIEW_WITH_LINK.png](https://owasp.org/www-community/assets/images/TABNABBING_OVERVIEW_WITH_LINK.png)
     30 
     31 ### Without back link
     32 
     33 Link between parent and child pages when prevention attribute is used:
     34 
     35 ![https://owasp.org/www-community/assets/images/TABNABBING_OVERVIEW_WITHOUT_LINK.png](https://owasp.org/www-community/assets/images/TABNABBING_OVERVIEW_WITHOUT_LINK.png)
     36 
     37 ### Examples <a href="#examples" id="examples"></a>
     38 
     39 Create the following pages in a folder and run a web server with `python3 -m http.server`\
     40 Then access `http://127.0.0.1:8000/vulnerable.html`, click the link, and observe that the original tab's URL changes.
     41 
     42 ```html
     43 <!DOCTYPE html>
     44 <html>
     45 <body>
     46 <h1>Victim Site</h1>
     47 <a href="http://127.0.0.1:8000/malicious.html" target="_blank" rel="opener">Controlled by the attacker</a>
     48 </body>
     49 </html>
     50 ```
     51 
     52 ```html
     53 <!DOCTYPE html>
     54 <html>
     55  <body>
     56   <script>
     57   window.opener.location = "http://127.0.0.1:8000/malicious_redir.html";
     58   </script>
     59  </body>
     60 </html>
     61 ```
     62 
     63 ```html
     64 <!DOCTYPE html>
     65 <html>
     66 <body>
     67 <h1>New Malicious Site</h1>
     68 </body>
     69 </html>
     70 ```
     71 
     72 ### Accessible properties <a href="#accessible-properties" id="accessible-properties"></a>
     73 
     74 In the scenario where a **cross-origin** access occurs (access across different domains), the properties of the **window** JavaScript class instance, referred to by the **opener** JavaScript object reference, that can be accessed by a malicious site are limited to the following:
     75 
     76 - **`opener.closed`**: This property is accessed to determine if a window has been closed, returning a boolean value.
     77 - **`opener.frames`**: Returns a window proxy for the opener's frame hierarchy; it does not expose cross-origin iframe DOM elements.
     78 - **`opener.length`**: Returns the number of child browsing contexts (frames).
     79 - **`opener.opener`**: A reference to the window that opened the current window can be obtained through this property.
     80 - **`opener.parent`**: This property returns the parent window of the current window.
     81 - **`opener.self`**: Access to the current window itself is provided by this property.
     82 - **`opener.top`**: This property returns the topmost browser window.
     83 
     84 When the documents are same-origin, normal same-origin `Window` access applies.<sup>[[3]](#references)</sup>
     85 
     86 ## Prevention
     87 
     88 Use `rel="noopener"` (and `noreferrer` when referrer suppression is also desired), avoid explicit `opener`, and null the opener for script-created windows where appropriate. OWASP's HTML5 cheat sheet documents these defenses.<sup>[[2]](#references)</sup>
     89 
     90 ## References
     91 
     92 - [1] [OWASP – Reverse Tabnabbing](https://owasp.org/www-community/attacks/Reverse_Tabnabbing)
     93 - [2] [OWASP Cheat Sheet Series – HTML5 Security Cheat Sheet (Tabnabbing prevention)](https://cheatsheetseries.owasp.org/cheatsheets/HTML5_Security_Cheat_Sheet.html#tabnabbing)
     94 - [3] [MDN - `Window.opener`](https://developer.mozilla.org/en-US/docs/Web/API/Window/opener)