Fixed bug #12739: XSS in shortcuts (thanks to Francois Suter and Georg Ringer)
authorOliver Hader <oliver.hader@typo3.org>
Wed, 28 Jul 2010 09:06:19 +0000 (09:06 +0000)
committerOliver Hader <oliver.hader@typo3.org>
Wed, 28 Jul 2010 09:06:19 +0000 (09:06 +0000)
git-svn-id: https://svn.typo3.org/TYPO3v4/Core/trunk@8380 709f56b5-9817-0410-a4d7-c38de5d9e867

ChangeLog
typo3/alt_shortcut.php
typo3/classes/class.shortcutmenu.php

index 08be6b2..831e1df 100755 (executable)
--- a/ChangeLog
+++ b/ChangeLog
@@ -14,6 +14,7 @@
        * Fixed bug #14215: XSS in beuser (thanks to Georg Ringer)
        * Fixed bug #12458: Session fixation possibility in new sesion machanism of the install tool (thanks to Benjamin Mack, Helmut Hummel and Ernesto Baschny)
        * Fixed bug #13989: Mitigate PHP's RNG vulnerability (thanks to Marcus Krause and Helmut Hummel)
+       * Fixed bug #12739: XSS in shortcuts (thanks to Francois Suter and Georg Ringer)
 
 2010-07-27  Steffen Kamper  <steffen@typo3.org>
 
