Secure your web api actions from authenticated users - security

I have this scenario:
1 User - N Project
1 Project - N Task
1 Project - N Comment
When a user is authenticated he can do:
/api/tasks/1
to delete his task but when he is doing /api/tasks/2 he deletes the task of someone else
/api/comments/1
to get his comment but when he is doing /api/comments/2 he reads the task of someone else
How can I intercept the user action (manipulating the URI) and check in a general way wether the user is allowed to delete this Task.
The Task and Comment does not know anything about a userId so how can forbide the user to delete other peoples data?
I am not talking about user and roles scenario.
I am talking about manipulating the URI to delete ressources belonging to someone else.
UPDATE to answer #A Khudairy`s question
1) email + password is sent to api.
2) Api returns user with user token.
3) Then with every request the token is sent to api,( so that Iknow which user is doing what and handle this in backend.)

well I wouldn't personally solve this using the URI (I don't think there is a secure way to achieve that). I will implement a custom authorization filter Check this link for help on how to do that if you are not familiar with it.
In the filter I would use the token to get the user id, and use the route data to see what procedure is the user trying to do (and id of task or comment), then make decision if the user can continue based on that.
Filters can be registered then on top of controller class, or just on some action methods, or from global.asax to all actions if required.

Sounds to me like you are either going to have to add the UserId to the Comment and Task entities so that you can check easily or you are going to need to ensure that the Task or Comment belongs to a project that the user has access too?
Unless I am misunderstanding your question?
If the Task or Comment does not have a UserId, how are you going to distinguish between your own comments and tasks and someone elses?

Related

How to use multiple #PreAuthorize?

I have an API which need to be authorized before running.
So, the allowed roles and authorities here is:
1. hasRole('ADMIN') + hasAuthority('Edit_Post')
2. hasRole('USER') + hasAuthority('Manage_Post')
3. author of the post
So, the user needs to be either ADMIN and has editpost authority, or need to be user with manage_post right, or author of the post to edit post.
I know #PreAuthorize can manage to do with multiple role by using hasAnyRole, but it doesn't work as I expected in this one. I know how to do each of these separately, but combining them together is an issue.
I thought about use #PreAuthorize('hasAnyRole') and check for Authority in the backend block, but it would be the best if I have a way to deal with #PreAuthorize.
How should I do this. Thank you

How can I protect a express route without authentication?

