Recently I got to the point to host a static webpage with a subscription option on aws s3 while website development is undergoing. My static web page makes an ajax call to another RESTful service with an email of a subscriber as a parameter. When subscription is done I need to notify a subscriber. Here it seams an issue with the callback.
$.ajax({
type: 'GET',
url: 'http://www.my-domain.com/api/Subscribe?email=' + email
}).success(function (data) {
if (data) {
alert('Thank you for registering!');
}
});
After subscription is done ".success(" doesn't fire up. Response on the request is:
Reload the page to get source for: http://www.my-domain.com/api/Subscribe?email=john.smith#simplyemail.com
Does anyone know if it's an s3 feature or something else?
As per your description this seems to be related with CORS policy.
Look to "why CORS" as Amazon defines it:
In order to keep your content safe, your web browser implements something called the same origin policy.
The default policy ensures that scripts and other active content
loaded from one site or domain cannot interfere or interact with
content from another location without an explicit indication that this
is the desired behavior.
In certain cases, the developer of the original page might have
legitimate reasons to write code that interacts with content or
services at other locations. CORS provides the mechanism to allow the
developer to tell the browser to allow this interaction.
I understood that:
[...] ajax call to another RESTful service[...]
Means call to another server, and this may be blocked by Browser because of CORS.
References:
Mozilla
W3C
Related
I want to login to a website and follow redirection whit ajax or XMLHttpRequest or any thing else exept php.
Actually whene i try to do it, i have error "302 Moved Temporarily" but the webpage is the right page so i don't know why i get this error.
The website is an external website (not on my server).
This is my code :
$.ajax({
type: "POST",
contentType: "application/x-www-form-urlencoded",
url: "http://website/index.php",
data: { username: "myuser", password: "123456" },
success: function(data) {
console.log("success ", data.response);
},
error: function(data) {
console.log("error ", data.error);
},
dataType: "html"
});
If you try use ajax outside your domain, you will probably get this error message:
XMLHttpRequest cannot load http://www.example.com/path/filename. Origin
null is not allowed by Access-Control-Allow-Origin.
The reason you get this error message is because of the Same-origin policy. The policy permits scripts running on pages originating from the same site to access each other's data with no specific restrictions, but prevents scripts access to data that is stored on a different domain.
This could be a problem if you are trying to access publicly hosted data, but there are ways around it.
Here is the list of methods:
Implement CORS (Cross-Origin Resource Sharing)
Use JSONP (JSON Padding)
Use postMessage method
Setting up a local proxy
CORS (Cross-Origin Resource Sharing)
CORS is a mechanism that allows resources on a web page to be requested from another domain outside the domain the resource originated from. In particular, JavaScript's AJAX calls can use the XMLHttpRequest mechanism. Such "cross-domain" requests would otherwise be forbidden by web browsers, per the same origin security policy. CORS defines a way in which the browser and the server can interact to determine whether or not to allow the cross-origin request. It is more useful than only allowing same-origin requests, but it is more secure than simply allowing all such cross-origin requests.
JSONP (JSON Padding)
JSONP or "JSON with padding" is a communication technique used in JavaScript programs running in web browsers to request data from a server in a different domain, something prohibited by typical web browsers because of the same-origin policy. JSONP takes advantage of the fact that browsers do not enforce the same-origin policy on <script> tags.
Because of the same origin policy, we can not make cross domain AJAX requests, but we can have <script> tags that load javascript files from other domains. JSONP uses this exception in order to make cross domain requests by dynamically creating a <script> tag with necessary URL.
postMessage method
window.postMessage method is part of HTML5 introductions. It allows communication between window frames without being subject to same origin policy. Using postMessage() one can trigger a message event with attached data on another window, even if the window has different domain, port or a protocol. The frame where the event is triggered must add an event listener in order to be able to respond.
Let's see an example. Assume, we are on http://example.com (1) website and would like to make a request to http://example2.net (2) domain. We first must obtain a reference to (2) window. This can be either iframe.contentWindow, window.open, or window.frames[]. For our case it's best to create a hidden iframe element and send messages to it.
Setup local proxy
This method overcomes same origin policy by proxying content on another domain through itself. Thus making cross-domain issue irrelevant. To use this method you will either a) setup your server as a reverse proxy to fetch content from another server or b) write a script that would do that.
This cross domain querying solution works because you actually loading content from your own domain. You request the URL and the proxy script on your server loads the content and passes it over to you.
http://www.ajax-cross-origin.com/how.html You can visit this link if you want to learn about these methods in details. There is also a jquery plugin named ajax cross origin to tackle similar issues.
I am trying to perform an AJAX request from my site which is deployed on 'HTTPS' protocol. but the request I am making to is deployed on 'HTTP' protocol.
So I am getting the following error:
This request has been blocked; the content must be served over
HTTPS
My Request is as follows:
$.ajax({
url: "http://testsite/service/process.php",
type: "POST",
data: { service: '#service', id: '#id' }
});
Is there any way/trick to bypass this error/issue without changing
anything at ServerSide (http://testsite/) or Is it necessary to
ENABLE/CONFIGURE C.O.R.S on Server Side because I have no controll over Server Side.
Alternatives to CORS
If your web application must run in browsers that do not support CORS or interact with servers that are not CORS-enabled, there are several alternatives to CORS that have been utilized to solve the cross-origin communication restriction.
JSONP. This is a technique that exploits the HTML script element exception to the same-origin security policy. Script tags can load JavaScript from a different domain and query parameters can be added to the script URI to pass information to the server hosting the script about the resources that you wish to access. The JSONP server will return JavaScript that is evaluated in the browser that calls an agreed upon JavaScript function already on the page to pass server resource data into your page.
OpenAjax Hub. This is an JavaScript Ajax library that allows integration of multiple client-side components within a single web application. Trusted and untrusted components to co-exist within the same page and communicate with each other as long as they all include the OpenAjax Hub JavaScript library. The framework provides a security manager to allow the application to set security policies on component messaging. Iframes are used to isolate components into secure sandboxes.
easyXDM. This is a JavaScript library that allows for string-based cross domain communication via iframes. It works on the same principals as OpenAjax Hub but does not have the security manager component.
Proxied Iframe. This do-it-yourself technique involves including an iframe on your page from the domain you wish to communicate with. This assumes that you are able to host pages on this other domain. The JavaScript running in the iframe serves as a rest proxy to the server containing the resources you wish to access. Communication between your application and the rest proxy will take place using post message. Post message is part of the HTML5 standard, but there is also a jQuery implementation for non HTML5-compliant browsers.
I've an API endpoint hosted (built via Django Rest Framework), for eg:- domain.com/api/fetch_all?start=0&end=50. This fetches all the results from the database in a pagination manner.
Now I'm representing this information on a webpage. Its more or less like an open forum where everyone can read the data, but only some can write. I'm viewing this data onto the webpage via an AJAX request hitting the above endpoint. For eg:-
$.ajax({
type:'get',
contentType: 'application/json',
url:'domain.com/api/fetch_all?start=0&end=50',
cache : true,
dataType:'json',
success:function(data)
{
// presenting the information when the page loads.
}
});
So, my questing is how can I secure my APIs, so that no robots can access the data that I'm presenting on my forum. For eg:- if any code/script tries to access my APIs, it should throw 403 Forbidden error.
import requests
# this should return 403 error
response = requests.get('domain.com/api/fetch_all?start=0&end=50')
However, if I try to get this data via the browser AJAX request, it should return the data. How can I make sure whether the request is coming from a browser(man-handled) or a robot?
PS: I cannot add OAuth functionality over here, since I dont have a login form.
It's not possible to restrict requesters in this way, because a robot could always add headers to spoof being a browser. Anything you do on your client can be copied by an attacker. Without requiring auth, the best you can do is rate limiting - track requests on a per-client basis, and only allow a certain number of requests per time unit.
A partially-functional solution would be to look at the User-Agent header. That should include browser information, and might let you knock out some robots, but not all or even most of them.
Given all the coverage FireSheep has been getting, I have been trying to work out the best practices for balancing HTTP / HTTPS usage for some sites I manage (e.g. blogging sites, magazine sites with user contributed comments).
To me, its over kill to deliver all pages over HTTPS if the user is logged in. If a page is public (e.g. a blog) there is little point encrypting the public page. All I want to do is prevent session hijacking by sniffing cookies over HTTP channels.
So, one plan is:
Login form is over HTTPS
Issue two cookies: One cookie is 'public' and identifies there user for read only aspects (e.g. 'welcome bob!'). The second cookie is private and 'HTTPS only'. This is the cookie that is verified whenever the user makes a change (e.g. adds a comment, deletes a post).
This means that all 'changing' requests must be issued over HTTPS.
We use a lot of AJAX. Indeed, many comment forms use AJAX to post the content.
Obviously, I cant use AJAX directly to post content to a HTTPS backend from a HTTP frontend.
My question is: Can I use script injection (I think this is commonly called 'JSONP'?) to access the API? So in this case there would be a HTTP public page that sends data to the private backend by injecting a script accessed via HTTPS (so that the private cookie is visible in the request).
Can you have HTTPS content inside a HTTP page? I know you get warnings the other way around, but I figure that HTTPS inside HTTP is not a security breach.
Would that work? It seems to work in chrome and FF, but its IE that would be the party pooper!
Another way is to have an iframe which points to a https page that can make all kinds (GET, POST, PUT etc) of Ajax calls to the server over https (same domain as iframe is on https too). Once the response is back inside the iframe, you can post a message back to the main window using HTML5 postMessage API.
Pseudo code:
<iframe src="https://<hostname>/sslProxy">
sslProxy:
MakeAjaxyCall('GET', 'https://<hostname>/endpoint', function (response) {
top.postMessage(response, domain);
});
This works in all modern browsers except IE <= 7 for which you'll have to either resort to JSONP or cross domain communication using Flash.
The problem with JSONP is that you can only use it for GETs.
Can you have HTTPS content inside a
HTTP page? I know you get warnings the
other way around, but I figure that
HTTPS inside HTTP is not a security
breach.breach.
Including HTTPS content inside a regular HTTP page won't raise any alerts in any browser.
However, I don't think JSONP will help you out of this one. Using GETs to post content and modify data is a very bad idea, and prone to other attacks like CSFR
I want to use mootools and SqueezBox class to handle a request to a RESTful service. I don't want to use any server-side script. I am using AJAX. I send a request to the following url using GET method.
http://www.idevcenter.com/api/v1/links/links-upcoming.json
but I receive a 404 error. Is it because cross-site scripting? here is my code:
SqueezeBox.initialize({handler:'url',ajaxOptions:{method:'GET'}});
$('a.modal').addEvent('click',function(e){
new Event(e).stop();
SqueezeBox.fromElement($('a.modal'));
});
In Firebug console, sometimes 'aborted' is shown and sometimes '404'.what is wrong with that?
XMLHttpRequest is subject to the Same Origin Policy; if the document your JavaScript is running within is not from the same origin as the service you're trying to call, the call will be disallowed for security reasons.
There is now a proposed standard for cross-origin resource sharing to address this. It may be that the service you're trying to use supports it; if so, using a browser that implements CORS (recent versions of Firefox and Chrome do, as do some others) may work. IE8 supports it but requires that you do extra work.
You cannot use XMLHttpRequest (that is, ordinary "ajax") to call a service on a server that is not in your domain.
You can, however, use the JSONP trick, which takes advantage of the fact that the browser will load Javascript from other domains. However, the service has to know that you're going to do that, and it has to understand the protocol. That particular service seems perfectly willing to give me a JSON response, but it doesn't pay attention when I give it a "callback" parameter. (I've tried both "callback" and "jsonp" and the JSON blob that comes back is the same, without a function call wrapper.)