I've been reading up on HTML5's sandbox attribute for <iframe>s. According to the documentation the sandbox attribute allows a developer to selectively restrict what actions can be done in an <iframe>. Is the sandbox attribute purely a security measure? Does the sandbox attribute enable web designers to implement any new functionality and if so can anyone point to any examples?
Well, it is purely a security feature, but it does allow new functionality as well. Take for example embedding third party (user) content (e.g. HTML files). Traditionally you would need to set up a separate domain from which you would serve that content, now however you can simply serve it from wherever you want to and have it treated as if it's from a separate domain.
On top of that it can prevent this third party content from doing certain things, which you could not have prevented previously like:
allow-top-navigation: Preventing it from breaking out
allow-pointer-lock: Preventing it from taking the cursor hostage
allow-popups: Preventing it from breaking out through popups
allow-scripts: Simply blocking all scripts (could also have been done through CSP)
Realistically the combination of the sandbox attribute combined with controlled CSP headers gives an incredible amount of control to run third party code in a safe environment. It's not 100% there yet, but we're getting quite close.
The sandbox can actually be pretty handy in testing. Consider the following:
tester.html
<script> document.cookie='foo=bar' </script>
<iframe src=testee.html>
testee.html
<script> console.log(document.cookie) </script>
When loading tester.html you will see on the console "foo=bar" which was dumped by testee.html.
Now add to the iframe the sandbox attribute and the cookie is gone - the sandbox created a separate runtime environment for testee.html, where it doesn't get cookie pollution from other pages that were/are open in the browser during the development process. So when you need a sterile test bed but can't or don't want to clear the browser cache, here's a quick and simple solution.
The sandbox attribute does not enable any extra functionality, it only restricts the functionality of the iframe. The only reason to use it is as a security measure.
The iframe sandbox is purely a security feature. A good resource is always the W3 HTML5 specification.
When the attribute is set, the content is treated as being from a unique origin, forms, scripts, and various potentially annoying APIs are disabled, links are prevented from targeting other browsing contexts, and plugins are secured.
Related
I'm trying to extract or just analyze the audio from a vimeo video with the web audio API and was wondering if it's possible and how.
Right now I get the error:
Uncaught TypeError: Failed to execute 'createMediaElementSource' on 'AudioContext': parameter 1 is not of type 'HTMLMediaElement'
… when I try a createMediaElementSource(video) where video is my iframe
Unfortunately I think it is not possible to do what you want. At least not exactly in the way you want it.
The createMediaElementSource() factory function only works with media elements. And those are only <audio/> and <video/> elements. This is why it doesn't work when you use it with the <iframe/> directly.
Normally you would query such a media element for example by its id like this:
document.querySelector('#myAudioElement');
But this is not that easy if the element is inside an <iframe/>. Then it is only possible to query an element if the <iframe/> and the parent document do have the same origin. This is because of the same-origin policy which is a security feature. Imagine what an attacker could do if it was possible to load any page in an <iframe/> and then modify it at will.
Of course it is a hindrance for your use case. Maybe building a browser extension is an option for you because they have usually more privileges and can query the DOM of any page the browser loads.
Alternatively it is also possible to disable the same-origin policy in some browsers. But that is usually only useful during development because you can only disable this policy for the whole browser which is a security problem unless you only open sites that you fully trust.
I've just noticed that the long, convoluted Facebook URLs that we're used to now look like this:
http://www.facebook.com/example.profile#!/pages/Another-Page/123456789012345
As far as I can recall, earlier this year it was just a normal URL-fragment-like string (starting with #), without the exclamation mark. But now it's a shebang or hashbang (#!), which I've previously only seen in shell scripts and Perl scripts.
The new Twitter URLs now also feature the #! symbols. A Twitter profile URL, for example, now looks like this:
http://twitter.com/#!/BoltClock
Does #! now play some special role in URLs, like for a certain Ajax framework or something since the new Facebook and Twitter interfaces are now largely Ajaxified?
Would using this in my URLs benefit my Web application in any way?
This technique is now deprecated.
This used to tell Google how to index the page.
https://developers.google.com/webmasters/ajax-crawling/
This technique has mostly been supplanted by the ability to use the JavaScript History API that was introduced alongside HTML5. For a URL like www.example.com/ajax.html#!key=value, Google will check the URL www.example.com/ajax.html?_escaped_fragment_=key=value to fetch a non-AJAX version of the contents.
The octothorpe/number-sign/hashmark has a special significance in an URL, it normally identifies the name of a section of a document. The precise term is that the text following the hash is the anchor portion of an URL. If you use Wikipedia, you will see that most pages have a table of contents and you can jump to sections within the document with an anchor, such as:
https://en.wikipedia.org/wiki/Alan_Turing#Early_computers_and_the_Turing_test
https://en.wikipedia.org/wiki/Alan_Turing identifies the page and Early_computers_and_the_Turing_test is the anchor. The reason that Facebook and other Javascript-driven applications (like my own Wood & Stones) use anchors is that they want to make pages bookmarkable (as suggested by a comment on that answer) or support the back button without reloading the entire page from the server.
In order to support bookmarking and the back button, you need to change the URL. However, if you change the page portion (with something like window.location = 'http://raganwald.com';) to a different URL or without specifying an anchor, the browser will load the entire page from the URL. Try this in Firebug or Safari's Javascript console. Load http://minimal-github.gilesb.com/raganwald. Now in the Javascript console, type:
window.location = 'http://minimal-github.gilesb.com/raganwald';
You will see the page refresh from the server. Now type:
window.location = 'http://minimal-github.gilesb.com/raganwald#try_this';
Aha! No page refresh! Type:
window.location = 'http://minimal-github.gilesb.com/raganwald#and_this';
Still no refresh. Use the back button to see that these URLs are in the browser history. The browser notices that we are on the same page but just changing the anchor, so it doesn't reload. Thanks to this behaviour, we can have a single Javascript application that appears to the browser to be on one 'page' but to have many bookmarkable sections that respect the back button. The application must change the anchor when a user enters different 'states', and likewise if a user uses the back button or a bookmark or a link to load the application with an anchor included, the application must restore the appropriate state.
So there you have it: Anchors provide Javascript programmers with a mechanism for making bookmarkable, indexable, and back-button-friendly applications. This technique has a name: It is a Single Page Interface.
p.s. There is a fourth benefit to this technique: Loading page content through AJAX and then injecting it into the current DOM can be much faster than loading a new page. In addition to the speed increase, further tricks like loading certain portions in the background can be performed under the programmer's control.
p.p.s. Given all of that, the 'bang' or exclamation mark is a further hint to Google's web crawler that the exact same page can be loaded from the server at a slightly different URL. See Ajax Crawling. Another technique is to make each link point to a server-accessible URL and then use unobtrusive Javascript to change it into an SPI with an anchor.
Here's the key link again: The Single Page Interface Manifesto
First of all: I'm the author of the The Single Page Interface Manifesto cited by raganwald
As raganwald has explained very well, the most important aspect of the Single Page Interface (SPI) approach used in FaceBook and Twitter is the use of hash # in URLs
The character ! is added only for Google purposes, this notation is a Google "standard" for crawling web sites intensive on AJAX (in the extreme Single Page Interface web sites). When Google's crawler finds an URL with #! it knows that an alternative conventional URL exists providing the same page "state" but in this case on load time.
In spite of #! combination is very interesting for SEO, is only supported by Google (as far I know), with some JavaScript tricks you can build SPI web sites SEO compatible for any web crawler (Yahoo, Bing...).
The SPI Manifesto and demos do not use Google's format of ! in hashes, this notation could be easily added and SPI crawling could be even easier (UPDATE: now ! notation is used and remains compatible with other search engines).
Take a look to this tutorial, is an example of a simple ItsNat SPI site but you can pick some ideas for other frameworks, this example is SEO compatible for any web crawler.
The hard problem is to generate any (or selected) "AJAX page state" as plain HTML for SEO, in ItsNat is very easy and automatic, the same site is in the same time SPI or page based for SEO (or when JavaScript is disabled for accessibility). With other web frameworks you can ever follow the double site approach, one site is SPI based and another page based for SEO, for instance Twitter uses this "double site" technique.
I would be very careful if you are considering adopting this hashbang convention.
Once you hashbang, you can’t go back. This is probably the stickiest issue. Ben’s post put forward the point that when pushState is more widely adopted then we can leave hashbangs behind and return to traditional URLs. Well, fact is, you can’t. Earlier I stated that URLs are forever, they get indexed and archived and generally kept around. To add to that, cool URLs don’t change. We don’t want to disconnect ourselves from all the valuable links to our content. If you’ve implemented hashbang URLs at any point then want to change them without breaking links the only way you can do it is by running some JavaScript on the root document of your domain. Forever. It’s in no way temporary, you are stuck with it.
You really want to use pushState instead of hashbangs, because making your URLs ugly and possibly broken -- forever -- is a colossal and permanent downside to hashbangs.
To have a good follow-up about all this, Twitter - one of the pioneers of hashbang URL's and single-page-interface - admitted that the hashbang system was slow in the long run and that they have actually started reversing the decision and returning to old-school links.
Article about this is here.
I always assumed the ! just indicated that the hash fragment that followed corresponded to a URL, with ! taking the place of the site root or domain. It could be anything, in theory, but it seems the Google AJAX Crawling API likes it this way.
The hash, of course, just indicates that no real page reload is occurring, so yes, it’s for AJAX purposes. Edit: Raganwald does a lovely job explaining this in more detail.
I'm building a single-page Dart web app that will essentially consist of 1 Dart file (cross-compiled to JS) and 1 HTML file that has several "views" (screens, pages, etc.). in it. Depending on what "view" the user is currently located at, I will hide/enable different DOM elements defined inside this HTML file. This way the user can navigate between views without triggering multiple page loads.
I would still like to use each browser's native history-tracking mechanism, so that the user click can the back- and forward-buttons in the browser, and I'll have a Dart Historian object figure out what view to load (again just hiding/enabling DOM elements) depending on what URL the browser has in its history.
I've pretty much figured everything out, with one exception:
Say the user is currently "at" View #3, which has a URL of, say, http://myapp.example.com/#view3. Then they click a button that should take them to View #4 at, say, http://myapp.example.com/#view4. I need a way, in Dart, to tell the browser to:
Set http://myapp.example.com/#view4 in the browser URL bar
Add http://myapp.example.com/#view4 to the browser's history
If not already enabled, enable the browser's back button
I believe I can accomplish #1 above like so:
window.location.href = "http://myapp.example.com/#view3";
...but maybe not. Either way, how can I accomplish this (Dart code communicates with browser's history API)?
Check out the route library.
angular.dart also has it's own routing mechanism, but it's part of a much larger framework, so unless you plan on using the rest of it, I would recommend the stand-alone route library.
If you want to build your own solution, you can take a look at route's client.dart for inspiration.
There are two methods of history navigation supported:
The page fragment method that you've used. Reassign the window location to the new page fragment: window.location.assign(newPathWithPageFragment). Doing this will automatically add a new item to the browser history (which will then enable the back button).
The newer History API, which allows for regular URLs without fragments (e.g. http://myapp.example.com/view3. You can use window.history to control the history.The History API is only supported by newer browsers so that may be a concern (although given that dart2js also only supports newer browsers, there are probably not too many instances of a browser that dart2js supports that doesn't support the History API).
One issue you will have to handle if you support History API is the initial page load. When a user navigates to http://myapp.example.com/view3, the browser expects to find a resource at that location. You will have to setup your server to respond to any page request by serving your Dart application and then navigate to the correct view on the client-side. This issue will apply whether you use route, angular.dart, or build your own solution, since this is a general server-side issue and the above are all client-side libraries.
Would it compromise the security of a website if users were allowed to create img tags with whatever src attribute they wanted?
What kind of damage would be possible?
Allowing arbitrary src values on an <img> element would allow Cross-Site Scripting and thus the execution of arbitrary JavaScript code on your page:
<img src="javascript:…">
It could also be used to forge arbitrary GET requests, similar to Cross-Site Request Forgery but with a referrer originating from your site.
can also be exploited to track your website visitors by using a web bug http://en.wikipedia.org/wiki/Web_bug
I have a problem where I have a frameset consisting of a parent frame loaded from one domain and a contained frame from a different domain. The contained domain also sets a cookie before the frameset is loaded. However, because of the 'same orgin' policy, enforced by most browsers, a contained frame will not pass cookies if it is not from the same domain as the parent.
Unfortunately I have no control over the parent frame (or its url) and the url for the contained frame is effectively static. So the only way to pass information to the contained site is via cookies.
The only solution I have come up with is to reload the contained domain in the parent frame but this negates some of the value of using frames in the first place.
Does anyone have a better work around for this problem?
There are a couple of methods of getting around the Same Origin Policy that is preventing your iframes from speaking to each other. If you control both servers then you can use Flash's crossdomain.xml file. If you don't control one of the servers or you would like to use JavaScript, then you are forced to use a "Cross-Domain Proxy", such as this one for java or python or php.
Cross-Site XHR is another option but it isn't supported by all browsers.
There are a lot of ways to do this. Here are two that I've used:
Have both the parent and child load
a script from a common source, using
a tag. Scripts loaded in
this way don't have same-origin
issues, and the data they return
becomes part of the document object
and can interact with other scripts
loaded by the document (this is the
way that AJAST works).
Create a reverse proxy in the parent domain, and load the frame via this proxy. To the browser, it appears that they're both served from the same domain. The downside is that this can affect caching, and bypasses any content delivery network (eg, Akamai) that you might be using.
There is also a right way of doing this in HTML 5 with postMessage.
See here: http://ajaxian.com/archives/cross-window-messaging-with-html-5-postmessage
One more thought in to this, where u can use Cross Domain Messaging API to send messages from one frame to another. here is an example! Read more on this.