What I did:
I created a index.html with a xss.js, which calls the jQuery.get() function. Then I’ve opened the index.html in a browser (Firefox, Chrome, IE and Opera) and tried to trigger the ajax request.
The Code
Here is my index.html:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>XSS</title>
<script src="libs/js/jquery-1.7.2.js" ></script>
</head>
<body>
<button id="request" >fire</button>
<script src="libs/js/xss.js" ></script>
</body>
</html>
and my xss.js:
function init()
{
$('#request').click(loadContent);
}
function loadContent()
{
$.get('http://www.example.com/', null, function(data){
alert('success');
$('body').html(data);
}, 'html');
}
init();
If I open the index.html within a browser (file:///C:/workspace/xss%20test/index.html), I get the following responses after clicking the button:
-
Firefox: no error code (
HTTP/1.1 200 OK), but the answer is empty -
IE: no answer
-
Chrome:
XMLHttpRequest cannot load http://www.example.com/. Origin null is not allowed by Access-Control-Allow-Origin. -
Opera: no error code (
HTTP/1.1 200 OK) and the complete html file as answer, but nothing will be displayed (the success callback is not being triggered)
This code will load the index.html into my Android WebView:
public class MainActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
WebView webview = (WebView) findViewById(R.id.webview);
webview.getSettings().setJavaScriptEnabled(true);
webview.setWebChromeClient(new WebChromeClient());
webview.setWebViewClient(new WebViewClient());
webview.loadUrl("file:///android_asset/www/index.html");
}
}
calls the success callback and also displays the content of www.example.com in the body of my index.html file, after the button is triggered.
(The same is possible on iPhone devices – I haven’t tested this on Windows Phone devices).
tl;dr – The Question:
Why is it possible to load content from a remote server to my mobile device – isn’t this a case of cross-domain scripting or am I missing something?
Due to browser security restrictions, most “Ajax” requests are subject to the same origin policy; the request can not successfully retrieve data from a different domain, subdomain, or protocol.
Also: Why does Opera receive an answer but does not display anything?
Thanks in advance.
Actually, your code fails on mobile browsers including ICS and Chrome on Android as well as Safari on iPhone. However, what you have shown is not loading the html file in a browser – it is loading it into a WebView – a different animal altogether.
A WebView or Webkit is just a UI widget that implements browser-like functionality. They are not browsers. They do not provide stuff like the usual browser chrome and they have very liberal security models by default compared to browsers. Though, you can add code to implement things like same-origin-policy etc. if you want.
It’s not only on mobile devices. Try creating a Webkit app on the desktop and you’ll see the same thing.
I believe the reason for this is that WebViews and Webkits are assumed to be used to display content that you control 100%. Unlike browsers where users can enter any URL in the address bar. Therefore it’s up to you to vet weather the things you’re loading are safe or not.