Serving cross-site content - JSONP, iframe or something else? - javascript

I'm building an ad network. This entails 3rd party sites including my javascript, then replacing divs they specify with my content.
We need to dynamically determine which piece of content to serve into those divs, so this requires a cross-site call. AFAIK the popular ways to achieve this are JSONP and iFrame. What are the pros and cons of each approach? Particularly, I'm interested in:
Browser compatibility
End user performance
Ad performance tracking
Resilience to 3rd party site tampering (i.e. faking clicks)
What existing ad networks use
If there are other technologies would like to learn about them also.
EDIT: After doing some research, another option seems to be an image tag that does a 302 redirect so the server can chose an image dynamically.

Another option is to implement CORS on yiur server, but that only works with modern browsers, so may not be a suitable option for you.

Related

Is is possible to style in external domain iframe in 2020?

client push me to change the CSS styles of an external site which is included in an iframe. Is it possible to do that? I found topics from 2011 with a solution, but after I tried to do that with CSS, js, jquery - I think is not possible if the site is not hosted by the same domain.
It's still not possible for security reasons. In order to allow this, you'd need control of both sites, and even then, you'd be potentially opening yourself up to allowing XSS attacks on the target site. Your best bet would see if the target site has an API that you could pull data from and display on your site with whatever styling you want. That's a separate topic altogether though.

How to allow only whitelisted resources (scripts, pixels etc.) to run within a sandboxed iframe?

I am looking for an approach to allow only whitelisted scripts to run within a sandboxed iframe. I was thinking of an iframe-sandbox directive that allows only whitelisted scripts to run within an iframe. The analogy is the script-src directive in the Content Security Policy.
The problem:
<iframe sandbox="allow-same-origin allow-scripts" src="https://app.thirdparty.com" width="100%" height="800" frameBorder="0"></iframe>
The app in the iframe provides valuable functionality for my website. However, it pulls in external resources that I would like to control (i.e., block), e.g., AnalyticsJavaScript.com and TrackingPixel.com. I would like to allow scripts from app.thirdparty.com but block AnalyticsJavaScript.com and TrackingPixel.com.
Any help appreciated.
The answer to this is unfortunately complicated. With the advent of iframe sandboxing the question seems simple enough, but the spec that you're looking for is very much a work in progress. Thus, if you want decent browser support, the issue devolves into how to modify an iframe's content, which usually involves some sort of proxy.
Content Security Policy
The spec you really need is the CSP. At its simplest, you would allow specific scripts with the iframe atribute csp="...".
<iframe ...
src=""
csp="script-src https://app.thirdparty.com/"
...></iframe>
Any scripts from domains not specified (i.e. tracking scripts as in the question) would not be allowed in the response. Note that limiting scripts to those from a specified source does rely on cooperation with the third party app's server. If the server does not inform the user agent that it will adhere to the CSP restrictions then the response will be blocked.
The CSP is still a working draft and may change in the future. As stated in the comments, Chrome 61 and Opera 48 have implemented the CSP spec, but at this stage there is no sign from Firefox, Edge or Safari that they will also implement it. Unless you can guarantee that your users will only be using a browser that supports the spec, the tracking scripts will still be present for a very large percentage of users.
The remaining suggestions all involve modifying the iframe's content to remove the offending scripts.
Reverse proxy
Creating a reverse proxy to block a couple of tracking scripts in an iframe is probably equivalent to using a nuclear warhead to light a camp fire as far as overkill goes. But, if you are able to configure your server to this extent, it is the most reliable and seamless method for iframe content injection/modification/blocking that I've found.
The Wikipedia page states:
A reverse proxy is a type of proxy server that retrieves resources on behalf of a client from one or more servers. These resources are then returned to the client, appearing as if they originated from the proxy server itself.
Because the reverse proxy is an intermediary between the third party app and your site, it can transparently modify the responses to remove the undesired scripts. I'll use Apache in this example, but your implementation really depends on what server you're already using.
You need a subdomain for the proxy that points to your server IP, e.g. proxywebapp.yourdomain.com. On your server you would then create a virtual host in httpd.conf that uses the Apache mod_proxy module. Within your virtual host configuration you would then substitute the script calls to AnalyticsJavaScript.com and TrackingPixel.com with blanks. If the third party app must use HTTPS then reverse proxying gets trickier as you need an SSL virtual host and a SSL certificate for the proxy's FQDN.
<VirtualHost *:*>
ServerName proxywebapp.yourdomain.com
ProxyPreserveHost On
ProxyPass "/" "http://app.thirdparty.com/"
ProxyPassReverse "/" "http://app.thirdparty.com"
# in case any URLs have the original domain hard coded
Substitute "s|app.thirdparty.com/|proxywebapp.yourdomain.com/|i"
# replace the undesired scripts with blanks
Substitute "s|AnalyticsJavaScript/| /|i"
Substitute "s|TrackingPixel/| /|i"
</VirtualHost>
Your iframe would then point to proxywebapp.yourdomain.com.
<iframe ... src="proxywebapp.yourdomain.com" ...></iframe>
Again: total overkill but should work transparently.
Proxy scripts
A third option to consider is implementing a proxy script on your server between the iframe and third party app. You would add functionality into the proxy script that searches for and removes the undesired scripts before they reach the iframe. Additionally the proxy means the iframe's content will validate the same-origin policy, thus you could instead remove the undesired content with JavaScript in the frontend, although this may not guarantee that the scripts won't run before they are removed. There are many proxy scripts available online for all manner of backends (PHP, Node.js etc. ad nauseum). You would likely install the script and add it as the iframe's src, something like <iframe ... src="proxy.php?https://app.thirdparty.com/" ...>.
Unless properly configured for all cases, the proxy may not correctly transfer data between the third party app and its parent server. Testing will be required.
Writing your own server side proxy to remove a couple of scripts from an iframe is probably a bit excessive.
If you can't access the backend, it is possible to scrape the web app's content using JavaScript and a CORS or JSONP web app, and modify it to remove the scripts. Essentially making your own proxy in JavaScript. Such web apps (Any Origin, All Origins, etc) allow you to bypass cross-domain policy restrictions, but because they are third party you can no longer assume any of the web app's data is private. The issue with correctly communicating any data transfer between the app and its parent server will still be present.
Summary
A widely supported pure frontend solution is not feasible at the moment. But there are many ways to skin a cat and perhaps even more ways to modify an iframe's content, regardless of cross-domain restrictions.
Content Security Policy does look promising and is exactly what you're asking for, but currently its lack of widespread support means it can only be used in very niche situations. A reverse proxy that modifies content may take a lot of configuring and in this situation is like driving a full size semi-trailer over a Hot Wheels track, but will likely operate seamlessly. Content modification from a forward proxy is somewhat simpler to implement, but may break communications with the third party app's parent server.
You can't do this the way you want (for now). As mentioned in comments CSP:EE is a thing yet to come.
However you can try proxying the request and removing the unnecessary scripts from the body on the server side or on the client side, e.g.:
1) Get the needed page via XMLHTTPRequest
2) Remove unwanted
3) Inject into iframe on the page
"Workability" of this method depends purely on external app functionality. I.e. it will not work if the aforementioned app needs registration/authorisation of the end user to work, however this can still be suitable for some simple cases.
P.S.: you can implement a workaround to make such thing work via browser extension, however I'm sure this is not what you want.

