1

I was participating in a bug bounty on a website we will call example.com, when I ran into a very strange edge case which I am not sure I should report. The website uses ads and tracking similar to google analytics from a website we can call tracking.com. When visiting the example website there is an iframe to the tracking website. The source of the iframe can be seen below.

<body>
<script type="text/javascript">
     ((function (e, t)
     {

          var n = function () {
               var e = t.createElement("iframe");
               e.src = "https://tracking.com/container/?utm_source=[INJECT];
               e.style.cssText = "position: absolute";
               t.body.appendChild(e)
          }

          if (t.readyState === "complete")
          {
               n()
          }
          else
          {
               if (typeof e.addEventListener !== "undefined")
               {
                    t.addEventListener("DOMContentLoaded", n, false)
               }
               else
               {
                    e.attachEvent("onload", n, false)
               }
          }
     })(window, document));
</script>
</body>

The example website also has a parameter called utm_source, into which javascript can be injected into the iframe (where I placed [INJECT] in the code above). For example, visiting https://example.com/?utm_source=";</script><script>alert(document.domain)</script> yields the alert embedded page at tracking.com says tracking.com. The issue is that the tracking website is not in scope of the bug bounty and I am not even sure that the issue is caused by the tracking website. It seems like the example website allows the user to inject arbitrary JS into the iframe of the tracking website. Is this a bug worth reporting or am I missing some easy way of escaping the iframe?

So far I have tried injecting </iframe> and things like e.onload=alert(1)to escape the iframe but have not been successful. Since the example and tracking websites are on different domains I cannot access things in the parent website (example) from the tracking website due to the "X-Frame-Options" header set to "SAMEORIGIN".

As a beginner this bug has me very confused as to how it should be classified and if it is exploitable in any way. Any tips would be greatly appreciated!

1 Answers1

1

From your description, it seems that example.com is properly handling the user-supplied value (ie you are not injecting into the given script / e.src, which is why what you tried didn't work). You can inspect the DOM of example.com to verify this.

Instead, example.com treats the value properly as string and passes it on to tracking.com which in turn handles it insecurely (you could verify this by directly visiting https://tracking.com/container/?utm_source=[INJECT], but given that it's out of scope, I'd try to avoid that; if you still have the HTTP logs from your accidental triggering on tracking.com, you can likely check those).

Given the above, and assuming that tracking.com isn't trusted by example.com in some other manner (eg accepting or sending interesting postmessages, CORS, etc), the SOP will prevent most malicious actions.

What you are left with is often called a frame injection. It might allow:

  • If example.com has sensitive GET parameters on a page where it frames tracking.com, and if it does not take measures to protect these, you may be able to log those.
  • You may be able to bypass some Clickjacking protections (see here).
  • You might be able to navigate away from example.com via top.location.href="http://www.evil.com"; (akin to tab nabbing)
  • You could inject your own content in place of the ads from tracking.com (defacement).
  • you may be able to steal focus from example.com via this.focus(); and log user keystrokes in the hope of intercepting sensitive information from inattentive users (if it works it will impact usability on example.com, so it's a very noisy attack, with a bit of application-level DOS thrown in).

If you want to test any of these, I'd probably redirect traffic to tracking.com to a host I control via /etc/hosts to avoid further hitting out of scope domains.

Whether you want to report this to example.com depends strongly on the program. Some would likely consider it out of scope (tracking.com is the vulnerable site after all) or informative (eg the tab nabbing impact example). But if you can show impact on example.com and especially if you can show how example.com may prevent it themselves (eg preventing referer leaks), it might be worth a try.

tim
  • 29,018
  • 7
  • 95
  • 119
  • That first option about stealing GET params sounds very reportable and the vulnerable tracker is indeed iframed in the login page which uses a GET request to send the creds. How would an attacker steal these credentials from the parent frame though without bypassing the SOP or am I missing something? – Michael Hoefler May 17 '20 at 19:59
  • 1
    @MichaelHoefler If `example.com` doesn't take measures to prevent leaking part or all of a referer (via referer policies), you can access it via `document.referrer`. A problem may be that the iframe injection you have is GET based; you'd need a situation where you control the iframe, but where there are still user-supplied parameters in the URL (maybe the iframe parameter is kept after logging in? or URL parameters are dynamically updated?). Even if it isn't possible, if the site leaks credentials to a 3rd party (one with maybe not so great security), that's something I'd consider reporting. – tim May 18 '20 at 08:11