Should I validate access permissions each request? - security

I've always wondered whether it's better to check the database for account access permissions every single request, or cache (say, an ACL) in the session state.
My current case isn't particularly mission-critical, but I feel it would be annoying to have to logout and log back in to refresh cached credentials. I've also considered using a temporary data store, with a TTL. Seems like it might be the best of both.

Security wise, it is better to check the DB every time for permissions. The security vulnerability comes in that if the user's permission are reduced after the session is created, they could potentially still be achieving a higher level of access than they should.
There are a few things you can do to stay secure without performing a full query, provided you're early enough in the development cycle. If you have role-based access control (RBAC), you can store a fast lookup table that contains a user's role. If the user's role changes during the session, you mark the permissions "dirty" in the lookup table, causing a querying of the DB for the new role. As long as the user's role stays the same, there's no need to query the DB. The lookup table then, is basically just a flag that you can set on the backend if the user's role changes. This same technique can be used even with individual access controls, provided the granularity is not too fine. If it is, it starts to become a bloat on your server. We use this technique at work to speed up transactions.
If you are late in the development cycle or if you value simplicity more than performance (simple is usually more secure), then I would query the DB every time unless the load gets too heavy for the DB.

Related

Caching user permissions in redis, good idea?

For last few days I am working on improving app performance. What do you think about caching user data and permission in redis? In my case every time when user create post or try to upload file app check in database, if user exist and fetch user permission and role. My first idea was to put permission and user role in session but user can have multiple session on different device, so every time when user get ban or user permission change app need to update every user's session and as far as I know express-session do not support this kind of feature.
Unfortunately it's a very open question with no strict answer. But as an advice, I'd say Redis is perfect for storing user session altogether. Moving parts of the session would still require you to query the database (you get the session, you must query for user information, and also ping Redis for permissions & roles). So I think you should put all session data in one place, and the fastest would be Redis. It would also let you save that data so it's not entirely in the memory. There are also many ways to optimize it, like when to write the data (like every second) and so forth.
Querying Redis is extremely fast and efficient since you don't have any user to user relations, and most of the times you won't search on anything different than "get me that user session by id".
It's a very standard solution to put user session in Redis, if not the most often used one :) Good luck!

OWIN with Identity 2 - avoid regularly hitting the database for common objects

I have just taken the plunge and started to learn the OWIN style of authorizing users into MVC applications. One issue I'm having is storing objects since the move away from session objects and into claims.
Traditionally what I would do is authenticate the user, and then store the User object in the session. This is useful when you are regularly using the data from that object all over the application.
Now that I have moved to OWIN with Identity, I instead store the UserId as a claim. I understand that the use of complex objects is best avoided with claims.
So I find that I'm regularly having to hit the database to read User information based on the UserId.
Here is how I am reading the UserId claim:
List<Claim> claims = HttpContext.Current.GetOwinContext().Authentication.User.Claims.ToList();
var ret = claims.FirstOrDefault(x => x.Type == StaffClaims.OrganisationId);
Is there a way that I can avoid taking this ID and reading the corresponding record from the DB each time? I want to achieve something like having the User object stored in memory somewhere.
Alternatively, does Entity Framework 6 allow caching so that I don't hit the database when repeating the same query (unless I know it has changed and should be re-read)?
First, storing the user object in the session is a hugely bad idea. Don't do that ever.
Second, you don't need to store the user id in a claim; you can get it anytime with User.Identity.GetUserId().
Third, Entity Framework does utilize caching, but not in a way I'd consider it as something you could rely on. If you want to cache something, then do it explicitly with System.Runtime.Caching. You can also utilize the OutputCache attribute on actions to cache the rendered view, which has the side effect of not requiring database calls to render it again.
Finally, this is not a big deal in the first place. Just fetch the user when you need it. Before you worry about this one simple query, there's probably 10,000 other areas of your application and could and should be optimized first.

Is this safe for client side code?

