REST and CORS.. how are they different? is it even correct to compare them? because I have seen a seemingly REST API use custom X- headers to make a pre-flighted request(Docebo LMS API). This means that maybe CORS and REST are used for different purposes.. But on the surface, it seems that both are designed to give access to resources stored on a different server. Also, Simple XMLHTTP requests seem to work like HTTP.(The headers sent and received by the browser are through HTTP).. So, are XMLHTTP objects translated into HTTP by the browser? I am really taking in a ton of information right now and I cant seem to make any real progress in understanding these things... Any help is appreciated.
CORS - Cross Origin Resource Sharing. A concept and set of techniques that enables sharing of resource/data across domains. Example, from your page /yourDomain.net you try to make an ajax call to myDomain.net to post some data. Read this Wikipedia and MDN articles.
REST - REpresentational State Transfer. A set of standards & guidelines that defines a specific way for systems to talk to each other. It follows state-less http like standards where URIs reprsent resource and client can work on them using http verbs. e.g. GET weatherApp.com/weather/rome. Refer this.
HTTP - Hyper Text Transfer Protocol. THE standard protocol to transfer data to/from web servers. Check this W3 specifications and Wikipedia page.
XMLHttp - A type of request generally used to make ajax calls from client (mainly html, javascript) applications to web servers. It works on http standards. Not bound to XML though. Read this and this.
Now, all of REST, XMLHttp, CORS work on HTTP is some way, meaning they all use the http infrastructure.
And any/all of them might be used to create a fully functional modern application. For example, a web application might use XMLHttp request to make REST service call to get some data. It can also utilize CORS to get/post data to another domain. Need not say, the whole system relies on http!
They are totally different things. Rest is a specifical approach to prrforming data calls. Basically is characterized by a systen where the state is not stored on the server but rather passed in calls. You can read more here
Cors is a technique for enabling javascript to perform data ervice calls to domains otheir than the server donain that they came from. Normally web browsers prevent javascript and other web technologies from doing cross origin or cross domain calls. These are calls where a js script came from google.com lets say, and now it wats to call microsoft.com. well the browser would stop that call because google.com and microsoft.com are different domains.
That example is obvious, so lets try a less obvious one. Your script on blogs.yoursite.com tries to call a service at shopping.yoursite.com. now these sires are both yoursite.com but they could still be considered cross domain and usually are. CORS allows you(on the html developer side) to say i trust these domains. And by trusting them, now you can call their webservices even if they would have been a cross domain call.
Related
I'm curious whether if it's possible to set up a server to respond with html fetched from another domain rather than simply redirect the requester to that domain.
For example, I set up a simple node express server that has a GET route /google, which fetches google.com, and then responds with the response from the fetch. However, in this case, it does not respond with the google webpage as I would expect.
It is not only possible but quite common especially in larger server environments. The term you are looking for is reverse-proxy.
Proxying is typically used to distribute the load among several servers, seamlessly show content from different websites, or pass requests for processing to application servers over protocols other than HTTP.
Source: https://docs.nginx.com/nginx/admin-guide/web-server/reverse-proxy/
Most major web servers support it.
More than likely the response you're getting from google (and passing on) is some kind of redirection. Try it with a static web page of your own to rule out any redirection shenanigans.
I am writing a REST API using Express Js and I have some questions regarding security.
My first question is what information can hackers get from a request made from the client side. Can they figure out the request link? What about the body and headers? Is body more secure than parameters/vice versa?
My second question is if I implemented a CORS whitelist that only allowed origins that I wanted to access my API, would that prevent anyone else from hitting the API endpoints? Can people find ways around CORS?
When a REST api is called from a browser client, everything should be treated as completely open. Anyone can read urls, headers, bodies, etc. There is no reasonable way around this, and you should design your system with this in mind.
CORS does not prevent someone from writing a script to call your API either. CORS does not add security, it takes it away by making it possible to call your API from browser applications on other domains. Not having CORS technically makes it harder to call your API in some contexts, and removes a potential security concern. The S in CORS stands for 'sharing', not 'security'.
Any security you need should be based on the server. For example, if you have data in your API that can only be read 1 user, then the server needs to make sure that a different user cannot read it. To do this, a user needs to authenticate itself.
I am currently implementing a Facebook Chat Extension which basically is just a web page displayed in a browser provided by the Facebook Messenger app. This web page communicates with a corporate backend over a REST API (implemented with Python/Flask). Communication is done via HTTPS.
My question: How to secure the communication the Web page and the backend in the sense that the backend cannot be accessed by any clients that we do not control?
I am new to the topic, and would like to avoid making beginners' mistakes or add too complicated protocols to our tech stack.
Short answer: You cant. Everything can be faked by i.e. curl and some scripting.
Slightly longer:
You can make it harder. Non browser clients have to implement everything you do to authenticate your app (like client side certificates and Signet requests) forcing them to reverse engineer every obfuscation you do.
The low hanging fruit is to use CORS and set the Access Allow Origin Header to your domain. Browsers will respect your setting and wont allow requests to your api (they do an options request to determine that.)
But then again a non official client could just use a proxy.
You can't be 100% sure that the given header data from the client is true. It's more about honesty and less about security. ("It's a feature - not a bug.")
Rather think about what could happen if someone uses your API in a malicious way (DDoS or data leak)? And how would he use it? There are probably patterns to recognize an attacker (like an unusual amount of requests).
After you analyzed this situation, you can find more information here about the right approach to secure your API: https://www.incapsula.com/blog/best-practices-for-securing-your-api.html
What options are available for authentication of an MVC3 Web API application that is to be consumed by a JQuery app from another domain?
Here are the constraints/things I've tried so far:-
I don't want to use OAuth; for private apps with limited user bases I cannot expect end users to have their accounts on an existing provider and there is no scope to implement my own
I've had a fully functioning HMAC-SHA256 implemention working just fine using data passed in headers; but this doesn't work in IE because CORS in IE8/9 is broken and doesn't allow you to send headers
I require cross-domain as the consuming app is on a different domain to the API, but can't use jsonp becuase it doesn't allow you to use headers
I'd like to avoid a token (only) based approach, as this is open to replay and violates REST by being stateful
At this point I'm resigned to a HMAC-SHA256 approach that uses either the URL or querystring/post to supply the hash and other variables.
Putting these variables in the URL just seems dirty, and putting them in the querystring/post is a pain.
I was succesfully using the JQuery $.ajaxSetup beforeSend option to generate the hash and attach it to the headers, but as I mentioned you can't use headers with IE8/9.
Now I've had to resort to $.ajaxPrefilter because I can't change the ajax data in beforeSend, and can't just extend data in $.ajaxSetup because I need to dynamically calculate values for the hash based on the type of ajax query.
$.ajaxPrefilter is also an issue because there is no clean/simple way to add the required variables in such a way that is method agnostic... i.e. it has to be querystring for GET and formdata for POST
I must be missing something because I just cannot find a solution that:-
a) supports cross-domain
a) not a massive hack on both the MVC and JQuery sides
c) actually secure
d) works with IE8/9
There has to be someone out there doing this properly...
EDIT
To clarify, the authentication mechanism on the API side is fine... no matter which way I validate the request I generate a GenericPrincipal and use that in the API (the merits of this are for another post, but it does allow me to use the standard authorization mechanisms in MVC, which I prefer to rolling my own... less for other developers on my API to learn and maintain)
The problem lies primarly in the transfer of authentication information from the client to the API:-
- It can't rely on server/API state. So I can't pass username/password in one call, get a token back and then keep using that token (open to replay attack)
- Anything that requires use of request headers is out, because IE uses XDR instead of XHR like the rest of the browsers, and it doesn't support custom headers (I know IE10 supports XHR, but realistically I need IE8+ support)
- I think I'm stuck generating a HMAC and passing it in the URL somewhere (path or querystring) but this seems like a hack because I'm using parts of the request not designed for this
- If I use the path there is a lot of messy parsing because at a minimum I have to pass a username, timestamp and hash with each request; these need to be delimited somehow and I have little control over delimiters being used in the rest of the url
- If I use data (querystring/formdata) I need to change the place I'm sending my authentication details depending on the method I'm using (formdata for POST/PUT/etc and querystring for GET), and I'm also polution the application layer data space with these vars
As bad as it is, the querystring/formdata seems the best option; however now I have to work out how to capture these on each request. I can use a MessageHandler or Filter, but neither provide a convienient way to access the formdata.
I know I could just write all the parsing and handling stuff myself (and it looks like I will) but the point is I can't believe that there isn't a solution to this already. It's like I have (1) support for IE, (2) secure and (3) clean code, and I can only pick two.
Your requirements seem a little bit unjustified to me. You can't ever have everything at the same time, you have to be willing to give something up. A couple of remarks:
OAuth seems to be what you want here, at least with some modifications. You can use Azure's Access Control Service so that you don't have to implement your own token provider. That way, you have "outsourced" the implementation of a secure token provider. Last I checked Azure ACS was still free. There is a lot of clutter when you look for ACS documentation because people mostly use it to plug into another provider like Facebook or Google, but you can tweak it to just be a token provider for your own services.
You seem to worry a lot about replay attacks. Replay attacks almost always are a possibility. I have to just listen to the data passing the wire and send it to your server, even over SSL. Replay attacks are something you need to deal with regardless. Typically what I do is to track a cache of coming requests and add the hash signature to my cache. If I see another request with the same hash within 5 minutes, I ignore it. For this to work, I add the timestamp (millisecond granularity) of the request and some derivative of the URL as my hash parameters. This allows one operation per millisecond to the same address from the same client without the request being marked as replay attack.
You mentioned jQuery which puzzles me a bit if you are using the hashing method. That would mean you actually have your hash algorithm and your signature logic on the client. That's a serious flaw because by just inspecting javascript, I can now know exactly how to sign a request and send it to your server.
Simply said; there is not much special in ASP.NET WebAPI when it comes to authentication.
What I can say is that if you are hosting it inside ASP.NET you'll get support by ASP.NET for the authentication and authorization. In case you have chosen for self-hosting, you will have the option to enable WCF Binding Security options.
When you host your WebAPI in ASP.NET, you will have several authentication options:
Basic Authentication
Forms Authentication - e.g. from any ASP.Net project you can enable Authentication_JSON_AppService.axd in order to the forms authentication
Windows Authentication - HttpClient/WebHttpRequest/WebClient
Or explicitly allow anonymous access to a method of your WebAPI
Although I "think" I understand it I need some clarity. With PURE Restful authentication, things do get a bit unwieldy and using forms helps a lot with the UI of the application (i.e., get to have separate login page, forgot password links, easier logout? etc.,)
Now Forms come along and some folks say "not restful" - what is "not restful" about them? Is it that there is no corresponding login resource so to speak? Or does it force something else that I'm missing?
Note: If ones create sessions with them, that's a different matter altogether. I'm more keen on know "why" are they branded as restful? Just googling for "Form based authentication vs restful authentication" throws up quite a few hits.
One could use these "forms" to authenticate and pass on tokens for the application to store in cookies etc., which I feel is entirely restful (assuming cryptographic security etc.,)...
There is nothing wrong with sending your credentials, perhaps through a form, for authentication. The problem is most Form based systems rely on sessions, thus requiring you to only log in "once".
Sessions are server state, thus violating the stateless constraint of a REST architecture.
If you have to send the credentials each time, you can either include them in the payload (i.e. using a form), or you can use the HTTP Authorization header.
If you include them in the payload, you can include them in the body, but only for a POST or PUT, and not a GET or DELETE (since they don't have bodies).
If you include them in the URL as part of the query parameters, then the URL is no longer necessarily representing the actual resource. One of the other tenets is that the URL matches the resource. Adding out of band information (such as credentials) within the query parameters muddies that constraint up a bit.
So, for a REST system over HTTP, you're better to use the existing HTTP Authorization mechanism than working out something else. You could also use client specific SSL certs as well, that works fine also.
Excellent question. I think that RESTful purists will likely say that having a URI associated with an action rather than a resource is what makes form-based auth not RESTful, which is something you pointed out yourself.
Honestly I think that the idea of a 100% pure RESTful application is somewhat of a Utopian ideal when it comes to web applications. I believe it is achievable, however, for RESTful web services, since the calling applications can pass credentials with the request header.
At the end of the day, I think that as long as your application works it is fine, and you should not worry about whether or not it is purely RESTful.
That's my $0.02.
From this answer:
To be RESTful, each HTTP request should carry enough information by itself for its recipient to process it to be in complete harmony with the stateless nature of HTTP.
It's not that form-based auth is not RESTful — it's not RESTful to have a session at all. The RESTful way is to send credentials with every request. This could easily be eavesdropped upon, however, but HTTPS/SSL/TLS closes that hole.
Form-based authentication does not use the authentication techniques that are built into HTTP (e.g. basic authentication, digest authentication).
REST purists will ask you to use the functionality built into HTTP wherever possible. Even though form-based authentication is extremely common, it is not a part of the official protocol. So the REST purist sees form-based authentication as an instance of "building functionality on top of HTTP when that functionality already exists within HTTP itself."
Now Forms come along and some folks say "not restful" - what is "not restful" about them?
The authentication credentials are not in the standard place.
REST doesn’t eliminate the need for a clue. What REST does is concentrate that need for prior knowledge into readily standardizable forms. -- Fielding, 2008
RFC 7235 describes the Authorization header; that gives us a standard way to distinguish authorized requests (which have the header) from anonymous requests (which don't have the header).
Because we can distinguish authorized and anonymous requests, general purpose components can do interesting things.
For example, if the origin server is restricting access to a resource, we probably don't want a shared cache to be re-using copies of the HTTP response to satisfy other requests. Because the authorization has a standardized form, we can define caching semantics that restrict what a shared cache is allowed to do.
Putting the same information into a cookie header, in effect, hides the authorization semantics from general purpose components.
(This is somewhat analogous to using POST requests for safe requests -- general purpose components can't distinguish semantically safe POST requests from semantically unsafe POST requests, and therefore can't do anything intelligently take advantage of the safe handling).
If we had smarter form processing -- form input controls that copied information into the Authorization header instead of the query string/request-body -- then forms would be fine. But (a) we don't have that and (b) we are unlikely to get it, because backwards compatibility.