Using form tokens for secure submissionsfor Drupal 8 , 9 , 10 , and 11

Last updated :  

Ensuring the security of form submissions in Drupal is crucial to protect against common web vulnerabilities such as Cross-Site Request Forgery (CSRF). Form tokens are a key component in safeguarding forms by verifying that submissions originate from the correct and expected source.

Understanding Form Tokens

A form token is a unique, hidden value embedded into each form instance in Drupal and tied to the user's session. When a form is submitted, Drupal checks the token to ensure it matches the expected value, preventing unauthorized actions possibly triggered via third-party sites.

Benefits of Using Form Tokens

  • Security: Prevents CSRF attacks by ensuring that form submissions are initiated by authorized users from vetted pages.
  • Integrity: Assures site users that data submissions (such as form inputs) are not compromised between the start and completion of the action.
  • Trust: Instills greater user confidence in the application by safeguarding interactive components.

Implementing Form Tokens in Drupal Forms

Drupal's Form API automatically manages tokens for forms, but understanding their role and confirming they're correctly implemented is vital for maintaining secure interactions.

Example: Ensuring Tokens in a Custom Form

We'll demonstrate verifying the presence of a form token in a custom feedback form, ensuring submissions are validated correctly.

Step 1: Create a Custom Form

Set up a basic form using the \Drupal\Core\Form\FormBase class. By default, Drupal takes care of generating and validating tokens for you:


// In src/Form/FeedbackForm.php
namespace Drupal\my_module\Form;

use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;

class FeedbackForm extends FormBase {
  
  public function getFormId() {
    return 'feedback_form';
  }

  public function buildForm(array $form, FormStateInterface $form_state) {
    $form['email'] = [
      '#type' => 'email',
      '#title' => $this->t('Your Email'),
      '#required' => TRUE,
    ];
    $form['feedback'] = [
      '#type' => 'textarea',
      '#title' => $this->t('Your Feedback'),
    ];
    $form['submit'] = [
      '#type' => 'submit',
      '#value' => $this->t('Submit'),
    ];

    return $form;
  }

  public function submitForm(array &$form, FormStateInterface $form_state) {
    drupal_set_message($this->t('Thanks for your feedback, we will review your input.'));
  }
}

Step 2: Understanding Automatic Token Implementation

When Drupal renders the form, it automatically generates a hidden token within the form. You can inspect this by viewing the HTML source code and looking for an input with name="form_token". This token is validated on form submission against the session values stored at render time.

Verifying Custom Forms

If you build custom form submissions outside of the Form API (for example, handling AJAX submissions), ensure tokens are explicitly included and validated to maintain security standards. Use Drupal's built-in functions for token validation when handling custom submissions.


// Example of manually verifying a token
use Drupal\Core\Form\FormStateInterface;

/**
 * Custom function to validate a form token.
 */
function validate_custom_submission($form, FormStateInterface $form_state) {
  $token = $form_state->getValue('form_token');
  if (!\Drupal::service('csrf_token')->validate($token, 'your_custom_action')) {
    // Handle invalid token scenario
    drupal_set_message(t('Invalid token, please try again.'), 'error');
  }
}

Key Considerations

  • Use the Form API whenever possible to benefit from built-in security practices.
  • Always verify tokens in custom form handlers, particularly with non-standard submission methods.
  • Regularly educate development teams about the importance of CSRF protection and tokens.

Summary

Leveraging form tokens in Drupal forms is a fundamental aspect of web security, ensuring the integrity and authenticity of form submissions. By allowing the Form API to automatically handle tokens, or by manually verifying them in custom implementations, you can provide a safer environment for your users.

Teaser for the Next Lesson

In our next tutorial, we will look at using Html::escape() for user input, which will help sanitize data and maintain security throughout your Drupal application. Stay tuned for further insights into secure coding practices!