[SECURITY] Information Disclosure in Wizards 80/26180/2
authorAnja Leichsenring <aleichsenring@ab-softlab.de>
Tue, 10 Dec 2013 09:51:05 +0000 (10:51 +0100)
committerOliver Hader <oliver.hader@typo3.org>
Tue, 10 Dec 2013 09:51:09 +0000 (10:51 +0100)
It has been possible for authenticated editors
to show content of arbitrary tables and fields
that are defined in TCA by manipulating
GET parameters of the forms and table wizard.

This change adds a check if the editor has access
to the given record.

Change-Id: I524ae9bd75a5cca9e37918e64f5c492c9fa3c36e
Fixes: #41714
Releases: 4.5, 4.7, 6.0, 6.1, 6.2
Security-Commit: 9ee30833350405d003de206501118d1300998bee
Security-Bulletin: TYPO3-CORE-SA-2013-004
Reviewed-on: https://review.typo3.org/26180
Reviewed-by: Oliver Hader
Tested-by: Oliver Hader
typo3/wizard_forms.php
typo3/wizard_rte.php
typo3/wizard_table.php

index 7b6465d..55dd39e 100644 (file)
@@ -313,7 +313,9 @@ class SC_wizard_forms {
         * @return      string          HTML content for the form.
         */
        function formsWizard()  {
-
+               if (!$this->checkEditAccess($this->P['table'], $this->P['uid'])) {
+                  throw new RuntimeException('Wizard Error: No access', 1385807526);
+               }
                        // First, check the references by selecting the record:
                $row = t3lib_BEfunc::getRecord($this->P['table'],$this->P['uid']);
                if (!is_array($row)) {
@@ -330,6 +332,37 @@ class SC_wizard_forms {
                return $content;
        }
 
+       /**
+        * Checks access for element
+        *
+        * @param string $table Table name
+        * @param integer $uid Record uid
+        * @return boolean
+        * @todo: Refactor to remove duplicate code (see wizard_table, wizard_rte)
+        */
+  protected function checkEditAccess($table, $uid) {
+               $calcPRec = t3lib_BEfunc::getRecord($table, $uid);
+               t3lib_BEfunc::fixVersioningPid($table, $calcPRec);
+               if (is_array($calcPRec)) {
+                       // If pages:
+                       if ($table == 'pages') {
+                               $CALC_PERMS = $GLOBALS['BE_USER']->calcPerms($calcPRec);
+                               $hasAccess = $CALC_PERMS & 2 ? TRUE : FALSE;
+                       } else {
+                               // Fetching pid-record first.
+                               $CALC_PERMS = $GLOBALS['BE_USER']->calcPerms(t3lib_BEfunc::getRecord('pages', $calcPRec['pid']));
+                               $hasAccess = $CALC_PERMS & 16 ? TRUE : FALSE;
+                       }
+                       // Check internals regarding access:
+                       if ($hasAccess) {
+                               $hasAccess = $GLOBALS['BE_USER']->recordEditAccessInternals($table, $calcPRec);
+                       }
+               } else {
+                       $hasAccess = FALSE;
+               }
+               return $hasAccess;
+       }
+
 
 
 
index e37c6b4..57d5de1 100644 (file)
@@ -301,7 +301,10 @@ class SC_wizard_rte {
         *
         * @param       string          Table name
         * @param       integer         Record uid
-        * @return      void
+        *
+        *@return       boolean
+        *
+        * @todo: Refactor to remove duplicate code (see wizard_form, wizard_table)
         */
        function checkEditAccess($table,$uid)   {
                global $BE_USER;
index 54df8ad..05ce515 100644 (file)
@@ -233,6 +233,9 @@ class SC_wizard_table {
         */
        function tableWizard()  {
 
+               if (!$this->checkEditAccess($this->P['table'], $this->P['uid'])) {
+                       throw new RuntimeException('Wizard Error: No access', 1349692692);
+               }
                        // First, check the references by selecting the record:
                $row = t3lib_BEfunc::getRecord($this->P['table'],$this->P['uid']);
                if (!is_array($row)) {
@@ -249,6 +252,38 @@ class SC_wizard_table {
                return $content;
        }
 
+       /**
+        * Checks access for element
+        *
+        * @param string $table Table name
+        * @param integer $uid Record uid
+        *
+        * @return boolean
+        * @todo: Refactor to remove duplicate code (see wizard_form, wizard_rte)
+        */
+       protected function checkEditAccess($table, $uid) {
+               $calcPRec = t3lib_BEfunc::getRecord($table, $uid);
+               t3lib_BEfunc::fixVersioningPid($table, $calcPRec);
+               if (is_array($calcPRec)) {
+                       // If pages:
+                       if ($table == 'pages') {
+                               $CALC_PERMS = $GLOBALS['BE_USER']->calcPerms($calcPRec);
+                               $hasAccess = $CALC_PERMS & 2 ? TRUE : FALSE;
+                       } else {
+                               // Fetching pid-record first.
+                               $CALC_PERMS = $GLOBALS['BE_USER']->calcPerms(t3lib_BEfunc::getRecord('pages', $calcPRec['pid']));
+                               $hasAccess = $CALC_PERMS & 16 ? TRUE : FALSE;
+                       }
+                       // Check internals regarding access:
+                       if ($hasAccess) {
+                               $hasAccess = $GLOBALS['BE_USER']->recordEditAccessInternals($table, $calcPRec);
+                       }
+               } else {
+                       $hasAccess = FALSE;
+               }
+               return $hasAccess;
+       }
+