Safe Twitter OAuth authentication in JavaScript / jQuery (plus server side helper) - javascript

What is the best way to do Twitter OAuth authentication safely in JavaScript?
I am trying to write a program to let the user analyze his Twitter usage and followers / friends. I've written a server side version which works using the python tweepy module.
I would like to share it with people, but I would like it to run in the browser to be scalable vs. running on my small server.
I see another question where the upshot is that it's not recommended and not safe:
JavaScript OAuth sign in with Twitter
Which makes sense if one were sending the consumer (app) secret or access (user) secret in the app's JavaScript.
But why couldn't I build the URL on the server side like here -
http://djangosnippets.org/snippets/1353/
Then send the authentication URL back to the browser, something like this from the OAuth Tool on Twitter's My Applications page (not valid credentials)
GET&https%3A%2F%2Fapi.twitter.com%2F1%2F&get%252Faccount%252Fverify_credentials_json%3D%26oauth_consumer_key%GD0bgcgMU4MDwNfKQpLFQS3%26oauth_nonce%3D24ad5049501dee1292afd8cf22307d68%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1329173626%26oauth_token%uPUpxsBc3D283768289LtQ6R1Ez1KeD8DOSsm5XpqJaKI28ysYh%26oauth_version%3D1.0
Then have jQuery use that to authenticate with the user's credentials and run the analysis.
It's a significant piece of work, I'd hate to do that and then find out it doesn't work or is an unsafe approach. (or it's already been done)
Is that safe? It doesn't seem to expose any secrets.
Will that work?
Any pointers/examples on the right way to do the authentication for a jQuery noob, with the necessary Authorization: header and cookie/redirect processing?
I feel like I'm missing something and either there's a reason this won't work, or it should already exist somewhere, but haven't found it. Many thanks!

The problem Mr. McNuts, is that the oAuth requires you to pass in your consumer secret, so even if you build the URL on the server, you'll still pass it back to the webpage, which will still expose your consumer secret via an HTTP Proxy.
To prevent exposing your secret, you'll need to use a proxy to do the twitter auth request, and return the oauth token back to the browser. If you're really worried about scale, I would look at a pay-for-scale solution like GAE or Heroku.

I don't understand very well the approach you are proposing. But in general terms OAuth can not be done safely implemented on a browser client side (except secure close environments like Java or Flash). Implementing OAuth process on Javascript is quite possible but you will expose your secret/consumer token. So anybody would be able to supplant your application identify with mischievous intentions like stealing your users sensitive data.
If you still want to work with JS, I recommend you to implement the secure process (authentification and final token storage) on server side using Node.js

Related

What is the relationship between authentication/authorization in my frontend and my api backend?

Frontend is Vue and my backend is an express rest api that pulls data from mysql. I want to secure both the frontend (login form) and backend api, but without limiting use of the api to just my frontend. I may want to use this api for other projects in the future.
What I'm strugging with is understanding how to have a user log in on the frontend but also give them access to the api without preventing future access to the api from other projects. I know I could set a JWT, but recently there seems to be a lot of "DON'T USE JWT!" articles out there, and I can understand why they might think this. Using cookies and sessions doesn't seem practical either without needing to create a session/cookie for each frontend and backend. Then I thought maybe using cookie/sessions for frontend, and having the frontend be authenticated with an API key to the backend API. This might allow other web applications to access the api while protecting it from unauthorized access.
Apologies for the lack of knowledge and seemingly rambling. I've been stuck on this aspect of my project for a while now. I know it's due to my poverty of knowledge on the subject. Any resources and points in the right direction will be greatly appreciated.
There is nothing wrong with JWTs, though it can depend on the implementation. The simplest way of doing it is just signing the JSON string with a private key. A little more complicated is base64 encoding it, encrypting it and signing only after that with a different key. And ofc. you need to send it through SSL. You need to add expiration time to it. Probably bind it to IP, browser, language, location, etc. too. If you want to revoke it, then you need to maintain a very small global revoked JWT database and remove it after it expired. You can add a JWT verification cache too, which spares you checking the signature for every request and which can be local too. If you want to avoid accessing it from Javascript code and probably leak it with XHR, then add it to a httpOnly cookie, though if you do so, then you need a CSRF token too. So I think all of the security issues are solveable with JWT too.
We need stateless communication between the REST client and the REST service, so if your frontend has a server side REST client, which uses for example JWT or any other method with Auhorization header, then it is perfectly fine from statelessness constraint perspective to do server side sessions with your frontend. As of the constraint itself, statelessness is needed for massive services with countless users global scale where handling server side sessions is an issue on its own, so better to move the stuff to the clients. These are typically social media services, search engines, global webshops, etc. If you have a limited user number, then you probably don't need this feature. Though using server side sessions between REST client and service would violate the statelessness constraint, which means you would not have a REST service. I don't think this is an issue. I mean it would be still a service, just not a REST service, it would work, would not scale as well as a REST service, but if this is what you need and it is simpler for you to implement it securely, then go on.
You can use API keys if you have some sort of revoke mechanism for those too. And keep in mind that API keys are server side stuff, so for mobile clients and in-browser application they are not good for identification, because they can be easily stolen by the users, so don't access your service directly from those with API keys just through a server. Another way is checking IP and using SSL to identify the clients, which is similar to using API keys, just more standard and the secret does not go through the communication channel. It really depends on your needs. If you have 3rd party clients, then you'll need OAuth too and let the users decide if they trust them.
Not sure if this helps.
By far the best thing you can do is adopt OAuth2. It has all the necessary components solve your problem and has ton of implementations.
The issue with JWT is that lots of people get it wrong. inf3rno does a good job accidentally pointing out many of the issues.