I'm trying to implement a GET method with Express in my nodeJs application.
I'd like to do something like this in order to display user data :
router.get("/user/:idUser", (req, res) => {
The user doesn't need to be authenticated in order to execute this code. However I don't want that anybody can execute this request with a user id of someone else. Because he could see data he's not supposed to see.
How could I proceed ? I thought about using some encryption process to have something like :
/user/PdfgdfJFDGTfrfgdsf
Your question isn't really making sense. You don't want authentication, but you only want a user to be able to view their own data so nobody else can view it.
The ONLY way to solve that is by using some form of authentication. The user has to prove to the server that they are allowed to view that data before the user renders the page for them.
Yes, you could obscure the URL (make it some mostly unguessable string of characters), but it's not clear what problem that is solving. The user themselves won't be able to remember it or type it so it would probably have to be a link in a web page and if it's a link in an unauthenticated web page, then anyone can get to it - thus defeating the purpose.
There are cases where temporary links (often done for privileged downloads) such as what you mention /user/PdfgdfJFDGTfrfgdsf are sent via an authenticated channel (either an authenticated webpage or sent to an email address known to belong to an authenticated user) and these links contain some unique and hard to guess code. The user can then click on that link (in authenticated webpage or in email) and access that resource without further authentication. In that case, the knowledge of the code in the URL is serving as a form of proof of authentication. Because URLs may be logged in service providers or corporate infrastructure and thus not remain entirely private, this technique has its limitations and is typically only used for short term (download this resource in the next 10 minutes) type of uses, not a long term substitute for authentication and not used for things that demand real security. You don't explain enough of your use case to know whether this is practical for your situation or not.
The user doesn't need to be authenticated in order to execute this code. However I don't want that anybody can execute this request with a user id of someone else. Because he could see data he's not supposed to see.
That's an inconsistent statement. You say "user doesn't need to be authenticated in order to execute this code" and then you say "I don't want that anybody can execute this request with a user id of someone else.". You can't have both. The user is either required to prove authorization or they aren't. Pick one. It can't be both.
you can use jwt for this and a auth middleware for this
upon decoding jwt token, you can implement logic to check if the decodedToken.user_id (given that you add user_id when encode token payload) is equal to the :idUser in route (or any kind of logic you want) there.

How do I limit privileges to a user in a express app?

I have a webpage which has a form which allows users to add comments to the page to give feedback.
https://express-chat-comment-ap.herokuapp.com/feedback
You'll notice a user can delete comments, not only their own comments, but all of them.
So my question is, how would you limit those privileges to only that current user?
There is a major piece to all of this which is the web page is being integrated to a website which has a user login/user account already.
Also do I have to do any research regarding what back end their using now? Or can I keep this all encapsulated with Express/Node?
What packages should I use?
Where do I start?
Thanks in advance for your help!
You're putting the horse before the cart. This isn't really a "Node/Express" question; you're not going to solve it at the Javascript level.
Instead, your main question is actually "How do I do 'security'?"
More specifically: "How do I 'authenticate' users?" "How do I grant access?" "How do I prevent access?" And so on...
SUGGESTIONS:
User Authentication with the MEAN Stack
MySQL Authentication using Passport
OAuth 2 Single Sign on Authentication with Passport
Node.js: Token based authentication
Heroku: Managing Organization Users and Application Access
You must have an authenticated and logged in userID for each user that your server authenticates and understands. Each comment must be saved with the userID of the creator and you must be able to retrieve that from your data store.
Then, your server can check who the user is that is attempting an operation (probably from a logged in cookie that accompanies the request), what the operation that is being attempted and decide if that operation is allowed by that user. For example, if the user logged in is "Bob" and they try to delete a comment from "Alice", then the server will refuse to carry out that operation.
And, your UI in the web page can not offer operations that are not allowed (though the server must always check anyway). So, if you have a delete button in the comment, you would only show that button on comments that belong to the current user.

CQRS and synchronous operations (such as user registration)

I'm in the process of adopting DDD concepts for designing our next projects, and more specifically CQRS.
After reading a LOT of stuff I'm now trying to implement a simple Proof Of Concept.
The thing is I'm stuck right after I started :p
I'm trying to apply this approach to a simple user registration process, where steps are:
User fills the registration form & submit the request
The app creates the user
The app authenticates the user (auto log in)
The app sends a verification email to the user
The app redirect the user somewhere else with a confirmation message
From an implementation point of view, what I get so far is:
The controller action maps the request data to a RegisterCommand object
The controller action asks the Command Bus to handle the RegisterCommand
The command handler (UserService) "register" method creates a new User object (whether by a new command or a factory object)
The model raises a RegisterEvent
The command handler asks the repository to store the new user object
That's it, the controller action doesn't know about any of that.
So, my guess is, since everything in this context HAS TO be done synchronously (except for the email sending), I can use a direct/synchronous command bus, and in the controller action, right after the command bus invocation, I can query for a read only User (query database) and if it exists assume that everything went well, so I can give the user a confirmation message.
The automatic log in process being handled by an Event Handler.
Assuming that this is correct, what if something goes wrong, how to inform the user with the correct information ?
A common example is often used in articles we can find over the internet: A customer pays his order by using an expired credit card. The system accepts the request, informs the user that everything is OK, but the user receives an email a few minutes later telling him that his order could not be processed.
Well, this scenario is acceptable in many cases, but for some other it is just not possible. So where are the examples dealing with these use cases ? :p
Thank you !
I think this registration use case is closer to the paying for an order use case than you think.
Most of the CQRS thought leaders suggest validating on the read side before issuing a command, thus giving your command a higher probability of success.
If the validation fails on the read side, you know how to handle this - make the user pick another name before you even send off the registration command. If validation succeeds, send the command - now you're talking probably a few hundred microseconds AT MOST where another user could've come in and taken the same username between the time you validated the command and sent it off. Highly unlikely.
And in the very rare case when that does happen, you act in the same as way as the expired credit card example - the next time the user logs in, you present them with an explanation and a form to submit a new username - or send them an email saying "hey - someone else has that username, please click here to select a new one". Why does this work? Because you have a unique ID for that user.
Look at a user registration page like Twitter. As soon as you enter a username, it does a little Ajax call and says "nope, this is taken" or "this one is good!" That's pre-validation.
I hope this helps!
The problem with contrived examples is that you can change your mind about how the "domain" functions, so there's little use in discussing this example in particular. The basic premise you seem to forego is that we must assume that things are just going to work. Everything else is about risk and mitigating it. Taking this example, if I ask you, what if I lost 1 user registration in 100000? What if I lost 1 out of 10? Why would that happen? Do I have bigger problems at that point in time? Would future users be likely to register again when the system comes back online and works as expected? When would that be? What if we monitored our quality of service and prevent users from registering because we can't assure the quality they've come to associate with our brand? What if the server exploded, or the datacenter got nuked? Do we want to protect against that? You see, there is no right answer. Just various shades of grey. So how do we mitigate the risk? We could make things synchronous but that is only a guarantee at that limited point in time. What if I had to restore a backup that's 2 hours old (e.g. because the disk corrupted)? That's 2 hours of registered users lost (maybe). These things happen ... I just wanted to point out the relativity of what I consider a false sense of security. Mitigate it, invest in what you can't afford to lose, make sure you have a good audit trail. Probably not the answer you were looking for ...

CouchDB - Figuring out database security

CouchDB offers validation prior to allowing an object/row to be inserted into the database. This make sure that if you have a public facing couch application, you're database won't be filled with junk by just anyone.
User <-> CouchDB
However, I'm tring to figure out what that looks like comming from the standard application design process where you have a trusted middle layer that does much of the auth work. For example, most apps place Ruby or PHP between the database and user agent which allows the application to figure out information about the user agent before allowing something like a post to be saved to the database.
User -> Ruby -> MySQL
User <- Ruby <- MySQL
How do you trust the user to do administrative tasks when the user can't be trusted?
For example, how would you do something like "email verification" prior to inserting a user row using just couchDB? You can't let the user agent insert the row - because they would fill the system with spam accounts. On the other hand, there is no middle layer either that can insert the row after they click the link in the email.
How about this, I would assume that you would allow anyone to enter their email by creating a new record in a public table like email_verify. This is something that a public user agent could do as the table would not do anything in the application - it would just be a holding tank.
Then node.js could track the _changes feed and send an activation email while creating a new entry in a private table (like email_confirm) (node.js would serve as a trusted middle layer). If the user clicks that link and comes back then... [unknown] ... and node.js could finally create a record in the private user table (user).
At this point we could then rely on couchdb validation for the rest of the application since we got a confirmed user account created.
As more background lets imagine a discussion built on couchdb that anyone can register for. We don't want to allow just anyone to directly submit content without some kind of verification - yet the user agents all directly run the system. (Tables would be Thread, Comment, & User). How would this work?
I would think about adding roles to existing users in this issue.
Using couchdb's validation and changing _design/_auth can be a good idea to add email, email_verified and randomly generated email_verification_code in _users database when the user firsts registers.
To send mail, get confirmation, resend confirmation you can use external processes. (for an example usage of external process you can check couchdb-lucene).
And at last you can again do a quick check in _design/_auth in user update process if verification code matches and add verified_user role for that user.
This way all your requests would pass over couchdb, you would use external process only when you need to send mail and get confirmation.
Edit : Forgot to add (since it was pretty obvious), I would add verified_user role to database readers.
Couldn't you just make use of CouchDb's Validation ?
Users could be flagged. Upon registration, a User is added to the Users database. He gets his mail and then is flagged "valid:true" or something like this upon answering to that mail or clicking a link.
With validation users could not only be "logged in/out" but also access authorization can be implemented with more granular access rights. E.g.: Only mark threads solved if one is the author, admin, whatever...
Or does this seem impracticable?
After talking with some people on #couchdb IRC, it seems that they can't figure out out a way to do something administrative (like activation users that click on a email link) with out using a "backend" process like a node.js server which keeps track of the _changes feed.
I was hoping for a pure couchdb app - but it seems like couchdb still has a little ways to go.
Still, the good news is that you can hand off 80% of your applications logic/processing to your users. The other 20% will be 1) a node.js instance for things like sending emails or checking recaptcha and 2) record validation functions running in your couchdb, and 3) map/reduce (query) functions. These three things cannot be offloaded to something "untrusted" like a user-agent.

Resources