Is XSRF needed when front and backend websites are separate? - csrf

I've been trying to get XSRF working with my front-end angular site and my back-end .NET site. They're two different websites. For example, client.example.com and api.client.example.com
When I call IAntiforgery.GetAndStoreTokens on the .NET side, it's going to generate the .AspNetCore.Antiforgery cookie with a SameSite=Strict policy, meaning the client can't use it.
That, plus the fact that .NET only provides the AutoValidateAntiforgeryTokenAttribute if you're using Razor leads me to wonder if XSRF is even needed in this case.

Related

RESTful API: how to distinguish users requests from front-end requests?

So, I have a RESTful API (built with Hapi.js) that has endpoints consumed by users and my front-end app (built with Next.js). GET api/candies is one of them, I'll take it as an example.
The front-end asks the list of candies stored in my DB and displays them on a page anyone can access (it has to be this way). The front-end doesn't provide an API token since people could read/use it. But, users who want to get this list of candies (to build whatever they want with it) must provide a valid API token (which they get by creating an account on my front-end app).
How could my API tell if a request for api/candies is from a user or from my front-end app, so it can verify (or not) the validity of their token?
I'm wondering if my problem isn't also about web scraping.
Can anyone help me please? :D
I thought about the same problem a while ago. If your frontend has a client side REST client (JS+XHR/fetch), then I don't think it is possible to do this reliably, because no matter how you identify your frontend REST client, your users will be able to copy it just by checking the HTTP requests in browser via CTRL+SHIFT+I. There are even automation tools, which use the browser e.g. Selenium. If you have a server side REST client (e.g. PHP+CURL), then just create a consumer id for the frontend and use a token. Even in this case I can easily write a few lines of code that uses the frontend for the same request. So if you want to sell the same service for money that you provide for free on your frontend, then you are out of luck here. This does not mean that there won't be consumers who are willing to pay for it.
I think your problem is bad business model.
Your requirement can be addressed by inspecting different headers sent by different user agents. You can also add custom headers from your front-end and validate the same on the backend.

Secure communication between Web site and backend

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

REST API Security JBoss EAP 6.4

I am coding a webapp (E-commerce) for learning purpose using AngularJS + BootStrap and REST.
I have used Apache Wink for REST WS and and application is deployed on JBoss EAP 6.4. My application is working fine.
I can access the back end data using AJAX and webpages are getting populated properly. The issue is security of REST WAS. If I use REST URL directly on browser, without going through front end, JSON data gets populated and my data is exposed. What design changes should i do ?
Please note that initial operation on the website for e.g. browsing the products, adding them to cart etc are stateless. No user's identity is needed for these operations. I still need to secure my data for these interactions. Please suggest, how can I do it.
Sunil
If you want to lock down the services, you may require some type of authentication (for example user/pass) that returns a security token (over https). Then all subsequent function calls may require the security token to be passed in as a parameter (if the operation is sensitive). The token will require a session timeout.
However, if the data is also publically shown on the site, then there's not really a security risk in itself. IOW, how is this any different than them using the public website to get/update data? The rest services usually shouldn't require any additional level of security beyond what is already used on the website to protect the data.

ASP.NET Web API Authentication Options

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

RESTful Browser User Agents and authentication

I've seen many questions about restful-authentication but I'm wondering what strategies are being used to keep browser user agents stateless while authenticating to a RESTful web-service.
Doing it with a custom REST Client is "easy": We can use Basic Auth, Digest, OAuth or roll your own (custom headers, tokens, signatures etc). Thus, for machine to machine we are pretty much covered but I'm only interested in authentication with everyday browser user agents (IE, Firefox etc). For example JSON is out since the browser can not render / use it ;)
Here are some of my thoughts in terms of browser limitations:
AFAICS there is no way for a browser to send custom headers such as those used by OAuth? (Right?)
I have a feeling that one should be able to have a login page (html+ssl for example) where the user does a login. (No Basic auth) The browser then captures a token(s) and passes it back the server with each request. The problem I have with Basic Auth is that I do not have a “nice custom login page”. Is the current authentication mechanism to extensible that we can keep it restful?
I'm careful in breaking / relaxing REST constraints because of the risk of loosing the benefits of scalability.
A similar answer here but I have a special case against cookies : (without going to much detail): The way browsers currently work in using cookies is out of the question since the server is in control of the cookies. ("Set-Cookie" header from server side state). The client does not understand or interpret the contents of cookies it's fed and just returns it. The problems is that the client is not in control of the cookie. Thus, yes we can use cookies in a restful way in "custom/machine to machine clients" but it's not the way browsers implements it.
What strategies and best practices are there that you have been using and what are your experiences? Any extra comments?
I think the browser limitations you mention are essentially insurmountable for most use cases. Our personal solution is to have a lightweight non-RESTful layer presented to the user which contains a custom REST client; for example, for JavaScript apps we expose a server-side REST client via JSON-RPC.
If you are using an apache web server, you might want to take a look at this document.