Submitting Protected Forms Programatically with Safe User Impersonation

Note: This article was originally published on the Growing Venture Solutions website.

When a form protected by spam prevention measures such as captcha or Mollom is submitted with drupal_execute, validation can fail unless the spam protection is properly suppressed.

This blog post describes the background and solution to a bug that previously existed in the Signup Integration for Ubercart module (uc_signup), and explains the techniques used to fix the bug. It is written with developers and aspiring developers in mind, though other people interested in how Drupal works might also find it interesting.

drupal_execute is a function often used in data imports that allows a developer to take a collection of form values and submit them programatically.
A main reason to use drupal_execute over another technique such as user_save() is that with drupal_execute, Drupal calls the validation and submission functions for the form.

The Context: How uc_signup Uses drupal_execute

In the Signup integration for Ubercart module, we sometimes create a new user account and populate the user's profile with data that was submitted on a form separate from the core user profile form. In earlier versions of uc_signup, we created the new account with user_save, however this allowed crafty users to leave required fields blank by skipping the form and proceeding to checkout, so we switched to drupal_execute which ensures that the form's validation gets executed.

The Problem

The drupal_execute function is relatively easy to use -- just pass in the form_id and form values you'd like to submit to the form.

However, we soon got a bug report with one user reporting a validation error at the time that the new user account is saved, with the captcha module enabled for the user registration form.

Captchas often take the shape of "those squiggly letters" used to determine whether you are a human being or a computer program that submits spam to websites.

Uc_signup can collect profile information for multiple users on a single "attendee contact information" form that is integrated into the Ubercart checkout process.


Uc_signup's Attendee Contact Information" form.

By design, this form has a unique form_id, so it isn't protected by captchas that protect the user registration form. The required fields on the attendee information form correspond to those on the user registration form -- except that on the attendee information form, there is no captcha. When uc_signup takes user-entered data from this form and submits it into the user registration form, validation on the user registration form fails because this form has a captcha, which was never presented to the user and is therefore not filled in.

Finding a Solution

So, we needed a way to bypass the captcha protection.
Should we unset the form validation function from the captcha element? Should we remove the captcha element from the form altogether?

The simplest and least error-prone solution turns out to be to prevent the captcha from ever being added to the user registration form for this specific situation.

Both internal spam prevention services (such as captcha and spam.module) and external ones (such as Mollom and Akismet) use Drupal's user permissions system to allow certain users to bypass the protection that they add to forms.

drupal_execute submits forms with the permissions of whichever user is logged in (or an anonymous user). In most cases, people who are using the attendee information form will not have permission to bypass spam protection site-wide. The solution to our captcha validation problem is to have our module submit the form as if it were a privileged user. That way, the captcha will never be added to the form.

User Impersonation: Not just for Halloween.

User impersonation is a technique that developers can use to allow a particular section of code to be run as a particular user. In Drupal, the user with UID 1 has all permissions available on a site. In uc_signup, we impersonate User 1 before performing the drupal_execute so that captcha waves protection for the form.

Practicing Safe Impersonation

It's important to follow best practices when performing user impersonation. Not doing so can allow users on your site to gain control over the account being used for the impersonation, resulting in a serious security vulnerability.

After calling global $user;, setting the $user variable equal to a different user account will cause the currently logged in user to switch to that account. That is why it is a best practice to use another variable, such as $account, when working with user accounts without the intention of impersonating users.

You must set session_save_session(FALSE); before switching to the impersonated user. The reason for this is that if your action fails or interrupts the request with a drupal_goto and session saving is enabled, the user will then be logged in as user 1, with all privileges on your site. By setting this value to FALSE and then back to TRUE, we make sure that the impersonation only exists when we're performing the required action, and does not persist if the action fails.

The code snippet below is a more heavily commented version of the code used in uc_signup. This code snippet impersonates User 1, submits the user registration form with the previously entered values, and then switches the session back to the user who was previously logged in. Note that we have three variables that refer to user accounts:

global $user - The account of the currently logged in user.
$temp_user - The variable used to store the current user's account while we temporarily switch the session to the privileged user.
$account - The account created as a result of submitting the user registration form.

This code actually appears inside of a foreach loop and some conditional logic, so that it if the attendee contact information form collects information for multiple new users, the user registration form is submitted once for each new account.

To get the full context of this snippet, you may wish to view the full contents of uc_signup.module.