index 9eb4bf1..92d5544 100644 (file)
@@ -164,6 +164,7 @@ class SC_alt_shortcut {
                global $BE_USER;
                $description = '';      // Default description
                $url = urldecode($this->URL);
+               $queryParts = parse_url($url);
 
                        // Lookup the title of this page and use it as default description
                $page_id = $this->getLinkedPageId($url);
@@ -187,8 +188,9 @@ class SC_alt_shortcut {
                }
 
 
-                       // Adding a shortcut being set from another frame
-               if ($this->modName && $this->URL)       {
+                       // Adding a shortcut being set from another frame,
+                       // but only if it's a relative URL (i.e. scheme part is not defined)
+               if ($this->modName && $this->URL && empty($queryParts['scheme'])) {
                        $fields_values = array(
                                'userid' => $BE_USER->user['uid'],
                                'module_name' => $this->modName.'|'.$this->M_modName,
index 1dc78f6..9294f93 100644 (file)
@@ -150,7 +150,7 @@ class ShortcutMenu implements backend_toolbarItem {
                        <tr id="shortcut-'.$shortcut['raw']['uid'].'" class="shortcut">
                                <td class="shortcut-icon">'.$shortcut['icon'].'</td>
                                <td class="shortcut-label">
-                                       <a id="shortcut-label-'.$shortcut['raw']['uid'].'" href="#" onclick="'.$shortcut['action'].'; return false;">'.$shortcut['label'].'</a>
+                                       <a id="shortcut-label-' . $shortcut['raw']['uid'] . '" href="#" onclick="' . $shortcut['action'] . '; return false;">' . htmlspecialchars($shortcut['label']) . '</a>
                                </td>
                                <td class="shortcut-edit">'.$editIcon.' id="shortcut-edit-'.$shortcut['raw']['uid'].'" /></td>
                                <td class="shortcut-delete">'.$deleteIcon.'</td>
@@ -183,7 +183,7 @@ class ShortcutMenu implements backend_toolbarItem {
                                        <tr id="shortcut-'.$shortcut['raw']['uid'].'" class="shortcut'.$firstRow.'">
                                                <td class="shortcut-icon">'.$shortcut['icon'].'</td>
                                                <td class="shortcut-label">
-                                                       <a id="shortcut-label-'.$shortcut['raw']['uid'].'" href="#" onclick="'.$shortcut['action'].'; return false;">'.$shortcut['label'].'</a>
+                                                       <a id="shortcut-label-' . $shortcut['raw']['uid'] . '" href="#" onclick="' . $shortcut['action'] . '; return false;">' . htmlspecialchars($shortcut['label']) . '</a>
                                                </td>
                                                <td class="shortcut-edit">'.$editIcon.' id="shortcut-edit-'.$shortcut['raw']['uid'].'" /></td>
                                                <td class="shortcut-delete">'.$deleteIcon.'</td>
@@ -508,61 +508,64 @@ class ShortcutMenu implements backend_toolbarItem {
                $queryParts      = parse_url($url);
                $queryParameters = t3lib_div::explodeUrl2Array($queryParts['query'], 1);
 
-               if(is_array($queryParameters['edit'])) {
-                       $shortcut['table']    = key($queryParameters['edit']);
-                       $shortcut['recordid'] = key($queryParameters['edit'][$shortcut['table']]);
+                       // Proceed only if no scheme is defined, as URL is expected to be relative
+               if (empty($queryParts['scheme'])) {
+                       if (is_array($queryParameters['edit'])) {
+                               $shortcut['table']    = key($queryParameters['edit']);
+                               $shortcut['recordid'] = key($queryParameters['edit'][$shortcut['table']]);
 
-                       if($queryParameters['edit'][$shortcut['table']][$shortcut['recordid']] == 'edit') {
-                               $shortcut['type']    = 'edit';
-                               $shortcutNamePrepend = $GLOBALS['LANG']->getLL('shortcut_edit', 1);
-                       } elseif($queryParameters['edit'][$shortcut['table']][$shortcut['recordid']] == 'new') {
-                               $shortcut['type']    = 'new';
-                               $shortcutNamePrepend = $GLOBALS['LANG']->getLL('shortcut_create', 1);
+                               if($queryParameters['edit'][$shortcut['table']][$shortcut['recordid']] == 'edit') {
+                                       $shortcut['type']    = 'edit';
+                                       $shortcutNamePrepend = $GLOBALS['LANG']->getLL('shortcut_edit', 1);
+                               } elseif($queryParameters['edit'][$shortcut['table']][$shortcut['recordid']] == 'new') {
+                                       $shortcut['type']    = 'new';
+                                       $shortcutNamePrepend = $GLOBALS['LANG']->getLL('shortcut_create', 1);
+                               }
+                       } else {
+                               $shortcut['type'] = 'other';
                        }
-               } else {
-                       $shortcut['type'] = 'other';
-               }
-
-                       // Lookup the title of this page and use it as default description
-               $pageId = $shortcut['recordid'] ? $shortcut['recordid'] : $this->getLinkedPageId($url);
 
-               if(t3lib_div::testInt($pageId)) {
-                       $page = t3lib_BEfunc::getRecord('pages', $pageId);
-                       if(count($page)) {
-                                       // set the name to the title of the page
-                               if($shortcut['type'] == 'other') {
-                                       $shortcutName = $page['title'];
-                               } else {
-                                       $shortcutName = $shortcutNamePrepend.' '.$LANG->sL($TCA[$shortcut['table']]['ctrl']['title']).' ('.$page['title'].')';
+                               // Lookup the title of this page and use it as default description
+                       $pageId = $shortcut['recordid'] ? $shortcut['recordid'] : $this->getLinkedPageId($url);
+
+                       if(t3lib_div::testInt($pageId)) {
+                               $page = t3lib_BEfunc::getRecord('pages', $pageId);
+                               if(count($page)) {
+                                               // set the name to the title of the page
+                                       if($shortcut['type'] == 'other') {
+                                               $shortcutName = $page['title'];
+                                       } else {
+                                               $shortcutName = $shortcutNamePrepend.' '.$LANG->sL($TCA[$shortcut['table']]['ctrl']['title']).' ('.$page['title'].')';
+                                       }
+                               }
+                       } else {
+                               $dirName = urldecode($pageId);
+                               if (preg_match('/\/$/', $dirName))      {
+                                               // if $pageId is a string and ends with a slash,
+                                               // assume it is a fileadmin reference and set
+                                               // the description to the basename of that path
+                                       $shortcutName .= ' ' . basename($dirName);
                                }
                        }
-               } else {
-                       $dirName = urldecode($pageId);
-                       if (preg_match('/\/$/', $dirName))      {
-                                       // if $pageId is a string and ends with a slash,
-                                       // assume it is a fileadmin reference and set
-                                       // the description to the basename of that path
-                               $shortcutName .= ' ' . basename($dirName);
-                       }
-               }
-
-                       // adding the shortcut
-               if($module && $url) {
-                       $fieldValues = array(
-                               'userid'      => $GLOBALS['BE_USER']->user['uid'],
-                               'module_name' => $module.'|'.$motherModule,
-                               'url'         => $url,
-                               'description' => $shortcutName,
-                               'sorting'     => $GLOBALS['EXEC_TIME'],
-                       );
-                       $GLOBALS['TYPO3_DB']->exec_INSERTquery('sys_be_shortcuts', $fieldValues);
 
-                       if($GLOBALS['TYPO3_DB']->sql_affected_rows() == 1) {
-                               $shortcutCreated = 'success';
+                               // adding the shortcut
+                       if($module && $url) {
+                               $fieldValues = array(
+                                       'userid'      => $GLOBALS['BE_USER']->user['uid'],
+                                       'module_name' => $module.'|'.$motherModule,
+                                       'url'         => $url,
+                                       'description' => $shortcutName,
+                                       'sorting'     => $GLOBALS['EXEC_TIME'],
+                               );
+                               $GLOBALS['TYPO3_DB']->exec_INSERTquery('sys_be_shortcuts', $fieldValues);
+
+                               if($GLOBALS['TYPO3_DB']->sql_affected_rows() == 1) {
+                                       $shortcutCreated = 'success';
+                               }
                        }
-               }
 
-               $ajaxObj->addContent('create', $shortcutCreated);
+                       $ajaxObj->addContent('create', $shortcutCreated);
+               }
        }
 
        /**