Securing OAuth clientId/clientSecret in AngularJS application - angularjs

I know this is probably an age-old question, but...are there any best practices for securing client secrets for performing OAuth2 authentication in AngularJS applications? I've been racking my brain trying to think of a solution to providing truly secure access to an API from modern style web applications (they need not necessarily be AngularJS.) In my experience, adding layers of abstraction and obfuscation really don't do anything to improve security...they just make cracking the security egg more difficult for any prospective hackers (however many of them prefer a good challenge, so all your really doing is just making the hack more fun.)
Aside from the obvious ineffective solutions such as obfuscation and convolution of code and things like that, are there any best practices for securing client secrets in modern day web applications? I know these questions arose with desktop client apps, and I don't believe there was ever a solution beyond "Might as well obfuscate, that'll slow hackers down". Are we in the same boat with web apps? Is there no real solution to this problem?
If there is not a solution...is there even really any point in securing REST APIs with OAuth?

Remember that OAuth is less about protecting against impersonation and more about protecting credentials. 3rd parties authenticated a user's identity for you without exposing the user's credentials. Since Tokens are not credentials, the amount of harm a hacker can do and his window to act are limited.
But OAuth is not inherently more secure for your application than regular username/pwd authentication. And on client-side apps, all your code is available for the world to see! As
you mentioned, client-side encryption is a questionable strategy.
While there aren't established best practices for protecting client interactions, here are some approaches to minimize your exposure:
1) SSL: Silver bullet? Maybe. The more you can use SSL in your site and your requests, the safer your users' requests will be. I honestly believe all privileged requests should be made by encrypted requests.
2) Short Token Life-Span: The shorter the life-span of your Token, the less incentive/advantage of sniffing it.
OAuth 2.0 creates a constant chatter out of authentication by exchanging Authentication Tokens for Refresh Tokens for Authentication Tokens. You, as the developer are now developing a chatty app that does a lot of "what's your token, here's another token, ask me for a token, here's your new token... so what do you want?" ... "oops, time's up, where's your Refresh Token?"
If that sounds like a pain, it kind of is. OAuth 2.0 is designed to make the process easier for you the developer. But the important point is, the shorter the life span of your tokens, the harder for a hacker to maintain a fraudulent identity.
Refresh Token reference
3) Enforce your Domain: Want to give sniffers less chance of abusing the chinks in your armor? Don't allow Cross Domain Requests!
Sure, we often have distributed environments. But if your Facade is on the Client's Domain, your exposure is lessened (word choice questionable).
Force the hacker to use your domain, limit their creativity.
4) Use 3rd party API's for maintaining you access as often as possible: Google and Facebook API's and Services have been unit tested, battle tested, and evolved. The more you can lean on them to maintain your user's Identity, the less work you will do and fewer chances you take.
5) Check IP addresses: Almost anything can be faked, but the hacker must know that IP Address is part of your validation. This is the least assured of all practices, but combined with 1,2, or more, the gaps for hackers to exploit get smaller and the payoffs for effort fade.
6) Use a "Secret" or 2nd parameter: You can pass your users more than tokens. You can pass your own Alter-Token.
Pretend it's an ID data being passed back and forth. Name the param in a non-obvious way. Make it a number (e.g. age, height, address). The important point is, your hacker knows little or nothing of what's being asked for on the other side!
You can throw a serious monkey-wrench by having 3 params that act as security.
7) Don't give error messages to inform the hacker they've been caught. Give timeout msgs rather than "Got You!" If the invaders don't realize the fraud was caught they don't adapt as well.
I can't say it enough -- SSL saves a lot of trouble.
Note: All client Providers I have seen allow access to their API's without exposing Secret. Secret should never be exposed on client.
Any data exposed on client can be gleamed
Any encryption algorithm you use, will be exposed on the client.

