首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用限制性内容安全策略将iframe注入页面

用限制性内容安全策略将iframe注入页面
EN

Stack Overflow用户
提问于 2014-07-08 21:04:44
回答 3查看 49.1K关注 0票数 50

我想要创建一个浏览器扩展,它创建一个侧边栏。Chrome没有一流的侧边栏,因此我们必须在页面中添加一个iframe。但是,由于内容安全策略,这在许多页面上会中断。例如,GitHub使用CSP,它不允许将来自其他站点的iframes嵌入其中。例如,如果您试图将capitalone.com网站放在GitHub上的iframe中,您将得到以下内容:

拒绝帧'https://www.capitalone.com/‘,因为它违反了以下内容安全策略指令:“frame 'self’render.githubusercontent.com www.youtube.com assets.braintreegateway.com”。

这里有一个简单的浏览器扩展来复制它:

代码语言:javascript
复制
chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) {
  if (changeInfo.status === 'complete') {
   chrome.tabs.executeScript(tabId, { code: 'document.body.innerHTML=\'<iframe style=\"width:600px; height:600px\" src=\"https://www.capitalone.com/\"></iframe>\' + document.body.innerHTML;' }, function() {
     console.log('Iframe injection complete');
   })
  }
}.bind(this));

然而,维基百科认为,尽管有任何内容安全策略,浏览器扩展应该能够注入iframe:

根据CSP处理模型,20个CSP不应干扰用户安装的浏览器插件或扩展的操作。CSP的这一特性有效地允许任何附加或扩展将脚本注入到网站中,而不管该脚本的来源如何,因此不受CSP策略的约束。

除了我正在做的事之外,还有什么别的方法可以让我注射iframe吗?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2014-07-09 08:48:20

无法在Chrome中插入外部iframe是一个缺陷(crbug.com/408932)。

如果要在外部网站中嵌入外部框架,则必须将其加载到随扩展打包的框架中。

manifest.json

代码语言:javascript
复制
{
    "name": "Embed external site",
    "version": "1",
    "manifest_version": 2,
    "content_scripts": [{
        "js": ["contentscript.js"],
        "matches": ["*://*/*"],
        "all_frames": true
    }],
    "web_accessible_resources": [
        "frame.html"
    ]
}

如果希望始终在文档中插入内容脚本,请不要使用chrome.tabs.onUpdated + chrome.tabs.executeScript。您的实现存在缺陷,可能导致脚本多次运行。相反,您应该使用在清单文件中声明内容脚本

(如果不想在每个子帧中插入框架,请删除"all_frames": true。)

contentscript.js

代码语言:javascript
复制
// Avoid recursive frame insertion...
var extensionOrigin = 'chrome-extension://' + chrome.runtime.id;
if (!location.ancestorOrigins.contains(extensionOrigin)) {
    var iframe = document.createElement('iframe');
    // Must be declared at web_accessible_resources in manifest.json
    iframe.src = chrome.runtime.getURL('frame.html');

    // Some styles for a fancy sidebar
    iframe.style.cssText = 'position:fixed;top:0;left:0;display:block;' +
                           'width:300px;height:100%;z-index:1000;';
    document.body.appendChild(iframe);
}

frame.html

代码语言:javascript
复制
<style>
html, body, iframe, h2 {
    margin: 0;
    border: 0;
    padding: 0;
    display: block;
    width: 100vw;
    height: 100vh;
    background: white;
    color: black;
}
h2 {
    height: 50px;
    font-size: 20px;
}
iframe {
    height: calc(100vh - 50px);
}
</style>
<h2>Displaying https://robwu.nl in a frame</h2>
<iframe src="https://robwu.nl/"></iframe>

重要的是要注意,我在框架中加载了一个https站点。如果试图在框架中加载HTTP站点,则如果父框架之一是https页面,则混合内容策略将阻止加载该框架。

https://robwu.nl/替换为http://example.com/,在https页面(如https://github.com )上,框架将保持为空白。同时,以下消息将被打印到控制台。

[blocked] The page at 'https://github.com/' was loaded over HTTPS, but ran insecure content from 'http://example.com/': this content should also be loaded over HTTPS

票数 82
EN

Stack Overflow用户

发布于 2017-07-28 09:57:20

罗伯?W的回答是正确的。你可以跟着这个https://transitory.technology/browser-extensions-and-csp-headers/。我已经成功地使它在我的Chrome扩展https://github.com/onmyway133/github-chat中工作了。

请注意,我使用的是Chrome 59,所以我可以使用大多数ES6功能

在清单中声明

代码语言:javascript
复制
"web_accessible_resources": [
  "iframe.html",
  "scripts/iframe.js"
]

在window.onload事件中创建iframe

代码语言:javascript
复制
let url    = decodeURIComponent(window.location.search.replace('?url=', ''))
let iframe = document.createElement('iframe')
iframe.src = url

iframe.id = 'github-chat-box-iframe-inner'
iframe.style.width = '100%'
iframe.style.height = '350px'
iframe.style.border = '0px'

window.onload = () => {
  document.body.appendChild(iframe)
}
票数 7
EN

Stack Overflow用户

发布于 2014-09-18 01:40:08

您的示例应该适用于Chrome,但它目前并不是因为一个bug:https://code.google.com/p/chromium/issues/detail?id=408932。罗伯·W的回答包含了一个很好的解决问题的方法。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24641592

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档