Disallow 'Back' in Rails - ruby-on-rails

I am creating a web application that asks user for randomized security question. However, when the user answer the initially given question incorrectly, the user can go back and try a different answer. Is there a way to make sure that the page will do a re-submission when the user clicks the 'Back' button?

Dont fall back to javascript as a last resort, add an attempted boolean field to the question in the database and use that in your controller to ensure users are not just guessing at security questions.
If the user submits the form too many times for one question mark that as attempted and redirect them to another question.

Maybe you should do it with javascript because it's all in the browser...
this could help:
http://www.hunlock.com/blogs/Mastering_The_Back_Button_With_Javascript

Related

Rails: Ask for register after submit content?

In my Rails App, I made a form_for to allow any visitor to submit their content.
But after submit, I want to ask user, whether they want to register for this site or not.
There are some approach to this:
Redirect after user submits the form, left the initial post anonymous.
Much the same as the first one. But somehow help user to reclaim the post they just make
Store the content in some place first and do not submit. Instead, ask for register. And after register, show the stored content before and ask user to submit again.
Basically, I can implement the 1st method. But it seems just not that good. For the 2nd and 3rd one, I do not know how to reclaim the post or store content beforehand.
Is there a standard way to do this? How can I solve this problem?
For solving the same kind of problem, I chose your 3rd option. For that you can use sessions, it will allow you to keep some information in memory related to a specific connection to your server.
http://guides.rubyonrails.org/action_controller_overview.html#session
There are some ways.
First of all you need to keep in mind that these are different behaviors from which you should chose first and do not let the implementation force you to chose one.
For the second case you can have the id of the post that was created (along with some guarantees that it is an orphan post) and then tweak your register method to also assign a post to a user after creating one.
The Third case can be implemented by storing the post data either to session or to a backend temporary store and retrieve them if needed.

Rails 3 - Prevent form_for DOM action change

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.

CakePHP2.1 remove id in url

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.

How to have previous and next button in the django admin (change_form)

I want to modify the django admin for a particular model to provide the following behaviour.
A user make a search on the change_list page. The the user click a specific entry and he lands on the change_form for that entry. Nothing different to the usual.
Now, what I want is a mean to navigate the former search results. Basically next and previous buttons on the edit page.
What would be the best approach to implement this feature without modifying the admin site too much?
I will need to memorize the search in the user session, then when an entry is clicked I will need to known which place it has within the results to place my "cursor" accordingly. But I'm a bit in the cloud as the implementation side.
One way is to just put the next and previous button in the template for that particular model.
This can be implemented using simple javascript.
I ended writing a fully custom admin for that.

Preventing double HTTP POST

I have made a little app for signing up for an event. User input their data and click "sign me in".
Now sometimes people are double in the database, the exact same data that got inserted 2 times very quickly after each other. This can only mean someone clicked the button twice, which caused two posts to happen.
This is common web problem, as credit card apps and forum apps often say: "Clicking once is enough!".
I guess you could solve it by checking for the exact same data to see if the post is unique, but I wonder if there are other methods.
This ofcourse does not count for ASP.NET webforms, because POST doesn't matter as much.
While JavaScript solutions can disable the submit button after it has been clicked, this will have no effect on those people who have JavaScript disabled. You should always make things work correctly without JavaScript before adding it in, otherwise there's no point as users will still be able to bypass the checks by just disabling JavaScript.
If the page where the form appears is dynamically generated, you can add a hidden field which contains some sort of sequence number, a hash, or anything unique. Then you have some server-side validation that will check if a request with that unique value has already come in. When the user submits the form, the unique value is checked against a list of "used" values. If it exists in the list, it's a dupe request and can be discarded. If it doesn't exist, then add it to the list and process as normal. As long as you make sure the value is unique, this guarantees the same form cannot be submitted twice.
Of course, if the page the form is on is not dynamically generated, then you'll need to do it the hard way on the server-side to check that the same information has not already been submitted.
Most of the answers so far have been client-side. On the server-side, you can generate a hidden field with a GUID when you first produce the form, and then record that GUID as a submitted form when the post is received. Check it before doing any more processing.
Whenever a page is requested from the server , generate a unique requestToken , save it in server side,mark status as NOT Processed and pass it along with the current requested page. Now whenever a page submit happens , get the requestToken from the "POST"ed data and check the status and save the data or take alternate action.
Most of the banking applications use this technique to prevent double "POST"ing.So this is a time proven & reliable way of preventing double submissions.
A user-side solution is to disable the submission button via Javascript after the first click.
It has drawbacks, but I see it often used on e-commerce websites.
But, it won't never replace a real server-side validation.
Client side techniques are useful, but you may want to couple it with some server side techniques.
One way to do this is to include a unique token in the form (e.g. a GUID or similar), so that when you come to process the form you can check to see whether the token has already been used, preventing a double submission.
In your case, if you have a table with event visitors, you might include this token as a column.
A client-only solution won't be enough, as stated in many of the answers here. You need to go with a server-side fail-safe.
An often overlooked reason that disabling the submit button doesn't work is, the user can simply refresh the submit target (and click OK on the "are you sure you want to resubmit the POST data?" dialog). Or even, some browsers may implicitly reload the submitted page when you try to save the page to disk (for example, you're trying to save a hard-copy of an order confirmation).
Almost no one has js disabled.
Think about coding your e-commerce website for the 70 year old woman who double clicks every link and button.
All you want to do is add a javascript to prevent her clicking "Order Now" twice.
Yes - check this at the server side too "be defensive" - but don't code for that case. But for the sake of a better UI do it on the client side too.
Here are some scripts that I found:
//
// prevent double-click on submit
//
jQuery('input[type=submit]').click(function(){
if(jQuery.data(this, 'clicked')){
return false;
}
else{
jQuery.data(this, 'clicked', true);
return true;
}
});
and
// Find ALL <form> tags on your page
$('form').submit(function(){
// On submit disable its submit button
$('input[type=submit]', this).attr('disabled', 'disabled');
});
None of the solutions address a load-balance server.
If you have some load balancer, send a UUID (or any type of unique number) to the server to store and read again will not work well if the server is not aware of other servers, because each request could be processed by a different server in a stateless environment. These servers need to read/write to the same place.
If you have multiple servers you will need to have some shared cache (like a Redis) among the servers to read/write the unique value in the same place (what could be an over-engineering solution, but works).
Client side alteration is a common technique:
Disable submit button
Change the screen to a "please wait" screen
If the form was modal, changing the screen back to their usual process (this has the benefit of making things look really slick)
But it's not perfect. It all relies on JS being available and if that's not the case, without back-end duplication detection, you'll get duplicates still.
So my advice is to develop some sort of detection behind the scenes and then improve your form to stop people with JS being able to double-submit.
You can track the number of times the form's been submitted and compare it to the number of unique visits to the page with the form on it in the session.
Beside the many good techniques already mentioned, another simple server-side method, that has the drawback of requiring a session, is to have a session variable that is switched off on the first submit.

Resources