Web Apps: Storing ID in hidden fields safe? - php

I just had this thought, I don't know if I am slow though.
Usually, I store the id of the item I am editing in a hidden field. Then in backend (I am using PHP/Zend Framework btw), I get it to determine which item gets edited. But then I thought, in something more secure, eg. edit profile, the user can somehow edit a hidden field right? Then he can edit someone else's profile. I know for edit profile, I can get the id form the session variable, but what if i got something that requires me to store the id somewhere?
I got ACL (Zend_Acl) I do this. Basically grab the id from the request params
$id = $req->getParam('id');
then check if the logged in user is allowed to edit the item. But the thing is I wonder if the url is something like /users/edit/1 where 1 is the id. But somehow, the hidden field is changed to 2, what will the request param be?
How would you deal with this?

You must store some kind of id at the client-otherwise how would you know which item to edit?
This does not free you from the mandatory check on the server that the current user has privileges to edit/see the edited item.
Other then that, why would you care how he got to edit the item (whether by lawful use of the web tool, or by editing the hidden/whatever field).

Storing ID in hidden value isn't quite safe. Generally, we store ID in session variable.

as ppshein said, storing sensitive ids in a hidden var is NOT safe. Would you store a password in a hidden var? Its really easy for even a novice hacker to get that data.
You need to make sure that all access control is enforced by the server.
in your case, you need to make sure that the user who is logged in (the one on the session) is the owner of the profile being edited. Or that the user who is making the edits has permissions to edit that profile (e.g. is an admin)

It should not be based on anything submitted by the user.
You should always check user permissions on server side.
An attacker can prepare any request to your server.

Agree with all the points above but if you really do need to store something clientside for whatever reason, you can always encrypt the data and decrypt when you need to use it but again, using sessions would be the best way to deal with it as they are not accessible client side.

Related

Safer way of storing post_id in input hidden field

I have to integrate the commenting section in one of the pages of my website. When a user comments on a particular post, the post id is used to identify the post user is commenting into. The post id is in a input hidden field of the corresponding post. Or, I can also use something like data-id attribute(HTML5) in a tag to store id. But is there a safer way to do so? The post id is open and anyone can inspect and change the value of it even from chrome. This is a big security concern. There can be a huge no of posts in that page and I am using ajax call to insert the comment. What would be the best way to do it?
Frankly, anything can be edited or abused when it comes to JavaScript. In the console, they can send whatever they want as a POST request. There's nothing you can do about it, but you can protect yourself from abuse.
The golden rule is never trust data coming from the user. For example if someone sends you an edit to a post with a given ID, verify that post belongs to the logged in user. If it does, even if they manipulated the ID on the form, it won't matter because it's theirs anyway.
You need to adjust your protection depending on the situation.

Why do people store variables in hidden form-inputs instead of acessing variable later?

Why does people store variables like this:
<input type="hidden" name="id" value="<?php echo $bookid; ?>">
Instead of just accesing the $bookid when it's needed?
Is there any security breaches with this? I thought you could acess and change the value of an input with developer-tools? Not making it safe to store them there.
Apart from the whole client versus serverside thing, the security 'issue' should be non-existent. If someone does make a page with a 'hidden' form field to really hide it from the user as in, the user should never be able to find out the contents, that someone is "going to have a bad time".
The point of hidden fields is to hide them not for security, but because the user doesn't need it.
Random example: Maybe I need to store the id of the Album you are looking at. You don't need to know that, why would you want to know that. But finding out I call this Album 2134125 in the back-end doesn't matter. Even if you change it, the only thing that will happen is you have just selected (bought, started to listen to, whatever your site does) a different Album. Unsellable albums, price, all stuff like that should be based on the ID, not on other stuff, so you can't hack it, you just confused yourself.
If you do need secure hidden fields there is an option btw:
Sometimes we need to send actual data in hidden fields that we don't want to change. This is true for some payment providers where you actually send the amount a person needs to pay from a hidden field. (I'm not making this one up). This is usually securty by adding a second hidden field with a form of hash. This is made with a secret known to the payment provider and the server, but not available in the form. If you do some hash, say sha1(hiddenvalue + secret), add it, and compare after sending the form, you will get a different has (so no equality, so an error) if the hiddenvalue was changed.
You are mixing things. $bookid is PHP variable, only visible in the server. It is stored in the hidden form so it can be used by the browser (either by Javascript, by a new request to the server, or both). $bookid is invisible in the client side, it will be replaced by its value before leaving the server.

Update DB w/ PHP Methodology

