There is a sensitive page in my website, so I want to authenticate visitors before they opening a link like: www.examples.com/builder.
I know if I use cookie based authentication everything will be simple, as the browser will send the credential message in cookies automatically. But in my situation, I have to use token based authentication. Browser don't send token if there is no pre-load script.
So my question is how to achieve token based authentication when someone open a sensitive page directly.
As far as I can understand,
you're looking for a way to avoid double roundtrips to send authentication headers to your web-service.
If I am correct, then this would only be possible via service worker which is a not widely supported feature. https://developers.google.com/web/fundamentals/primers/service-workers/
If, depending on your requirements, you can't go for service workers, then, the only left option is to use cookies.
I normally have a secondary authentication flow which uses cookies allowing a web service to authenticate a user on its first get request (the one made by the browser).
There are also some spa framework which implement routing resolvers but this will require a double roundtrip (1. load javascript, 2. send the token).
Related
I'm looking a way to securely share a token between one webapp with the front-end of a second webapp.
Environment details:
webapp.local: A PHP webapp that stories some data that are restricted to specific users. This webapp is accessible by VPN only.
otherwebapp.example: This is a Zendesk instance, it allows us to create a plugin (HTML + JavaScript) that is loaded on the client-side.
Notes:
webapp.local and otherwebapp.example use different domains (they aren't sub-domain).
otherwebapp.example is not able to access the webapp.local. But the front-end will be able (the user are connected to the VPN).
I did some research, and found some options:
HTTP Coockies: the "SameSite" need to be "None" (reference), is it a secure option? I did some tests and seems that they need to be on the same sub-domain.
JS postMessage: It will need to open a popup or a iframe, I did some tests but still trying to make it works.
The question is:
Is there a best practice or another way to share a sensitive data (token) between a webapp and a front-end located on other domain/app?
I think there is not a fully secure way to do it because you want to handle the share on the client side and that will be always exposed, though you can take a different approach like share a request token via GET param to the second webapp and there call a validation API that validates the origin of the request (should be restricted to the second webapp domain) and also validate the passed token and then return the actual session token.
I am trying to embed facebook auth into my application.
My initial effort was to login in browser and obtain code. I pass this code back to my api and obtain access token (that stays with the server) and route all my requests to FB Api through my server. Seemed totally secure to me as my client has no information to be able to make authorized calls to FB as my app.
I however have been looking at FB Javascript SDK to avoid writing code for dialog opening and closing and noticed that it allows me to getLoginStatus and returns me the access token. Also, I went over FB auth flows in their documentation and they say that client-server hybrid flow is okay to do where server actually gives "Long lived access token" back to the client and advises me to use HTTPS (fair).
Now all this gets me thinking if this is a security concern. Can't I as a potential hacker inject some javascript into the user's webpage that could either a) make a getLoginStatus and get the access token or b) just get the access token by making a request to my api server and get the access token and then use that to post (assuming that user authorized my app to do so) to facebook as if my app was doing it?
I am a security newbie and maybe overlooking a bunch of stuff here but could someone help me understand what I'm missing?
Thanks in advance!
PS: I do know I can enable further security to ensure that I need the app secret every time I want to make a request which the client can't do as that information will never be available on client side.
I am not a security expert, just some thoughts: in your question, you are assuming that the hacker somehow injects the script into the webpage in the user browser using malware and that script then interacts with the data you have client-side.
Now, if we imagine this actually happened and the evil script has full access to the web-page data, even if you don't have the access token on the client, what prevents the evil script to make requests to your server and interact with facebook through your server?
Moreover, if the user opens facebook itself and authorizes there, the evil script could be injected into facebook page and do any actions on behalf of the user, just sending the requests to facebook server.
This way, it looks for me that if the situation you describe happened, it would not really matter if you storing the access token client side or not - anyway the evil script will be able to do it's job.
Practically, if you are worried about security - first carefully check all the facebook docs related to authentication and security and follow their recommendations. Second - search for common known attack vectors and recommendations of how to avoid security risks in your application.
If the user already has malware on his computer which is able to alter browser behavior (like inject additional scripts into pages), you probably can't do much about it.
You can only get your access token if you have a valid redirect URI which equivalent to your Site URL on your facebook application settings..
also, it needs permissions before you can post using the facebook access_token.
You can check the API calls at https://developers.facebook.com/tools/explorer/
I'm a regular reader here at stack overflow but this is my first question.
I'm developing an authorization-server using the OAuth2 specs. And I just got stuck with how do I ensure the first-party client authenticity while using the password flow. I read many forums and this is what I got:
Javascript single-page clients
This blog post by Alex Bilbie, he states that to avoid the client_secret problem we should just:
It’s simple; proxy all of your API calls via a thin server side component. This component (let’s just call it a proxy from here on)
will authenticate ajax requests from the user’s session. The access
and refresh tokens can be stored in an encrypted form in a cookie
which only the proxy can decrypt. The application client credentials
will also be hardcoded into the proxy so they’re not publicly
accessible either.
But now this proxy can be accessed by someone impersonating my
angular app. And then I came across this blog post from Andy
Fielder: How Secure is the OAuth2 Resourc Owner Password Flow
for Single Page Apps. He basically says to rely on CORS to
avoid impersonating JS clients.
It is a good idea to use both approaches to secure my JS app?
Native Apps (Desktop and Mobile)
In the case of mobile apps, I only found cases for Authorization
Code and Implicit flows. This is not what I want, as the redirects
will compromise the user experience. So my thoughts on this is:
I will use the ROP flow and then register the client with a
client_id generated for this particular installation and attach it
to the user account, receiving the access_token and a
client_secret as response. Any other token request made by this
client MUST carry this credentials (as the client_id is specific
for the installation, I will be able to check if this client is
already authenticated). This way if someone uses any credential for
impersonating a client, or even registers a bogus client, I can take
mesures to revoke the user and client access.
I know that this can be overthinking, and I also know that some of this matters doesn't avoid anything. I just feel that is my job to protect my API as much as I can.
I would really appreciate your thoughts about this matters! Am I really overthinking? Should I just use the concept of a 'public client' and carry on?
Thank you all and happy coding!
First of all, this problem is not a common priority because most applications are developed first with website, and after with the API. This is probably the reason because no one knows how to deal first clients with oauth2, because everyone have developed other ways to do that and oauth2 is needed only to grant user access to third party applications.
Even if you have develop the oauth2 authorization server only for your first clients applications (thinking about a single authentication mechanism instead of developing many), you should try to develop the authorization code or implicit grant types. You will realize that you need a way to check what user is actually logged in.
The two common methods are:
user session (based on Cookies)
user access from localStorage (based javascript)
In either ways you need to check your application security, user session is vulnerable to CSRF, localStorage are vulnerable to XSS. There are a lot of articles about how to secure your website against either, so I will not suggest anything here, you just need to know that they exist.
Now that you choose your authentication method we can start to do some consideration about:
Javascript single pages applications
Proxy
Having a proxy that filter all requests in my opinion is like to have a door with the keys always inserted. It's useless even build the door.
However, for session based authentication it's the only way to do it. Allowing session authentication on your Rest API will open to CSRF security issues, so you need to have a proxy layer that get the user session, retrieve the access token from the session and do the request to the Rest API adding the Authorization header.
CORS
With this method you need to store the user access token in the localStorage, because the token is retrieved from the Js client directly.
Using CORS you are sure that other websites cannot do requests to your Rest API from a browser. But your first client need to be public (ie: it does not have a client_secret).
Native Apps (Desktop and Mobile)
In my first application I tried to use the same mechanism that you suggest to secure the auth flow. However that type of mechanism require that you identify every user client in an unique way. This is not possible in iOS for privacy reasons and with some probability it will denied in the future releases of Android. So you should rely on a public client and add only the client_id in your native application code.
This means that your native app client/your js client can be impersonalized? Yes, and there is no way to prevent this with oAuth2 resource owner password credentials grant type.
The main reason about this is because oAuth2 is not for authentication, only for third-party authorization, and that grant type was added only for specific third-party applications trusted enought to use directly the user password. You could read more about this argument here and here.
At the end
You still need a way to auhorize your user, and I think that the best you can achieve using oAuth2 is what Auth0 did.
Essentially this Saas manage your users with an oAuth2 server + OpenID connect, so you are always managing your users like its a third-party application and everything works fine.
Indeed, you can see on this page that for mobile applications they suggest to use a browser based login form, because the native one can be impersonalized by everyone that decompile your application, but if you wrap it into an authorization code flow it works fine.
We're developing a system using AngularJS and PHP. I have some concerns about the security on the matter of authentication. I wrote a basic authentication based upon multiple different examples around the web (I only started learning Angular), which uses a database via REST API calls. On some routes it checks if the user information exists before it creates a promise, but I have a few questions:
Can session information be stored in$window.sessionStorage or $cookieStorage without the client being able to modify these values or should I keep them server-side with PHP $_SESSION and fetch them from there, never storing them anywhere in JS? Session information can contain uid, role, email and name
Can I store a value, like let's say $rootScope.role or $scope.role without the client being able to modify this value? Let's say for example we have multiple levels of user accounts where super-admin is the highest. If I create a route with a resolve which would check the $rootScope.rolelevel, can a novice go change the $rootScope.role value to super-admin gaining access to restricted backend sections?
Will I have to implement a GET /session check on every route to which gets $_SESSION data to actually make sure this data stays untouched?
Or am I just paranoid?
You're not paranoid, any client-side authentication should be questioned. When it comes to security, you can't assume that the client is forbidden or unable to do anything on their own device.
Security related functions must stay on the backend, an environment you set up and control.
can a novice go change the $rootScope.role value to super-admin gaining access to restricted backend sections?
Asking questions like "can a novice..." are futile in my opinion. Do you only want security against novice malicious users? If your "restricted backend sections" can be accessed by modifying the frontend, you're doing something wrong.
Great question! Front end security requires the cooperation of the browser and your server.
Javascript is an untrusted environment, so you can’t reliably enforce any authorization there (i.e. you can’t use properties on $scope to prevent a user from doing something). Your server needs to enforce these rules by ensuring that every API request is properly authenticated and authorized.
API requests are typically authenticated with a cookie. The cookie typically contains a session identifier, which points to a row in your database which contains the authorization information (i.e. what the user is allowed to access). The user can get this cookie by logging in (presenting hard credentials like a username and password).
The cookie may also contain a signed access token, such as a JWT. Depending on your architecture you can remove the session database and rely purely on the signed token for authentication.
In either case you want to set the HttpOnly flag on the cookie when your server is sending the cookie to the browser. This will prevent the JavaScript environment from reading the cookie, this is a good security measure to yourself against XSS attacks.
You also need to protect yourself against CSRF attacks. This is a situation where another website can trigger a GET or POST request to your API, and this will send along the authentication cookies. You can guard against this by creating another cookie that does NOT have the HttpOnly flag, and storing a random value in it. The JS environment must attach this value to any request, typically as a custom HTTP header. Your server then asserts that the value is associated with the session or token.
I’ve tried to cover all the bases in this answer. If you’d like to read more, you can check out these blog posts that I’ve written, they discuss token authentication, but each has sections that cover front-end security issues:
Token Based Authentication for Single Page Apps (SPAs)
https://stormpath.com/blog/build-secure-user-interfaces-using-jwts/
Disclaimer: I work at Stormpath and we provide a secure, hosted user management solution for any application, including Angular! See https://docs.stormpath.com to learn more and find the SDK for your server.
I am designing a multi-platform application at the moment (clients would include internally developed mobile apps, and an AJAX heavy javascript client initially) centred around a REST API. Since in the future the API may be open to third parties, I am looking at using OAuth 2.0 for authentication and authorization with the API.
I am trying to get my head around some of the security issues with this arrangement, particularly with regard to the javascript client. I don't want this client to behave like a third party client might, with a whole bunch of redirects and popups and stuff, which is what most OAuth documentation seems to focus on. Since it will be delivered from my own domain, I am thinking that the server side of the webapp can be the actual client, and store the client secrets and refresh tokens, while the javascript retrieves new auth tokens from the server as it needs them.
To put it in step by step form:
The user logs in using non-ajax html form, generating auth and refresh tokens which are stored server side. This sets a HTTP-only login session cookie.
The javascript client code is sent to the user's browser after login.
The javascript client makes a request to a resource that is part of its own application (not part of REST api) to retrieve the token. The session cookie ensures that the client is genuine, and the referer will also be checked. Auth token is returned.
The javascript client validates the token with the REST API.
The client can now use the token to make requests against the REST API until it expires.
If the auth token expires or the page is closed and re-opened, the javascript client can request a new token. The server side of the webapp takes care of refreshing the token and sends the new token, as long as the login session cookie is still valid.
Does this make sense, or would it leave massive holes in the system? In particular, is it insane to have a resource on the web that hands out authentication tokens based on a cookie being set?
Just make sure that any communication to browser is HTTPS, so that no one in the middle can steal your tokens. And set the "secure" flag on your auth cookies.
Most browser authorization schemes nowadays boil down to a session token that's passed in a cookie. The OAuth 2 scheme is a couple steps ahead because a) the tokens (can be) dumb tokens with no dangerous user info inside, and b) they expire.
(Just to put that comment in context: one time I popped open a session token from a site and discovered my home address and phone number was in there. Ack!)
I've seen code that does HMAC signing of requests inside the brower javascript, but it came with a huge disclaimer: don't use this in production. A signing scheme requires the client (javascript) to know a "secret" string, but the browser/javascript is so insecure that it amounts to handing your secret strings to the world.
But if you keep all your commuinication over HTTPS, then you're really just putting an OAuth twist on the familiar scheme of passing session tokens as cookies.