I'm trying to use the Hapi's plugin Crumb to implement a solution againts CSRF attacks, but seems that I didn't get the solution flow.
I could simply set a token in each http response as a cookie. And here comes the question, how REST can validate CSRF token, if token issued by client? How REST backend understand what this random string is valid for this request and another random string is not?
It's not possible to generate CSRF token on the client. It should be send from server to client first, and some JS frameworks extract it automatically from the cookie and send it to the server.
The basic idea is that user is supposed to send token along with a cookie and also in the post data. Here is a simple example. If attacker will trick a user to send a particular request to a service, for instance malicious website can have an image with this link src="gmail.com/deleteaccount=true". If user is logged in to gmail. Gmail will think that it was a user who made the request, because cookie send along with request is valid. So, in order to make sure that it was actually a user, gmail also requires a token send with a request data: so instead of gmail.com/deleteaccount=true it needs gmail.com/deleteaccount=true&token=987y23459827345sdfg. Token have to match the one stored in the cookie. So when request is received by a server, it checks if token in the cookie equals to token in the request body. Attacker have no access to user's cookies and don't know the token.
Here is the simplified data flow:
In more details it looks like this:
1) User sends GET request to a server
2) Server sets the cookie with
sessionid, and saving session data with the token
3) server returns HTML with a form containing token in a hidden field.
4) User submits
form, along with a hidden field
5) server compares token from the
submitted form (hidden field) with the token saved in the session storage. If they match, it means that form is submitted by a user.
Here is another grate answer: Why is it common to put CSRF prevention tokens in cookies?
Related
OAuth2(PKCE flow)
A client app makes a call to /authorize endpoint of the authorization server with code_challenge and code_challenge_method. Both code_challenge and code_challenge_method are required in the subsequent requests of the authorization server along with user credentials to generate the authorization code.
I can think of 2 options for how to store code_challenge and code_challenge_method to use in the subsequent calls:
persist the code_challenge and code_challenge_method before redirecting to the login page or user consent page
pass the code_challenge and code_challenge_method to the login page in query parameters, those then will be submitted along with the credentials
As RFC does not talk about this much, which option is better and why, or are there any other options? Please suggest.
Also, are there any best design practices about authorization server endpoints(except /authorize and /token) implementations in OAuth2(PKCE flow)?
According to Add Login Using the Authorization Code Flow with PKCE
There are 2 codes when doing PKCE :
Code verifier, the random string
Code challenger, the hashed string from the code verifier, and his hash method, the code_challenge_method
In the Oauth2 authorization_code flow, a client needs 2 tokens:
authorization token, to request accessToken
accessToken, to access resources
To get the authorization token with PKCE, a client app will have to pass the code challenger & method in the URL parameter, then the user is redirected to login page.
After login, the authorization server redirect user back to the client app, with authorization token in url parameters.
Finally the client app request access token with authorization token, code verifier, client id, and all other parameters.
When the ressources server receive the request for access token, it has to "remember" which code challenge to use to test with the code verifier.
Suppose there are 1000 users authorizing in the same time, there will be 1000 authorizations & code challengers per app client id.
The authorization server should accurately find the right user (authorization & code challenge) along the 1000 users to verify the code & generate access code.
I think this answers your question, storing code challenge after user login, which means pass it to login page (but encrypted, because there is a code challenge methode named plain...)
I don't see how we can link the user & code challenge when the authorization server first receive the authorization request.
RFC 7636 Section 4.4 states (emphasis mine):
Typically, the "code_challenge" and "code_challenge_method" values
are stored in encrypted form in the "code" itself but could
alternatively be stored on the server associated with the code. The
server MUST NOT include the "code_challenge" value in client requests
in a form that other entities can extract.
This rules out your option 2, as the challenge would be available in plain text to the user agent. It does however specify another option to encode this information into the code value, but it seems like this is not what you're looking for.
You're looking for a way to store the challenge while redirecting the user to the login page, before generating the code. In this case you could store the challenge in an encrypted httpOnly cookie in order to maintain a stateless design. A successful login would redirect the user agent back to your /authorize endpoint where you can extract the cookie again and generate the authorization response.
After having developed my first web portal (using railstutorial.org), I'm now making my way in building my first API (with some help).
Authentication for the web portal works with session as well as with a cookie (if the user wants his log in to be remembered).
For the API I understand that using session is insecure; you need to work only with a token. So, just as for the web portal, when a user logs into the API his credentials get checked, and if they are valid a token is generated of which the digest is stored to the database.
But then: I understand there are then three options what to do with the token: to store the token on the user's computer using a cookie, include the token as parameter or use the HTTP header. I read for APIs using the HTTP header is the preferred option.
If using the cookie, it is the same as the 'remember me' option for the web portal: the token is stored in the cookie and a digest of the token is stored in the database. With each API request the cookie is read and it is checked if it's token matches the digest.
Each time the API sends data to the user or the user makes a call to the API, the token is included as a parameter. I understand that this displays the token in the URL, which is not desirable.
My understanding of using the HTTP header fails.
What does it mean to use the HTTP header to send the token, instead of a cookie? What is the process/logic behind it? When to use a cookie, a parameter or the HTTP header?
Am I correct in my understanding that each time the API sends data to the user, it should include the token in the HTTP header? And each call the user makes to the API should include that same token?
I think this link is a good place to start : http://devcenter.kinvey.com/rest/guides/security
Also, reading up on some documentation of HttpAuthentication::Token should give you a basic overview of how/when you should utilize it.
http://api.rubyonrails.org/classes/ActionController/HttpAuthentication/Token.html
You should look into how a cookie works. Setting a cookie is also sending a standardized http header to the client. When client sends a request, they can send cookie along with the request.
There is also a standard for http token in rails: Link Which is also setting a specific header in the request
I am learning about Token-based authentication with JSON Web Tokens and here is how I see it now for a mobile app, built with, e.g. Swift:
I can create an object inside the app using user input, like
{
username: "patrickbateman",
password: "ismyknifesharp",
role: "regular",
...
}
Then I can generate a JWT token from it with a library.
Then I send it to a supported API endpoint, like /api/contacts/list. Or do I have to send login/password as they are to authenticate?
Server somehow checks the token correctness. But how? Should this server-generated token be saved in the database and used as a key? Or do I have to generate the token on server each time I get a request from client and compare it to client token?
Get and manage all the data I need.
Here are my conclusions:
I don't need to send login/password pair to server to authenticate the user.
I need to send token each time I need to get auth-only data.
I should implement some algorithm that changes the generated token due to some factors, like time passing, so that to make tokens expirable.
I should send the token inside headers, but not necessarily, as it can be done inside the body of the JSON requests.
Are these conclusions correct? What's the way to check token that client sends?
My opinions:
We should not keep password of user on client. Client should post password to server when sign up/ sign in, and don't save it anywhere in client. Request should be https, and password should not be encrypted. We will encrypt password later at server side.
Server will generate a token for this user after user login successfully. The token will contain the expired date in itself. We will use the token to authenticate permission with server.
I think every request to API should provide the token, except the sign up / sign in/ forgot password requests.
Token should be put inside the header of request.
Server should allow client request a new token with the old token (maybe be expired)
And the answer for "How to server check the token from client?". There are many ways to do that. The way below is my current approach:
Server side generate a token, which is a encrypted string of a user info (such as token expired time, userid, role... of user) and a password (keep only on server side) with HMAC or RSA algorithms. When user submit a token, server can decrypt and get the user info, expired time without querying from database.
Anyway, this question does not relate with Swift tag.
I'm writing a REST API server(using Rails), and here is a question about session management.
I think for a REST API server, we don't need to save the log in state(or session) for each user. So I just add an authentication token for each user. If they log in, this server will return this token to them, and if log out, destroy it.
And I'm wondering if it's necessary to authenticate this token destroy action? There might be a malicious user who iterate all possible tokens(maybe!) and wrap them in a DELETE request to my server...
Thanks a lot!
One of the aspects of restful web services is statelessness as described in the Wikipedia article.
The client–server communication is further constrained by no client context being stored on the server between requests. Each request from any client contains all the information necessary to service the request, and session state is held in the client.
The server should not contain any information about sessions, that means, that the authentication information must be contained in each request and no login or logout methods are needed.
Best practice would be providing a resource (like some OAuth2 implementations), that returns a token with a special scope and an expiration time. At the creating process, the token should be stored in the database of the backend. After the token expires, the information must be deleted from the database and the client has to obtain a new copy of the token.
UPDATE:
#Ekkehard, that's exactly what I meant with my comment. Instead of using ‚stateful' http sessions with a session id, cookies and a session timeout, the token should be provided by an additional resource.
[...] no client context being stored on the server between requests.
If the client wants to access special services of the backend, it had to send a POST request to the token resource (where the backend stores the new token with a special expiration time in the database).
In the POST request, the client could also provide an additional query parameter scope, to create a token, that only allows you to access special parts of your backend (Google for example provides many different APIs like Google Drive, Google Mail, etc. and if the client is a mail application only access to Google Mail is necessary. It’s an additional security feature.).
The response returns the token and the client had to add this token in the header of each request to other resources.
Each request from any client contains all the information necessary to service the request, and session state is held in the client.
The tokens will be verified from the backend based on the information stored in the database.
Token resources could also provide a DELETE http method, to allow the user to delete existing tokens before the end of the expiration time. After the expiration timeout, the tokens will be automatically deleted from the database of the backend.
You can use authentication token for API. Concept is simple if your username and password matched you just create a token and send to user.
You need to set a expiration time for this token.
After expiration time or when API request for destroy you just delete this token.
Token must be send with each request.
In this approach you don't need any session.
RESTful applications must be stateless and the security tokens need to be sent within each request using the header Authorization. Such security tokens are gotten from an authorization server using credentials or using OAuth2 authentication flow (see this link for more details http://www.bubblecode.net/en/2013/03/10/understanding-oauth2/). Such tokens have expiration dates or can be invalidated from this server.
This link could also you give more hints about the way to use tokens within RESTful applications:
Implementing authentication with tokens for RESTful applications: https://templth.wordpress.com/2015/01/05/implementing-authentication-with-tokens-for-restful-applications/
Hope it helps you,
Thierry
If someone knows your token then they can use it to authenticate as you. In other words, by sending the token in to delete, you are authenticating yourself. No additional credentials beyond the token should be needed in a DELETE action.
There are simply too many possible tokens to iterate over for this to be a plausible attack. The attack you are worrying about is not unique to DELETE. If a user could iterate over all tokens then they would be able to impersonate any user for any action.
Simple answer is: YES, you need to authenticate this token destroy action
Here is three things:
If username and password matches user get a token. You need to set a expiration time for this token.
User must have to send token in each request. So, no session in server side is necessary.
If user want to logout, destroy the token from client side, and reset token in server side. And also authenticate this token destroy action
Note: destroy the token after expiration time.
Another Note: Devise gem reset the remember_token, when we logout from web UI.
I am by no means an oauth2 expert and am open to suggestions.Ok, I have setup an Oauth2 server and I am having a problem deciding on the flow when registering a new user from an application.
The user registration form sits on the client and not on the oauth2 server.
1.user goes to example.com/register
2.user fills in the form and clicks send
3.I send a request to my oauth 2 server with the client_credentials grant and scope to receive an token on behalf of the client/app.
I send a request to POST /users/register with the form values using the token from the previous request.
If registration has failed I list the validation rules in a json array.
6.If registration was successful i use the scope originally used to generate the new access token for the user.This is then returned.The user is also flagged as inactive in the db.
7.I have to activate the user somehow and send a request to GET /users/activate using my user token ftom the previous requst.
My question is,does this flow sound right and what should i send as the link in for the activation email?
Your response would be appreciated.
After point 6. When new user is created, back-end should create some unique string or code or (token or hash) which is used to activate the user. Then in email could be like link with /users/activate/(token or hash) after the URL (as pathparameter). Now when the user clicks it, it makes GET request to your endpoint with the unique hash or token and now the back-end can identify the hash or token and activate the user whom the unique hash or token belongs to. So the token or hash is one-to-one relation with user and can be used only once, when it is used it is deleted from DB.