Api Token Authentication - through parameters or headers? - api

I wrote some API. It requires an API token.
I only access this API through backend.
Should I receive the API token through headers only, or is it ok to receive it from query string parameters?
Are there differences security-wise?
Edit: forgot to mention, of course I use SSL

All the Authorization is in Headers only headers are more secure
In query parameter these are expose for the public
for eg. if you send in Like a query it will be public to all
Don't do this Ever
curl -X GET http://localhost:5051/v1/user/verifytoken?token=bearer-xdrRxfdfdfdf

You may need a refresher on the differences between cookies and tokens to assist you in finding your answer.
The purpose of cookies is to bring state to what is inherently a stateless protocol which is http, the http protocol has no concept of state and it's only by introducing these cookies or tiny bits of data on requests that identify us to the server.
Cookies are included on all http requests by default, they manifest themselves as a property on the header of any request. A server can choose to place information on a users cookie that identifies them uniquely to that particular server.
So if they were logging into a website I were making I could stick some information into that cookie that says this is user13794 and on any follow up request they would have a cookie 13794 that says this is the same user coming back, it's another request from the same person.
Cookies are automatically included on all requests and very importantly, are unique to each domain, such as Google.com versus eBay.com. A cookie you have that is tied to google.com is not and cannot be shared by default with ebay.com, that is how we get some level of security on all of our requests. So if I logged on to google.com and then went to hacker.com, the hacker.com website could not lift my cookie from Google and hijack my session.
SO cookies cannot be sent to different domains, that is something that exists for security purposes so you cannot easily hijack peoples sessions.
Opposed to cookies are the ideas of tokens, this was introduced as a convention, to use tokens in place of cookies where cookies stop being useful.
There is nothing done automatically for us with tokens, we have to manually include a header with our token which might be a string of letters and numbers and we might include it on a specific header so we have to manually wire up our tokens at all times.
The benefits of tokens is that we can send them to any domain that we wish, so if I am on google.com and I want to make an authenticated request to an entirely different domain, I can do so by using a token.
I would make my request to that other domain, include my particular token and boom! I am authenticated on that other domain.
So that's my long winded way of saying, like with cookies, tokens are manually wired up through headers only, not query parameters.

Related

How token based authentication helps in cors, cdn, CSRF , mobile ready?