How do you implement digest authentication with SHA-256 when modern web browsers disable SubtleCrypto when you're not in a secure context (https)?

I've got a very basic web server running on an ESP8266 microcontroller, so system resources are very limited, but I figure it can probably deal with SHA-256 (I'll guess we'll see, but that's a separate issue).
I've got the barebones digest authentication implementation working well enough that I can access the site via curl.
This microcontroller is not meant to be exposed to the internet, it's only something you'd access internally via your lan, so SSL isn't an option (not sure how well the microcontroller would hold up if it tried to support HTTPS).
So, here's my scenario:
User tries to access the site on the microcontroller from their favourite web browser. They are given a 401 code and redirected to a login page (along with the WWW-Authenticate header).
This login page needs to take the information from the WWW-Authenticate header, as well as the username and password input by the user and generate the hash it needs to send in an Authorization header.
Unfortunately, the built in functionality for generating SHA-256 hashes is disabled if you're not connected via HTTPS (according to https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto) - So does this mean that digest authentication is not supported by web browsers natively (unless they choose to use MD5 instead of something more secure)? If you're implementing digest authentication, you need to supply your own hashing functions?
I also don't quite understand why disabling the ability to do hashes helps user security (in a non-https context).
An assumption:
After a cursory google search, it seems that digest authentication only makes sense for http, as if you're using https then you've already got better encryption protecting your credentials.
So to answer my own question (partly):
It turns out that the user side is handled entirely by the browser (i.e. Generic login modal pop-up). Java script doesn't even have access to the response headers anyway.
I guess to prevent poorly implemented non-secure logins?
The examples I've seen work around it by providing functionality entirely via xhttprequests.
I still don't know what benefit denying access to hashing algorithms provides though

Using Active Directory (with LDAP) to authenticate on an angularjs/javascript fronted - what should the flow of the process be?

