How to securely set authorization header using angularJs? - angularjs

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.

Related

Client Side Rendering and API Security [duplicate]

I'm developing the restful web app that using some popular web framework on the backend, say (rails, sinatra, flask, express.js). Ideally, I want to develop client side with Backbone.js. How do I let only my javascript client side interact with those API calls? I don't want those API calls to be public and be called by curl or simply by entering the link on browser.
As a first principle, if your API is consumed by your JS client, you have to assume, that it is public: A simple JS debugger puts an attacker into a position, where he can send a byte-for-byte identical request from a tool of his choice.
That said, if I read your question correctly, this is not, what you want to avoid: What you really don't want to happen is, that your API is consumed (on a regular basis) without your JS client being involved. Here are some ideas on how to if not enforce, then at least encourage using your client:
I am sure, your API has some sort of authentication field (e.g. Hash computed on the client). If not, take a look at This SO question. Make sure you use a salt (or even API key) that is given to your JS client on a session basis (a.o.t. hardcoded). This way, an unauthorized consumer of your API is forced into much more work.
On loading the JS client, remember some HTTP headers (user agent comes to mind) and the IP address and ask for reauthentication if they change, employing blacklists for the usual suspects. This forces an attacker to do his homework more thoroughly again.
On the server side, remember the last few API calls, and before allowing another one, check if business logic allows for the new one right now: This denies an attacker the ability to concentrate many of his sessions into one session with your server: In combination with the other measures, this will make an abuser easy detectable.
I might not have said that with the necessary clarity: I consider it impossible to make it completely impossible for an abuser to consume your service, but you can make it so hard, it might not be worth the hassle.
You should implement some sort of authentication system. One good way to handle this is to define some expected header variables. For example, you can have an auth/login API call that returns a session token. Subsequent calls to your API will expect a session token to be set in an HTTP header variable with a specific name like 'your-api-token'.
Alternatively many systems create access tokens or keys that are expected (like youtube, facebook or twitter) using some sort of api account system. In those cases, your client would have to store these in some manner in the client.
Then it's simply a matter of adding a check for the session into your REST framework and throwing an exception. If at all possible the status code (to be restful) would be a 401 error.
There's an open standard now called "JSON Web Token",
see https://jwt.io/ & https://en.wikipedia.org/wiki/JSON_Web_Token
JSON Web Token (JWT) is a JSON-based open standard (RFC 7519) for
creating tokens that assert some number of claims. For example, a
server could generate a token that has the claim "logged in as admin"
and provide that to a client. The client could then use that token to
prove that they are logged in as admin. The tokens are signed by the
server's key, so the server is able to verify that the token is
legitimate. The tokens are designed to be compact, URL-safe and usable
especially in web browser single sign-on (SSO) context. JWT claims can
be typically used to pass identity of authenticated users between an
identity provider and a service provider, or any other type of claims
as required by business processes.[1][2] The tokens can also be
authenticated and encrypted.[3][4]
Set a SESSION var on the server when the client first loads your index.html (or backbone.js etc.)
Check this var on the server-side on every API call.
P.S. this is not a "security" solution!!! This is just to ease the load on your server so people don't abuse it or "hotlink" your API from other websites and apps.
Excuse me #MarkAmery and Eugene, but that is incorrect.
Your js+html (client) app running in the browser CAN be set up to exclude unauthorized direct calls to the API as follows:
First step: Set up the API to require authentication. The client must first authenticate itself via the server (or some other security server) for example asking the human user to provide the correct password.
Before authentication the calls to the API are not accepted.
During authentication a "token" is returned.
After authentication only API calls with the authentication "token" will be accepted.
Of course at this stage only authorized users who have the password can access the API, although if they are programmers debugging the app, they can access it directly for testing purposes.
Second step: Now set up an extra security API, that is to be called within a short limit of time after the client js+html app was initially requested from the server. This "callback" will tell the server that the client was downloaded successfully. Restrict your REST API calls to work only if the client was requested recently and successfully.
Now in order to use your API they must first download the client and actually run it in a browser. Only after successfully receiving the callback, and then user entry within a short frame of time, will the API accept calls.
So you do not have to worry that this may be an unauthorized user without credentials.
(The title of the question, 'How do I secure REST API calls', and from most of what you say, that is your major concern, and not the literal question of HOW your API is called, but rather BY WHOM, correct?)
Here's what I do:
Secure the API with an HTTP Header with calls such as X-APITOKEN:
Use session variables in PHP. Have a login system in place and save the user token in session variables.
Call JS code with Ajax to PHP and use the session variable with curl to call the API. That way, if the session variable is not set, it won't call and the PHP code contains the Access Token to the API.

