diff --git a/core/modules/dblog/src/Controller/DbLogController.php b/core/modules/dblog/src/Controller/DbLogController.php
index 44828e4..cccd91d 100644
--- a/core/modules/dblog/src/Controller/DbLogController.php
+++ b/core/modules/dblog/src/Controller/DbLogController.php
@@ -8,8 +8,9 @@
 namespace Drupal\dblog\Controller;
 
 use Drupal\Component\Utility\Html;
-use Drupal\Component\Utility\Unicode;
+use Drupal\Component\Utility\SafeMarkup;
 use Drupal\Component\Utility\String;
+use Drupal\Component\Utility\Unicode;
 use Drupal\Component\Utility\Xss;
 use Drupal\Core\Controller\ControllerBase;
 use Drupal\Core\Database\Connection;
@@ -229,7 +230,6 @@ public function overview() {
    * @return array
    *   If the ID is located in the Database Logging table, a build array in the
    *   format expected by drupal_render();
-   *
    */
   public function eventDetails($event_id) {
     $build = array();
@@ -240,6 +240,22 @@ public function eventDetails($event_id) {
         '#theme' => 'username',
         '#account' => user_load($dblog->uid),
       );
+      // Validate the event link if it is safe.
+      if (!SafeMarkup::isSafe($dblog->link)) {
+        $event_link = Xss::filterAdmin($dblog->link);
+      }
+      else {
+        $event_link = SafeMarkup::set($dblog->link);
+      }
+
+      // Validate the message if it is safe.
+      if (!SafeMarkup::isSafe($message)) {
+        $message = Xss::filterAdmin($message);
+      }
+      else {
+        $message = SafeMarkup::set($message);
+      }
+
       $rows = array(
         array(
           array('data' => $this->t('Type'), 'header' => TRUE),
@@ -255,11 +271,11 @@ public function eventDetails($event_id) {
         ),
         array(
           array('data' => $this->t('Location'), 'header' => TRUE),
-          $this->l($dblog->location, $dblog->location ? Url::fromUri($dblog->location) : Url::fromRoute('<none>')),
+          $this->l($dblog->location, (!empty($dblog->location) ? Url::fromUri($dblog->location) : new Url('<front>'))),
         ),
         array(
           array('data' => $this->t('Referrer'), 'header' => TRUE),
-          $this->l($dblog->referer, $dblog->referer ? Url::fromUri($dblog->referer) : Url::fromRoute('<none>')),
+          $this->l($dblog->referer, (!empty($dblog->referer) ? Url::fromUri($dblog->referer) : new Url('<front>'))),
         ),
         array(
           array('data' => $this->t('Message'), 'header' => TRUE),
@@ -275,7 +291,7 @@ public function eventDetails($event_id) {
         ),
         array(
           array('data' => $this->t('Operations'), 'header' => TRUE),
-          $dblog->link,
+          $event_link,
         ),
       );
       $build['dblog_table'] = array(
@@ -299,7 +315,7 @@ public function eventDetails($event_id) {
    */
   protected function buildFilterQuery() {
     if (empty($_SESSION['dblog_overview_filter'])) {
-      return;
+      return NULL;
     }
 
     $this->moduleHandler->loadInclude('dblog', 'admin.inc');
@@ -329,7 +345,7 @@ protected function buildFilterQuery() {
   /**
    * Formats a database log message.
    *
-   * @param stdClass $row
+   * @param \stdClass $row
    *   The record from the watchdog table. The object properties are: wid, uid,
    *   severity, type, timestamp, message, variables, link, name.
    *
@@ -352,7 +368,7 @@ public function formatMessage($row) {
     else {
       $message = FALSE;
     }
-    return $message;
+    return ($message) ? Xss::filterAdmin($message) : FALSE;
   }
 
   /**
diff --git a/core/modules/dblog/src/Tests/DbLogTest.php b/core/modules/dblog/src/Tests/DbLogTest.php
index d6a59ad..f306ad3 100644
--- a/core/modules/dblog/src/Tests/DbLogTest.php
+++ b/core/modules/dblog/src/Tests/DbLogTest.php
@@ -7,9 +7,11 @@
 
 namespace Drupal\dblog\Tests;
 
+use Drupal\Component\Utility\String;
 use Drupal\Component\Utility\Unicode;
 use Drupal\Component\Utility\Xss;
 use Drupal\Core\Logger\RfcLogLevel;
+use Drupal\Core\Url;
 use Drupal\dblog\Controller\DbLogController;
 use Drupal\simpletest\WebTestBase;
 
@@ -50,7 +52,12 @@ protected function setUp() {
     $this->drupalPlaceBlock('system_breadcrumb_block');
 
     // Create users with specific permissions.
-    $this->adminUser = $this->drupalCreateUser(array('administer site configuration', 'access administration pages', 'access site reports', 'administer users'));
+    $this->adminUser = $this->drupalCreateUser(array(
+      'administer site configuration',
+      'access administration pages',
+      'access site reports',
+      'administer users',
+    ));
     $this->webUser = $this->drupalCreateUser(array());
   }
 
@@ -61,7 +68,7 @@ protected function setUp() {
    * Database Logging module functionality through both the admin and user
    * interfaces.
    */
-  function testDbLog() {
+  public function testDbLog() {
     // Login the admin user.
     $this->drupalLogin($this->adminUser);
 
@@ -71,6 +78,8 @@ function testDbLog() {
     $this->verifyEvents();
     $this->verifyReports();
     $this->verifyBreadcrumbs();
+    $this->verifyLinkEscaping();
+    $this->verifyMessageEscaping();
     // Verify the overview table sorting.
     $orders = array('Date', 'Type', 'User');
     $sorts = array('asc', 'desc');
@@ -129,21 +138,18 @@ private function verifyCron($row_limit) {
    *
    * @param int $count
    *   Number of watchdog entries to generate.
-   * @param string $type
-   *   (optional) The type of watchdog entry. Defaults to 'custom'.
-   * @param int $severity
-   *   (optional) The severity of the watchdog entry. Defaults to
-   *   \Drupal\Core\Logger\RfcLogLevel::NOTICE.
+   * @param array $options
+   *   (optional) An array of options that override the default values.
    */
-  private function generateLogEntries($count, $type = 'custom', $severity = RfcLogLevel::NOTICE) {
+  private function generateLogEntries($count, $options = array()) {
     global $base_root;
 
-    // Prepare the fields to be logged
-    $log = array(
-      'channel'     => $type,
-      'message'     => 'Log entry added to test the dblog row limit.',
+    // Prepare the fields to be logged.
+    $log = $options + array(
+      'channel'     => 'system',
+      'message'     => 'Dblog test log message',
       'variables'   => array(),
-      'severity'    => $severity,
+      'severity'    => RfcLogLevel::NOTICE,
       'link'        => NULL,
       'user'        => $this->adminUser,
       'uid'         => $this->adminUser->id(),
@@ -151,11 +157,18 @@ private function generateLogEntries($count, $type = 'custom', $severity = RfcLog
       'referer'     => \Drupal::request()->server->get('HTTP_REFERER'),
       'ip'          => '127.0.0.1',
       'timestamp'   => REQUEST_TIME,
-      );
-    $message = 'Log entry added to test the dblog row limit. Entry #';
-    for ($i = 0; $i < $count; $i++) {
-      $log['message'] = $message . $i;
-      $this->container->get('logger.dblog')->log($severity, $log['message'], $log);
+    );
+
+    $logger = $this->container->get('logger.dblog');
+    if ($count > 1) {
+      $row_message = $log['message'] . ' Entry #';
+      for ($i = 0; $i < $count; $i++) {
+        $log['message'] = $row_message . $i;
+        $logger->log($log['severity'], $log['message'], $log);
+      }
+    }
+    else {
+      $logger->log($log['severity'], $log['message'], $log);
     }
   }
 
@@ -240,13 +253,89 @@ private function verifyEvents() {
    * @param string $order
    *   The order by which the table should be sorted.
    */
-  public function verifySort($sort = 'asc', $order = 'Date') {
+  protected function verifySort($sort = 'asc', $order = 'Date') {
     $this->drupalGet('admin/reports/dblog', array('query' => array('sort' => $sort, 'order' => $order)));
     $this->assertResponse(200);
     $this->assertText(t('Recent log messages'), 'DBLog report was displayed correctly and sorting went fine.');
   }
 
   /**
+   * Tests the escaping of links in the operation row of a database log detail
+   * page.
+   */
+  private function verifyLinkEscaping() {
+    $link = \Drupal::l('View', Url::fromRoute('entity.node.canonical', array('node' => 1)));
+    $message = 'Log entry added to do the verifyLinkEscaping test.';
+    $this->generateLogEntries(1, array(
+      'message' => $message,
+      'link' => $link,
+    ));
+
+    $result = db_query_range('SELECT wid FROM {watchdog} ORDER BY wid DESC', 0, 1);
+    $this->drupalGet('admin/reports/dblog/event/' . $result->fetchField());
+
+    // Check if the link exists (unescaped).
+    $this->assertRaw($link);
+
+    // Check for XSS filtering.
+    $js_txt = 'This should not pop up!';
+    $js = '<script>alert("' . $js_txt . '");</script>';
+    $this->generateLogEntries(1, array(
+      'message' => $message,
+      'link' => $link . $js,
+    ));
+
+    $result = db_query_range('SELECT wid FROM {watchdog} ORDER BY wid DESC', 0, 1);
+    $this->drupalGet('admin/reports/dblog/event/' . $result->fetchField());
+
+    // Check if the link exists (unescaped).
+    $this->assertRaw($link);
+
+    // Check if javascript was escaped.
+    $this->assertNoRaw($js, 'Detail view: javascript in link is blocked');
+    $this->assertRaw($js_txt, 'Detail view: javascript text exists');
+  }
+
+  /**
+   * Test the escaping of message in the operation row of a database log detail
+   * page.
+   */
+  private function verifyMessageEscaping() {
+    $link = \Drupal::l('View', Url::fromRoute('entity.node.canonical', array('node' => 1)));
+    $message = String::format('%message', array(
+      '%message' => 'Log entry added to do the verifyMessageEscaping test.',
+    ));
+    $this->generateLogEntries(1, array(
+      'message' => $message,
+      'link' => $link,
+    ));
+
+    $result = db_query_range('SELECT wid FROM {watchdog} ORDER BY wid DESC', 0, 1);
+    $this->drupalGet('admin/reports/dblog/event/' . $result->fetchField());
+
+    // Check if the link exists (unescaped).
+    $this->assertRaw($message);
+
+    // Check for XSS filtering.
+    $js_txt = 'This should not pop up!';
+    $js = '<script>alert("' . $js_txt . '");</script>';
+    $this->generateLogEntries(1, array(
+      'message' => $message . $js,
+      'link' => $link,
+    ));
+
+    $result = db_query_range('SELECT wid FROM {watchdog} ORDER BY wid DESC', 0, 1);
+    $this->drupalGet('admin/reports/dblog/event/' . $result->fetchField());
+
+    // Check if the link exists (unescaped).
+    $this->assertRaw($message);
+
+    // Check if javascript was escaped.
+    $this->assertNoRaw($js, 'Detail view: javascript in message is blocked');
+    $this->assertRaw($js_txt, 'Detail view: javascript text exists ');
+  }
+
+  /**
    * Generates and then verifies some user events.
    */
   private function doUser() {
@@ -338,7 +427,11 @@ private function doUser() {
    */
   private function doNode($type) {
     // Create user.
-    $perm = array('create ' . $type . ' content', 'edit own ' . $type . ' content', 'delete own ' . $type . ' content');
+    $perm = array(
+      'create ' . $type . ' content',
+      'edit own ' . $type . ' content',
+      'delete own ' . $type . ' content',
+    );
     $user = $this->drupalCreateUser($perm);
     // Login user.
     $this->drupalLogin($user);
@@ -497,7 +590,10 @@ protected function testFilter() {
           'type' => $type_name,
           'severity' => $severity++,
         );
-        $this->generateLogEntries($type['count'], $type['type'], $type['severity']);
+        $this->generateLogEntries($type['count'], array(
+          'channel' => $type['type'],
+          'severity' => $type['severity'],
+        ));
       }
     }
 