iframe or JS to embed Rails in 3rd party sites?

I want to create embedable widgets for a Rails app, that would allow users to interact with the app from external websites.
I was all set to try using iframes to achieve this. But then I found a couple of forum responses that seemed to suggested iframes are not the best way to achieve this, and instead to use JS to embed HTML elements. This surprised me - I thought iframes would be a clear winner simply because of the isolation of CSS and scripts.
So, what is the best way to embed (limited) app functionality in a third party website. This interaction will be limited to login and a single simple form. Is iframes of JS embed the best way to go? And as a side question, are there security issues to be aware of with either approach?
I think using iframes suck hard. It's just not the feeling of a whole website, it's like a website inside another, mostly the styles won't match, or you have a scrollbar or the responsive layout is not applying right. So here's a little pro/con list:
iframe PRO:
requests are not cross site origin (most likely more secure)
"sandbox" javascript (no conflicts)
iframe CON:
style guides
history not changing (e.g. if you do a submit a form with GET you cannot paste the URL and send it to a friend)
js PRO:
Full control about the navigation (you can override link clicks with $.load etc).
Ability of changing the browser history (history API, see MDN)
smooth handling of html components
style's are automatically inherited
js CON:
CORS see https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS
Handle (override) events like link clicking, form submitting. (see Sending multipart/formdata with jQuery.ajax)
Sessions/cookies
I wrote a little rails plugin which allows you to embed your rails app as a js frame inside another (it's still really really beta): https://github.com/Elektron1c97/better_frame. The plugin handles most of the js problems like the link/form events and write to the browser history.
So.. If you need to run an app which should be really embed in a site like a store on another website I would use js embedding.
If you create a custom item to share like the soundcloud player you may want to use an iframe.
If you want third party sites to react to interactions with your widgets then you should absolutely use javascript. Although it is possible to pass messages between different domains through an iframe it is not the most convenient to use. See https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage
As for using javascript, you can simply ask your users to embed a javascript file that will render your widget. To bypass any CORS issues, your widget should interact with an API that supports JSONP responses.

Workaround for X-Frame-Options:deny or sameorgin?

I'm displaying web pages (from other domains) in an IFrame to have navigation at the side. However, some websites have the header X-Frame-Options:deny or X-Frame-Options:sameorigin, which prevents the pages from loading in my iframe. Is there a workaround to this? How would I display the web page?
I noticed that StumbleUpon has the same issue. Here's an example with the X-Frame-Options issue: http://www.stumbleupon.com/su/53D0nJ/news.yahoo.com/worlds-dumbest-idea-taxing-solar-energy-111300623.html/
No.
It would be entirely pointless for browser vendors to provide a way for websites to say Don't let third parties put my content in a frame if they also provided a way for third parties to tell browsers to ignore that instruction.
The closest you could come would be to copy their content so it is accessible via a URL on your own server. That approach would probably cause you to run afoul of international copyright law.

Cross Domain Scripting (IE and Firefox only)

Ive been asked to tackle a challenge where if we have JS delivered into an non-Friendly (aka Cross Domain) IFRAME (3rd party code being written to page), and from inside that IFRAME determine the x&y offset of the iframe into which the code is delivered. Due to cross site scripting limitations historically this has been deemed a non-starter, but we now have a need to have this ability. Anyone aware of any techniques that could get me started ?
I would start by ditching the iframe, honestly. Cross-site scripting is one thing, but what you may be looking for is a web scraper.
http://en.wikipedia.org/wiki/Web_scraping
Although I'm wondering if your intentions are benevolent if you're grabbing content from another site...

Categories