PHP form posting to prevent navigation/reposting problems - php

I have created a user registration form using PHP/smarty. The form posts back to itself since I don't know of any reason not to do it this way. The problem here is that if the user refreshes the welcome page, the code will attempt to recreate the account. What is the best way to do this from both a user and security perspective?
if (isset($_POST['submit'])) {
/* Create customer account */
$smarty->display($welcome_template);
} else {
$smarty->display($form_template);
}

after the account has successfully been created, do a HTTP redirect and send them to a separate "success" page: http://en.wikipedia.org/wiki/Post/Redirect/Get

I guess that is a reason to not do it this way. I think the standard solution is the Post/Redirect/Get pattern, which means: make the POST request and then redirect to a GET request to a confirmation page. That page can then be reloaded without any problem.

the user may of course try to recreate their account at any time, so care must be taken for that.
For your needs, as post-action page shows confirmation,
the easiest solution would be
//at end of post-action
echo '<script type="text/javascript">document.location = 'yoururl?cmd=confirm</script>';
die();
regards,
//t

Related

Do not refresh php page

On my page, after the user has submitted a code, the script makes a new record in the database. If after he has submitted the code the user hits refresh, it will make a duplicate record in the database. If he hits refresh 10 times, it will make 10 records with the same data...
Is there some way I can make the page not to refresh for the second time?? Or to limit the number of refreshes the page can get? What solutions can be applied to avoid this situation?
Thank you in advance.
Before adding the record into the data table, use select query to check the data is alreary exists or not in the data table and redirect the page to a new page, say thank you or confirmation of insertion.
Select id from TABLE where data='".$_POST["data"]."';
....
....
if(empty($rs["id"])){
// insert the data in table;
}else{
// do edit or skip to redirect
}
and Rediret
header("location:thankyou.php");
exit();
After the records are saved in the database, use header() and redirect to the same page.
Check the answer to this question, maybe you can use the same code.
It sounds like the PHP script that produces the form is the same one that processes it. You may want to consider setting up a separate PHP script to handle the form. For example:
<form action="action_handler.php" method="post">
Then, at the end of action_handler.php, you would redirect to the original page as follows:
header('Location: original_page.php');
Simple one is unset($_POST["data"]) after inserting it to database or try header('location:.')
When dealing with POST-data you should always employ a POST/REDIRECT/GET setup (Wikipedia. This way, when a user refreshes the destination page, nothing really happens besides a refresh.
The best way for a redirect method is to use status code 303 (HTTP Status Codes), which tells the browser that the POST-data has been received, processed and that the user should go to a new page for the 'response'. When a user hits 'back' he or she should get a message that the page is no longer available or valid (this disabling rePOSTing via that route).
You can use this example to redirect to another page (fairly generic example, but I have baseline code I could use):
header("HTTP/1.1 303 See Other");
header("Location: http://www.yourdomain.com/desitnation.php");

prevent double form submission on refresh

I have a simple question. I know that I can prevent a form to re-submit itself when the user reloads the page by using the Post/Redirect/Get Pattern. But my question is, will this pattern work if I'm redirecting the user back to the same page where the form was submitted? I mean, I don't want to redirect the user to another page.
Any help please
Thank you
yes, but you have to remember to redirect him without the GET params.
so you can
header('Location: same_page.php?status=done');
die();
this way you are removing the param, and you need to support the status=done to show a message or what ever you want.

redirect user on previous page after successfull task

What should be good way to redirect user after successful action like edit or delete any item, in delete condition we could use $_SERVER['HTTP_REFERER'] but in case of edit, we show first of all edit form and then user clicks update, so if we use same approach user would be redirected to edit page not main page. I hope you got idea about my confusion. thanks.
If 'update' is handled through a Form post, just put a hidden input in reflecting the landing spot.
<input type="hidden" name="next_url" value="foo.php" />
The PHP uses the value as the place to redirect to.
<?php
// Do operations.
header('Location: '.$_REQUEST['next_url']);
This is especially important because HTTP_REFERER is not guaranteed to work. It works most of the time, but there are issues with relying on it.
I advice to never use HTTP_REFERER.
It is possible it isn't set at all.
It can be anything, don't expect your previous page.
I advice an solid solution using (as above mentioned) hidden field, session storage, or simply have a solid routing in your application so you know which route someone took. Pick the best.
If you're OK with $_SERVER['HTTP_REFERER'] you can simply store that value in Session Information, and redirect to it when editing is finished.
For example, before showing the edit form you can do:
$_SESSION['originalReferer'] = $_SERVER['HTTP_REFERER'];
And after clicking "Update" (if successful):
header("Location: ".$_SESSION['originalReferer']);
But again, use this only if you trust $_SERVER['HTTP_REFERER'] !
Similar to the previous answer, I would suggest keeping track of the page you wish to redirect to using sessions., and then once you want to redirect, just use
header('Location: '.$redirect_var);
The reason why I would put it in the session, rather than posting in a form, is that form posting can be manipulated by the user, whereas sessions are server side, and are entirely under your own control.
Save the url in session when you are coming to Edit page and when you submit just use the below snippet after executing the update query:
header('Location: '.$_SESSION['redirect_url']);

PHP clear browser cache to avoid form data resend after refresh

I'm developing a PHP-MySQL app that enables registered users to enter text comments. Problem is:
User sign-in into the web site - OKAY
User presented with a form to submit text comment - OKAY
User enters text comment and submits - OKAY
I have a routine that sanitize the comment & save it into MySQL (with userid, textcomment, datetime stamp) & present back the user that his/her comment is entered - OKAY
User decides to refresh browser - a duplicate comment is entered - BAD!
I was thinking 3 options:
OPTION 1: Routine that checks: last time user posted comment, and if so, check if this is a duplicate. If duplicate then display error message.
OPTION 2: Routine that does not allow a user to post too quickly. So basically do not allow postings of comments within 1 minute or so. So if browser is refreshed the comment will be ignored.
OPTION 3: Manipulate the browser cache to clear out its contents so when refreshed no duplicate will be entered.
Now in the context of my application, my concerns with OPTION 1 and OPTION 2 is performance PHP-MySQL since I already have various queries within the same page that push/get data from databases. So OPTION 3 may target the issue differently.
Questions is: If I go for OPTION 3 can this be considered a Best Practice? meaning clearing the browser cache is the best most effective solution? I have read that there are consequences too? your thoughts are appreciated!
Just do a redirect after submitting data to the database. It's a common practise.
An http redirect instructs the browser to issue an http GET for the url specified (as opposed to the http POST that is used to submit the form) . If you do this right after you have inserted data into the database, when the user refreshes his browser nothing will happen other than him seeing the same page again.
This question on SO tells how you redirect with php.
Just unset the posted variable after you have inserted it in the database
<?php
if(isset($_POST["comment"])){
//store in the database
//on successful storage
unset($_POST["comment"]);
}
?>
Thus the value won't be posted back when user refreshes the page...
You need to implement the Post/Redirect/Get pattern.
I would use Option 4: Use a one-time form token that authenticates the form request. If the request was successful, invalidate the token.
When doing this, even returning to the form after a redirection won’t allow it to send the form again. Additionally, this will also make CSRF attacks harder.
After entering data into database redirect the page using header or location.href
i have found new way try this.
function PreventResendData($invalidpage='index.php'){
if( $_POST && !is_array( $_SESSION['post_var'] ) ) {
$_SESSION['post_var'] = $_POST;
header('location:'.$_SERVER['PHP_SELF']);
}
else if($_SESSION['post_var'])
{
$_POST = $_SESSION['post_var'];
$_SESSION['post_var'] = '';
}
else
{
header("location:".$invalidpage);
}
}

Code igniter authentication code in controller security question

I have a main controller to handle the very front-end of my authentication system, it handles login, logout, update user info, etc. functions that I anticipate calling by POST'ing from views/forms. What about something like a "delete_user" function though? My thoughts are a button in someones admin panel would say "Delete Account" and it would post to "/auth/delete", and the function would delete the user based on their session username or id. This seems a bit open ended, you could send out a link to someone and when they opened it while in that application it would delete their account.. Whats the best way to handle this?
What you are concerned about is actually called Cross Site Request Forgery, or XSRF. You can read more about it on the OWASP Website.
A few things that you should do overcome this problem -
Use POST for the delete operation. This doesn't protect you from XSRF, but protects you from link followers/page accelerators. Its also a http best practice.
Post your session identifier in the body of the request. On the server side, compare the session identifier from cookie and from the request - if they are different, reject the request. This is the "double submit cookie" method to prevent XSRF.
Alternatively, you can ask the user to solve a captcha.
Additionally, a "soft-delete" on the lines of what Tom mentions is also a good idea.
It sounds like adding some other piece of information to the function is the answer. Here is the function in question:
function delete() {
$id = $this->session->userdata('user_id');
$this->auth->delete_user($id);
redirect('home');
}
In code igniter this can be accessed by just visiting site.com/class/delete which is my problem. I think a good plan will be to post an authentication token (saved in cookie) with the delete button, so it can't take action via the URL:
function delete() {
if($this->input->post("token") == $this->session->userdata('token')) {
$id = $this->session->userdata('user_id');
$this->auth->delete_user($id);
}
redirect('home');
}
I don't think i need a soft-delete right now, but thank you for that good tip! If you see any other issues please explain, thank you.
The way i handle this is as follows. On your account page you have a link to delete the account. They click that page and are greeted with another page asking if they are really sure and if so please enter their password to confirm they are sure.
After they do that i deactivate their account (not delete) and send an email saying that their account was deactivated and if this was intended no other action is needed on their part. If it was not intended they can login to their account and it will reactivate it. (within 48 hours) after 48 hours i delete their account and information.
Have a look at one of the better known authentication libraries for CodeIgniter:
https://github.com/benedmunds/CodeIgniter-Ion-Auth
If you don't decide to just use it, you can at least get some good ideas about how to go about creating your own

Categories