annotate core/modules/block/tests/src/Functional/BlockXssTest.php @ 19:fa3358dc1485 tip

Add ndrum files
author Chris Cannam
date Wed, 28 Aug 2019 13:14:47 +0100
parents 4c8ae668cc8c
children
rev   line source
Chris@0 1 <?php
Chris@0 2
Chris@0 3 namespace Drupal\Tests\block\Functional;
Chris@0 4
Chris@0 5 use Drupal\block_content\Entity\BlockContent;
Chris@0 6 use Drupal\block_content\Entity\BlockContentType;
Chris@0 7 use Drupal\Core\Url;
Chris@0 8 use Drupal\system\Entity\Menu;
Chris@0 9 use Drupal\Tests\BrowserTestBase;
Chris@0 10 use Drupal\views\Entity\View;
Chris@0 11
Chris@0 12 /**
Chris@0 13 * Tests that the block module properly escapes block descriptions.
Chris@0 14 *
Chris@0 15 * @group block
Chris@0 16 */
Chris@0 17 class BlockXssTest extends BrowserTestBase {
Chris@0 18
Chris@0 19 /**
Chris@0 20 * Modules to install.
Chris@0 21 *
Chris@0 22 * @var array
Chris@0 23 */
Chris@0 24 public static $modules = ['block', 'block_content', 'menu_ui', 'views'];
Chris@0 25
Chris@0 26 /**
Chris@0 27 * Tests that nothing is escaped other than the blocks explicitly tested.
Chris@0 28 */
Chris@0 29 public function testNoUnexpectedEscaping() {
Chris@0 30 $this->drupalLogin($this->drupalCreateUser(['administer blocks', 'access administration pages']));
Chris@0 31 $this->drupalGet(Url::fromRoute('block.admin_display'));
Chris@0 32 $this->clickLink('Place block');
Chris@0 33 $this->assertNoEscaped('<');
Chris@0 34 }
Chris@0 35
Chris@0 36 /**
Chris@0 37 * Tests XSS in title.
Chris@0 38 */
Chris@0 39 public function testXssInTitle() {
Chris@0 40 $this->container->get('module_installer')->install(['block_test']);
Chris@0 41 $this->drupalPlaceBlock('test_xss_title', ['label' => '<script>alert("XSS label");</script>']);
Chris@0 42
Chris@0 43 \Drupal::state()->set('block_test.content', $this->randomMachineName());
Chris@0 44 $this->drupalGet('');
Chris@0 45 $this->assertNoRaw('<script>alert("XSS label");</script>', 'The block title was properly sanitized when rendered.');
Chris@0 46
Chris@0 47 $this->drupalLogin($this->drupalCreateUser(['administer blocks', 'access administration pages']));
Chris@0 48 $default_theme = $this->config('system.theme')->get('default');
Chris@0 49 $this->drupalGet('admin/structure/block/list/' . $default_theme);
Chris@0 50 $this->assertNoRaw("<script>alert('XSS subject');</script>", 'The block title was properly sanitized in Block Plugin UI Admin page.');
Chris@0 51 }
Chris@0 52
Chris@0 53 /**
Chris@0 54 * Tests XSS in category.
Chris@0 55 */
Chris@0 56 public function testXssInCategory() {
Chris@0 57 $this->container->get('module_installer')->install(['block_test']);
Chris@0 58 $this->drupalPlaceBlock('test_xss_title');
Chris@0 59 $this->drupalLogin($this->drupalCreateUser(['administer blocks', 'access administration pages']));
Chris@0 60 $this->drupalGet(Url::fromRoute('block.admin_display'));
Chris@0 61 $this->clickLink('Place block');
Chris@0 62 $this->assertNoRaw("<script>alert('XSS category');</script>");
Chris@0 63 }
Chris@0 64
Chris@0 65 /**
Chris@0 66 * Tests various modules that provide blocks for XSS.
Chris@0 67 */
Chris@0 68 public function testBlockXss() {
Chris@0 69 $this->drupalLogin($this->rootUser);
Chris@0 70
Chris@0 71 $this->doViewTest();
Chris@0 72 $this->doMenuTest();
Chris@0 73 $this->doBlockContentTest();
Chris@0 74
Chris@0 75 $this->drupalGet(Url::fromRoute('block.admin_display'));
Chris@0 76 $this->clickLink('Place block');
Chris@0 77 $this->assertNoRaw('&amp;lt;', 'The page does not have double escaped HTML tags.');
Chris@0 78 }
Chris@0 79
Chris@0 80 /**
Chris@0 81 * Tests XSS coming from View block labels.
Chris@0 82 */
Chris@0 83 protected function doViewTest() {
Chris@0 84 // Create a View without a custom label for its block Display. The
Chris@0 85 // admin_label of the block then becomes just the View's label.
Chris@0 86 $view = View::create([
Chris@0 87 'id' => $this->randomMachineName(),
Chris@0 88 'label' => '<script>alert("view1");</script>',
Chris@0 89 ]);
Chris@0 90 $view->addDisplay('block');
Chris@0 91 $view->save();
Chris@0 92
Chris@0 93 // Create a View with a custom label for its block Display. The
Chris@0 94 // admin_label of the block then becomes the View's label combined with
Chris@0 95 // the Display's label.
Chris@0 96 $view = View::create([
Chris@0 97 'id' => $this->randomMachineName(),
Chris@0 98 'label' => '<script>alert("view2");</script>',
Chris@0 99 ]);
Chris@0 100 $view->addDisplay('block', 'Fish & chips');
Chris@0 101 $view->save();
Chris@0 102
Chris@0 103 $this->drupalGet(Url::fromRoute('block.admin_display'));
Chris@0 104 $this->clickLink('Place block');
Chris@0 105
Chris@0 106 // \Drupal\views\Plugin\Derivative\ViewsBlock::getDerivativeDefinitions()
Chris@0 107 // has a different code path for an admin label based only on the View
Chris@0 108 // label versus one based on both the View label and the Display label.
Chris@0 109 // Ensure that this test is covering both code paths by asserting the
Chris@0 110 // absence of a ":" for the first View and the presence of a ":" for the
Chris@0 111 // second one. Note that the second assertion is redundant with the one
Chris@0 112 // further down which also checks for the Display label, but is included
Chris@0 113 // here for clarity.
Chris@0 114 $this->assertNoEscaped('<script>alert("view1");</script>:');
Chris@0 115 $this->assertEscaped('<script>alert("view2");</script>:');
Chris@0 116
Chris@0 117 // Assert that the blocks have their admin labels escaped and
Chris@0 118 // don't appear anywhere unescaped.
Chris@0 119 $this->assertEscaped('<script>alert("view1");</script>');
Chris@0 120 $this->assertNoRaw('<script>alert("view1");</script>');
Chris@0 121 $this->assertEscaped('<script>alert("view2");</script>: Fish & chips');
Chris@0 122 $this->assertNoRaw('<script>alert("view2");</script>');
Chris@0 123 $this->assertNoRaw('Fish & chips');
Chris@0 124
Chris@0 125 // Assert the Display label doesn't appear anywhere double escaped.
Chris@0 126 $this->assertNoRaw('Fish & chips');
Chris@0 127 $this->assertNoRaw('Fish &amp;amp; chips');
Chris@0 128 }
Chris@0 129
Chris@0 130 /**
Chris@0 131 * Tests XSS coming from Menu block labels.
Chris@0 132 */
Chris@0 133 protected function doMenuTest() {
Chris@0 134 Menu::create([
Chris@0 135 'id' => $this->randomMachineName(),
Chris@0 136 'label' => '<script>alert("menu");</script>',
Chris@0 137 ])->save();
Chris@0 138
Chris@0 139 $this->drupalGet(Url::fromRoute('block.admin_display'));
Chris@0 140 $this->clickLink('Place block');
Chris@0 141
Chris@0 142 $this->assertEscaped('<script>alert("menu");</script>');
Chris@0 143 $this->assertNoRaw('<script>alert("menu");</script>');
Chris@0 144 }
Chris@0 145
Chris@0 146 /**
Chris@0 147 * Tests XSS coming from Block Content block info.
Chris@0 148 */
Chris@0 149 protected function doBlockContentTest() {
Chris@0 150 BlockContentType::create([
Chris@0 151 'id' => 'basic',
Chris@0 152 'label' => 'basic',
Chris@0 153 'revision' => TRUE,
Chris@0 154 ])->save();
Chris@0 155 BlockContent::create([
Chris@0 156 'type' => 'basic',
Chris@0 157 'info' => '<script>alert("block_content");</script>',
Chris@0 158 ])->save();
Chris@0 159
Chris@0 160 $this->drupalGet(Url::fromRoute('block.admin_display'));
Chris@0 161 $this->clickLink('Place block');
Chris@0 162
Chris@0 163 $this->assertEscaped('<script>alert("block_content");</script>');
Chris@0 164 $this->assertNoRaw('<script>alert("block_content");</script>');
Chris@0 165 }
Chris@0 166
Chris@0 167 }