I'm trying to write an app that basically is a frontend for editing database records. I have heard that a way to ensure the right row in the DB is being updated is to include a hidden form field on the update form with the row unique ID in it, and use this to add a conditional to the backend update statement.
However, this seems insecure. Anybody could edit the HTML on the page pre-submit and change the record being updated, no? What is the proper way to pass the unique ID of the row the user is editing along with their edits? I would imagine this may be done with cookies/session tracking, but couldn't this be edited client side prior to submitting as well?
Thanks!
If a client is allowed to modify the record in question anyway, it doesn't matter whether he does so by modifying the id in a hidden field or by going to the correct page and submitting the form from there.
When any client submits any form, the server needs to a) make sure the client has the right to modify the record he attempts to modify and b) validate that the submitted data is allowable for the record. Then all your business rules are being protected and taken care of, whether the user uses the proper forms or not.
You can also save a hash of all hidden fields in the session server-side and check that on submission to catch hidden field-manipulation attempts, if that's still in your interest.
You may create a field with default value TIMESTAMP.
Also you may pass this data from one page to another using php sessions
More details here
Hope this helps.. :)
When you load the form page, store the id in the session however you want to.
When they submit, on the post page, grab the id from the session.
The insecure part is, how are you letting people decide which id they want to edit? Where is the input for that?

Only allow webpage to be viewed via link click

Is there a way to only let a webpage be viewed if the link pointing to it is pressed. I am sending emails to members of my organization with links that attach values to the URL so I can use phps $_GET to figure out who they are on the webpage and update appropriately. What I am worried about is individuals changing the values of the link and changing other members data. If there is a better method for doing this, I am all ears. Using a log in system is not an option.
Not exactly, no.
What you could do is include some token that you keep associated with a particular user id and is very difficult to guess, and include that in the link as well - then, when you get a GET request, you check to make sure the token matches the one you know is correct for that userid. (You'd store the "correct" tokens locally in a database when sending out the emails.)
For instance, you might have...
/modify_info_script?user_id=123&token=aSDqWEqwejk2123salskq
And then you'd have a database table or some other storage that has...
user_id token
----------------------
... ...
122 klqwkejajwie8u8213nak
123 aSDqWEqwejk2123salskq
... ...
and thus if someone tried to change the user_id in the URL, the token wouldn't match and you could reject their request. For instance, this would get rejected...
/modify_info_script?user_id=122&token=aSDqWEqwejk2123salskq
since the right token for 122 would be klqwkejajwie8u8213nak, not aSDqWEqwejk2123salskq.
This is probably the best option if using a login system isn't an option. However, you should really make sure that using a login system isn't an option at all, because user data really should be protected by a login.
This is really not the proper way to secure your site.
However, the simple fix for you is to check the "referer" header and make sure it's not blank. If it's not blank, then it came from a click (or they spoofed it, which is why this isn't secure).
The real way to protect data is to implement a login system with a set of permissions.
To check, if someone came from a link, see $_SERVER['HTTP_REFERER'].
To protect the application against link manipulation, you can combine it with a secret passphrase (only internally, the passphrase must not be known to anyone) and use md5() on the result. Attach the MD5 to the url. If anyone manipulates the url, you will know because the MD5 of "the url plus your passphrase minus the MD5" will be different.
Quite a lot password reset systems work like this so you could say it's reasonably safe provided you use long enough random token. Something like 32 chars should be fine.
Just providing the token should be enough since you don't need the user ID to check it against issued tokens in database.
/modify_info_script?token=aSDqWEqwejk2123salskqfilltill32chars
The other alternative is to have login system where use has to type in their credentials in order to change information.
Also if you really fear that someone might try to guess it, just timeout/ban users after 3 wrong token attempts. No one should be trying to type them in by hand anyway.

Is it ok to place user id's from a db in the GET string for a php app page?

apologies if I make any cardinal errors in question asking, this is my first post.
Building a simple app in php where the user has permissions to a number of different sets of data which are held in a db with corresponding id's. Currently I have the user switching the set of data they are viewing by choosing a set from a dropdown. My security knowledge being somewhat weak leads to my question: is it inherently bad to expose actual row id's from a database to the outside world?
In this case it would appear in the form: http://www.***app.com/app.php?currentDataSetID=44
Thanks for input (and again apologies for any noobesqueness in the question). SO rocks.
This is usually perfectly fine. As you can see in the question URL, Stack Overflow does the same thing!
You need to concentrate on making sure that nobody without the right permissions can actually access ID 44 even if they enter the correct URL.
Usually user's access to data is based on sessions or cookies. Sessions are stored on the server side, cookies in user's browser. So you can expose user's id in URL but take care that only user with appropriate cookie can access his/her data. Try to search google for .. php cookie based login ...

Categories