To generalize this question I asked this morning, and please accept my apologies if this has been asked before and I simply don't know what to search for, but I'm curious how Rails handles the following situation:
Using Devise, I log in a user, with an ID of 2.
I click on a link that has been created to "edit my profile" (which simply would go to the /users/2/edit page).
Using Firebug (or something similar), I modify the form and change the action from action='/users/2' to action='/users/5'.
I change an element on the form, and click submit.
At this point, Rails appears to allow the submission and update user with ID 5 with my changes.
I'm guessing I'm not the first one to ask this question. It seems to me like Rails should handle this "out of the box", but I could be wrong. Does Rails handle this natively and I'm just missing something? Has this been asked before on SO or somewhere else that I'm missing?
A few things:
Don't create a route that accepts a DB id. Instead, make it something like /my_profile.
If an id is passed in the params, ignore it entirely in the controller. Instead lookup the current_user that is logged in and show them their own profile regardless of what profile/user id is passed in.
Finally, and possibly most important, use authorization (what a user is allowed to do) in order to disallow one user from editing another user's profile. Not to be confused with authentication (user logins/logouts).
With this approach it won't matter if the DOM is changed, because the server should never implicitly trust what is passed to it, which is the problem you're facing now. Any web/app server must always confirm that the parameters being passed to it are actually valid in the context of what the current user is allowed to do.
This idea that the server should never trust what's passed to it is a critical idea to apply to every single action in your app, without exception.
Related
I have just started working with Gluu, and mostly it is working exactly as I want it to.
However I am experiencing some difficulties with registration.
Currently when a user registeres he/she is redirected to the gluu page. What I would like to happen is the user being redirected back to the page that sent the user to the registration page(or at the very least a static page).
I know that this needs to be done in the postRegistration part och the user registration script, however I am not quite sure about what it is that I need to do.
So has anyone done something like this before?
Edit:
So this is where I am currently at...
The postRegistration function takes in 4 parameters, self, user, requestParameters and configurationAttributes.
self I assume is just a reference to itself and therefore it is not really valuable in this case as there are no set functions that redirects in that class and it does not seem to hold any valuable parameters.
user is the user that is about to be registered and is sent down from org.gluu.oxtrust.action.RegisterPersonAction and is a org.gluu.oxtrust.model.GluuCustomPerson Object.
I believe that this is my best bet at fixing this problem... although I am not sure about how.
It does have a function setSourceServerName that seemed promising, but setting it did not change the outcome in any way.
requestParameters is just the query parameters sent in the URL. I tried setting these to valid openid code authentication parameters, but it had no effect.
configurationAttributes is simply the static parameters sent into the script from Gluu (just parameters set statically to the script)
Moreover the function must return a boolean so I assume that what needs to be done is changing the input parameters as a side effect and thus my only two options are the user object and requestParameters. requestParameters seems to be just a private map object in the registerPersonAction class, which does not seem to do anything special with it, so changing this shouldn't have the outcome that I want.
Therefore it must be the user object that I need to modify. However as previously stated, I do not yet know in what way
As a dirty hack you can edit the gluu pages to insert javascript that redirects the user
I am using cakephp 2.1 and I have written some actions like view, edit and delete.
In url it looks like 'view/1', 'edit/1', 'delete/1', So that I can change the ids in url.
I don't want to change it in url and it should not allow to edit the ids. Please help me to do that. The work will be more appreciable.
OK... I think I understand your question. You are concerned that if people can edit the ID's, as they are visible in the URL's, then it will be a security threat?
First, view actions:
You should check on the server-side if the user has permission to view the record with that particular ID. If they don't, then you can give an error. If they do, then let them view it - don't worry about how they got there, whether they edited the ID in the URL or not. If they have permission to view the record, just let them view it.
Second, delete actions:
Again, just like view actions, you should check on the server-side to see if a user has permission to delete the record. If they do, then let them delete it! Don't worry if they edited the ID in the URL. If the user doesn't have permission to delete the record, then your server-side check will stop them, even if they've edited the ID in the URL.
Third, edit actions:
This is slightly more complicated, but still pretty easy. I'll assume you're editing a record with an HTML form, and submitting via POST. OK, so the ID in the URL determines which record to fetch and edit. As with view and delete, you should do a server-side check to make sure the user has permission to edit that item. If they do have permission, then return the form.
Once the form has loaded, the URL showing in the browser is of no importance. The URL which the form submits to, and the data that the form submits, is important. Now, by default, the edit form will store the ID in a hidden input field. A user could change that ID, and thereby change the record they are editing.
To prevent this, use CakePHP's security component. All you need to do is include the component, and CakePHP will automatically put a hash on the form when it's loaded, which it will check again when the form is submitted. If a user has edited hidden input fields, this check will fail, and CakePHP won't allow the edit to go ahead.
Note that to use the security componenent in this way, you must build your forms using CakePHP's form helper (which you probably already are).
And a final note... sometimes people are a bit paranoid about anyone seeing the ID's in their database - and therefore don't want them showing in URL's or anywhere else. But, in almost all cases, there's nothing 'secret' about ID's at all. It doesn't matter who sees them. All they are is a means for your application, and the database, to identify a record. So long as your application is secure, then you should be able to show all your ID's to the whole world, and have nothing to worry about.
Guys i'have a question.
I'm currently buiding a wizard that has 5 step's until being completed.
The user starts by the first step where he generates the entry id.
From there on i start passing the id over the url like this:
host.com/{controller}/{view}/{id}
This is how my url looks like after the step1,
------- currently at view step2 passing the id=120
host.com/{controller}/step2/120
This isn't safe because as you know, anyone can change the id and affect other users's entries. Ofc, it can be quickly solved by reading if the authenticated user is proprietary of the entry that he must be trying to access in each view.
Now, my question is... is there a better way to do this?
Any tips for future work?
Is what i'm doing enougth?
(begginer doubt praying for a expert awnser)
Cheers
...It can be quickly solved by reading if the authenticated user is proprietary of the entry that he must be trying to access in each view.
Yes, that's true. You should start there.
Here are some other things that you could do:
You could make your entry ids Guids instead, so that a would-be hacker would never try to guess an entry id.
Because using GET for sensitive data is a bad idea, you could, as endyourif suggests, pass the entry ids with hidden fields instead.
If you are truly concerned about the user altering the ID in the URL, then you must spend the additional time adding an "isOwnedBy" like functionality.
As an additional security measure, you could pass it via a hidden variable in the form so it is at least not as easy to change as well.
Edit: I like #LeffeBrune's suggestion of encrypting the idea as well. However, I still suggest that the validation is performed on the function to ensure the user owns the object. It's just good practice.
How do miscellaneous account management pages fit into a RESTful design in Rails 3?
For example, a user registers (create action) and is then forwarded to a registration success page (? action) where they are asked to now verify their email address via a url with a token (emailed to them).
When they click the link in the email, technically they are "updating" their account as part of the verification process right? So I'm thinking that would somehow map to the "update" action but the update action is expecting a PUT request. Is that correct? How do you make that work via the email?
I'm also wondering how forgot password, reset password, etc also fit into a RESTful design? Just trying to wrap my head around this.
Just because you have a result design, doesn't mean you HAVE to restrict yourself to only CRUD verbs that map 1:1 to Get/Post/Put/Delete. That said, if you want to get really RESTful, you can start to think of some of these things in terms of being their own resources. For example user verification:
User signs up, and gets sent a verification email, you already have that all squared away RESTfully it looks like
Verification url looks like: http://app.com/user_verifications/new?token=foobar (GET)
They follow the url and maybe are presented with a "Hello Dan, welcome back! Click here to verify your account" at that point you submit a form to http://app.com/user_verifications to trigger the create action there. Now on the backend, you can perform whatever actions you want, updating the user, setting them to active, or actually creating a "UserVerification" model.
Not a perfect example, but the idea is that the RESTful interface you are providing has an additional resource, in this case "user_verifications" and a user is acting upon it via HTTP methods in order to achieve the user's goals. You can apply similar logic to reset/forgot password either with a "UserSession" type resource or even as specific as a specific "ForgotPassword" resource.
Success page is just create.html.erb file. Usually you are redirecting from create action, but here you can just render success template.
Verifying. If you want to stay REST you should add one more step: GET verify, where is the form with your token present, which will lead to PUT update action. User recieves a link to this page.
But I prefer to use simple GET request here, which will update information without any additional clicks.
The same way you work with restoring passwords and other functionality. You add a page to with form that gets email, then you send a letter with link to a page with form filled with tokens and so on.
I am new to RESTful architecture or at least new to using it properly I have only had true experience with SOAP. I am having a problem wrapping my head around some things. I know there are other questions that are similar but none, that I have found, answer my question satisfactorily.
I am just starting this app so I want to get it started the right way and what I am looking at now is a user registration screen. I have two validation calls that occur before the registration form is even submitted. First I have a validation call that checks to make sure the email entered by the user is unique and second I have a validation call that checks to make sure an access code we provide to the customer exists in the database.
I currently have it structured as a POST (which I believe should be a GET) and I have an action argument that defines what I am wanting to do. So for the email I have an argument string such as
action=validateemail&value=email#email.com
and it is calling the User action of my MembershipController. I am entirely sure this is wrong as I should only be using the verbs GET, POST, PUT, and DELETE yet I am defining my own verb using the action argument.
Honestly, I don't know how to do this. I believe the User should be my resource but possibly for the email validation Email should be my resource. I guess what I am asking is how would you do what I am trying to do? I know some of you might just say do all the validation upon the submit, but I would prefer to do it both ways really. I would like the asynchronous validation as well as the validation I will perform when the user submits.
We do something similar and our resource is called "Account". For the validation I would do a GET for the Account specified and validate the HTTP return code. I would expect a 404 - Not Found to let me know the proposed account doesn't exist. If they passed in mangled data a 400 - Bad Request would tell you something was wrong. To create the Account a POST of the same resource would do. To do something like change a password, a PUT might be appropriate. I think that if you already are making a trip to the server, you might as well return the account(200 - Ok on the GET) if it exists to save yourself the second trip.