Switch auth from header/local storage to cookie
Due to security concerns (#2299) we should consider switching our authentication scheme to cookies.
Requirements:
- User needs to know when and as whom it is logged in
- User needs to be able to login
- User needs to be able to logout
- User want only to login once on site with multiple embeds
- Developer want the setup to work on local machines (ideally w/o nginx)
- Administrators want a migration path for existing installations
- Attackers should not be able to get a valid session through XSS-Attacks
- Attackers should not be able to do CSRF (via XSS or forms)
- Attackers should not be able to do requests with users session from other origins
- User wants t o reloggin when the session expires or is invalid (due to new authentication scheme) (currently we have a quite technical error message)
Steps:
- [ ] Unify frontend and backend server (R5)
- [ ] Adopt production nginx and varnish setup to that change (R6)
- [ ] Extend backend to not allow
PostwithContent-Typeother thanapplication/json(R8) - [ ] Drop CORS headers everywhere (R9)
- [ ] Provide
/api/logouton the backend (R3)- deletes session on server
- deletes cookie
- [ ] Provide
/api/sessionon the backend (R2)- provides info about current user path
- [ ] Extend
/api/login_usernameand/api/login_emailto set cookie (R1)- ensure
same-siteandhttp-onlyis set - use domain from
Hostheader and location/
- ensure
- [ ] Enable cookie based auth in api rest view
- set secure flag if
X-Forwarded-ProtoisHTTPSorHostheader starts withhttps://
- set secure flag if
- [ ] Extend
/api/login_usernameand/api/login_emailto setcsfr-tokencookie (R8)- set secure flag as described with auth cookie
- use domain from
Hostheader and location/ - maybe use pyramid to generate csrf value
- [ ] Rewrite
AdhCredentialsService(R1/R2/R4)- get user path by using api defined above
- remove deleteToken, storeAndEnableToken (add login and logout function instead)
- stop setting X-User-token
- extend login and logout to store/delete current userpath in local store (R4)
- add api to listen on changes of that user path (R4) and use it in AdhPermission
- once logged in enable angular csrf feature and disable on logout
- [ ] Change production varnish config (R6)
- stop deleting cookies
- do cache splitting based on user cookie
- [ ] Remove session from response of
/api/login_usernameand `/api/login_email- disable header based auth in api rest view
- [ ] Check (in api rest view) that a csfr token is provided as
Csfr-Tokenheader- applies to POST, PUT, PATCH, DELETE
- maybe pyramid has us covered
- we need an exception for POSTs/PUTs that do not require login (BPlan)
- we might also want to enable it for GET (and maybe HEAD) of protected resources (private process, user)
- [ ] handle session timout in the frontent (R10)
- [ ] Roll out for fun an profit
@liqd/write-access-adhocracy-3 Please leave comments and so we can extend the sections as needed.
I don't feel well without CSRF protection. There are plenty of different possiblities for this attack and I don't know if we really consider everything.
Okay than but how does CSRF protection works on a RestAPI?
I only did a short research but the more secure solutions i found have "double" authentication. Normal cooky auth and a csrf token send with HTTP-header (stored in local storage or cooky)
Examples: http://de.slideshare.net/robertjd/jwt-authentication-with-angularjs https://docs.djangoproject.com/en/dev/ref/csrf/#ajax
I worked with the csrf-token solution in django (rest framework) and angular in the frontedn and it worked fine
cool
Okay thanks for the feedback, I added CSRF to the ticket.
added "handle session timout in the frontend (R10)"
You suggest use one endpoint for token and cooky based authentication. To simplify documentation/implementation if would prefere one dedicated endpoint for each authentication method.
Also the difference between email and login name login does not make much sense from the client point of view. The backend could support both without much effort.
Befor we refactor authentication we should think about using "standard" architectures like Oauth2 (revoke + access token), we need to deal with this anyway. Here is an example with Oauth2, JWT, cookies http://de.slideshare.net/robertjd/jwt-authentication-with-angularjs . Benefits for the SinglePageApplication use case:
- same session management for token and cooky authentication
- no data base acess to check acess token
- access token can be renewed automatically We could also consider using an exiting angular module for authentication to simplify frontend code.