[英]Detect if JavaScript is Executing In a Sandboxed Iframe?
I have a product that's playing a video in Flash (if available), and falls back to HTML5 if Flash isn't available. 我有一个产品在Flash中播放视频(如果可用),如果Flash不可用,则会回退到HTML5。
I'm not able to find a way to determine if JavaScript is executing within an Iframe with the "sandbox" attribute, which is necessary for my solution because sandboxed iframes disable all plugins. 我无法找到一种方法来确定JavaScript是否在具有“sandbox”属性的Iframe中执行,这对我的解决方案是必需的,因为沙盒iframe会禁用所有插件。 The sandboxed iframe could be as simple as this:
沙盒iframe可以像这样简单:
<iframe src="http://www.cross-domain.com/" sandbox="allow-scripts">
To determine if Flash is enabled, I'm using swfobject's method of checking navigator.plugins["Shockwave Flash"].description, which is set even when in a sandboxed iframe. 要确定Flash是否已启用,我使用swfobject的方法检查navigator.plugins [“Shockwave Flash”]。描述,即使在沙盒iframe中也会设置。 I can load the swf object, but it doesn't play.
我可以加载swf对象,但它不会播放。
To reproduce this issue, visit http://jsfiddle.net/max_winderbaum/9cqkjo45/ , open your chrome inspector and click "Run". 要重现此问题,请访问http://jsfiddle.net/max_winderbaum/9cqkjo45/ ,打开Chrome检查器并单击“运行”。 The script on the cross-domain site will pause in the context of the sandboxed iframe.
跨域网站上的脚本将在沙盒iframe的上下文中暂停。
According to the W3 spec at http://dev.w3.org/html5/spec-preview/browsers.html#sandboxing-flag-set , there is supposed to be an "active sandboxing flag set" on the document that JavaScript can access (at least that's how I'm reading the spec). 根据http://dev.w3.org/html5/spec-preview/browsers.html#sandboxing-flag-set上的W3规范,应该在文档上有一个“活动沙盒标志集”,JavaScript可以访问(至少我是如何阅读规范)。 There doesn't seem to be any flag set on the iframe's document.
iframe的文档似乎没有设置任何标记。
Does anyone have any ideas / solutions on how to detect if JavaScript is executing from within a sandboxed iframe? 有没有人有任何关于如何检测JavaScript是否在沙盒iframe中执行的想法/解决方案?
I will consider different kinds of iframes (choose the first case which applies): 我会考虑不同种类的iframe(选择适用的第一种情况):
Iframes with the sandboxed scripts browsing context flag iframes与沙盒脚本浏览上下文标志
That is, iframes with a sandbox
attribute which doesn't contain the allow-scripts
keyword. 也就是说,iframe具有不包含
allow-scripts
关键字的sandbox
属性。
This flag blocks script execution . 该标志阻止脚本执行 。 In particular, you can't use a script to check if the iframe is sandboxed.
特别是,您无法使用脚本来检查iframe是否为沙盒。
Same-origin iframes without the sandboxed origin browsing context flag 没有沙盒原点浏览上下文标志的同源iframe
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. 也就是说,没有
sandbox
属性的同源iframe,或者包含allow-same-origin
和allow-scripts
关键字的sandbox
属性的同源iframe。
In this case, you can use the frameElement
global property to access the frame element (returns null
when not used inside an iframe). 在这种情况下,您可以使用
frameElement
全局属性来访问frame元素(在iframe中未使用时返回null
)。
Once you have a reference to the iframe, you can use hasAttribute
or getAttribute
to check its sandboxed
attribute. 一旦引用了iframe,就可以使用
hasAttribute
或getAttribute
来检查其sandboxed
属性。 There is also the sandboxed
property, which should return a DOMSettableTokenList
(old browsers might return a string according to an old spec). 还有一个
sandboxed
属性,它应该返回一个DOMSettableTokenList
(旧的浏览器可能会根据旧规范返回一个字符串)。
Cross-origin iframes without the sandboxed origin browsing context flag 没有沙盒原点浏览上下文标志的跨源iframe
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. 也就是说,没有
sandbox
属性的跨源iframe,或者包含allow-same-origin
和allow-scripts
关键字的sandbox
属性的跨源iframe。
In this case, the use of frameElement
is blocked: 在这种情况下,阻止使用
frameElement
:
SecurityError
exception. SecurityError
异常。 This is implemented by Chrome. null
. null
。 This is implemented by Firefox. allow-same-origin
in a cross-origin iframe isn't much useful, consider assuming the iframe isn't sandboxed. allow-same-origin
并不是很有用,因此请考虑假设iframe不是沙盒。 Iframes with the sandboxed origin browsing context flag 具有沙盒来源浏览上下文标志的 iframe
That is, iframes with a sandbox
attribute which doesn't contain the allow-same-origin
keyword but contains the allow-scripts
keyword. 也就是说,具有
sandbox
属性的iframe不包含allow-same-origin
关键字但包含allow-scripts
关键字。
As in the previous case, the use of frameElement
is blocked. 与前一种情况一样,阻止使用
frameElement
。
However, you can detect this case because document.domain
will be the empty string. 但是,您可以检测到这种情况,因为
document.domain
将是空字符串。
Note : Firefox treats data URIs as same-origin, so it's OK. 注意 :Firefox将数据URI视为同源,因此可以。 However, Chrome treats them as cross-origin.
但是,Chrome将它们视为交叉来源。 Then
frameElement
doesn't work and document.domain
is the empty string regardless of whether the iframe is sandboxed or not. 然后
frameElement
不起作用, document.domain
是空字符串,无论iframe是否为沙盒。 You can check whether location.protocol
is 'data:'
string to detect data URIs. 您可以检查
location.protocol
是否为'data:'
字符串以检测数据URI。
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';
}
A project sandblaster can help you detect if you running being sandboxed. 项目喷砂机可以帮助您检测您是否正在运行沙盒。
Sandbox check if itself is framed first and then scans through the attributes of the frame element to detect several information about itself. 沙箱检查是否自己先构成框架然后扫描框架元素的属性以检测有关其自身的若干信息。 These includes
framed
, crossOrigin
, sandboxed
, sandboxAllowances
, unsandboxable
, resandboxable
, sandboxable
. 这些包括
framed
, crossOrigin
, sandboxed
, sandboxAllowances
, unsandboxable
, resandboxable
, sandboxable
。
To detect if itself is sandboxed in our case, it checks if the frame element has an attribute sandbox
. 为了检测在我们的情况下它本身是否为沙箱,它会检查框架元素是否具有属性
sandbox
。
// On below `frameEl` is the detected frame element
try {
result.sandboxed = frameEl.hasAttribute("sandbox");
}
catch (sandboxErr) {
result.sandboxed = null;
if (typeof errback === "function") {
errback(sandboxErr);
}
}
I tried to replicate your issue and to test if this solution works, I had to paste the script into the window itself due to the security issue. 我试图复制你的问题,并测试这个解决方案是否有效,由于安全问题,我不得不将脚本粘贴到窗口中。
<html>
<head>
</head>
<body>
<script>
//Paste the contents of the script(https://raw.githubusercontent.com/JamesMGreene/sandblaster/master/dist/sandblaster.js) here
var result = sandblaster.detect();
if(result.sandboxed === true) {
//sandboxed
}
debugger;
</script>
</body>
</html>
Here is a demo: http://jsfiddle.net/Starx/tzmn4088/ that shows this working. 这是一个演示: http : //jsfiddle.net/Starx/tzmn4088/ ,显示这个工作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.