I'm writing a GWT application where users login and interact with their profile. I understand that each form entry needs to be validated on the server, however, I am unsure about potential security issues once the user has logged in.
Let me explain. My application (the relevant parts) works as follows:
1 - user enters email/pass
2 - this info is sent back to the server, a DB is queried, passwords are checked (which are salted and hashed)
3. if the passwords match the profile associated w/ the email, this is considered success
Now I am unsure whether or not it is safe to pass the profile ID back to the client, which would then be used to query the DB for information relevant to the user to be displayed on the profile page.
Is there a possibility for a potential user to manually provide this profile ID and load a profile that way? My concern is that somebody w/ bad intentions could, if they knew the format of the profile ID, load an arbitrary amount of information from my DB without providing credentials.
-Nick
What you are dealing with here is a session management issue. Ideally, you want a way to keep track of logged in users (using random values as the session key), know how long they have been idle, be able to extend sessions as the user is using the site, and expire sessions.
Simply passing the profile ID to the client, and relying on it to send it back for each request is not sufficient - you are correct with your concern.
You want to keep a list of sessions with expiration times in a database. Every time an action is executed that needs user permissions (which should be pretty much everything), check to see if the session is still valid, if it is, extend it by however long you want. If it is expired, kill the session completely and log the user out.
You can store your session keys in a cookie (you have to trust the client at some point), but make sure they are non-deterministic and have a very large keyspace so it cannot be brute forced to get a valid session.
Since you're logging a user in, you must be using a backend that supports sessions (PHP, .Net, JAVA, etc), as Stefan H. said. That means that you shouldn't keep any ids on your client side, since a simple id substitution might grant me full access to another user's account (depending on what functionality you expose on your client, of course).
Any server request to get sensitive info (or for any admin actions) for the logged in user should look something like getMyCreditCard(), setMyCreditCard(), etc (note that no unique ids are passed in).
Is there a possibility for a potential user to manually provide this profile ID and load a profile that way? My concern is that somebody w/ bad intentions could, if they knew the format of the profile ID, load an arbitrary amount of information from my DB without providing credentials.
Stefan H is correct that you can solve this via session management if your session keys are unguessable and unfixable.
Another way to solve it is to use crypto-primitives to prevent tampering with the ID.
For example, you can store a private key on your server and use it to sign the profile ID. On subsequent requests, your server can trust the profile ID if it passes the signature check.
Rule 1 - Avoid cooking up your own security solution and use existing tested approaches.
Rule 2 - If your server side is java then you should be thinking along the lines of jsessionid. Spring Security will give you a good starting point to manage session ids with additional security features. There will be similar existing frameworks across php too (i did not see server side language tags in the question).
Rule 3 - With GWT you come across javascript based security issues with Google Team documents and suggests XSRF and XSS security prevention steps. Reference - https://developers.google.com/web-toolkit/articles/security_for_gwt_applications

Should Domain Entities always be loaded in their entirety?

