Improve image proxy implementation
authorMatthias Schmidt <gravatronics@live.com>
Thu, 6 Aug 2015 17:39:44 +0000 (19:39 +0200)
committerMatthias Schmidt <gravatronics@live.com>
Thu, 6 Aug 2015 17:39:53 +0000 (19:39 +0200)
wcfsetup/install/files/lib/action/ImageProxyAction.class.php
wcfsetup/install/files/lib/system/bbcode/ImageBBCode.class.php

index ce138aa9d2a60ea44dd71f002fa60273653ff7e8..8ce807f6387261918e674e2dd7f5f33cf3dcb436 100644 (file)
@@ -4,6 +4,7 @@ use wcf\system\exception\IllegalLinkException;
 use wcf\system\exception\SystemException;
 use wcf\util\FileUtil;
 use wcf\util\HTTPRequest;
+use wcf\util\PasswordUtil;
 use wcf\util\StringUtil;
 
 /**
@@ -35,7 +36,7 @@ class ImageProxyAction extends AbstractAction {
        public function readParameters() {
                parent::readParameters();
                
-               if (isset($_REQUEST['url'])) $this->url = urldecode(StringUtil::trim($_REQUEST['url']));
+               if (isset($_REQUEST['url'])) $this->url = rawurldecode(StringUtil::trim($_REQUEST['url']));
                if (isset($_REQUEST['hash'])) $this->hash = StringUtil::trim($_REQUEST['hash']);
        }
        
@@ -46,39 +47,37 @@ class ImageProxyAction extends AbstractAction {
                parent::execute();
                
                $hash = sha1(IMAGE_PROXY_SECRET.$this->url);
-               if ($this->hash != $hash) {
+               if (!PasswordUtil::secureCompare($this->hash, $hash)) {
                        throw new IllegalLinkException();
                }
                
                try {
                        $request = new HTTPRequest($this->url);
                        $request->execute();
-                       $reply = $request->getReply();
+                       $image = $request->getReply()['body'];
                        
-                       $fileExtension = '';
-                       if (($position = mb_strrpos($this->url, '.')) !== false) {
-                               $fileExtension = mb_strtolower(mb_substr($this->url, $position + 1));
-                       }
-                       
-                       // check if requested content is image
-                       if (!isset($reply['headers']['Content-Type']) || !StringUtil::startsWith($reply['headers']['Content-Type'], 'image/')) {
+                       // check if image is linked
+                       // TODO: handle SVGs
+                       $imageData = getimagesizefromstring($image);
+                       if (!$imageData) {
                                throw new IllegalLinkException();
                        }
                        
                        // save image
+                       $fileExtension = pathinfo($this->url, PATHINFO_EXTENSION);
                        $fileLocation = WCF_DIR.'images/proxy/'.substr($hash, 0, 2).'/'.$hash.($fileExtension ? '.'.$fileExtension : '');
                        $dir = dirname($fileLocation);
                        if (!@file_exists($dir)) {
                                FileUtil::makePath($dir, 0777);
                        }
-                       file_put_contents($fileLocation, $reply['body']);
+                       file_put_contents($fileLocation, $image);
                        
                        // update mtime for correct expiration calculation
                        @touch($fileLocation);
                        
                        $this->executed();
                        
-                       @header('Content-Type: '.$reply['headers']['Content-Type']);
+                       @header('Content-Type: '.$imageData['mime']);
                        @readfile($fileLocation);
                        exit;
                }
index 44172ebad81391a086709416af6add2023ab6b61..f4a4b6c18d329338da4103b9a39f771c86d1e021 100644 (file)
@@ -84,7 +84,7 @@ class ImageBBCode extends AbstractBBCode {
                
                return LinkHandler::getInstance()->getLink('ImageProxy', [
                        'hash' => $hash,
-                       'url' => urlencode($link)
+                       'url' => rawurlencode($link)
                ]);
        }
 }