//Load the global $user object that contains the account of the currently logged in user.
global $user;
//Preserve this account in the $temp_user variable so that we can switch back to it after impersonating the privileged user.
$temp_user = $user;
//We must set this to FALSE in case the operation on the following lines fails.
session_save_session(FALSE);
//Switch the currently logged in user to user 1.
$user = user_load(1);
//Submit the user registration form.
drupal_execute('user_register', $form_state);
//Switch back to the account we saved in the $temp_user variable.
$user = $temp_user;
//Restore session saving.
session_save_session(TRUE);
//Populate the $account variable with the account created as a result of submitting the user_register form. We later go on to sign up this user to one or more events that are being purchased.
$account = $form_state['user'];
?>

Tags: 

Comments

nice work

The quality of content is fine and the conclusion is excellent.I would like to ask if it would be Okay if I mentioned some of that on my own blog.Thank You for the post That is genuinely helpful. Altadena Garage Door Repair I must acknowledged you for the information you shared. I like the services that amazingly surprised me that this kind of work should be done in the proper way and also thanks for the information you shared.This looks absolutely perfect.I am very much overwhelmed by your thoughts for this particular story.

So Good

This blog is written very popular, too creative too ideas. I strongly support your point of view, very much agree with your views; I always wanted to understand the comprehensive features. Thank you so much . website This really is this kind of a awesome resource that you're offering and you give it away for totally free. I take pleasure in seeing sites that realize the value of supplying a prime resource for absolutely free.

Thanks Your Post has a lot of

Thanks Your Post has a lot of great information and it has really helped me alot. Excellent post and wonderful blog, HCG Drops I really like this type of interesting articles keep it u.Really impressed! Everything is very open and very clear explanation of issues. It contains truly information. Your website is very useful. Thanks for sharing.It is nice to find a site about my interest. My first visit to your site is been a big help.

main title

A classic gaming experience with the laughing sun: Fancy a quick game to not so sunny days? ThenMercury Magnus might be just for you and you can quickly forget the rainy weather. A classically-held slot game presents you with the merkur spiele .So with you the sun rises, the well-known symbol of good luck is also part again. Moments of happiness you'll certainly have, because there are big profits possible in this great retro style slot machines. Fortuna so it really kind to you, we'll tell you the rules of the game here. Over and over, then plunge to people who suspect, distinguish preferable alternatives and receive they have more sense than triple chance kostenlos spielen

I wanted to leave a little

I wanted to leave a little comment to support you and wish you a good continuation. Wishing you the best of luck for all your blogging efforts. Natural Link Profile This is my first chance to chat this website I found some attractive things and I will apply to the development of my blog.There are a lot of blogs and articles out there on this topic

Thanks., same feeling. Scrum

Thanks., same feeling. Scrum is for management people who do not have programming experience, not for programmer. Zapatillas Trail Running Brooks Cascadia 8 Those people also need programmers to divide tasks and estimate time.For sure many student don't want that ROTC to be included on their university, and if they imposed it mandatory, I guess follow some personal rights which protects the dignity of every student by having that Don't ask Don't tell policy.

Thanks a lot for such a

Thanks a lot for such a wonderful post, the stuff posted were really interesting and useful. The quality of the content was good and clear.Glad to visit your blog, I look forward to more good articles and I think we all like to thank so many good articles, blog to share with us.This is just the information I am finding everywhere. child care marketing Me and my friend were arguing about an issue similar to this! Now I know that I was right.Thanks for the information you post.

Thanks Your Post has a lot of

Thanks Your Post has a lot of great information and it has really helped me alot. Excellent post and wonderful blog, I really like this type of interesting articles keep it u.Really impressed! Everything is very open and very clear explanation of issues. Tradzik It contains truly information. Your website is very useful. Thanks for sharing.It is nice to find a site about my interest. My first visit to your site is been a big help.

nice

Yellow Pages Cybo A reliable informative post that you have shared and appreciate your work for sharing the information. Got some entertaining information and would like to provide it a try. Appreciate your work and keep sharing your information.

Once the seller and buyer

Once the seller and buyer have signed the contract, the agent or real estate broker must make sure that all terms of the contract are met before the closing date of the contract. If the seller agrees letting agents london to make repairs, agents and brokers must ensure that they are carried out. Increasingly, agents and brokers must deal with environmental issues, such as advising buyers about lead paint on the walls.

Again, you can't connect the

Again, you can't connect the dots looking forward; you can only connect them looking backwards. So you have to trust that the dots will somehow connect in your future. You have to trust in something - your gut, destiny, life, karma, whatever. This approach has never let me down, and it has made all the difference in my life.
www.eyewearsegment.com

online game casino

themulti player online games Everyone knows it. With the right bingo zahlen can make a lot of money! We also thought that for a long time and asked us if there is a formula that lets you win more often than average at bingo. After many trials, which cost us a lot of money, we have made ??contact with a professor of mathematics at the University of Berlin in order to shed light on the whole statistically.