使用限制性内容安全策略将iframe注入页面 [英] Injecting iframe into page with restrictive Content Security Policy

查看:399
本文介绍了使用限制性内容安全策略将iframe注入页面的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想创建一个浏览器扩展,它创建一个侧边栏.Chrome没有第一级边栏,所以我们必须在页面中放置一个iframe。但是,由于内容安全策略的原因,这会在很多页面上打破。例如。 GitHub使用CSP,它不允许来自其他站点的iframe被嵌入其中。例如。如果您尝试将capitalone.com网站放在GitHub上的iframe中,您会得到以下结果:


拒绝框架https://www.capitalone.com/ ',因为它违反了以下内容安全策略指令:frame-src'self'render.githubusercontent.com www.youtube.com assets.braintreegateway.com。


以下是一个简单的浏览器扩展程序来重现这一点:

  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,尽管有任何内容安全策略:

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


除了我正在做的事情之外,是否还有其他方法可以注入iframe?

解决方案

无法在Chrome中插入外部iframe是一个错误( 在与您的扩展程序一起打包的框架中。

manifest.json



  {
name:嵌入外部网站,
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



  //避免递归框架插入... 
var extensionOrigin ='chrome-extension://'+ chrome.runtime.id;
if(!location.ancestorOrigins.contains(extensionOrigin)){
var iframe = document.createElement('iframe');
//必须在manifest.json中的web_accessible_resources处声明
iframe.src = chrome.runtime.getURL('frame.html');

//一些花式边栏的样式
iframe.style.cssText ='position:fixed; top:0; left:0; display:block;'+
'宽度:300像素;高度:100%; z索引:1000;';
document.body.appendChild(iframe);
}



frame.html



< style>
html,body,iframe,h2 {
margin:0;
border:0;
padding:0;
display:block;
宽度:100vw;
身高:100vh;
背景:白色;
颜色:黑色;
}
h2 {
height:50px;
font-size:20px;
}
iframe {
height:calc(100vh - 50px);
}
< / style>
< h2>在框架中显示https://robwu.nl< / h2>
< iframe src =https://robwu.nl/>< / iframe>

请注意,我加载了 https 在框架中的网站。如果您尝试在框架中加载http站点,则混合内容策略将阻止框架在其中一个父框架是https页面的情况下加载。



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


[blocked]'https:/ /github.com/'是通过HTTPS加载的,但是运行的内容不安全:'http://example.com/':这些内容也应该通过HTTPS加载



I want to create a browser extension which creates a sidebar.Chrome does not have a first-class sidebar, and so we must instead put an iframe in the page. However, this breaks on many pages due to content security policy. E.g. GitHub uses a CSP, which does not allow iframes from other sites to be embedded within it. E.g. if you try to put the capitalone.com website in an iframe on GitHub you get the following:

Refused to frame 'https://www.capitalone.com/' because it violates the following Content Security Policy directive: "frame-src 'self' render.githubusercontent.com www.youtube.com assets.braintreegateway.com".

Here's a simple browser extension to reproduce that:

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));

Yet, according to Wikipedia, a browser extension should be able to inject an iframe despite any content security policy:

According to the CSP Processing Model,[20] CSP should not interfere with the operation of browser add-ons or extensions installed by the user. This feature of CSP effectively allows any add-on or extension to inject script into web sites, regardless of the origin of that script, and thus be exempt to CSP policies.

Is there some other way that I should be injecting an iframe besides what I'm doing?

解决方案

The inability to insert an external iframe in Chrome is a bug (crbug.com/408932).

If you want to embed an external frame in an external website, then it must be loaded in a frame that is packaged with your extension.

manifest.json

{
    "name": "Embed external site",
    "version": "1",
    "manifest_version": 2,
    "content_scripts": [{
        "js": ["contentscript.js"],
        "matches": ["*://*/*"],
        "all_frames": true
    }],
    "web_accessible_resources": [
        "frame.html"
    ]
}

Do NOT use chrome.tabs.onUpdated + chrome.tabs.executeScript if you want a content script to always be inserted in a document. Your implementation is flawed and can cause the script to be run multiple times. Instead, you should declare the content script in the manifest file.

(remove "all_frames": true if you don't want to insert the frame in every subframe.)

contentscript.js

// 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

<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>

It is important to observe that I loaded a https site in the frame. If you attempt to load a http site in the frame, then the mixed content policy will block the frame from being loaded if one of the parent frames is a https page.

Replace https://robwu.nl/ with http://example.com/ and the frame will remain blank on https pages such as https://github.com. Simultaneously, the following message will be printed to the console.

[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

这篇关于使用限制性内容安全策略将iframe注入页面的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