accessing https iframe element on chrome-extension - google-chrome

I added an iframe and jquery to my popup.html.
<iframe id="xyz" border="0" src="https://xyz.com/test"></iframe>
and trying to reach an element of this iframe with this command via console :
$("#xyz").contents().find("body").fadeIn();
but it giving this error :
Unsafe JavaScript attempt to access frame with URL https://xyz.com/test from frame with URL chrome-extension://my-extension-id/popup.html. The frame requesting access has a protocol of 'chrome-extension', **the frame being accessed has a protocol of 'https'. Protocols must match**
I searched google for this error but there is no error like this. All of them saying domain must match etc. But this one saying only protocols must match. How can I solve this protocols problem?
And I have this line on my manifest file.
"permissions": [
"*://xyz.com/*"
]

Seems like an issue with same origin policy.
Try following the solution mentioned in this discussion. Also, try doing it through native Javascript first before trying to do it using jQuery.

Related

Why are two files in the same folder treated as cross-resource?

I've added an iframe to an Rmarkdown document. The iframe is an HTML file that is stored in the same folder as my .Rmd file and the HTML file it generates. I would like to determine the appropriate height/width to display the iframe based on the HTML file dimensions. I should be able to use iframe.contentWindow.document.body.scrollWidth/iframe.contentWindow.document.body.scrollHeight to do this.
Here is an example of what I tried in my Rmd file:
<iframe src="./test_file.html" style="display:block; border:none;
width:100%;" id="test"></iframe>
```{js}
var iframe = document.getElementById('test');
iframe.addEventListener('load', function(event) {
iframe.height = iframe.contentWindow.document.body.scrollHeight;
iframe.width = iframe.contentWindow.document.body.scrollWidth; });
```
However the contentWindow value is null for the iframe. When I look at the HTML page generated by Rmarkdown with Developer Tools, I see the error:
Uncaught DOMException: Blocked a frame with origin
"https://website.host.name" from accessing a cross-origin frame.
at HTMLIFrameElement. (https://website.host.name/R/Rmd_test/generate_preview.html:1636:42)
So it seems that the files are being treated as cross-origin resources rather than coming from the same-origin. I'm not sure why that is since they are both located in the same folder and their location.protocol, location.host, & location.port values are the same (port is null for both, which from my reading should be fine).
I did find a workaround to get the height/width using postMessages to have the pages communicate, but I'd like to figure out how to have the iframe content recognized as same-resource. Any ideas what I'm doing wrong/missing?
I don't think this is a duplicate of SecurityError: Blocked a frame with origin from accessing a cross-origin frame. I used that post to figure out my workaround to get the height/width. The accepted answer notes that the origin is considered to be different if the protocol, hostname, or port differs between the two resources. In my case, when I open each HTML file, that information is the same. Why are they being treated as cross resource?

Failed to load data inside of iFrame

I tried to fetch the URL of an old website, and an error happened:
Fetch API cannot load http://xyz.
No 'Access-Control-Allow-Origin' header is present on the requested resource.
Origin 'http://abc' is therefore not allowed access.
If an opaque response serves your needs, set the request's mode to 'no-cors'
to fetch the resource with CORS disabled.
my code looks like this
render(){
return (
<div>
<iframe src="http://localhost:8080/.../StockExchangeWidget.html" />
</div>
)
}
when I load this outside of iFrame, everything is OK, but when I try to load it with iFrame well then I get lot's of errors, but only for data for charts, as you can see the frame and buttons are loaded.
I'm also getting WebSocket error when I try to load HTML page over url inside of
WebSocket connection to 'wss://widgetdata.tradingview.com/socket.io/websocket?from=widgetembed%2F&date=2018_06_09-17_59' failed: Error during WebSocket handshake: Unexpected response code: 403
The domain that hosts the iframe needs to amend its CORS Policy to allow requests from your domain to reach their site. Without the CORS headers present on that page, your browser will not render the content of the iframe (for security reasons).
Yes, the answer is in the CORS Policy as PANAYIOTIS pointed to me.
my code now looks like this
render(){
return (
<div>
<iframe
sandbox="allow-same-origin"
title="FirstIFrame"
src="http://www.tricky.web.siteHome.do"
/>
</div>
)
}
I added sandbox="allow-same-origin" inside of my iframe, and all 'cookies' and 'can not upload' problems are solved.
for more info read this post It's great for this kind of problems:

How to CSP restrict to file:/// urls in chrome?

I have an iframe in a webview which loads a script from the android app's asset using the following :-
<script src='file:///android_asset/trusted-iframe-script.js'></script>
Now I want to have a content security policy on the iframe such that no other script can be loaded.
For this I added the following to the iframe CSP
script-src: 'file:///android_asset/trusted-iframe-script.js';
This doesn't work since the file uri is ignored by chrome.
The source list for Content Security Policy directive 'script-src' contains an invalid source: 'file:///android_asset/trusted-iframe-script.js'. It will be ignored.
Refused to load the script 'file:///android_asset/trusted-iframe-script.js' because it violates the following Content Security Policy directive: "script-src file:///android_asset/trusted-iframe-script.js".
I read about filesystem uri, but that requires requesting access to the user but I actually only need access to my own assets and not filesystem in general. I also read about blob: urls but that feels akin to inlining the whole script
What is the right way to csp restrict to only file urls ?
CSP URI's don't have quote marks - so try script-src: file:///android_asset/trusted-iframe-script.js;
If that doesn't work most Android browsers now support CSP2, which lets you specify a hash for a supported script.
If the CSP is set on the "page" which contains the iframe you should use
the ​child-src: directive instead of script-src: (Source)
Then, i am not use how to include an assert file and you could try with:
​child-src: file:///android_asset/trusted-iframe-script.js
// i cannot test it
​child-src: filesystem:///android_asset/trusted-iframe-script.js
// source and check if still requires requesting access to the user
child-src: https://your.trusted.website.com/trusted-iframe-script.js
// this should work but it requires to have a trusted server and the app must connect to the web (no obvious condition)
In short, this cannot be done for a sandboxed iframe.
Chrome CSP doesn't allow file urls to be whitelisted as a script src. You could use the directive file: (without any url) and that would work if the iframe wasn't sandboxed. But this is a bad idea, since
A. my iframe is sandboxed, and
B. this is an undocumented keyword which may stop working at anytime.
I also tried creating a blob url for the content and instead passing that to the iframe but that too doesn't work unless you set allow-same-origin on the iframe sandbox attribute.

Viewing IFRAME independent of whether using HTTP or HTTPS

Let's say I have the following IFRAME. It works fine as long as the browser is viewing the page using HTTP, however, if the browser is viewing the page using HTTPS, it will result in errors, and the IFRAME must be changed to also use HTTPS.
<iframe id="sitePreview" name="sitePreview" src="http://preview.administrator.test6.example.com/index.php?cid=17&preview=1330668404"></iframe>
Without using server script to customize the protocol of the HTML based on the protocol being used to view the page, is it possible to create the URI so that they will work with both HTTP and HTTPS?
Also, please comment if this applies to other links such as:
<img alt="Map" src="http://maps.google.com/maps/api/staticmap?markers=color:blue|31 Milk St Boston MA&zoom=14&size=400x400&sensor=false" class="map">
<script src="http://maps.googleapis.com/maps/api/js?v=3.exp&sensor=false&libraries=places" type="text/javascript"></script>
Keep in mind cross site iframe calls can be tricky, read this article:
http://blog.cakemail.com/the-iframe-cross-domain-policy-problem/, however, since it does load, I'm assuming you are including an iframe from the same domain.
To answer your question, simply drop the protocol off the src, you would reference it as:
<iframe id="sitePreview" name="sitePreview" src="//preview.administrator.test6.example.com/index.php?cid=17&preview=1330668404"></iframe>
This will make sure that it will use whatever protocol the parent is using...
You could also hardcode it to https, but that would mean that every request will serve a secure image which creates unnecessary overhead...
I think this would work:
If(location == "https://whatever.com")
{
//this is https
}
Else
{
//it's http
}
Let me know if I didn't get it right and I will recode it.

Chrome extension, replace HTML in response code before browser displays it

i wonder if there is some way to do something like that:
If im on a specific site i want that some of javascript files to be loaded directly from my computer (f.e. file:///c:/test.js), not from the server.
For that i was thinking if there is a possibility to make an extension which could change HTML code in a response which browser gets right before displaying it. So whole process should look like that:
request is made
browser gets response from server
#response is changed# - this is the part when extension comes in
browser parse changed response and display page with that new response.
It doesnt even have to be a Chrome extension anyway. It should just do the job described above. It can block original file and serve another one (DNS/proxy?) or filter whole HTTP traffic in my computer and replace specific code to another one of matched response.
You can use the WebRequest API to achieve that. For example, you can add a onBeforeRequest listener and redirect some requests:
chrome.webRequest.onBeforeRequest.addListener(function(details)
{
var responseData = "<div>Some text</div>"
return {redirectUrl: "data:text/html," + encodeURIComponent(responseData)};
}, {urls: ["https://www.google.com/"]}, ["blocking"]);
This will display a <div> element with the text "some text" instead of the Google homepage. Note that you can only redirect to URLs that the web server itself is allowed to redirect to. This means that redirecting to file:/// URLs is not possible, and you can only redirect to files inside your extension if these are web accessible. data: and http: URLs work fine however.
In Windows you can use the Proxomitron (proxomitron.info) which is a local proxy that can intercept any page or file being loading into your browser and change it using regular expressions (no DOM parsing) however you want, before it is rendered by the browser.