I came here looking for the answer to this very question - how to handle the secret/id in an SPA. I came up with my own solution that hides the secret in the server but I wanted to confirm what I was doing was best practice. So since answers avoid this I will explain my flow in hopes that it will help anyone out there.
Our architecture - we have a ruby server as the api server and an express server serving up the Angular app.
Normally all communication is simply done RESTfully thru the api so the node server is just serving static files and not really doing a whole lot.
Since we were at the point of implementing the login/signup flows I came across the - what was new to me - OAuth 2.0 flow of how to handle things.
Before we can make any requests to the server and the server will take us seriously we need to get ourselves the Bearer token. I chose to implement it as a node endpoint thus to hide the client secret inside the node server itself.
So our customer has entered all their juicy data and are redy to become a user in our app they hit the submit button.
The app fires the request to the node server to get ourselves a yummy token that we can use as the Bearer. I chose to pass the client id as a GET request query parameter. First off I had both client id and secret in the node server but it felt like the id could/should be on the, well, client. So I went with this way.
The node server receives the client id thru the GET request and then proceeds to fire the POST to the host(ruby api). Constructing the url + grant type + client id + client secret. Thus hiding the implementation from the world.
The ruby server return a token for us to use which we then return to the client that initialized the signup request.
The SPA now has a Bearer token which we can use in the header of the signup request.
Thus completing our flow and having a hidden cient secret from the world.
Since we have a token with a certain lifespan we also have a request error interceptor that will catch tokens that have expired and thus make a new token request and then refire the failed call.
I have chosen to use on the Angular side of things this lib for users flow.
https://github.com/sahat/satellizer
Its a super handy lib that gets all the boring boilerplate code that has to be written every time we want an app to have authentication thru email/password and also thru oauth....very handy.
So since this is my own interpretation of how to do such things - feedback is kindly requested.

Related

User login in Django + React

I have looked through quite a few tutorials (e.g. this, this, and this) on user authentication in a full-stack Django + React web app. All of them simply send username and password received from the user to the backend using a POST request. It seems to me that, if the user leaves the computer unattended for a minute, anyone can grab his password from the request headers in network tools in the browser. Is this a valid concern that must be taken care of? If so, how should these examples be modified? A tutorial / example of the correct approach would be appreciated.
It seems to me that, if the user leaves the computer unattended for a minute, anyone can grab his password from the request headers in network tools in the browser
If the user leaves the computer unattended then what you are describing will probably be the least of his/her worries.
Authentication is a complex topic, if you really do not want to use existing libraries that handle this for you then you will need to spend quite some time to get things right (knowing that even then, risk 0 does not exist), the most basic thing being to never store plain text credentials on your DB and using https to transmit them over an encrypted connection. You can then start thinking about JWTs, avoiding local storage, CSRF and securing cookies, refresh tokens, etc.
You cannot do much however about cases like the one you describe of people giving away access to their computers or sharing their passwords with others except reminding them they should never do such a thing.
On a side note, if the user didn't have the network monitoring tool open when making the request to your website, opening it afterwards will not show the previously submitted plain text credentials (there are workarounds to this however)

identityServer4 with Login Step-up and MFA

In one of my Projects i need to implement Login Step-up. That means a user can login an application with simple username and password to get some readonly access access on website and API behind it.
If user want to performan any sensetive data operations like "write/update", he need to authenticate via second factor (via SMS code).
second factor login is for maximum 10 minutes valid, if user does not interect the website for 10 minuets, he will be automatically logout from second factor, but he still remain logged in with one factor.
can identityserver4 support this szenario out of the box? or do i need to implement it by my own ?
Here is my solution proposal:
for one factor login, identityserver provide a one factor scope, which client need to understand. it provide a access token which also have limited scope.
when client application need two factor scope, it call identityserver again where user must provide second factor authentication. hence a new token with second factor scope sent back to client. with this token client can call API methodes which need second factor authentication.
second factor authentication token has a validity of 10 minutes
after 10 min token is invalid, but one factor token is still valid as it has long life time.
Questions:
- Can IdentityServer4 offer Login Step-up out-of-box? if no, what are the alternative solutions ?
what is your suggesstion regarding my solution proposal?
Thanks in Advance
What you wrote in the bullet points is basically how I'd see it implemented in IdentityServer4. It's just setting up two different scopes and issuing two separate tokens for the same user. First scope 'readonly', lifetime=24h, acceptable only by safe operations in the application api, second scope 'full' with lifetime=10mins acceptable by all operations. No big problem, it should be perfectly doable with basic IdentityServer4. However, you will have to RT(F)M and configure the scopes, clients, tokens, etc. in the IdentityServer4 config. And also, you'll have to implement the two-token access policies in your app's backend api implementation, and of course client apps will have to be careful about which token they obtain and which token they use for which backend call.. but all of that is more-or-less obvious (and you seem to understand that, judging from that bullet points) so I don't quite see what you'd want by saying "out of the box" or what are you worried about in terms of support for that on the IdentityServer4 side..