Best Way For Token Validation in Angular

In a WebApp development with AngularJS which uses token validation for authentication purposes, what's the best way to do this validation? For example:
Validate the Token every time I have a route transition. For this I have to make a rest call for everytime I want to validate.
Validate the token just one time, with one rest call, and then store the token in local storage. (The token itself just have a boolean telling if it is authenticated or not)
My concern is to not make a rest call in every route transaction, I don't want to consume that much of http traffic. But, if there isn't another way, I will do that.
If we look into what a JSON Web Token (JWT) is (although you're not specifically referring to JWT, but simply to "token"), you will realize that once you got a JWT you do not need to validate it every time you make a transition in the client app (Angular). This is because JWT are usually signed, so the server can be sure the senders (in this case the Angular app) are who they say they are when they make a request.
What you need to do is to send the JWT on every request in a header to the API server every time you try to consume a resource. The server is in charge of checking that you are sending a valid JWT and to assign the proper permissions to that request in order to get access to the resources.
Concluding (and answering your questions)
1.Validate the Token every time I have a route transition. For this I
have to make a rest call for every time I want to validate.
No, this is useless, since the given token is already signed by the server. If the token is manipulated in the client in any way the resource server will know it and will answer with the proper HTTP Status Code (usually a 401 HTTP Status).
What you can do is, in case the server respond with a 401, you can use a Refresh Token (if the server provides it) in order to get a new access token and use it again on every request. This way the final user will never know what's going on behind scenes (and won't see a login form again) because you won't ask him/her again about the username and password.
2.Validate the token just one time, with one rest call, and then store the token in local storage. (The token itself just have a boolean
telling if it is authenticated or not)
This is a correct approach (and used by most people), this way you do not overload the traffic with unnecessary requests. Actually, when you get the access token, you do not need to validate it because as I said before the token itself is Self-contained (it contains all the required information about the user and other necessary data the token provider considers important).
If I were you I would read a lot about this since there is much more to get to know than what any answerer can put together in a single answer here on SO (I put some links to sources I've used and which describe pretty well these topics).
Bear in mind that all theses behaviors can be modified according to your needs and not all of them have to be the way I just described. I just put some examples of how it could be.
The image below will give you a big picture about all these matters I just described.

How to protect my api call from CSRF attack

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.

Session Token Authentication Security

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

RESTful Token Authentication Clarification

I've read almost every answer on SO and some blog postings, but I can't figure out one simple thing. In a simple token authentication scheme where the server generates a token and sends it back to the user after verifying credentials, how does the client store and then resend that token in each request? I have seen both cookie examples and header examples. I would like to use the HTTP Headers if possible, but I can't figure out the mechanics of how to send the token to the client, where it will sit, and then have it sent back in the header upon requesting a REST resource.
I am using Jersey/Guice with AngularJS on the front end. Here are the resources I started with:
http://porterhead.blogspot.co.uk/2013/01/writing-rest-services-in-java-part-6.html
Session management : How to generate Authentication token for REST service ? (Jersey)
It depends on your needs. You can use HTTP basic or digest auth, if it is appropriate for you. If not, then if you don't need a permanent storage, you can store credentials in memory. If you need a permanent storage, then you can store them in localstorage, or any other client side storage, but aware, that they are considered not secure.
Anyways I think if your client or service is compromised somehow with xss, then you lost, and it does not matter what else you do about it. Otherwise you can send the credentials in plain text securely as long as you use HTTPS with proper settings. (But that's just an opinion, I am not a security expert, at least not in this topic.) So I think you should concentrate on not being xss vulnerable. For example you should use the proper headers and filter the input against js injection (and by firefox data URI injection). And use TextNode in your client instead of innerHTML wherever it is possible.
For example if you are using Javascript you can store the token in localstorage like window.localStorage["token_id"] on the client side.

Resources