Detect if JavaScript is Executing In a Sandboxed Iframe?

前端 未结 2 1068
时光取名叫无心
时光取名叫无心 2020-12-18 21:13

I have a product that\'s playing a video in Flash (if available), and falls back to HTML5 if Flash isn\'t available.

I\'m not able to find a way to determine if Java

2条回答
  •  挽巷
    挽巷 (楼主)
    2020-12-18 22:10

    I will consider different kinds of iframes (choose the first case which applies):

    • Iframes with the sandboxed scripts browsing context flag

      That is, iframes with a sandbox attribute which doesn't contain the allow-scripts keyword.

      This flag blocks script execution. In particular, you can't use a script to check if the iframe is sandboxed.

    • Same-origin iframes without the sandboxed origin browsing context flag

      That is, same-origin iframes with no sandbox attribute, or same-origin iframes with a sandbox attribute which contains the allow-same-origin and allow-scripts keywords.

      In this case, you can use the frameElement global property to access the frame element (returns null when not used inside an iframe).

      Once you have a reference to the iframe, you can use hasAttribute or getAttribute to check its sandboxed attribute. There is also the sandboxed property, which should return a DOMSettableTokenList (old browsers might return a string according to an old spec).

    • Cross-origin iframes without the sandboxed origin browsing context flag

      That is, cross-origin iframes with no sandbox attribute, or cross-origin iframes with a sandbox attribute which contains the allow-same-origin and allow-scripts keywords.

      In this case, the use of frameElement is blocked:

      • According to W3C, it should throw a SecurityError exception. This is implemented by Chrome.
      • According to WHATWG, it should return null. This is implemented by Firefox.

      Then, I don't think you can distinguish whether the iframe is sandboxed or not in this case. However, since using allow-same-origin in a cross-origin iframe isn't much useful, consider assuming the iframe isn't sandboxed.

    • Iframes with the sandboxed origin browsing context flag

      That is, iframes with a sandbox attribute which doesn't contain the allow-same-origin keyword but contains the allow-scripts keyword.

      As in the previous case, the use of frameElement is blocked.

      However, you can detect this case because document.domain will be the empty string.

    Note: Firefox treats data URIs as same-origin, so it's OK. However, Chrome treats them as cross-origin. Then frameElement doesn't work and document.domain is the empty string regardless of whether the iframe is sandboxed or not. You can check whether location.protocol is 'data:' string to detect data URIs.

    In general, you might try something like

    function isSandboxedIframe() {
      if (window.parent === window) return 'no-iframe';
      try { var f = window.frameElement; } catch(err) { f = null; }
      if(f === null) {
        if(document.domain !== '') return 'unkown'; // Probably 'non-sandboxed'
        if(location.protocol !== 'data:') return 'sandboxed';
        return 'unkown'; // Can be 'sandboxed' on Firefox
      }
      return f.hasAttribute('sandbox') ? 'sandboxed' : 'non-sandboxed';
    }
    

提交回复
热议问题