I have a custom ASP.NET Membership Provider that I am trying to add password history functionality to. User's passwords expire after X days. Then they have to change their password to one that has not been used in their past X changes.
I already had the User entity, which has a password attribute for their current password. This maps to the User table in the db. Since I needed a list of previous passwords I created a UserPassword table to store this information with a FK reference to the UserId.
Since passwords are value objects, and have no meaning outside of the user, they belong inside the User aggregate, with the User as the root. But here in lies my dilemma. When I retrieve a User from the repository do I always have to get all of their previously used passwords? 99% of the time I don't care about their old passwords, so retrieving them each time I need a User entity seems like a dumb thing to do for db performance. I can't use lazy loading because the User entity is disconnected from the context.
I was thinking of creating a PasswordHistory entity but for the reason stated above, passwords aren't really entities.
How would you DDD experts out there handle this situation?
Thanks.
Edit 1: After considering this some more, I realized this is essentially a question about Lazy Loading. More specifically, how do you handle lazy-loading in a disconnected entity?
Edit 2: I am using LINQ to SQL. The entities are completely detached from the context using this from CodePlex.
It is hard to fully answer this question because you do not specify a platform, so I cannot be exactly sure what you even mean by "disconnected". With Hibernate "disconnected" means you have an object in a valid session but the database connection is not currently open. That is trivial, you simply reconnect and lazy load. The more complicated situation is where you have an object which is "detached" i.e no longer associated with an active session at all and in that case you cannot simply reconnect, you have to either get a new object or attach the one you have to an active session.
Either way, even in the more complicated scenarios, there is still not a whole lot to lazy loading strategies because the requirements are so inflexible: You have to be "connected" to load anything, lazy or otherwise. Period. I will assume "disconnected" means the same thing as detached. Your strategy comes down to two basic scenarios: is this a situation where you probably need to just reconnect/attach on the fly to lazy load, or is it a scenario where you want to make a decision to sometimes conditionally load additional objects before you disconnect in the first place?
Sometimes you may in fact need to code for both possibilities.
In your case you also have to be connected not only to lazy load the old passwords but to update the User object in the first place. Also since this is ASP.NET you might be using session per request, in which case your option is now basically down to only one - conditionally lazy load before your disconnect and that is about it.
The most common scenario would be a person logs in and the system determines they are required to change their password, and asks them to do so before proceeding. In that case you might as well just take care of it immediately after login and keep the User connected. But you are probably using session per request, so what you could do is in the first request process the time limit and if it is expired, you are still connected here so go ahead and return a fully loaded User (assuming you are using the historic passwords in some kind of client side script validation). Then on the submit trip you could reattach or just get a new User instance and update that.
Then there is always the possibility you also have to provide them with the option to change their password at any time. They are already logged in. Does not matter much here, you have a User but the request ended long ago and it does not have passwords loaded. Here, I would probably just write a service method where when they invoke a change password function the service gets a second copy of the User object with the full history for update purposes only, then updates the password, and then discards that object without ever even using it for session or authentication purposes. Or if you are using Session per request you have to do the equivalent - get a fully initialized object for client side validation purposes, then when the data is submitted you can either reattach either one you already have or just get yet a third instance to actually do the update.
If the password is needed after beginning an authenticated session, you could still do the same things and either replace the local User or update the local User's in memory password version as well.
If you have too much stuff going on with multiple levels of authentication most likely you are going to have to require them to logoff and do a full log back in after a password change anyway, so the state of the User does not matter much once they request a password change.
In any case if you are using session per request and your objects become fully detached after every request, in the first scenario you can still lazy load while you are on the server on the original request to return data for client side validation. In the second scenario you have to make another trip (there really is no such thing as lazy loading here). In both case though you have to weigh your two update options because you are always disconnected before an update. You can either just get a second instance from the database on the submit trip to update, or you can reattach the one you already have. It depends on what is optimal/easiest - does saving a db round trip for an uncommon event really matter? Does reattaching using your ORM of choice possibly hit the database again anyway? I would probably not bother to reattach and instead just get a new instance for the actual update as I needed it.

CouchDB - prevent unauthorized reads

CouchDB has a mechanism in place to prevent unauthorized writes.
Can it also prevent unauthorized reads?
Yes, CouchDB can prevent unauthorized reads. Unfortunately, it is slightly less straightforward.
Imagine a secret auction application. You bid $20 and I bid $10; each bid in a couch document. Couch lets us read our own bid documents but no others. However, there is a map-reduce view showing the average. I load the view and see that the average is $15, so I conclude that your bid is $20 and I have broken the security policy. View output can leak some or all of a document's information. It is not feasible to enforce security at the document level. That is why read access is at the database level.
I know, it sucks. But that is the only correct, scalable answer.
This is part of the reason the Couch philosophy is to create many databases—even one (or more!) per user. Read permission to a database is set in the readers value of the database _security object. (Note, the field readers was renamed to members in CouchDB trunk because it also specifies who may write to the DB.)
The technique works like this:
Create a database for each user. It will hold all documents the user may read. Add the user (or the user's role) to the _security object.
In the master database, create a filter function which implements the read policy. (It could share code with validate_doc_update.)
Replicate from the master database to the user's database with ?filter=my_filter_function.
Allow the user to load (or replicate from) their database.
Of course, this is all for a pure Couch application, where users access Couch directly. If you have a middle layer (MVC controller, or just a reverse HTTP proxy), then you can enforce policy there, between the user and the couch. But be careful. For example, a _show function or a _rewrite rule might allow a user to load a view or document despite your policy.
Good luck!

Resources