Authentication for single-page apps

Background
I am looking at the OAuth 2.0 Implicit Grant flow where a user is redirected to an authentication service and a JWT token is sent back a Single Page Application(SPA). The token is stored in a cookie or in local storage and, in the examples i have seen, the application will hide/show certain pages based on whether it can find the token in storage.
Issue
The problem is that in all the examples (official from service providers), i was able to manually add any random but properly formed token to the browser's local storage and got access to the 'secured' pages.
It was explained to me that you cannot validate the token in the SPA because that would require exposing the client secret and that you should validate the token on the API server. This means that you can 'hide' the pages but it is really easy to see them if someone wants to. Having said that you are unlikely to cause any real damage because any data retrieval or actions would need to go through the API server and the token should be validated there.
This is not really a vulnerability but the documentation and examples I have seen do not explicitly cover this nuance and i think that it could lead naive programmers (like myself) to think that some pages are completely secure when it is not strictly the case.
Question
It would be really appreciated if, someone who is better informed than i am, confirm that this is indeed how SPA authentication supposed to work?
I am far from an expert, but I have played a bit in this space. My impression is that you are correct, any showing/hiding of functionality based solely on the presence of a token is easily spoofed. Your SPA could, of course, get into verifying an access token.
But that may just make it a little more challenging to spoof. If someone wants to fake the client into thinking it has a valid token, they can likely manipulate the client-side JS to do that. Unfortunately that's the nature of client-side JS. Much of the code can be manipulated in the browser.
Thus far this is speaking to protecting the user from seeing a UI/UX. Most applications are only beneficial when they have data to populate their UI. That's where the API access token strategy is still sound. The server will verify the token and not give the client any data without it.
So while it's unfortunate that JS can be easily spoofed and manipulated to show things the developer would rather not make visible, this isn't typically a deal-breaker. If you have some awesome UI feature that doesn't need data, and you need to secure access to that UI itself, this model may not be the greatest.

Mobile App authentication for admin actions

I am developing an application where users are playing a game and upon completion their results are sent to my back end through a POST request. Since I do not want this POST request to be done manually by someone who finds this endpoint (and mess with his results), I need a way to restrict it so that it can be done only through the application. However is it safe to hardcode a token that provides this access?
What is the correct way to go around this problem ?
I would not recommend to use hard-coded tokens, if the token gets compromized, you have to change the server as well as the client.
I would recommend some sort of auth mechanism as JWT with ssl with one rudimentary username/password system.

Endpoints API with authentication

My question is : can I use endpoints API or a service with OAuth protocol in general, in sort of that i not need to authenticate the user all time that it send a request to the server but only the first time and for the other times I will use type of token or whatever to use the server directly without check oaut. ALl that in a secure way of course.
the process of check oaut is slowing the response.
Thanks
It depends what you mean by "authenticate the user". OAuth as implemented by Endpoints (and demonstrated with samples) suggests you authenticate the user the first time they use the application (either at install time, or each time they load the app in the browser). From then on, the identity of the user is represented by a token, managed by the client library, and sent along with each request. The server will always verify this token to determine who is making the request, but it does not require user-facing interaction.
If you're asking whether you can use OAuth without continually making the user identify themselves (via an OAuth popup, etc.), yes, this is the way it works by default in the samples.
If you're asking whether you can use OAuth without verifying the tokens on each request, you could, but it's not worth doing, because it doesn't get you a lot from a security perspective or save you much performance-wise.

Resources