To avoid xss attack, MVC generating some antiforgery token.
But in our project we have Angularjs with web api.
My need is
Do we need antiforgery token to prevent xss attack in Angularjs project with web api?
If we need, how to implement?
The antiforgery token is against cross-site request forgery (CSRF). In very short and somewhat simplified, an attacker may be able to set up his own website, trick your user into visiting that website, and then create a webpage for the user that will make the user's browser post a valid request to your application, something your user did not want to do. The standard protection against this is generating a random token in your application that the attacker won't know and won't be able to send. OWASP has a nice description of CSRF and also a protection cheat sheet. This problem only comes up if authentication info (the session id or access token) is sent automatically by the browser with requests, ie. when it is in a cookie. Otherwise the attack is not possible.
This has nothing to do with cross-site scripting (xss). An attacker may want to inject Javascript into your page when viewed by other users so that he can access data displayed to or stored on the client by victim users. To solve this, you need to encode all output according to its context, or in Angular (and Javascript in general) you need to make sure that you only use bindings that may not create a script node in the page dom but only bind as text. OWASP has a cheat sheet for XSS too.
In case of Angular talking to Web API, you need to take care of CSRF in the Web API code if (and only if) you use cookie-based authentication / sessions. If the access token is stored anywhere else and you have to insert it into each request in code (like for example the token is stored in a Javascript object and added to each request as a request header by jQuery), it's fine and you don't need further protection against CSRF.
If the Web API serves JSON content, it's fine to have unencoded data in JSON responses (obviously this means you should encode data for JSON itself, but standard serializers do that for you, and you don't need to care about presentation at that level). When such data is received in Angular, you need to make sure that you only use safe bindings to actually bind that data to the UI so that Javascript cannot be inserted. Angular is reasonably good at that, but code can still be vulnerable. Also DOM XSS (a form of XSS) is a very common vulnerability in Javascript-heavy applications.
How exactly to implement these is way beyond the scope of an answer here unfortunately. It all depends on the details.
Related
I am working on angular js app,and tried to make a simple login page and tried to request my server API for authenticate my login call.Here what and how i planned to do.
Note: I am assuming that server is responsible for validating my token and request.
Provide username password to server via API call.
On getting authenticated the server will generate a token for my App(through which i made a call).
I stored this in my browser's COOKIE.
This Cookie (auth token) will be further used by app to to make each and every HTTP call to API.
Now this approach is working fine for me,but I believe it is openly available for CSRF attack.
In order to avoid the CSRF attack from my browser,i provide APP id or (version id) to my code which also travel with cookie to the API for http call.
The idea behind using this version id or App id,is this can be treated as a signature of my code,ie request is coming from the signed (verified) app who has alloted token=cookie value.
i just want to know how better my approach is and how much secure it is for my basic app point of view and for my major (wide project) app.
Here i am trying to show via a rough diagram
apologies for this tiny view and bad handwriting of the diagram.
Backend frameworks like Laravel have this pretty built in: csrf-protection.
You can pass the token to Angular by using angular's constant function: $provide#constant.
So after you initialize your app you could say: angular.module('myApp').constant('<?php echo csrf_token(); ?>'); and Laravel would do the rest. If you would want to implement a technique like this yourself, you should look into Laravel's source code: https://github.com/laravel/framework/blob/a1dc78820d2dbf207dbdf0f7075f17f7021c4ee8/src/Illuminate/Foundation/Http/Middleware/VerifyCsrfToken.php.
Adding App ID + Version ID to each request won't protect your system from a CSRF attack, unless these are in a custom header - and if they are you might as well just use X-Requested-With because any non standard header is protected going cross domain, provided you haven't enabled CORS with an open policy.
The reason that checking App ID + Version if set in the query string or POST data is that the attacker can readily gain this information to add the App ID + Version ID to their cross site requests. Another method that would work for you is the Double Submit Cookies technique. Generate a random 128 bit string using a CSPRNG and then set this as a cookie value (e.g. CSRFCookie). On each request to your API, also pass this value. e.g. in the query string: CSRFCookie=<generated value>. On the server side you simply check that the values match. An attacker does not know the cookie value, therefore they cannot add the same value to the query string.
This method does have some minor vulnerabilities, only really exploitable in a MITM scenario or if you do not control all subdomains. Short answer: Use HTTPS only for all your subdomains and implement HSTS.
I have bought an API that can be used in a mobile application. API includes the Key and username as expected.
Within the app, this API needs to be called on Payment confirmation.
I found that using tools like Fiddler, one can see the request made by the application. If that is the case, it is just a matter of seconds to fully get access to the API signature.
It would be of great help if someone can help out/add to this issue.
My thoughts:
Use a server to make this API call instead of calling it directly
from the application.
If a server is used, the issue would still exist as the API call made to the server(eventually which calls the bought API) can also be interrupted/accessed
How to secure the call made to the server from the application?
Technologies: Angular JS, Node JS, Ionic framework
Look at my answer to this question. Instead of using the user name and password, your backend could provide an additional resource that allows the user to create a token with a special scope.
In your AngularJS application you can use the $http or $resource services (if the ngResource module is included) and obtain such kind of token that allows you to access only the parts of your backend your client really needs.
This token must be cached at the client side and included in the header of each request.
In AngularJS storing the token in the header of each request can be done at a central place if you are using the config function of the module you created.
app.config(function($httpProvider) { $httpProvider.defaults.xsrfCookieName = "TOKEN" }
AngularJS also provides some additional security features. For example you could use the JSON vulnerability protection mechanism. If you are using this, your backend had to add the characters )]}', (you could also override the default characters) to each JSON response body.
For other clients the JSON response will be invalid Javascript code, but in your AngularJS application the characters will be automatically removed.
UPDATE
The best way for implementing security for your application would be reading and understanding the OAuth2 specification.
In this video from minute 11:36 to 17:26 the JavaScript flow is described.
This site provides some implementation of the standard for different programming languages.
Some of the aspects in this standard are that all clients and redirect urls must be registered in an additional authentication server. Client are identified by a unique client id.
To avoid that some other application intercepts your requests for extracting the token, the original token should only be active for a small amount of time and each api request must be SSL encrypted.
For providing Single sign-on also refresh tokens can be used.
I need some advice regarding using session tokens to authenticate users. I am building an AngularJS app which uses an API to tie in with the backend. I am only building the front end, not the backend. The documentation states that all calls to the API have a session token attached in the body of the request (POST).
I would like to know about the security of storing this token in localStorage. That is where I am storing it now and retrieving and attaching it to each API request. After login, the server sends the session token in the body and I save it from there.
There is no documentation about an x-access-token header that should be sent with the request made to the server. It is not being checked server side. What are the implications of this? I feel that it is susceptible to attacks without this added layer of security.
My main concern is the security of this setup. I want to know what the best setup is to make sure this app is as secure as possible and recommend changes to the way the backend is setup to facilitate this.
Thanks!
As you tell, you are only working on the UI part and not the backend. It is up to the backend team to ensure headers are properly evaluated and security is enforced (btw request headers do not belong to request body). Just put the token into the x-access-token header as they tell.
Storing the token inside the localStorage gives you a little more control over the cookie: You will not accidentally send it to unnecessary URLs. However, older browsers do not support it - you may need to use a shim for that.
In a case of SPA, you may consider not storing the token at all: It could be fetched each time your application is accessed and then stored within a service in angularjs, but it depends how your fetch/login operation is implemented (is it always interactive, how long does it take, etc).
I would suggest use $cookies rather than localstorage. As localstorage does not support some legacy browser.
I am using cookies to store token in my project
It is common to authenticate to web services using an authorization header which contains a secret token. And since the security of this mechanism depends on the token to be secret care should be taken that this token is not leaked.
There are countless tutorials on the web which explains how such an authorization header can be set using angular and least the ones that I have actually read use an $http interceptor and now one discusses that the token is not leaked.
There are some public and some private APIs out there which can be talked to cross domain thanks to CORS. And obviously I do not want to send my internal authorization tokens on any of those requests.
Some other techniques come to mind such as setting the token manually only on each and every request, but that means lots of duplicate code. The $http server could be wrapped in an $authenticatedHttp service so that it is always appearent from the object used whether it is the authenticated service or the normal one. However the $http service has so many methods to be wrapped.
Is there a better solution?
UPDATE
From the answers I have the impression that my question was not understood. I try it with a more concrete example:
I have a private web page. People have to login with username/password and let's say for simplicity's sake that we use HTTP basic auth, so username/password are bas64 encoded and are transmitted on every request in the HTTP header "Authorization". So far there is no problem.
But there is this great&free weather widget. I can retrieve the current weather information in JSON format from https://myWhateverWeatherService.tld/weather.json. After the login to my private web service I also retrieve the weather information (CORS allows me to do this).
The problem is that even though myWhateverWeatherService.tld does not require any authentication at all, angular's $http service will still append the Authorization header. And I don't trust the guys at myWhateverWeatherService.tld. Maybe they just set up the service so they can steal Authorization token and do lot's of nasty stuff with them.
I need some reliable way to deal with that. I already thought about checking the url with some regex in the interceptor. This is possible, but it is also not to difficult to forget about a certain case that my regex will miss.
The token is always sent through the wire, I guess that is the most vulnerable part of it.
Since the token must always be present on the http header itself, the only way to make the request more secure is to encrypt the whole request, and for that you should use SSL.
If you are concerned about the safety of storing the token on the client machine, you can keep it only on the browser´s memory, without persisting it on a localstorage or something like that. So every time the user closes the browser and open it again, s/he must log in.
I have an Angular application (SPA) that communicates with a REST API server and I'm interested in finding out the best method to store an access token that is returned from an API server so that the Angular client can use it to authenticate future requests to the API. For security reasons, I would like to store it as a browser session variable so that the token is not persisted after the browser is closed.
I'm implementing a slightly customized version of OAuth 2.0 using the Resource Owner Password grant. The Angular application provides a form for the user to enter their username and password. These credentials are then sent to the API in exchange for an access token which must then be sent as a header (Authorization: Bearer %Token%) for all outbound requests to the API so that it can authorize requests to other routes.
I'm fairly new to the realm of Angular, but the workflow I would like to implement as far as handling these tokens is summarized as follows.
1) The client makes a request to the API providing it with user credentials.
2) If this request is successful, the token is stored somewhere (where is the question)
3) Intercept HTTP requests. If token is set, pass it along as a header to API
4) Token is destroyed when the browser/tab is closed.
I know Angular offers $window.sessionStorage, which appears to be what I am looking for, but I am concerned by the potential for it not to work on all browsers according to various resources I've read. This is an enterprise grade application and must be compatible across a broad range of browsers (IE, Chrome, Firefox). Can I safely use this with the confidence that it will be stable?
The alternatives, from what I understand, are either $window.localStorage or cookies ($cookies, $cookieStore). This would not be an ideal solution for me since I don't want this data to persist, but if this is more reliable I'll have to sacrifice efficiency for compatibility. I was also thinking it might be possible to simply set it as a value on the $rootScope and reference it this way, but I'm not sure if this is feasible.
I hope that all made sense. Any help / suggestions would be greatly appreciated.
Thanks!
If you are looking for something that will definitely not persist then I would simply keep the token in memory and not rely on the browser for storage. However storing inside rootScope would not be best practice.
I would recommend that you wrap your server access code in an Angular Service if you have not done so already. You can then encapsulate your token within that Service at runtime (e.g. as a property) without worrying about having to access it when calling from other parts of your application.
Angular Services are singleton so your "server service" will be a global instance that can be accessed using normal dependency injection.
$window.sessionStorage is the way to go unless you're targeting very old browsers.
According to www.w3schools.com sessionStorage is supported from IE 8.0, Chrome 4.0, Firefox 3.5, and Safari 4.0.