* Security enhancement: Prevent image access through thumbs.php. For details...
authorMichael Stucki <michael.stucki@typo3.org>
Tue, 5 Dec 2006 00:18:07 +0000 (00:18 +0000)
committerMichael Stucki <michael.stucki@typo3.org>
Tue, 5 Dec 2006 00:18:07 +0000 (00:18 +0000)
       * Security enhancement: Refuse BE logins of usernames starting with _CLI_ (they are only used by real CLI scripts)

git-svn-id: https://svn.typo3.org/TYPO3v4/Core/trunk@1854 709f56b5-9817-0410-a4d7-c38de5d9e867

ChangeLog
t3lib/class.t3lib_befunc.php
t3lib/class.t3lib_userauth.php
t3lib/thumbs.php
typo3/class.file_list.inc
typo3/show_item.php
typo3/sysext/cms/tslib/class.tslib_content.php

index f990587..acfb21c 100755 (executable)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,8 @@
-2006-11-25  Michael Stucki  <michael@typo3.org>
+2006-12-05  Michael Stucki  <michael@typo3.org>
 
         * Updated font-copyright information in t3lib/fonts/readme.txt - many thanks to Christian Welzel for taking care of this!
+       * Security enhancement: Prevent image access through thumbs.php. For details, see http://typo3.org/teams/security/security-bulletins/typo3-20061205-1/ - thanks to Marc Bastian Heinrichs for discovering and reporting this issue.
+       * Security enhancement: Refuse BE logins of usernames starting with "_CLI_" (they are only used by real CLI scripts)
 
 2006-11-21  Martin Kutschker  <martin.t.kutschker@blackbox.net>
 
