3 namespace Drupal\KernelTests\Core\Form;
5 use Drupal\Core\Form\FormInterface;
6 use Drupal\Core\Form\FormStateInterface;
7 use Drupal\KernelTests\KernelTestBase;
8 use Drupal\user\Entity\User;
9 use Symfony\Component\HttpFoundation\Request;
12 * Ensures that form actions can't be tricked into sending to external URLs.
16 class ExternalFormUrlTest extends KernelTestBase implements FormInterface {
21 public static $modules = ['user', 'system'];
26 public function getFormId() {
27 return 'external_form_url_test';
33 public function buildForm(array $form, FormStateInterface $form_state) {
34 $form['something'] = [
35 '#type' => 'textfield',
36 '#title' => 'What do you think?',
44 public function validateForm(array &$form, FormStateInterface $form_state) {}
49 public function submitForm(array &$form, FormStateInterface $form_state) {}
54 protected function setUp() {
56 $this->installSchema('system', ['key_value_expire', 'sequences']);
57 $this->installEntitySchema('user');
59 $test_user = User::create([
61 'mail' => 'foobar@example.com',
64 \Drupal::service('current_user')->setAccount($test_user);
68 * Tests form behaviour.
70 public function testActionUrlBehavior() {
71 // Create a new request which has a request uri with multiple leading
72 // slashes and make it the master request.
73 $request_stack = \Drupal::service('request_stack');
74 /** @var \Symfony\Component\HttpFoundation\RequestStack $original_request */
75 $original_request = $request_stack->pop();
76 // Just request some more so there is no request left.
77 $request_stack->pop();
78 $request_stack->pop();
79 $request = Request::create($original_request->getSchemeAndHttpHost() . '//example.org');
80 $request_stack->push($request);
82 $form = \Drupal::formBuilder()->getForm($this);
83 $markup = \Drupal::service('renderer')->renderRoot($form);
85 $this->setRawContent($markup);
86 $elements = $this->xpath('//form/@action');
87 $action = (string) $elements[0];
88 $this->assertEqual($original_request->getSchemeAndHttpHost() . '//example.org', $action);
90 // Create a new request which has a request uri with a single leading slash
91 // and make it the master request.
92 $request_stack = \Drupal::service('request_stack');
93 $original_request = $request_stack->pop();
94 $request = Request::create($original_request->getSchemeAndHttpHost() . '/example.org');
95 $request_stack->push($request);
97 $form = \Drupal::formBuilder()->getForm($this);
98 $markup = \Drupal::service('renderer')->renderRoot($form);
100 $this->setRawContent($markup);
101 $elements = $this->xpath('//form/@action');
102 $action = (string) $elements[0];
103 $this->assertEqual('/example.org', $action);