Here is a tricky question I've been trying to solve...
The issue happens on a mobile website.
I use codeigniter to create a form, pass some values to the db and then redirect the user to the article that the user sent.
The problem is that when in Android WebView (which is a custom app), probably on other mobile devices too, so when the user hits the back button it resends the data and posts the article again. The article is being posted as many time as the user hits the back button, with no warning.
Any suggestions? Has someone had this issue?
Oh and by the way, if the whole history is erased (not sure if that is even possible, because its client side, and I don't fancy using javaScript for that) and the user hits back button, he will be taken out of the app, which I don't want to happen.
Pages that are loaded via POST will cause the browser to ask the user to resubmit the information to view the page resulting in the actions performed by that page happening again. If the pages is requested via GET and has variables in the querystring the same thing happens but silently (without the user being prompted to d it again).
The best to work around this is to use the POST/REDIRECT/GET pattern. I used it in an example about processing payments that I wrote for Authorize.Net. Hopefully that points you in the right direction.
I solve a similar problem ( also in phones ) like this.
Generate a token ( random string of 15 char ) and save in the SESSION['token'] ie.
Save this token in a hidden input in the html form.
when the form is submit, and before touching the db, compare the token submitted with the session one, in case match, proceed and unset() the session token, else error token mismatch.
hope it helps.
Related
I have a Codeigniter panel for users.
In my site, I have a textarea where my clients put informations and press the "go" button. When the button is pressed, my script get the information of textarea and make a searchers and tests, and return a value.
This working all right in my old site, but now I create a new site in codeigniter, and this not working more. Now, when I press "go" button the page refresh and get this error.
I read about, and I think is an error of CSRF or anything like this.
Someone know whats this error is happends and how I can fix it?
Did you already check CSRF token before and sent to the form ( or maybe an ajax )?
I've experienced that. caused by CSRF which is different from when CSRF is sent and received by form. You can do two things. The first one to take and immediately send the CSRF token manually. The second one uses the GET method (not recommended if you want to POST)
I have a PHP application where users can apply for a bonus. But there is a confirmation page before the bonus redemption code runs.
The issue is that in IE, if you hit f5 right after you click the continue button, the confirmation page refreshes while the bonus redemption code had already been triggered by the continue button and actually goes through. But because the user still sees the confirmation page, they would hit the continue button again and now they get an error cause they are already registered.
Is there a way i can disable the f5 button using javascript? Is this the best way to go about this? I have tried many scripts i found online to do this, but none of them achieves it. Is there a better way I can go about this? Perhaps from the application side?
Edit: If the outcome of claiming a bonus is databased, you can load existing claims on your confirmation screen and test that one already exists.
Edit: the other neat trick you can do is serailize/json_encode the $_POST and produce a hash from this, store it in the database or user session, and test against it.
I would generate and database a single use token (hash) for the form as a hidden field, if post data is re-sumbited, the token would have already been consumed, and you can invalidate the post request.
There are couple of methods to solve your issue:
Checkout here: http://bjw.co.nz/developer/general/75-how-to-prevent-form-resubmission
I have been using second method (Using sessions) and it's really working well.
Let's suppose that you have a website that contains a single button.
When this button is pushed, an ajax request is sent to the server - who receives the request and adds 1 in an internal counter on its database.
An user could copy the entire request (and its headers) and create a script to send infinite requests to overload the server (and mess with the counter).
I'm trying to avoid:
Recording the user IP
Using Captcha
I'm using php in my back-end. Is there any way to prevent this situation? Is there some way to send an "invisible" request?
Your problem is called "cross site request forgery".
A good way to solve this problem is to generate a random string when the page with the button on it is called, write it into the users session and into the generated page, and send it together with your button press (for example in a GET request).
On the backend side you check if the submitted string matches with the string in the users session and then delete the string from the session. Only proceed if both strings matched and weren't empty.
This way every request URL is only valid one time and only valid for the user who initially opened the page with the button on it.
you can create a unique token that is assigned to the button and can only be submitted once with the button press.
this will mean that the user will need to refresh the page to get a new button, if thats a problem, associate the token with the user and not the button
the above method means that you need to add server side code. you might be able to get away with using something like evercookie to log the button press on the clientside and attempt to prevent the user from sending another request and recieving another request from user - i dont recommend doing this in prod, but it might be fun ;)
ill try to be bit more clear:
generate the button so that it submits a form containing a hidden field called 'uuid' that contains a pre-generated uuid for that button. this uuid will need to be kept in the database or in memory. if you use a good uuid lib, the chance of the user generating an existing uuid are infinitesimal.
now, the user clicked the button and the action goes to /my-button/?uuid=3394b0e0-a3bb-11e1-b3dd-0800200c9a66
now the server checks if the uuid is a previously generated one. if it is, it deletes the uuid from where its stored and lets the action do whatever. the uuid does not exist, it returns a 404.
You can't possibly know how a request is initiated, all you can do is make it more difficult to fake. But if this is something to do with security, then it's the people who can successfully fake the request that you need to be most aware of. So it's likely useless (or even misleading) to attempt this as some kind of security measure.
You can try an encrypted key that the server will only accept once within a certain time lmit, but you will still not know how the request was initiated (and you really shouldn't depend on that). Buttons are a UI feature that might be converted into some other UI artifact based on whatever the user agent has been configured to present to the user (if there is a user invovled at all).
I am doing my work in PHP.
I have 3 pages,
A is plain HTML and contains a search field.
B is .php and returns results of the search.
C is also php and allows user to update some details for the displayed results.
When I'm doing Refresh my B page or Go-Back from C to then I
get this message
"To display this page, Firefox must
send information that will repeat any
action (such as a search or order
confirmation) that was performed
earlier."
I saw "When i'm using "POST" method then I get this message, if I'm used GET then
I don't.
Any buddy Explain me ,why???
The GET method should be used to obtain information from a web page.
The POST method should be used to send information to a web page.
The reason it asks you to confirm whether or not to send information again is because it's not always the user's intention to repost a form if they press back. One example is at an online store, you would not want to repost a form to purchase a product twice, otherwise you could be billed for the product twice. This is theoretical of course since someone who makes an online store should ensure that an accidental purchase can't happen.
Also, if you use GET, then all information is appended to the URL of the PHP page. This is a potential security issue, especially if the form contents are private. For such forms, you should be using POST.
A wild guess,
POST is not written in the URL, so you need to resend it, while GET, when you click to return to B, the arguments are still in the URL so you dont need to resend.
Mozilla added this message to warn you from sending the information twice.
Like in the form of registration, you don't want to register twice.
Firefox developers added that warning for POST method. It will warn you for POST in case of back/forward also.
This is an added safeguard for users. Because, most shopping carts/banking portals use POST method for checkout/transaction confirmation (actually I have not seen or developed any web app to use get method for this purpose).
So, Firefox (and most other common browsers) warn you in this scenario (when your are sending POST request indirectly, i.e. using back/forward/refresh button). This prevents the user from multiple checkout.
Another reason to add this warning is, sometimes chekout is time consuming. So, when some time is passed after the original submission, some impatient users think that the browser/server has stopped working. So, they tend to press the refresh button. This warning gives them a good hint.
I think the point is that GET requests should be used to get information without changing anything on the server so if you reload the same information there's no issue. POST requests should be used to change data on the server so when you reload the page that may have undesirable effects.
Firefox should normally allow you to navigate back to your B page from your C page. However if your B page is not in the cache, possibly because it sends a Cache-control: no-store header, then you will get the POSTDATA warning.
On the other hand explicitly reloading page B will always generate a POSTDATA warning.
When you submit data in the POST method, it sends headers to the page you submit to. When you refresh the page or go back, your browser repeats your POST request and Firefox warns you of this.
I have an application that supplies long list of parameters to a web page, so I have to use POST instead of GET. The problem is that when page gets displayed and user clicks the Back button, Firefox shows up a warning:
To display this page, Firefox must send information that will repeat any action (such as a search or order confirmation) that was performed earlier.
Since application is built in such way that going Back is a quite common operation, this is really annoying to end users.
Basically, I would like to do it the way this page does:
http://www.pikanya.net/testcache/
Enter something, submit, and click Back button. No warning, it just goes back.
Googling I found out that this might be a bug in Firefox 3, but I'd like to somehow get this behavior even after they "fix" it.
I guess it could be doable with some HTTP headers, but which exactly?
See my golden rule of web programming here:
Stop data inserting into a database twice
It says: “Never ever respond with a body to a POST-request. Always do the work, and then respond with a Location: header to redirect to the updated page so that browser requests it with GET”
If browser ever asks user about re-POST, your web app is broken. User should not ever see this question.
One way round it is to redirect the POST to a page which redirects to a GET - see Post/Redirect/Get on wikipedia.
Say your POST is 4K of form data. Presumably your server does something with that data rather than just displaying it once and throwing it away, such as saving it in a database. Keep doing that, or if it's a huge search form create a temporary copy of it in a database that gets purged after a few days or on a LRU basis when a space limit is used. Now create a representation of the data which can be accessed using GET. If it's temporary, generate an ID for it and use that as the URL; if it's a permanent set of data it probably has an ID or something that can be used for the URL. At the worst case, an algorithm like tiny url uses can collapse a big URL to a much smaller one. Redirect the POST to GET the representation of the data.
As a historical note, this technique was established practice in 1995.
One way to avoid that warning/behavior is to do the POST via AJAX, then send the user to another page (or not) separately.
I have been using the Session variable to help in this situation. Here's the method I use that has been working great for me for years:
//If there's something in the POST, move it to the session and then redirect right back to where we are
if ($_POST) {
$_SESSION['POST']=$_POST;
redirect($_SERVER["REQUEST_URI"]);
}
//If there's something in the SESSION POST, move it back to the POST and clear the SESSION POST
if ($_SESSION['POST']) {
$_POST=$_SESSION['POST'];
unset($_SESSION['POST']);
}
Technically you don't even need to put it back into a variable called $_POST. But it helps me in keeping track of what data has come from where.
I have an application that supplies long list of parameters to a web page, so I have to use POST instead of GET. The problem is that when page gets displayed and user clicks the Back button, Firefox shows up a warning:
Your reasoning is wrong. If the request is without side effects, it should be GET. If it has side effects, it should be POST. The choice should not be based on the number of parameters you need to pass.
As another solution you may stop to use redirecting at all.
You may process and render the processing result at once with no POST confirmation alert. You should just manipulate the browser history object:
history.replaceState("", "", "/the/result/page")
See full or short answers