I'm working on a project in which we need to authenticate the user in an application by using his/hers windows credentials. Frontend is using Angularjs and backend java.
After doing a sensible amount of research, I discovered that there is no way on the the frontend to obtain directly the Windows user & pass due to security concerns.
But I'm thinking that the whole process should start here, from the frontend, by obtaining these two encrypted credentials or at least a token and sending them to the backend in order to kickstart the ntlm authentication process.
And also, not sure if the user should have to log in the app by typing his windows credentials or if it should automatically be done with ntlm passthrough.
I do not have a good grip on the concept, and that is because most of the related sources that I found are referring to backend solutions (C# 80% of them), but almost nothing for fronted. So, I humbly require some clarifications on this topic. Is there some sort of middleware or npm package that I should use in order to obtain the user & pass, or what would you advise?
Web servers expose certain server variables to code handling requests they serve.
For me, using IIS, these are described here: https://learn.microsoft.com/en-us/previous-versions/iis/6.0-sdk/ms524602%28v%3dvs.90%29
Since I am using IISNode; my node.js environment is completely embedded into IIS; I have access to these server variables. As the link described, each programming language seems to have their own way to access these variables.
So I would doubt it if Java does not have those as well. The exact code to use will depend on you back end.
But a quick search for "java server variables" already yields me the following:
https://docs.oracle.com/cd/E19534-01/820-3288/gawim/index.html for the java access manager.
http://users.polytech.unice.fr/~buffa/cours/internet/POLYS/servlets/Servlet-Tutorial-CGI-Variables.html for old school JSP.
How can I obtain server variables using apache wicket 1.54? for java wicket server.
So have a look at the documentation of your specific web server software or Java API.
There should be a list and example code of how to access these.
Once you obtain this data server side, you can do the LDAP query and then return the results client side.

webapi backend with pure javascript frontend, security

So now I am pretty much sold to the idea of having pure html+js front end where all processing happens at client side browser and the backend provides all the data in JSON/xml/other format and so on.
Here's the dilemma,
For authentication, I am using OAuth2 Bearer token which gets generated when user authenticate using username and password (for e.g. at login stage).
There is an extra security for which clientside application (i.e.a front end web server or mobile app) that is making request to this WebAPI. When it makes the initial request, it passes "client_id " and "client_secret" to make sure the client is app is authorized to make this request to back end server.
In traditional .NET way I would store the encrypted clientid and key in web.config and my C# (Or VB.NET) code would retrieve it and send it over SSL to the server. So in the manner the client_id and client_secret is not exposed in rendered HTML (for e.g.) to the client side browser.
In pure javascript environment how can I secure my client_id and client_secret (or any other sensitive data for that matter)?
Thanks
I don't think you can secure your "secrets".
HTML5/JS code is pure text, anyone with a text editor can see it. What people normally try to do is obfuscate their code by using javascript minifiers/compressors; see here for a good discussion. The practice is called Security through Obscurity. But note that obfuscation is not security. Given time and effort, a determined "hacker" will eventually find your secrets. Another step you can take to deter, delay and frustrate such attacks is to spread bits of your secrets in the code, in different modules, etc. Having said that, you'll need to write code to assemble them at some point, so again, no real security.
I have a similar problem because I wanted to use a "shared secret" with the server so I can hash my client requests such that they are tamper-proof and can't be recreated without the attacher knowing the shared secret. Unfortunately I had to give up on the idea, since I realised I couldn't keep it secret enough.

Securing my Node.js app's REST API?

I could do with some help on my REST API. I'm writing a Node.js app which is using Express, MongoDB and has Backbone.js on the client side. I've spent the last two days trying to work out all of this and not having much luck. I've already checked out:
Securing a REST API
Securing my REST API with OAuth while still allowing authentication via third party OAuth providers (using DotNetOpenAuth)
http://www.thebuzzmedia.com/designing-a-secure-rest-api-without-oauth-authentication/
http://tesoriere.com/2011/10/10/node.js-getting-oauth-up-and-working-using-express.js-and-railway.js/
I want to keep my backend and frontend as separate as possible so I thought about using a carefully designed REST API would be good. My thinking is that if I ever get round to developing an iPhone app (or something else like that), it could use the API to access data.
BUT, I want this to be secure. A user has logged into my web app and I want to ensure my API is secure. I read about OAuth, OAuth 2.0, OpenID, Hmac, hashes etc... I want to avoid using external logging in (Facebook/Twitter/etc) I want the registering and logging in to be on my app/server.
...but I'm still confused here. Maybe it's late at night or my brain is just fried, but I could really do with some steps on what to do here. What are the steps for me to create a secure API?
Any help, any information, any examples, steps or anything would be great. Please help!
In order of increasing security / complexity:
Basic HTTP Auth
Many API libraries will let you build this in (Piston in Django for example) or you can let your webserver handle it. Both Nginx and Apache can use server directives to secure a site with a simple b64encoded password. It's not the most secure thing in the world but it is at least a username and password!
If you're using Nginx you can add a section to your host config like so:
auth_basic "Restricted";
auth_basic_user_file /path/to/htpasswd;
(Put it in your location / block)
Docs: http://wiki.nginx.org/HttpAuthBasicModule
You'll need to get the python script to generate that password and put the output into a file: http://trac.edgewall.org/browser/trunk/contrib/htpasswd.py?format=txt
The location of the file doesn't matter too much as long as Nginx has access to it.
HTTPS
Secure the connection from your server to the app, this is the most basic and will prevent man in the middle attacks.
You can do this with Nginx, the docs for it are very comprehensive: http://wiki.nginx.org/HttpSslModule
A self-signed certificate for this would be fine (and free!).
API Keys
These could be in any format you like but they give you the benefit of revoking access should you need to. Possibly not the perfect solution for you if you're developing both ends of the connection. They tend to be used when you have third parties using the API, eg Github.
OAuth
OAuth 2.0 is the one to go with here. While I don't know the underlying workings of the spec it's the defacto standard for most authentication now (Twitter, Facebook, Google, etc.) and there are a ton of libraries and docs to help you get those implemented. That being said, it's usually used to authenticate a user by asking a third party service for the authentication.
Given that you doing the development both ends it would probably be enough to put your API behind Basic HTTP Auth and serve it over HTTPS, especially if you don't want to waste time messing around with OAuth.
Here's a different way of thinking about it:
Let's suppose for a moment that you're not using an API. Your user logs into the app, providing some credentials, and you give a cookie or similar token of some sort to the user, which you use to identify that user has logged in. The user then requests a page containing restricted information (or creating/modifying/deleting it), so you check that this token to ensure that the user is allowed to view that information.
Now, it sounds to me that the only thing you're changing here is the way that information is delivered. Instead of delivering the information as rendered HTML, you're returning the information as JSON and rendering it on the client side. Your AJAX requests to the server will carry that same logged-in token as before, so I suggest just checking that token, and restricting the information down to 'just what the user is allowed to know' in the same way.
Your API is now as secure as your login is - if anyone was to know the token necessary for accessing the api, they would also be logged into the site and have access to all the information anyway. Best bit is, if you've already implemented login, you've not really had to do any more work.
The point of systems such as OAuth is to provide this 'logging in' method, usually from a third party application and as a developer. This would potentially be a good solution for an iPhone app or similar, but that's in the future. Nothing wrong with the API accepting more than one authentication method!
The answers so far do a great job of explaining, but don't give any actual steps. I came across this blog post that goes into great detail about how to create and manage tokens securely with Node + Passport.
http://aleksandrov.ws/2013/09/12/restful-api-with-nodejs-plus-mongodb/
Tips valid for securing any web application
If you want to secure your application, then you should definitely start by using HTTPS instead of HTTP, this ensures a creating secure channel between you & the users that will prevent sniffing the data sent back & forth to the users & will help keep the data exchanged confidential.
You can use JWTs (JSON Web Tokens) to secure RESTful APIs, this has many benefits when compared to the server-side sessions, the benefits are mainly:
1- More scalable, as your API servers will not have to maintain sessions for each user (which can be a big burden when you have many sessions)
2- JWTs are self contained & have the claims which define the user role for example & what he can access & issued at date & expiry date (after which JWT won't be valid)
3- Easier to handle across load-balancers & if you have multiple API servers as you won't have to share session data nor configure server to route the session to same server, whenever a request with a JWT hit any server it can be authenticated & authorized
4- Less pressure on your DB as well as you won't have to constantly store & retrieve session id & data for each request
5- The JWTs can't be tampered with if you use a strong key to sign the JWT, so you can trust the claims in the JWT that is sent with the request without having to check the user session & whether he is authorized or not, you can just check the JWT & then you are all set to know who & what this user can do.
Node.js specific libraries to implement JWTs:
Many libraries provide easy ways to create & validate JWTs, for example: in node.js one of the most popular is jsonwebtoken, also for validating the JWTs you can use the same library or use express-jwt or koa-jwt (if you are using express/koa)
Since REST APIs generally aims to keep the server stateless, so JWTs are more compatible with that concept as each request is sent with Authorization token that is self contained (JWT) without the server having to keep track of user session compared to sessions which make the server stateful so that it remembers the user & his role, however, sessions are also widely used & have their pros, which you can search for if you want.
One important thing to note is that you have to securely deliver the JWT to the client using HTTPS & save it in a secure place (for example in local storage).
You can learn more about JWTs from this link

Categories

Resources