owncloud /
updater
This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
| 1 | <?php |
||
| 2 | |||
| 3 | /** |
||
| 4 | * @author Victor Dubiniuk <[email protected]> |
||
| 5 | * |
||
| 6 | * @copyright Copyright (c) 2015, ownCloud, Inc. |
||
| 7 | * @license AGPL-3.0 |
||
| 8 | * |
||
| 9 | * This code is free software: you can redistribute it and/or modify |
||
| 10 | * it under the terms of the GNU Affero General Public License, version 3, |
||
| 11 | * as published by the Free Software Foundation. |
||
| 12 | * |
||
| 13 | * This program is distributed in the hope that it will be useful, |
||
| 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
| 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||
| 16 | * GNU Affero General Public License for more details. |
||
| 17 | * |
||
| 18 | * You should have received a copy of the GNU Affero General Public License, version 3, |
||
| 19 | * along with this program. If not, see <http://www.gnu.org/licenses/> |
||
| 20 | * |
||
| 21 | */ |
||
| 22 | |||
| 23 | namespace Owncloud\Updater\Controller; |
||
| 24 | |||
| 25 | use Owncloud\Updater\Utils\Checkpoint; |
||
| 26 | use Owncloud\Updater\Utils\ConfigReader; |
||
| 27 | use Pimple\Container; |
||
| 28 | use Owncloud\Updater\Formatter\HtmlOutputFormatter; |
||
| 29 | use Owncloud\Updater\Http\Request; |
||
| 30 | use League\Plates\Engine; |
||
| 31 | use League\Plates\Extension\Asset; |
||
| 32 | use League\Plates\Extension\URI; |
||
| 33 | use Symfony\Component\Console\Output\BufferedOutput; |
||
| 34 | use Symfony\Component\Console\Input\StringInput; |
||
| 35 | |||
| 36 | /** |
||
| 37 | * Class IndexController |
||
| 38 | * |
||
| 39 | * @package Owncloud\Updater\Controller |
||
| 40 | */ |
||
| 41 | class IndexController { |
||
| 42 | |||
| 43 | /** @var Container */ |
||
| 44 | protected $container; |
||
| 45 | |||
| 46 | /** @var Request */ |
||
| 47 | protected $request; |
||
| 48 | |||
| 49 | /** @var string $command */ |
||
| 50 | protected $command; |
||
| 51 | |||
| 52 | /** |
||
| 53 | * @param Container $container |
||
| 54 | * @param Request|null $request |
||
| 55 | */ |
||
| 56 | public function __construct(Container $container, |
||
| 57 | Request $request = null) { |
||
| 58 | $this->container = $container; |
||
| 59 | if (is_null($request)){ |
||
| 60 | $this->request = new Request(['post' => $_POST, 'headers' => $_SERVER]); |
||
| 61 | } else { |
||
| 62 | $this->request = $request; |
||
| 63 | } |
||
| 64 | |||
| 65 | $this->command = $this->request->postParameter('command'); |
||
| 66 | } |
||
| 67 | |||
| 68 | /** |
||
| 69 | * @return string |
||
| 70 | */ |
||
| 71 | public function dispatch() { |
||
| 72 | /** @var ConfigReader $configReader */ |
||
| 73 | $configReader = $this->container['utils.configReader']; |
||
|
0 ignored issues
–
show
|
|||
| 74 | |||
| 75 | // strip index.php and query string (if any) to get a real base url |
||
| 76 | $baseUrl = preg_replace('/(index\.php.*|\?.*)$/', '', $_SERVER['REQUEST_URI']); |
||
| 77 | $templates = new Engine(CURRENT_DIR . '/src/Resources/views/'); |
||
| 78 | $templates->loadExtension(new Asset(CURRENT_DIR . '/pub/', false)); |
||
| 79 | $templates->loadExtension(new URI($baseUrl)); |
||
| 80 | |||
| 81 | // Check if the user is logged-in |
||
| 82 | if(!$this->isLoggedIn()) { |
||
|
0 ignored issues
–
show
The expression
$this->isLoggedIn() of type null|boolean is loosely compared to false; this is ambiguous if the boolean can be false. You might want to explicitly use !== null instead.
If an expression can have both $a = canBeFalseAndNull();
// Instead of
if ( ! $a) { }
// Better use one of the explicit versions:
if ($a !== null) { }
if ($a !== false) { }
if ($a !== null && $a !== false) { }
Loading history...
|
|||
| 83 | return $this->showLogin($templates); |
||
| 84 | } |
||
| 85 | |||
| 86 | try { |
||
| 87 | $fullEndpoint = $this->getEndpoint(); |
||
| 88 | $this->container['application']->setEndpoint($fullEndpoint); |
||
| 89 | $this->container['application']->setAuthToken($this->request->header('X_Updater_Auth')); |
||
| 90 | $this->container['application']->initConfig(); |
||
| 91 | $this->container['application']->assertOwnCloudFound(); |
||
| 92 | } catch (\Exception $e){ |
||
| 93 | $content = $templates->render( |
||
| 94 | 'partials/error', |
||
| 95 | [ |
||
| 96 | 'title' => 'Updater', |
||
| 97 | 'version' => $this->container['application']->getVersion(), |
||
| 98 | 'error' => $e->getMessage() |
||
| 99 | ] |
||
| 100 | ); |
||
| 101 | return $content; |
||
| 102 | } |
||
| 103 | |||
| 104 | if (is_null($this->command)){ |
||
| 105 | /** @var Checkpoint $checkpoint */ |
||
| 106 | $checkpoint = $this->container['utils.checkpoint']; |
||
| 107 | $checkpoints = $checkpoint->getAll(); |
||
| 108 | $content = $templates->render( |
||
| 109 | 'partials/inner', |
||
| 110 | [ |
||
| 111 | 'title' => 'Updater', |
||
| 112 | 'version' => $this->container['application']->getVersion(), |
||
| 113 | 'checkpoints' => $checkpoints |
||
| 114 | ] |
||
| 115 | ); |
||
| 116 | } else { |
||
| 117 | header('Content-Type: application/json'); |
||
| 118 | $content = json_encode($this->ajaxAction(), JSON_UNESCAPED_SLASHES); |
||
| 119 | } |
||
| 120 | return $content; |
||
| 121 | } |
||
| 122 | |||
| 123 | /** |
||
| 124 | * @return bool |
||
| 125 | */ |
||
| 126 | protected function isLoggedIn() { |
||
| 127 | /** @var ConfigReader $configReader */ |
||
| 128 | $locator = $this->container['utils.locator']; |
||
| 129 | $storedSecret = $locator->getSecretFromConfig(); |
||
| 130 | if ($storedSecret === '') { |
||
| 131 | die('updater.secret is undefined in config/config.php. Either browse the admin settings in your ownCloud and click "Open updater" or define a strong secret using <pre>php -r \'echo password_hash("MyStrongSecretDoUseYourOwn!", PASSWORD_DEFAULT)."\n";\'</pre> and set this in the config.php.'); |
||
| 132 | } |
||
| 133 | $sentAuthHeader = ($this->request->header('X_Updater_Auth') !== null) ? $this->request->header('X_Updater_Auth') : ''; |
||
| 134 | |||
| 135 | if(password_verify($sentAuthHeader, $storedSecret)) { |
||
| 136 | return true; |
||
| 137 | } |
||
| 138 | |||
| 139 | return false; |
||
| 140 | } |
||
| 141 | |||
| 142 | /** |
||
| 143 | * @param Engine $templates |
||
| 144 | * @return string |
||
| 145 | */ |
||
| 146 | public function showLogin(Engine $templates) { |
||
| 147 | // If it is a request with invalid token just return "false" so that we can catch this |
||
| 148 | $token = ($this->request->header('X_Updater_Auth') !== null) ? $this->request->header('X_Updater_Auth') : ''; |
||
| 149 | if($token !== '') { |
||
| 150 | return 'false'; |
||
| 151 | } |
||
| 152 | |||
| 153 | $content = $templates->render( |
||
| 154 | 'partials/login', |
||
| 155 | [ |
||
| 156 | 'title' => 'Login Required', |
||
| 157 | ] |
||
| 158 | ); |
||
| 159 | return $content; |
||
| 160 | } |
||
| 161 | |||
| 162 | /** |
||
| 163 | * @return array |
||
| 164 | */ |
||
| 165 | public function ajaxAction() { |
||
| 166 | $application = $this->container['application']; |
||
| 167 | |||
| 168 | $input = new StringInput($this->command); |
||
| 169 | $input->setInteractive(false); |
||
| 170 | |||
| 171 | $output = new BufferedOutput(); |
||
| 172 | $formatter = $output->getFormatter(); |
||
| 173 | $formatter->setDecorated(true); |
||
| 174 | $output->setFormatter(new HtmlOutputFormatter($formatter)); |
||
| 175 | |||
| 176 | $application->setAutoExit(false); |
||
| 177 | |||
| 178 | // Some commands dump things out instead of returning a value |
||
| 179 | ob_start(); |
||
| 180 | $errorCode = $application->run($input, $output); |
||
| 181 | if (!$result = $output->fetch()){ |
||
| 182 | $result = ob_get_contents(); // If empty, replace it by the catched output |
||
| 183 | } |
||
| 184 | ob_end_clean(); |
||
| 185 | $result = nl2br($result); |
||
| 186 | $result = preg_replace('|<br />\r.*<br />(\r.*?)<br />|', '$1<br />', $result); |
||
| 187 | |||
| 188 | return [ |
||
| 189 | 'input' => $this->command, |
||
| 190 | 'output' => $result, |
||
| 191 | 'environment' => '', |
||
| 192 | 'error_code' => $errorCode |
||
| 193 | ]; |
||
| 194 | } |
||
| 195 | |||
| 196 | protected function getEndpoint(){ |
||
| 197 | $endpoint = preg_replace('/(updater\/|updater\/index.php)$/', '', $this->request->getRequestUri()); |
||
| 198 | $fullEndpoint = sprintf( |
||
| 199 | '%s://%s%sindex.php/occ/', |
||
| 200 | $this->request->getServerProtocol(), |
||
| 201 | $this->request->getHost(), |
||
| 202 | $endpoint !== '' ? $endpoint : '/' |
||
| 203 | ); |
||
| 204 | |||
| 205 | return $fullEndpoint; |
||
| 206 | } |
||
| 207 | |||
| 208 | } |
||
| 209 |
This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.
Both the
$myVarassignment in line 1 and the$higherassignment in line 2 are dead. The first because$myVaris never used and the second because$higheris always overwritten for every possible time line.