index 288826f..f7d322f 100755 (executable)
@@ -1612,9 +1612,14 @@ class t3lib_BEfunc       {
                                        $thumbData.='<a href="#" onclick="'.htmlspecialchars($onClick).'"><img src="'.$backPath.$url.'" '.$imgInfo[3].' hspace="2" border="0" title="'.trim($url).'"'.$tparams.' alt="" /></a> ';
                                                // New 190201 stop
                                } elseif ($ext=='ttf' || t3lib_div::inList($GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext'],$ext)) {
+                                       $theFile_abs = PATH_site.($uploaddir?$uploaddir.'/':'').trim($theFile);
                                        $theFile = ($abs?'':'../').($uploaddir?$uploaddir.'/':'').trim($theFile);
+
+                                       $check = basename($theFile_abs).':'.filemtime($theFile_abs).':'.$GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey'];
                                        $params = '&file='.rawurlencode($theFile);
                                        $params .= $size?'&size='.$size:'';
+                                       $params.= '&md5sum='.t3lib_div::shortMD5($check);
+
                                        $url = $thumbScript.'?&dummy='.$GLOBALS['EXEC_TIME'].$params;
                                        $onClick='top.launchView(\''.$theFile.'\',\'\',\''.$backPath.'\');return false;';
                                        $thumbData.='<a href="#" onclick="'.htmlspecialchars($onClick).'"><img src="'.htmlspecialchars($backPath.$url).'" hspace="2" border="0" title="'.trim($theFile).'"'.$tparams.' alt="" /></a> ';
@@ -1639,8 +1644,11 @@ class t3lib_BEfunc       {
         * @return      string          Image tag
         */
        function getThumbNail($thumbScript,$theFile,$tparams='',$size='')       {
+               $check = basename($theFile).':'.filemtime($theFile).':'.$GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey'];
                $params = '&file='.rawurlencode($theFile);
                $params .= trim($size)?'&size='.trim($size):'';
+               $params.= '&md5sum='.t3lib_div::shortMD5($check);
+
                $url = $thumbScript.'?&dummy='.$GLOBALS['EXEC_TIME'].$params;
                $th='<img src="'.htmlspecialchars($url).'" title="'.trim(basename($theFile)).'"'.($tparams?" ".$tparams:"").' alt="" />';
                return $th;
index 2a3755e..831c1bc 100755 (executable)
@@ -403,6 +403,11 @@ class t3lib_userAuth {
                                        // delete old user session if any
                                $this->logoff();
                        }
+
+                               // Refuse login for _CLI users (used by commandline scripts)
+                       if ((strtoupper(substr($loginData['uname'],0,5))=='_CLI_') && (!defined('TYPO3_cliMode') || !TYPO3_cliMode))    {       // although TYPO3_cliMode should never be set when using active login...
+                               die('Error: You have tried to login using a CLI user. Access prohibited!');
+                       }
                }
 
 
index a4ba6a0..c076a07 100755 (executable)
@@ -82,8 +82,6 @@ require(PATH_t3lib.'config_default.php');
 if (!defined ('TYPO3_db'))     die ('The configuration file was not included.');
 if (!$TYPO3_CONF_VARS['GFX']['image_processing'])      die ('ImageProcessing was disabled!');
 
-require_once(PATH_t3lib.'class.t3lib_db.php');         // The database library
-$TYPO3_DB = t3lib_div::makeInstance('t3lib_DB');
 
 
 
@@ -125,6 +123,7 @@ class SC_t3lib_thumbs {
                // Internal, static: GPvar:
        var $file;              // Holds the input filename (GET: file)
        var $size;              // Holds the input size (GET: size)
+       var $mtime = 0;         // Last modification time of the supplied file
 
 
        /**
@@ -137,23 +136,41 @@ class SC_t3lib_thumbs {
                global $TYPO3_CONF_VARS;
 
                        // Setting GPvars:
-               $this->file = t3lib_div::_GP('file');
-               $this->size = t3lib_div::_GP('size');
+               $file = t3lib_div::_GP('file');
+               $size = t3lib_div::_GP('size');
+               $md5sum = t3lib_div::_GP('md5sum');
 
                        // Image extension list is set:
                $this->imageList = $TYPO3_CONF_VARS['GFX']['imagefile_ext'];                    // valid extensions. OBS: No spaces in the list, all lowercase...
 
                        // if the filereference $this->file is relative, we correct the path
-               if (substr($this->file,0,3)=='../')     {
-                       $this->input = PATH_site.substr($this->file,3);
-               } else {
-                       $this->input = $this->file;
+               if (substr($file,0,3)=='../')   {
+                       $file = PATH_site.substr($file,3);
                }
 
                        // Now the path is absolute.
                        // Checking for backpath and double slashes + the thumbnail can be made from files which are in the PATH_site OR the lockRootPath only!
-               if (!t3lib_div::isAllowedAbsPath($this->input)) {
-                       $this->input='';
+               if (t3lib_div::isAllowedAbsPath($file)) {
+                       $mtime = filemtime($file);
+               }
+
+                       // Do an MD5 check to prevent viewing of images without permission
+               $OK = FALSE;
+               if ($mtime)     {
+                               // Always use the absolute path for this check!
+                       $check = basename($file).':'.$mtime.':'.$GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey'];
+                       $md5_real = t3lib_div::shortMD5($check);
+                       if (!strcmp($md5_real,$md5sum)) {
+                               $OK = TRUE;
+                       }
+               }
+
+               if ($OK)        {
+                       $this->input = $file;
+                       $this->size = $size;
+                       $this->mtime = $mtime;
+               } else {
+                       die('Error: Image does not exist and/or MD5 checksum did not match.');
                }
        }
 
@@ -184,7 +201,7 @@ class SC_t3lib_thumbs {
                        }
 
                                // ... so we passed the extension test meaning that we are going to make a thumbnail here:
-                       $this->size = $this->size ? $this->size : $this->sizeDefault;   // default
+                       if (!$this->size)       $this->size = $this->sizeDefault;       // default
 
                                // I added extra check, so that the size input option could not be fooled to pass other values. That means the value is exploded, evaluated to an integer and the imploded to [value]x[value]. Furthermore you can specify: size=340 and it'll be translated to 340x340.
                        $sizeParts = explode('x', $this->size.'x'.$this->size); // explodes the input size (and if no "x" is found this will add size again so it is the same for both dimensions)
@@ -193,7 +210,6 @@ class SC_t3lib_thumbs {
                        $sizeMax = max($sizeParts);     // Getting max value
 
                                // Init
-                       $mtime = filemtime($this->input);
                        $outpath = PATH_site.$this->outdir;
 
                                // Should be - ? 'png' : 'gif' - , but doesn't work (ImageMagick prob.?)
@@ -201,7 +217,7 @@ class SC_t3lib_thumbs {
                        $thmMode = t3lib_div::intInRange($TYPO3_CONF_VARS['GFX']['thumbnails_png'],0);
                        $outext = ($ext!='jpg' || ($thmMode & 2)) ? ($thmMode & 1 ? 'png' : 'gif') : 'jpg';
 
-                       $outfile = 'tmb_'.substr(md5($this->input.$mtime.$this->size),0,10).'.'.$outext;
+                       $outfile = 'tmb_'.substr(md5($this->input.$this->mtime.$this->size),0,10).'.'.$outext;
                        $this->output = $outpath.$outfile;
 
                        if ($TYPO3_CONF_VARS['GFX']['im'])      {
index fd87213..9b8e618 100755 (executable)
@@ -498,7 +498,13 @@ class fileList extends t3lib_recordList {
                                                $thumbData=Array();
                                                $theFile_R = rawurlencode($theFile['path'].$theFile['file']);
                                                $titleCol=$this->fieldArray[0];
-                                               $href = $this->backPath.$this->thumbScript.'?&dummy='.$GLOBALS['EXEC_TIME'].'&file='.$theFile_R;
+
+                                               $theFile_abs = $theFile['path'].$theFile['file'];
+                                               $check = basename($theFile_abs).':'.filemtime($theFile_abs).':'.$GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey'];
+                                               $params = '&file='.$theFile_R;
+                                               $params.= '&md5sum='.t3lib_div::shortMD5($check);
+                                               $href = $this->backPath.$this->thumbScript.'?&dummy='.$GLOBALS['EXEC_TIME'].$params;
+
                                                $thumbData[$titleCol]='<img src="'.htmlspecialchars($href).'" hspace="2" title="'.htmlspecialchars(trim($theFile['file'])).'" alt="" />';
                                                $out.=$this->addelement(4,'',$thumbData);
                                        }
index b9a1b9b..e24d82c 100755 (executable)
@@ -428,7 +428,9 @@ class SC_show_item {
                                // Font files:
                        if ($ext=='ttf')        {
                                $thumbScript = 'thumbs.php';
+                               $check = basename($this->file).':'.filemtime($this->file).':'.$GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey'];
                                $params = '&file='.rawurlencode($this->file);
+                               $params.= '&md5sum='.t3lib_div::shortMD5($check);
                                $url = $thumbScript.'?&dummy='.$GLOBALS['EXEC_TIME'].$params;
                                $thumb = '<br />
                                        <div align="center">'.$returnLinkTag.'<img src="'.htmlspecialchars($url).'" border="0" title="'.htmlspecialchars(trim($this->file)).'" alt="" /></a></div>';
index 24575f3..94691cb 100755 (executable)
@@ -3902,7 +3902,9 @@ class tslib_cObj {
                                                if ($GLOBALS['TYPO3_CONF_VARS']['GFX']['thumbnails'])   {
                                                        $thumbSize = '';
                                                        if ($conf['icon_thumbSize'] || $conf['icon_thumbSize.'])        { $thumbSize = '&size='.$this->stdWrap($conf['icon_thumbSize'], $conf['icon_thumbSize.']); }
-                                                       $icon = 't3lib/thumbs.php?dummy='.$GLOBALS['EXEC_TIME'].'&file='.rawurlencode('../'.$theFile).$thumbSize;
+                                                       $check = basename($theFile).':'.filemtime($theFile).':'.$GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey'];
+                                                       $md5sum = '&md5sum='.t3lib_div::shortMD5($check);
+                                                       $icon = 't3lib/thumbs.php?dummy='.$GLOBALS['EXEC_TIME'].'&file='.rawurlencode('../'.$theFile).$thumbSize.$md5sum;
                                                } else {
                                                        $icon = t3lib_extMgm::siteRelPath('cms').'tslib/media/miscicons/notfound_thumb.gif';
                                                }