API Design - securing user registration API endpoint with multiple clients - ruby-on-rails

I'm currently working on a proof of concept system which involves a backend API which is used by multiple possible client applications, including mobile clients and a isomorphic React client.
I've largely taken care of authentication and authorization, the only remaining problem (that I can see at least) is the route to register users - POST /users/, as it is public with no authorization required. My main concern is protecting that route from malicious spamming beyond implementing CORS and rate limiting.
E.g. curl -X POST -d "{ email: 'hello#gmail.com', password: 'nahnah' }" http://host.com/api/v1/users
What would my options be here?
One solution I've come up with is force the SPA to submit the sign up form to an express route within the server that serves the SPA (it requires SSR) to make the API call on the server, meaning the browser's network tab will have no record of the API call. This would mean I'd also have to implement a CSRF token in the SPA.
Also, is this is just generally a bad idea?

I would recommend including a captcha in your registration.
The spamming problem you describe actually consists of 2 parts:
Someone could endlessly spam your endpoint, draining resources of legitimate users. This is can avoided using rate limiting, Denial of Service detection methods, or hiding behind a CDN.
Someone could register a large amount of invalid users in your application. A captcha will stop any requests that arrive at your API from actually getting registered.

Related

Consuming my own Public API on my website

I have a website that exposes a public API. I want to secure this public API using OAuth 2. In order to minimize the number of code paths to maintain, I want to refactor my website to use the OAuth 2-secured public API endpoints.
The way I intend to do this is to register an OAuth 2 Client in my server as "my website", and then have that fetch a short-lived token. I see 2 problems with this approach:
My client would have to effectively have every scope, since the
website encompasses every possible action. The API is just a subset
of this (though I'm hoping to change that). The second issue is
security and caching of the token. The token would live for an hour.
If the user refreshes the page, do I fetch another token? If I store
it locally in a cookie or localStorage, is there a security
vulnerable of some sort?
Let's say I register a different OAuth Client for each page of my UI. The would make it so that the token in #2 would have limited scope if stolen, but it gets extremely tedious.
The alternative is to not use the public API on my website, and protection relies on CORS. Malicious attackers cannot access these endpoints because they are only allowed to come from the domain the user is on (and things like nonces).
Sounds like you want towards a model based on a Browser UI calling APIs directly, which is certainly the most attractive architecturally.
This may be the first step to a Single Page App architecture, which tends to provide the simplest and cleanest solution.
See Open Id Connect for browser apps for latest standards.
In an SPA the UI is cookieless and it is common to store short lived access tokens in HTML5 session storage, which means the user can refresh the page ok
It is true that all scopes are retrieved after login, but if you keep scopes simple and authorize in your API based on user rights you can mitigate that
The above token storage is the default behaviour for the certified OIDC Client Library and widely used.
There is a cross site scripting risk, that malicious content in your browser tab can get a token and call the API - but you should be protecting against this anyway.
Older solutions such as use of auth cookies tend to have their own (and bigger) risks such as cross site request forgery, where any malicious content in any browser tab can send the cookie to your API.
Evaluating whether to use HTML5 storage of tokens is about more than just the technical mechanism - it is about acceptable trade offs around usability and what can be done with the token. My blog post on UI token storage drills into this.
If it helps, my blog also has quite a few posts and code samples on SPAs, in case it is of interest.

Encrypt/sign a client-to-API request?

We are building a JSON API on top of our Web application, using JSONAPI::Resources to expose endpoints and Doorkeeper to handle user authentication.
Most of our API endpoints will be exposed only to authenticated users, and Doorkeeper will probably do a great job at enforcing that. But we still have a couple endpoints that will not be authenticated: signup, login, account confirmation, and maybe a couple others.
I am worried that letting those API endpoints completely open will expose us to attacks, in the form of spamming new accounts for example.
Maybe I am worrying more than necessary? Do APIs usually let this kind of endpoint unsecure, and add prevention systems like throttling? (Rack::Attack!!!?)
If not, is signing (or encrypting) my requests before sending them to the API server the right approach?
And if that's so, do you have any recommendation, or preferred approach, in doing so?
I tried to Google keywords like "rails api sign request" or "rails api encrypt request", but I'm not sure the results are pertinent, or which one would be recommended.
The first clients that will talk to this API will be Android then iOS applications, and we might add in the future client-side web applications (at the moment, our web application is monolithic and does not use the API).

In which cases do you need to implement these complex token authentication on devise (Rails 3.2)

I'm building a Rails app on Heroku.
I installed devise to manage user authentication on which I wanted to add "token authenticatable".
I basically used this tutorial and it works great
However, I ran across more complex tutorial about token authenticatable like these two ones:
http://matteomelani.wordpress.com/2011/10/17/authentication-for-mobile-devices/
http://mojoware.com/posts/mobile-rails-api-with-devise
I don't understand why they get much more complex than what I implemented? They seem to mention "mobile" stuff so does that mean it's a more complex way to use "token authenticatable" because it allows to authenticate in more cases of use such as on mobile?
Really in the dark so I appreciate any help.
For the most part, authentication in a (native) mobile app works pretty much the same way as authentication through a browser: the user gives his credentials, these are sent over the wire to the server/app, and the app responds by giving the user a 'token' representing an authenticated session.
The main differences: browser-based clients will generally submit said credentials using HTTP POST of an HTML form, using application/x-www-form-urlencoded. The returned token is usually given as a session cookie, which the browser presents with every subsequent HTTP request.
Native mobile clients, on the other hand, while functioning as the browser aren't restricted to the HTML way of doing things, and most of them don't use cookies.
The typical mobile client uses a Web service API. Most APIs are designed to be as stateless as possible (unlike browser/cookie-based sessions).
Most Web service APIs also need/want to be able to send & receive as much hierarchical, complex data as possible, using as little bandwidth as possible. Hence, they favor more compact representations of structured data such as JSON (or in some cases, BSON).
In most cases, as well, it is undesirable to present the authentication token as a URL query parameter (or, if you're sending over a JSON payload you might as well include the token in there).
For that reason, the stock Devise session controller and token authentication mechanism is inadequate, and hence numerous examples of how to provide alternative, REST-ful or JSON-based authentication that extends Devise.

oAuth implementation from the beginning or later

I'm starting a new system creating using .NET MVC - which is a relatively large scale business management platform. There's some indication that we'll open the platform to public once it is released and pass the market test.
We will be using ExtJs for the front-end which leads us to implement most data mining work return in JSON format - this makes me think whether I should learn the OAuth right now and try to embed the OAuth concept right from the beginning?
Basically the platform we want to create will initially fully implemented internally with a widget system; our boss is thinking to learn from Twitter to build just a core database and spread out all different features into other modules that can be integrated into the platform. To secure that in the beginning I proposed intranet implementation which is safer without much authentication required; however they think it will be once-for-all efforts if we can get a good implementation like OAuth into the platform as we start? (We are team of 6 and none of us know much about OAuth in fact!)
I don't know much about OAuth, so if it's worth to implement at the beginning of our system, I'll have to take a look and have my vote next week for OAuth in our meeting. This may effect how we gonna implement the whole web service thing, so may I ask anyone who's done large-scale web service /application before give some thoughts and advice for me?
Thanks.
OAuth 1 is nice if you want to use HTTP connections. If you can simply enforce HTTPS connections for all users, you might want to use OAuth 2, which is hardly more than a shared token between the client and server that's sent for each single request, plus a pre-defined way to get permission from the user via a web interface.
If you have to accept plain HTTP as well, OAuth 1 is really nice. It protects against replay attacks, packet injection or modification, uses a shared secret instead of shared token, etc. It is, however, a bit harder to implement than OAuth 2.
OAuth 2 is mostly about how to exchange username/password combinations for an access token, while OAuth 1 is mostly about how make semi-secure requests to a server over an unencrypted connection. If you don't need any of that, don't use OAuth. In many cases, Basic HTTP Authentication via HTTPS will do just fine.
OAuth is a standard for authentication and authorization. You can read about it in many places and learn; Generally the standard lets a client register in the authentication server, and then whenever this client attempts to access a protected resource, he is directed to the auth-server to get a token (first he gets a code, then he exchanges it with a token). But this is only generally, there are tons of details and options here...
Basically, one needs a good reason to use oAuth. If a simpler authentication mechanism is good for you - go for it.

Will using a master login username and password when implementing web services considered secure

I am working on an asp.net mvc-4 web application and I have started implementing some web services which provides statistical information about my site. But to make sure that only authorized and authenticated consumers can call and consume the web services I am thinking of defining a master login username and password for each consumer, and when a consumer sends a web service request he should include these master login username and password (stored as a hash value ) in the web service calls.
For example the web service link to call specific web service from my web site will look as follow:-
/web/json/statistic/getsummaryinfo/areacode?j_username=masterusername&hash=D012B772672A55A0B561EAA53CA7734E
So my question is whether the approach I am following will provide a secure solution to my web services and to the consumers? OR my approach have security holes I am unaware of ?
:::EDITED::
I am using the WebAPI controllers to implement the web services inside my asp.net mvc-4.**
Best Regards
There are a few ways to make sure things are secure.
http://techcrunch.com/2012/11/08/soa-softwares-api-management-platform-and-how-it-compares-to-its-sexy-counterparts/ This article just came out today highlighting some API tools. I'm not sure how big you are or are planning to be, but if you're looking for scale, these tools seem to be pretty popular (note: I haven't had a large scale API project myself, so I haven't used these).
You can use something like ServiceStack to build your API layer. It has authorization and authentication built in with a boatload of authentication providers. It scales well and, after a call to authenticate, is session-based so you don't have to authenticate each call.
You can use "signed" requests. Signed requests often look something like: "take all the parameters for the request as a querystring, append a 'secret consumer key' to the end of the request', and then sign the request by appending the md5 hash of the results (without the secret key!!) to the request." This is a safe way of doing things because even if the request is made client-side (AJAX) it is generated server-side using a secret key. So you can ensure that things weren't tampered with.
You can go the oauth/token route (which often still uses method #3 above).
You can go with a simple API key that can be revoked (again, fotne used with method #3). bit.ly uses this method I think.
Option #2 is my favorite. I like ServiceStack. But to be honest the learning curve for your first project can be a little steep.
A master username and hashed password feels weak to me, so I'd strongly consider at least looking around at how others are doing it.
HTH
I do not consider your way to be safe. If I could listen on the wire and cache the request I will have the login an the password to the service. There even does not matter if the password is hashed or not. I like the point 3. in Eli Gassert's answer. It sounds very useful and light weight and you are not exposing the password because it is hashed "somewhere" in the request.

Resources