Use CryptoUtil in ImageProxy
authorTim Düsterhus <duesterhus@woltlab.com>
Fri, 7 Aug 2015 23:11:46 +0000 (01:11 +0200)
committerTim Düsterhus <duesterhus@woltlab.com>
Fri, 7 Aug 2015 23:11:46 +0000 (01:11 +0200)
com.woltlab.wcf/option.xml
wcfsetup/install/files/acp/install.php
wcfsetup/install/files/lib/action/ImageProxyAction.class.php
wcfsetup/install/files/lib/system/bbcode/ImageBBCode.class.php

index de61ea460449f58994048fda1629bd1a61558b70..f2acd558dae41efbc0cc6c0a49df242e86801ed4 100644 (file)
@@ -995,11 +995,6 @@ redis:cache_source_redis_host,!cache_source_memcached_host]]></enableoptions>
                                <defaultvalue>0</defaultvalue>
                                <enableoptions><![CDATA[image_proxy_secret]]></enableoptions>
                        </option>
-                       <option name="image_proxy_secret">
-                               <categoryname>message.general.image</categoryname>
-                               <optiontype>text</optiontype>
-                               <allowemptyvalue>0</allowemptyvalue>
-                       </option>
                        <option name="image_proxy_expiration">
                                <categoryname>message.general.image</categoryname>
                                <optiontype>integer</optiontype>
index 6f3b17dd4b3a6249771e67a469003dfdd9bde1fa..a86c1ec0d0c24b63c80c7dcfba569c64d08f6065 100644 (file)
@@ -65,14 +65,3 @@ if ($timezone = @date_default_timezone_get()) {
                $statement->execute(array($timezone, 'timezone'));
        }
 }
-
-// set image proxy secret
-$sql = "UPDATE wcf".WCF_N."_option
-       SET     optionValue = ?
-       WHERE   optionName = ?";
-$statement = WCF::getDB()->prepareStatement($sql);
-$statement->execute([
-       StringUtil::getRandomID(),
-       'image_proxy_secret'
-]);
-
index 8ce807f6387261918e674e2dd7f5f33cf3dcb436..f8a2d089ef03afecf065b7211245546ebd91436c 100644 (file)
@@ -2,9 +2,10 @@
 namespace wcf\action;
 use wcf\system\exception\IllegalLinkException;
 use wcf\system\exception\SystemException;
+use wcf\util\exception\CryptoException;
+use wcf\util\CryptoUtil;
 use wcf\util\FileUtil;
 use wcf\util\HTTPRequest;
-use wcf\util\PasswordUtil;
 use wcf\util\StringUtil;
 
 /**
@@ -19,16 +20,10 @@ use wcf\util\StringUtil;
  */
 class ImageProxyAction extends AbstractAction {
        /**
-        * hashed image proxy secret and image url
+        * The image key created by CryptoUtil::createSignedString()
         * @var string
         */
-       public $hash = '';
-       
-       /**
-        * image url
-        * @var string
-        */
-       public $url = '';
+       public $key = '';
        
        /**
         * @see \wcf\action\IAction::readParameters()
@@ -36,8 +31,7 @@ class ImageProxyAction extends AbstractAction {
        public function readParameters() {
                parent::readParameters();
                
-               if (isset($_REQUEST['url'])) $this->url = rawurldecode(StringUtil::trim($_REQUEST['url']));
-               if (isset($_REQUEST['hash'])) $this->hash = StringUtil::trim($_REQUEST['hash']);
+               if (isset($_REQUEST['key'])) $this->key = StringUtil::trim($_REQUEST['key']);
        }
        
        /**
@@ -46,13 +40,13 @@ class ImageProxyAction extends AbstractAction {
        public function execute() {
                parent::execute();
                
-               $hash = sha1(IMAGE_PROXY_SECRET.$this->url);
-               if (!PasswordUtil::secureCompare($this->hash, $hash)) {
-                       throw new IllegalLinkException();
-               }
-               
                try {
-                       $request = new HTTPRequest($this->url);
+                       $url = CryptoUtil::getValueFromSignedString($this->key);
+                       if ($url === null) throw new IllegalLinkException();
+                       
+                       $fileName = sha1($this->key);
+                       
+                       $request = new HTTPRequest($url);
                        $request->execute();
                        $image = $request->getReply()['body'];
                        
@@ -64,8 +58,8 @@ class ImageProxyAction extends AbstractAction {
                        }
                        
                        // save image
-                       $fileExtension = pathinfo($this->url, PATHINFO_EXTENSION);
-                       $fileLocation = WCF_DIR.'images/proxy/'.substr($hash, 0, 2).'/'.$hash.($fileExtension ? '.'.$fileExtension : '');
+                       $fileExtension = pathinfo($url, PATHINFO_EXTENSION);
+                       $fileLocation = WCF_DIR.'images/proxy/'.substr($fileName, 0, 2).'/'.$fileName.($fileExtension ? '.'.$fileExtension : '');
                        $dir = dirname($fileLocation);
                        if (!@file_exists($dir)) {
                                FileUtil::makePath($dir, 0777);
@@ -84,5 +78,8 @@ class ImageProxyAction extends AbstractAction {
                catch (SystemException $e) {
                        throw new IllegalLinkException();
                }
+               catch (CryptoException $e) {
+                       throw new IllegalLinkException();
+               }
        }
 }
index f4a4b6c18d329338da4103b9a39f771c86d1e021..0bb94f0fd31d3e4520e2a5bd2ded03b0a9c0024a 100644 (file)
@@ -1,5 +1,7 @@
 <?php
 namespace wcf\system\bbcode;
+use wcf\util\exception\CryptoException;
+use wcf\util\CryptoUtil;
 use wcf\util\StringUtil;
 use wcf\system\WCF;
 use wcf\system\request\LinkHandler;
@@ -69,22 +71,26 @@ class ImageBBCode extends AbstractBBCode {
         * @return      string
         */
        protected function getProxyLink($link) {
-               $hash = sha1(IMAGE_PROXY_SECRET.$link);
-               $fileExtension = '';
-               if (($position = mb_strrpos($link, '.')) !== false) {
-                       $fileExtension = mb_strtolower(mb_substr($link, $position + 1));
+               try {
+                       $key = CryptoUtil::createSignedString($link);
+                       // does not need to be secure, just sufficiently "random"
+                       $fileName = sha1($key);
+                       
+                       $fileExtension = pathinfo($this->url, PATHINFO_EXTENSION);
+                       
+                       $path = 'images/proxy/'.substr($fileName, 0, 2).'/'.$fileName.($fileExtension ? '.'.$fileExtension : '');
+                       
+                       $fileLocation = WCF_DIR.$path;
+                       if (file_exists($fileLocation)) {
+                               return WCF::getPath().$path;
+                       }
+                       
+                       return LinkHandler::getInstance()->getLink('ImageProxy', [
+                               'key' => $key
+                       ]);
                }
-               
-               $path = 'images/proxy/'.substr($hash, 0, 2).'/'.$hash.($fileExtension ? '.'.$fileExtension : '');
-               
-               $fileLocation = WCF_DIR.$path;
-               if (file_exists($fileLocation)) {
-                       return WCF::getPath().$path;
+               catch (CryptoException $e) {
+                       return $link;
                }
-               
-               return LinkHandler::getInstance()->getLink('ImageProxy', [
-                       'hash' => $hash,
-                       'url' => rawurlencode($link)
-               ]);
        }
 }