I was reading articles about token based authentication.
And when I was going through this article "Cookies Vs Tokens", I did not understand the following four points (I have asked my doubts below each of the quoted points)
Cross-domain / CORS: cookies + CORS don't play well across different
domains. A token-based approach allows you to make AJAX calls to any
server, on any domain because you use an HTTP header to transmit the
user information.
Why now there will not be cors problem ? What if someone one from the neighboring tab in the browser steals your token(because in javascript of that domain there is code which can clearly tell where the token is stored and how it is retrieved) and starts making
requests ?
And more over it is said "cookies + cors" . why is it said that cookie and cors don't play well ?
CDN: you can serve all the assets of your app from a CDN (e.g.
javascript, HTML, images, etc.), and your server side is just the API.
Why is this an advantage in token based auth systems ? We were using cdn's even when we were doing cookie based authentication right ?
This was because script tags can call scripts from other domains any way right ?
CSRF: since you are not relying on cookies, you don't need to protect
against cross site requests (e.g. it would not be possible to
your site, generate a POST request and re-use the existing
authentication cookie because there will be none).
What if someone one from the neighboring tab in the browser(from some other domain) steals your token and starts making
requests ? I cannot understand this either.
Mobile ready: when you start working on a native platform (iOS,
Android, Windows 8, etc.) cookies are not ideal when consuming a
secure API (you have to deal with cookie containers). Adopting a
token-based approach simplifies this a lot.
Did not understand it completely . Can someone explain , how?
The linked article is a bit sloppily written and does not properly define and distinguish between the various concepts.
First, you have to define what exactly you mean by "token based". The article does not do that, but it seems it has OAuth 2.0 JWT access tokens with the Bearer Token Usage (http://self-issued.info/docs/draft-ietf-oauth-v2-bearer.html) in mind. This means that:
Bearer access tokens are used. The upside of bearer tokens (as opposed to MAC token usage) is simplicity of usage -- all a client needs to pass to a server is a token. The downside is that whoever gets hold of such a token is considered its rightful owner, so he can do whatever he wants with it.
Tokens are passed in the Authorization HTTP header, following a specific syntax.
Then you have to define what you really mean by "cookie based" authentication -- which again, the article does not do. A cookie, essentially, is just a transport mechanism to pass data back and forth between client and servers of a specific domain, without the client having to do anything explicitly. So you can really stuff pretty much anything into a cookie -- even OAuth 2 access tokens.
What the author seems to have in mind is server side-managed sessions where a session id is passed in a cookie.
With these definitions in mind, it is possible to answer your questions:
Cross-domain / CORS: cookies + CORS don't play well across different domains. A token-based approach allows you to make AJAX calls to any server, on any domain because you use an HTTP header to transmit the user information.
This is true, but for different reasons: Cookies are scoped to a specific domain, so as long as you use cookies to pass a session id between clients and servers, you are bound to having to put all servers under one domain. This looks like a limitation, but the true limitation is somewhere else -- when using server side-managed sessions, a session id will only make sense to those servers who have access to the server side session management. Any server outside the domain most likely cannot make any sense of a session id.
A JWT access token, however, is self contained and can be interpreted by other parties as well. This is why access tokens are well suited for cross-domain/cross-service calls.
CDN: you can serve all the assets of your app from a CDN (e.g. javascript, HTML, images, etc.), and your server side is just the API.
Yes. But this does not really matter in practice because anyting you put into a CDN will most likely not require authentication in the first place -- so this is kind of a silly argument.
CSRF: since you are not relying on cookies, you don't need to protect against cross site requests (e.g. it would not be possible to your site, generate a POST request and re-use the existing authentication cookie because there will be none).
The danger of cookies w.r.t. CSRF is that they are passed implicitly to the server -- the browser adds a cookie to the request, regardless of whether it was good of rogue code that triggered the request.
When tokens are passed in a cookie, this danger applies to tokens we well. However, when they are passed in a header (as the Bearer Token Usage spec defines), this danger does not exist as the header needs to be added to teh request explicitly, every single time. This makes this approach more CSRF-safe than cookies.
However, when the rogue code can get hold of the token some other way (because it was passed as a URL parameter, for example (which the spec allows), it is still possible to make CSRF attacks with tokens.
Mobile ready: when you start working on a native platform (iOS, Android, Windows 8, etc.) cookies are not ideal when consuming a secure API (you have to deal with cookie containers). Adopting a token-based approach simplifies this a lot.
Dealing with cookie containers is usually easier than setting up OAuth, so I do not buy into this one.
Alright, I'll try to go through these in as structured a way as possible:
CORS + Cookies: Cookies were never meant to travel across domains. A cookie must be submitted to the server from its origin, cross-origin cookies don't exist. There is no need to worry about another application accessing the token if it's stored in localstorage since that one is site-specific, e.g every site gets it own allotted space of localstorage.
I'm not certain about this one. I'd assume they mean an authenticated CDN, e.g you provide a token to get access to the resources
Again, the token won't be stolen by a neighbour, because of how localstorage works. If you're worried you could actually issue a new token from the server with every response, effectively making one-time use tokens. That way, even if your token is compromised, it is far less likely to work.
Cookies are fairly complex structures, and if you one day decide you want to consume your API on a mobile device, it will be much easier to use a token, which is just a string (compared to a structured object)
The most important difference is that tokens are stateless, while cookies are not. Cookies will contain information about the authenticated user and context-specific data. A token, on the other hand, is just a string that an API consumer assumes can be used to access restricted data.

API Token Safety in Angular application

I'm building an Angular app with an API backend. On a combination of pieces of advice, I built the API with a flavor of token authentication. The flow is roughly as follows:
POST to login endpoint with credentials
Validate credentials and authorization, then generate a new token
Return token to client
Client uses token via HTTP Basic to access API resources
This is all working well. The problem arises in creating a session based on this token. I don't believe I should simply hold the token on the client in a cookie, but I do need a session to persist between page refreshes, etc. My Angular app is stateless and completely populated via API calls.
I'm looking for a recommendation as to hanging on to this token on the client. I feel there's danger in holding the token in a cookie because the cookie could be stolen and simply used to authenticate as someone else, but perhaps this is incorrect.
Thanks in advance for your assistance!
The only known way for me to identify a user is to use some token on the client.
HTTP is stateless and can't know which request is coming from which user (browser). You can't identify the user by his ip address (many users are behind a router and share a connection). You could try browser fingerprinting, it can work on some browsers but not on all.
I would recommend using a cookie to store this token on the client.
They are send to the server on every request and you can do some protection to keep them from getting stolen.
To protect this cookie from man in the middle attacks you need to use an encrypted connection over HTTPS to the server.
Set the following attributes on the cookie:
HTTPOnly: cookie can't be accessed by javascript (XSS protection)
Secure: cookie will only be send over https
Path: cookie will only be send on specified path e.g. /login
I would also define an expiration date on the cookie, so the cookie is invalid in like 2 days or something.
But you are right. If this token gets stolen someone else can login as this user.
Since its an Angular app, I'd assume all authenticated methods will only be served to ajax requests (you can tell your server to only respond to ajax) in which case CORS will help you.
The only way to be completely secure is HTTPS, however this method is probably more secure than you think. Read up on CORS a bit for more info, but essentially the idea is that servers will only respond to ajax requests coming from html pages that were served by that same domain.
Pre-flight OPTIONS requests are often sent to verify this. The browser sends an OPTIONS request with an Origin header (the origin of the page) before the actual request. If the origin matches the domain of the server receiving it, the subsequent request is allowed. Otherwise, it violates the Same Origin Policy and will be rejected.
This prevents someone from sniffing out the token and sending a request with the token from a page that your server didn't serve (like something running on the hackers local machine).
If you are doing credit card transactions or anything super secure, you should use HTTPS though.
http://en.wikipedia.org/wiki/Cross-origin_resource_sharing

Authentication security concerns

I am a beginner web-developer and I have some doubts about the security of an API that I developed. It's a simple web-service that requires authentication in order to access/modify data.
I am wondering what are the best practices for authenticating users via HTTP.
Currently my app works like this:
User authenticates through an API request (POST) which requires the username and the password. The response contains info about the user and a TOKEN which will be used in the future for further requests.
My concerns: I don't know if the auth request should be POST. It sounds more like a GET, because POST should create something (at least this is the convention in Ruby on Rails). And then, even with POST or GET, the information is still "visible" during the transfer of the information. I heard something about HTTPS - how does that solves the problem?
The token is generated at user creation time - and remains the same in time. Is this bad? Should the token be generated again after a "logout"? I've seen APIs that use an API_KEY along a token for authentication. How does that work?
I have some GET requests to retrieve information about something. With this request I pass as an parameter the token retrieved from the authentication request. Is this ok? I mean that token is sensitive information.
Where can I find more information about these concerns of mine (book, article, w/e)?
HTTPs encrypts all traffic to your web site, and so would hide any get and post requests. It requires you to purchase an HTTPS certificate (which are cheap), and get a non-shared IP to host on (not so cheap). (If anyone talks about self signed certificates - well, it's possible, but ill advised if external people want to talk to your service).
Having a long lasting login token can be bad, it depends what sort of non-repudiation you want. If someone can log in 2 years ago, and continue using a token how do you know it's still the original requestor? Tokens should expire and have a way to re-request.
API keys generally work on a shared secret which is swapped out of band (by getting it from the hoster's web site generally). A custom authentication scheme and header is used, and must be calculated and checked for each request. This doesn't require HTTPS - the shared secret is used to generate the authentication header, but isn't sent with it, so the secret doesn't travel with each request. Of course you need to write this code, and figure out what you want the process to be. I'd generally avoid this unless you know what you're doing - you need to take a canonical representation of the request, sign it, then use that as the header. It's not complicated, but it's not simple either.
The problem with GET is more one of physical security than web security - I know that I log into sites regularly at work or at home in the company of others - I certainly don't want my credentials appended to the URL as a query string.
Using HTTPS (SSL) will secure your postdata as the information is encrypted before it is sent over the line. The encryption algortihm uses some quite clever maths in generating its decryption tokens to ensure that it's not susceptible to a man-in-the-middle attack.

REST GET requests, verbs and apikey

I want to create a flexible API Rest server. I will allow the clients to authenticate using HTTP or an APIKEY.
My question is: what is the correct way to add the apikey to a GET request? My problem is the apikey pollutes the url.
I imagine something like this : /book/1/apikey/s4cr4t !
In my opinion you should only use the Authorization header. That's what it is there for.
Putting it in the URL is a bad idea because:
a) as you said it pollutes the URL
b) if you decide to go SSL for security then the API will still appear in log files
c) caches will end up creating multiple copies of the same representation, one for each api key.
For more information on creating your own Authorization scheme go here.
Credentials may be passed using the Authorization header:
GET http://domain.com:/book/1
Authorization: apikey="s4cr4t"
It all depends on how far you want to go but the mechanics stays the same:
Context
The goal is to identify the client with some level of security. (Note: Security is another detailed discussion). Remember that one if the “features” of REST is to be stateless: That means no session state on the server except for resources. To keep the client stateless, it needs to supply on each request enough information that the request is independent. It must give the server a way to identify the client such as a username/password, API Key or token.
You have various options to do this so here are some:
Add HTTP headers to identify the client
Here one can use the Authorization header and send it with each request. There are various authentication schemes but stick to the standard ones such as Basic Auth. Here you would probably stick to SSL. The authentication process generates a kind of token if you like.
You can also make use of a cookie. The cookie must contain no information except that it is a “pointer or key” to a stateful session resource on your server (note: session it a resource which is “rest-legal”). You can create this resource by doing a PUT (+info) with response 200 OK or POST (+info) with a response of 201 Created and Location: /sessions/123334. The session can then be validated by the server such as timeout, valid client ip address, api key etc.
With the method above, you can also define a customer header such as Api-Key: XXXX. But then you limit yourself to special client. Set-Cookie are “well known” headers so browser will handle them kind of transparently. The authentication process can then be done by following links and filling in forms (PUT + POST) to authenticate (create session resource).
Encode an identifier in the content
Here you are free to do what you want too. Just add a field/token/id to your content and let the server verify it.
A RESTful API does application flow by resolving links. See also HATEOAS and Fielding's words. This also applies when you have a separate process of logging in to the application.
Do not encode any data in the URIs. (Out of band information)

REST and authentication variants

I am currently working on a REST library for .net, and I would like to hear some opinions about an open point I have: REST and authentication.
Here is an example of an RESTful interface used with the library:
[RestRoot("/user")]
public interface IUserInterface
{
[RestPut("/")]
void Add(User user);
[RestGet("/")]
int[] List();
[RestGet("/get/{id}")]
User Get(int id);
[RestDelete("/delete/{id}")]
void Delete(int id);
}
The server code then just implements the interface and the clients can obtain the same interface through a factory. Or if the client is not using the library a standard HTTP request also works.
I know that there are the major ways of either using HTTP Basic Auth or sending a token to requests requiring authenticated users.
The first method (HTTP Basic Auth), has the following issues (partly web browser specific):
The password is transmitted with every request - even with SSL this has some kind of "bad feeling".
Since the password is transmitted with a request header, it would be easy for an local attacker to look at the transmitted headers to gain the password.
The password is available in the browsers memory.
No standard way to expire user "sessions".
Login with a browser interrupts the look and feel of a page.
The issues for the second method are more focused on implementation and library use:
Each request URI which needs authentication must have a parameter for the token, which is just very repetitive.
There is a lot more code to write if each method implementation needs to check if a token is valid.
The interface will become less specific e.g. [RestGet("/get/{id}")] vs. [RestGet("/get/{id}/{token}")].
Where to put the token: at the end of the URI? after the root? somewhere else?
My idea was to pass the token as parameter to the URL like http:/server/user/get/1234?token=token_id.
Another possibility would be to send the parameter as an HTTP header, but this would complicate usage with plain HTTP clients I guess.
The token would get passed back to the client as a custom HTTP header ("X-Session-Id") on each request.
This then could be completely abstracted from the interface, and any implementation needing authentication could just ask which user the token (if given) belongs to.
Do you think this would violate REST too much or do you have any better ideas?
I tend to believe that authentication details belong in the header, not the URI. If you rely on a token being placed on the URI, then every URI in your application will need to be encoded to include the token. It would also negatively impact caching. Resources with a token that is constantly changing will no longer be able to be cached. Resource related information belongs in the URI, not application related data such as credentials.
It seems you must be targeting web browsers as a client? If so you could investigate using HTTP Digest access authentication or issuing clients their own SSL certificates to uniquely identify and authenticate them. Also, I don't think that session cookies are necessarily a bad thing. Especially when having to deal with a browser. As long as you isolate the cookie handling code and make the rest of the application not rely on it you would be fine. The key is only store the user's identity in the session, nothing else. Do not abuse server side session state.
If you are targeting clients other than the browser then there are a number of approaches you can take. I've had luck with using Amazon's S3 Authentication mechanism.
This is all very subjective of course. Purity and following REST to the letter can sometimes be impractical. As long as you minimize and isolate such behavior, the core of your application can still be RESTful. I highly recommend RESTful Web Services as a great source of REST information and approaches.
I agree with workmad3, if session life time needs to be maintained you should create a session resource. Post on that resource with user credentials (either basic authentication or credentials in the body content) will return unique session id. Delete on /session/{id} will log out the user.
If you want to control the session expiry time. When creating new session (post on session resource) the server will set a cookie on the response (using standard set-cookie header).
The cookie will contain expiry time. The cookie string should be encrypted on the server, so only the server can open that cookie.
Every consequent request to the server will send the session cookie in the cookie header. (it will be done automatically for you if your client is a browser). The server needs to "renew" the cookie for every request, i.e. create new cookie with new expiry time (extend session's timeout).
Remember to clear the cookie when the user calls delete on the session resource.
If you want your application to be more secured you can store the client IP in the cookie itself, so when a request arrives the server can validate that it was sent from the "original" client. But remember that this solution can be problematic when proxies are involved, because the server might "see" all the requests as coming from the same client.
The rest authentication I've seen treats the sessions as a REST resource for creation, destruction etc. and then the session ID is passed to and fro. The ones I've seen tend to use the session cookie for this as it's the only way to secure it really. If you pass the session id in the URL, you don't have any way of really authenticating it came from the correct client.
Authentication is a tricky problem with REST though, as it requires some form of state to be kept outside the URL which infringes upon REST principles of the URL being all that is required to represent state.