I have a script which I give to my clients and they put it in their web pages.
I want to check inside that script if the domain is safe using Google's Safe Browsing API.
When the script loads, I make an API request for the current domain with the client key I got from Google.
"Client key" according to Google:
API requests are sent directly to Google from your clients' browsers
$.ajax({
url: "https://sb-ssl.google.com/safebrowsing/api/lookup?client=demo-app&key=AIzaSyBx5EyJlhg-oB4inoO15fMlP37ljeDP98o&appver=1.5.2&pver=3.1&url=http%3A%2F%2Fstackoverflow.com",
method: "GET",
success: function (result) {
self.onDataReceived(result);
}
});
But the browser blocks my request due to No 'Access-Control-Allow-Origin' header is present on the requested resource.
It appears that the Safe Browsing API does not support cross origin requests and your best option is running a proxy on your domain.
Related
I'm trying to get the current time from http://timeapi.org/utc/now.json. I'm using the following:
var date;
$.ajax({
dataType: 'jsonp',
url: 'http://timeapi.org/utc/now.json',
success: function (result) {
date = result.dateString;
}
});
The URL is only available as HTTP, but I'm calling it from an HTTPS site. This leads to the error:
'https://myurl.com' was loaded over HTTPS, but requested an insecure script 'http://timeapi.org/utc/now.json?callback=jQuery1122020058229618158618_1466258121249'. This request has been blocked; the content must be served over HTTPS.
The timeapi website does not actually exist as https, so changing the URL to https leads to a new error: http://timeapi.org/utc/now.json
How can I force it to load? There do not seem to be any https web time services, but I imagine there has to be a way in which people on https sites are using external time-keeping services as well.
You can't.
From HTTPS, only HTTPS. From HTTP you can call HTTP and HTTPS.
What you could do is to create an https wrapper (in php or node) in your own webserver and retrieve the value from timeapi.org from there.
Something like this:
<?php
header('Content-Type: application/json');
echo(file_get_contents('http://timeapi.org/utc/now.json'));
You can't make http requests from an https.
It is restricted by same origin policy
The same-origin policy is a critical security mechanism that restricts how a document or script loaded from one origin can interact with a resource from another origin. It helps isolate potentially malicious documents, reducing possible attack vectors.
I have encountered a problem with an API I want to use. The API returns plain JSON but its a cross domain AJAX call so I have to use jsonp.
$.ajax({
type: "GET",
url: url + query,
contentType: "application/json",
dataType: "jsonp",
success: function(data){
console.log(data);
}
});
The problem is when I change the dataType to "json" an error occurs:
No 'Access-Control-Allow-Origin' header is present on the requested
resource. Origin 'X' is therefore not allowed access.
This is because its a cross domain ajax call. But when it is jsonp it says:
Uncaught SyntaxError: Unexpected token :
In other words it does not recognize the json format.
I am using jquery for the ajax call. Any suggestions how to solve this?
Since you dont have access to the server where the API is hosted, you use can a web service utility like CURL to access the API. AJAX calls requires CORS (Cross Origin Resource Sharing) to be enabled on the server where the API is served.
You can call a web service on your local server page via AJAX from where the CURL call will be made and appropriate response returned.
There are several methods of bypassing cross-domain restrictions (CORS, JSONP, Iframe transport, etc.) but all methods have in common that the API server needs to corporate. So if you don’t have privileges on the API server, you cannot come across the cross-domain restrictions.
The only way to make this work would be putting a proxy in front of the API that you can control (the proxy could either live on the same domain or inject the appropriate CORS headers). However, this will affect performance and might also have legal implications.
Regarding JSONP, here’s an excellent explanation of how and why this works:
What is JSONP all about?
I am trying to create a simple login form for my Adobe Connect account, however it's not working, I'm getting the error:
No 'Access-Control-Allow-Origin' header
However I'm doing other Ajax calls just fine on my machine.
Here's some example code that I'm using.
var request $.ajax({
url: 'http://example.com/api/xml?action=login&login=' + username + '&password=' + password
type: "GET"
});
request.done(function(){
...
})
Does anyone have any suggestions?
Your local machine calls are working because you're making calls inside the same domain. As soon as you try to do ajax calls to something outside the bounds of the caller's domain you'll run into issues with the browser's Same-Origin policy.
Basically it's a security policy that allows scripts to run on pages originating from the same site (comprised by the combination between schema, hostname and port. eg. mysite != mysite:8080) So if you have an ajax call executed from a site running on mysite to a site running on mysite:8080, the browser will consider this a same-origin policy hence blocking that request.
You should read about CORS (Cross-Origin Resource Sharing) in order to find options to help you relax the same-origin policy.
I know that this has been talked about many times here, and I have read most of these threads but I can't seem to get my script working.
Problem is that I am trying to use bitly api to shorten urls in google chrome extension. I am saving users login and apiKey in localstorage and before I do so I validate them.
The code to do so is:
$.ajax({
url:"http://api.bit.ly/v3/validate",
dataType:'jsonp',
data:{
login: login,
apiKey: apiKey,
x_login :"test",
x_apiKey :"test"
},
success:function (jo, textStatus, jqXHR) {
if (jo.status_code == 200) {
setItem('dg_BitlyApiKey', apiKey);
setItem('dg_BitlyLogin', login);
alert('Saved');
} else {
alert('Incorrect login and/or apiKey!')
}
}
});
I do have my permissions set to "permissions": ["tabs", "notifications", "http://*/*", "https://*/*"] but I still keep getting:
Refused to load script from 'http://api.bit.ly/v3/validate?callback=jQuery17204477599645033479_1334062200771&login=&apiKey=&x_login=test&x_apiKey=test&_=1334062201506' because of Content-Security-Policy.
The script itself works outside the extension so I assume the problem isn't within the script but with the permissions.
What am I doing wrong here?
The problem is that you aren't really doing a XHR request, you're doing a JSONP request on an insecure HTTP resource. See the question How to load an external JavaScript inside an extension popup and the related Chromium bug report.
Yeah, we're no longer allowing insecure scripts in extensions. If you load a script over HTTP, an active network attacker can inject script into your extension, which is a security vulnerability.
JSONP operates by dynamically adding a new script tag into your page and then executing the contents. In your case, the script resource is fetched over HTTP (instead of HTTPS). If your extension uses version 2 of the extension manifest, its background pages cannot fetch non-HTTPS scripts.
Solution: If you use the Bitly API over HTTPS, I believe that will fix your issue. Send your Ajax call to https://api-ssl.bitly.com/v3/validate (instead of your current value of http://api.bit.ly/v3/validate)
You need to package your app/extension for cross domain requests to work. A hosted application will not be able to do cross domain requests. See:
Cross-Origin XMLHttpRequest in chrome extensions
To make Cross-Origin Requests in Chrome Extension you need to Avoid Cross-Origin Fetches in Content Scripts.
Full answer you can found in
https://stackoverflow.com/a/56929473/3680164
Or in the documentation
https://www.chromium.org/Home/chromium-security/extension-content-script-fetches
I'm trying to do an XMLHttpRequest from a local file (file://) using JQuery.ajax to something on http:// and from what I can see it looks like the request is going out (the success callback is called and Firebug shows the request) but there is simply no response coming back.
Here's basically what I'm doing:
$.ajax({
url: "https://stackoverflow.com/users/63736/bruce-van-der-kooij",
dataType: "text",
success: function(text) {
alert(text)
}
})
Note I'm using datatype: "text" but it doesn't really matter what you use.
This will show an empty alert.
Now, if I had to guess I'd have to say this has something to do with the same origin policy, but I'm not getting the typical NS_ERROR_DOM_SECURITY_ERR exception (there's nothing at all in the error console).
So does anybody have an explanation for what's going on?
Related
Problem with making a simple JS XmlHttpRequest call
UPDATE:
So I came across a July 2009 article at hacks.mozilla.org that seems to explain what is going. Apparently Firefox >= 3.5 implements the Cross-Origin Resource Sharing (CORS) specification which provides a mechanism to allow you to make cross-site requests. What is happening in this case is explained in the article:
In Firefox 3.5 and Safari 4, a cross-site XMLHttpRequest will not successfully obtain the resource if the server doesn’t provide the appropriate CORS headers (notably the Access-Control-Allow-Origin header) back with the resource, although the request will go through.
Note that in my case the request is sent out with a header Origin: null and a 200 OK response is returned. However, the server isn't sending back the appropriate headers so the response body is not retrieved.
Also see:
Mozilla Developer Center - HTTP access control
(Answering my own question)
The reason the request goes out is because Firefox >= 3.5 implements the Cross-Origin Resource Sharing (CORS) specification which provides a mechanism to allow you to make cross-site HTTP requests. By default these requests will not send along any credentials (HTTP Cookies and HTTP Authentication information).
However a cross-site HTTP request will not successfully obtain the resource if the server doesn't provide the appropriate CORS headers (notably Access-Control-Allow-Origin) back with the resource. The response will simply be ignored by the browser.
Here's an example of a successful cross-site request (it retrieves my YouTube profile):
$.ajax({
url: "http://gdata.youtube.com/feeds/api/users/brucevdk?v=2&alt=json",
dataType: "json",
success: function(response) {
alert(response)
}
})
If you take a look at the response headers you'll see:
Access-Control-Allow-Origin: *
Which means "allow requests from any origin".
Resources
Mozilla Developer Center - HTTP access control
cross-site xmlhttprequest with CORS
Additional Notes:
* 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.
That is from the page you've mentioned. jQuery ajax requests does not support cross-domain requests out of the box. There are some workarounds that a Google search can provide though...