3 namespace Drupal\metatag\Tests;
5 use Drupal\simpletest\WebTestBase;
8 * Ensures that meta tags do not allow xss vulnerabilities.
12 class MetatagXssTest extends WebTestBase {
15 * String that causes an alert when page titles aren't filtered for xss.
19 private $xssTitleString = '<script>alert("xss");</script>';
22 * String that causes an alert when meta tags aren't filtered for xss.
26 private $xssString = '"><script>alert("xss");</script><meta "';
29 * Rendered xss tag that has escaped attribute to avoid xss injection.
33 private $escapedXssTag = '<meta name="abstract" content="">alert("xss");" />';
36 * String that causes an alert when meta tags aren't filtered for xss.
38 * "Image" meta tags are processed differently to others, so this checks for a
43 private $xssImageString = '"><script>alert("image xss");</script><meta "';
46 * Rendered xss tag that has escaped attribute to avoid xss injection.
50 private $escapedXssImageTag = '<link rel="image_src" href="">alert("image xss");" />';
53 * Administrator user for tests.
55 * @var \Drupal\user\UserInterface
62 public static $modules = [
75 protected function setUp() {
78 // Create a user that can manage content types and create content.
79 $admin_permissions = [
80 'administer content types',
83 'administer meta tags',
84 'administer site configuration',
86 'administer content types',
88 'administer node fields',
91 // Create and login a with the admin-ish permissions user.
92 $this->adminUser = $this->drupalCreateUser($admin_permissions);
93 $this->drupalLogin($this->adminUser);
95 // Set up a content type.
96 $this->drupalCreateContentType(['type' => 'metatag_node', 'name' => 'Test Content Type']);
98 // Add a metatag field to the content type.
99 $this->drupalGet('admin/structure/types/manage/metatag_node/fields/add-field');
100 $this->assertResponse(200);
102 'label' => 'Metatag',
103 'field_name' => 'metatag_field',
104 'new_storage_type' => 'metatag',
106 $this->drupalPostForm(NULL, $edit, t('Save and continue'));
107 $this->drupalPostForm(NULL, [], t('Save field settings'));
111 * Verify XSS injected in global config is not rendered.
113 public function testXssMetatagConfig() {
114 $this->drupalGet('admin/config/search/metatag/global');
115 $this->assertResponse(200);
117 'title' => $this->xssTitleString,
118 'abstract' => $this->xssString,
119 'image_src' => $this->xssImageString,
121 $this->drupalPostForm(NULL, $values, 'Save');
122 $this->assertText('Saved the Global Metatag defaults.');
125 // Load the Views-based front page.
126 $this->drupalGet('node');
127 $this->assertResponse(200);
128 $this->assertText(t('No front page content has been created yet.'));
130 // Check for the title tag, which will have the HTML tags removed and then
131 // be lightly HTML encoded.
132 $this->assertEscaped(strip_tags($this->xssTitleString));
133 $this->assertNoRaw($this->xssTitleString);
135 // Check for the basic meta tag.
136 $this->assertRaw($this->escapedXssTag);
137 $this->assertNoRaw($this->xssString);
139 // Check for the image meta tag.
140 $this->assertRaw($this->escapedXssImageTag);
141 $this->assertNoRaw($this->xssImageString);
145 * Verify XSS injected in the entity metatag override field is not rendered.
147 public function testXssEntityOverride() {
148 $save_label = (floatval(\Drupal::VERSION) <= 8.3) ? t('Save and publish') : t('Save');
150 $this->drupalGet('node/add/metatag_node');
151 $this->assertResponse(200);
153 'title[0][value]' => $this->randomString(32),
154 'field_metatag_field[0][basic][title]' => $this->xssTitleString,
155 'field_metatag_field[0][basic][abstract]' => $this->xssString,
156 'field_metatag_field[0][advanced][image_src]' => $this->xssImageString,
158 $this->drupalPostForm(NULL, $edit, $save_label);
160 // Check for the title tag, which will have the HTML tags removed and then
161 // be lightly HTML encoded.
162 $this->assertEscaped(strip_tags($this->xssTitleString));
163 $this->assertNoRaw($this->xssTitleString);
165 // Check for the basic meta tag.
166 $this->assertRaw($this->escapedXssTag);
167 $this->assertNoRaw($this->xssString);
169 // Check for the image meta tag.
170 $this->assertRaw($this->escapedXssImageTag);
171 $this->assertNoRaw($this->xssImageString);
175 * Verify XSS injected in the entity titles are not rendered.
177 public function testXssEntityTitle() {
178 $save_label = (floatval(\Drupal::VERSION) <= 8.3) ? t('Save and publish') : t('Save');
180 $this->drupalGet('node/add/metatag_node');
181 $this->assertResponse(200);
183 'title[0][value]' => $this->xssTitleString,
184 'body[0][value]' => $this->randomString() . ' ' . $this->randomString(),
186 $this->drupalPostForm(NULL, $edit, $save_label);
188 // Check for the title tag, which will have the HTML tags removed and then
189 // be lightly HTML encoded.
190 $this->assertEscaped(strip_tags($this->xssTitleString));
191 $this->assertNoRaw($this->xssTitleString);
195 * Verify XSS injected in the entity fields are not rendered.
197 public function testXssEntityBody() {
198 $save_label = (floatval(\Drupal::VERSION) <= 8.3) ? t('Save and publish') : t('Save');
200 $this->drupalGet('node/add/metatag_node');
201 $this->assertResponse(200);
203 'title[0][value]' => $this->randomString(),
204 'body[0][value]' => $this->xssTitleString,
206 $this->drupalPostForm(NULL, $edit, $save_label);
208 // Check the body text.
209 // $this->assertNoTitle($this->xssTitleString);
210 $this->assertNoRaw($this->xssTitleString);