I'm trying to figure out the best practice, as well as safest, way to store a variable with javascript for a web app I'm developing.
I have pages that are generated using php, $_GET and mod_rewrite. They are generated from the id that's given through the url. For example: http://example.com/1125/ (because of mod_rewrite what's actually happening is: http://example.com?id=1125). The php takes $_GET['id'] and retrieves information from the database in accordance the id given, etc... you get the gist.
The problem I'm having is, I have a form on that page where a user can post a question, which is sent via ajax. And I don't know the best way to store the page's id ($_GET['id']).
Right now, I have the id stored in a hidden input within the form (for example: " />). And when the form is submitted to the server and php takes a look a $_POST, it contains ["id"] => 1125. That's how I'm sending the page's id when a question is submitted via the form in the page.
The reason I think that's not secure is, anyone can edit the html (for example through Chrome's inspect element) and change the hidden input's (id) value to any other id.
So my question is, what's the safest way I can store that id with javascript, so when that question form is submitted, It can safely send the correct id to the server? Or any other suggestions thought out with best practice methods?
You only just need to validate the id in the php page that receives the ajax, if the id is valid and the user has permission to use it, then it's ok and it doesn't matter if he changed it through chrome or whatever, but you need to validate because if he changed it for the id that belongs to other user then you have to detect that and error out in that case.
This is just a matter of validate your input according to the priveleges in your application.
Related
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.
I am a little new to PHP, and I have gotten in the habit of creating a specific file that handles all the form processing.
For example, I have one PHP file that displays the actual form, let's called it "registration.php" for example, and it specifies as its action "registration-process.php". A user fills out the registration form on registration.php, hits submit, and the data is POSTed to registration-process.php because it was specified as the action file by the form.
Now my question is this: Can't someone who knows what they are doing POST data to registration-process.php without going through registration.php? This would have the potential to lead unexpected consequences.
Is there any way to ensure that registration-process.php will ONLY accept POSTed data from registration.php? Like maybe a hidden field with a value that gets encrypted via some PHP code, and that value gets checked by the registration-process.php file? I wouldn't know how to do that, however, or if that's even the best solution.
Yes, using a hidden "security token" field is a common way to verify a forms integriy. Many public forums are using this method.
Try Google for php form security token or check out this site:
http://css-tricks.com/serious-form-security/
Can you only accept POST data from one location, probably. It is worth it, probably not.
As long as you are validating your form fields correctly (make sure what you're getting is within the realm of what you're expecting) there won't be any negative consequences of leaving it so anything can POST to it.
Also, technically you can send POST data to any file on the web, it just depends on what the file does with it whether or not it means anything.
Also, what Mario Werner is talking about is CSRF tokens. That won't stop other things from posting to your site, it just adds a level of security that makes sure the request came from the right place. For a detailed explanation, you can read this: http://en.wikipedia.org/wiki/Cross-site_request_forgery
I have been googling a lot but i am still without an answer so i decided to ask this question here:
Is there a way in PHP how to check that the data i am receiving in some script are from the specific form on the page? I am asking because everyone can see the name of the script i am using for saving the data to my database, so if somebody is able to find out the whole URL, he is also able to send some fake data to the script and i need a condition, that the saving process is triggered only when the data comes from the proper form on my page.
I am using jQuery to call AJAX function, so basically if i click on the button "send", the $.POST() method is triggered to call the script for saving the data.
Thanks,
Tomas
Use tokens to check if request is valid
You could always add some kind of security token when submitting data:
Tokens can be easily extended for many different uses and covers wide area when it comes to checking if some request is valid, for example you could let your non critical forms open for public, ask users to get their secret keys from some page (forcing them to open that page) and then use those keys to identify them when submitting data.
Of course all of this can be completely transparent to user as you could give keys from front page via cookies (or session cookies, it does not matter here, no more or less security as server keys should change after use and invalidate within specified time or when user's identity changes).In this example of use, only user that opened front page can submit data to server.
Another case is when cookies is given away at same page which contains form for submitting data to server. Every user that open page will have their keys to submit data straight away, however if someone tries to make request from outside it will fail.
See OWASP Cross Site Request Forgery
and codinghorror.com Blog CSRF and You
Only with AJAX?
Here is my answer to another question, this answer covers different methods for inserting additional data to ajax request: Liftweb: create a form that can be submitted both traditionally and with AJAX (take a closer look at
$.ajax({
...
data: /* here */
...
Currently I am using tokens this way:
Form used to submit
This hidden input can be added to form, it is not requirement as you can use methods described earlier at another answer.
<input type="hidden" name="formid" value="<?php echo generateFormId(); ?>" />
Function generateFormId()
Simply generate random string and save it to session storage
function generateFormId() {
// Insert some random string: base64_encode is not really needed here
$_SESSION['FORM_ID'] = 'FormID'.base64_encode( uniqid() );
// If you want longer random string mixed with some other method just add them:
//$_SESSION['FORM_ID'] = 'FormID'.base64_encode( crypt(uniqid()).uniqid('',true) );
return $_SESSION['FORM_ID'];
}
Processing submitted form data
if (!isset($_SESSION['FORM_ID']) || $_SESSION['FORM_ID'] != $_POST['formid']) {
// You can use these if you want to redirect user back to form, preserving values:
//$_SESSION['RELOAD_POST'] = $_POST;
//$_SESSION['RELOAD_ID'] = uniqid('re');
echo 'Form expired, cannot submit values.';
//echo 'Go back and try again';
exit(1); // <== Stop processing in case of error.
}
If you need to check which form is submitting data
Then you could just add prefix when generating id's and check for that prefix when processing form data.
This is case when one php script deals with many different forms.
Remember that only ultimate answer to prevent evil users is to pull off all wires from your server...
This is an interesting topic, but you are missing an important point: A spam robot / bad user could also bomb your database by using that specific form page (!).
So, the question is not how to check if the request comes from that page or not, the question is how to check if he's a regular user or a robot/spammer/bot.
Do it with a captcha, like http://www.recaptcha.net
In case i slightly misunderstood the question: If you want to be sure that the request comes from a "real" user you will have to work with a login system / user system and check for users id / password (via db or sessions) every time you want to do a db request.
You can verify that the page is being requested via AJAX with checking against this:
strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) != 'xmlhttprequest'
You could also check the HTTP_REFERER.
But it sounds like you're trying to protect a page that processes vulnerable data. This requires more than just the two things above. I'd recommend googling 'CSRF Forgery' to get more information on this.
These are something that you should take a look at.
Capthcas.
Referer check.
Use POST than GET. [Still Curl can automate it.]
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?
I've been trying to use jQuery to grab the information from $_POST and return the user back to the actual form if their email address already exists in the system, however I can't seem to get jQuery to grab the php variable $post (which has all the information from $_POST) and spit them back to the original form. Could someone help me out please? :)
**************** EDIT ****************
So here's the basic structure.
Form: Name, Email, Address.
Submitting the form calls a php function to check if user exists in the database. If the email address is in the database, I want it to say "sorry this email already exists, click here to try again".
After clicking on the link to try again, I want the form to re-display with the fields they just typed in to display again. <- this is what I thought jQuery could do to re-post the information back to the form page..?
If the user doesn't exist, the user is saved into the database.
Does that make more sense?
From the sound of your question what you're trying to do doesn't make sense. This is because PHP is a server side language while Javascript is a client side (in the browser). This means that Javascript, and therefore jQuery, don't have access to PHP's variables ($_POST included).
There are two common ways to solve this:
Have PHP generate the form. You would output the values from $_POST, or another data location, into the form (ex., echo the variable into the input tag's value attribute). This is by far the easiest method. For example: printf('<input type="text" name="foo" value="%s"/>', $someCleanVariable);
Have the PHP generate JSON or XML, and use AJAX to get the data from the PHP script. You would have to parse out the values into the form. This is basically the same as the previous example, except it's more portable: you can have any source consume the data instead of just your form.
However, make sure that you protect your users when doing this: you need to clean the data that you're sending back to the user to make sure that there is no HTML, Javascript, or other malicious code in it. You don't want people being able to alter the look of your page by passing it data. See Cross-site Scripting Attacks.
Cheers.