Skip to content

Commit

Permalink
fix(appmanager): Fix tainted file path when loading appinfos
Browse files Browse the repository at this point in the history
Signed-off-by: Joas Schilling <[email protected]>
  • Loading branch information
nickvergessen committed Oct 7, 2024
1 parent 5bd1873 commit e90f9e3
Show file tree
Hide file tree
Showing 6 changed files with 34 additions and 27 deletions.
5 changes: 0 additions & 5 deletions build/psalm-baseline-security.xml
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,6 @@
<code><![CDATA['Location: ' . \OC::$WEBROOT . '/']]></code>
</TaintedHeader>
</file>
<file src="lib/private/App/InfoParser.php">
<TaintedFile>
<code><![CDATA[$file]]></code>
</TaintedFile>
</file>
<file src="lib/private/AppFramework/Utility/SimpleContainer.php">
<TaintedCallable>
<code><![CDATA[$name]]></code>
Expand Down
4 changes: 0 additions & 4 deletions build/psalm-baseline.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2750,10 +2750,6 @@
<NullArgument>
<code><![CDATA[null]]></code>
</NullArgument>
<TypeDoesNotContainNull>
<code><![CDATA[$appId === null]]></code>
<code><![CDATA[$appId === null]]></code>
</TypeDoesNotContainNull>
</file>
<file src="lib/private/legacy/OC_Helper.php">
<InvalidArrayOffset>
Expand Down
35 changes: 21 additions & 14 deletions lib/private/App/AppManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -744,28 +744,35 @@ public function getAppsNeedingUpgrade($version) {
*/
public function getAppInfo(string $appId, bool $path = false, $lang = null) {
if ($path) {
$file = $appId;
} else {
if ($lang === null && isset($this->appInfos[$appId])) {
return $this->appInfos[$appId];
}
try {
$appPath = $this->getAppPath($appId);
} catch (AppPathNotFoundException $e) {
return null;
}
$file = $appPath . '/appinfo/info.xml';
throw new \InvalidArgumentException('Calling IAppManager::getAppInfo() with a path is no longer supported. Please call IAppManager::getAppInfoByPath() instead and verify that the path is good before calling.');
}
if ($lang === null && isset($this->appInfos[$appId])) {
return $this->appInfos[$appId];
}
try {
$appPath = $this->getAppPath($appId);
} catch (AppPathNotFoundException $e) {
return null;
}
$file = $appPath . '/appinfo/info.xml';

return $this->getAppInfoByPath($file, $lang);
}

public function getAppInfoByPath(string $path, ?string $lang = null): ?array {
if (!str_ends_with($path, '/appinfo/info.xml')) {
return null;
}

$parser = new InfoParser($this->memCacheFactory->createLocal('core.appinfo'));
$data = $parser->parse($file);
$data = $parser->parse($path);

if (is_array($data)) {
$data = \OC_App::parseAppInfo($data, $lang);
}

if ($lang === null) {
$this->appInfos[$appId] = $data;
if ($lang === null && isset($data['id'])) {
$this->appInfos[$data['id']] = $data;
}

return $data;
Expand Down
2 changes: 1 addition & 1 deletion lib/private/Installer.php
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ public function installApp(string $appId, bool $forceEnable = false): string {
}

$l = \OCP\Util::getL10N('core');
$info = \OCP\Server::get(IAppManager::class)->getAppInfo($basedir . '/appinfo/info.xml', true, $l->getLanguageCode());
$info = \OCP\Server::get(IAppManager::class)->getAppInfoByPath($basedir . '/appinfo/info.xml', $l->getLanguageCode());

if (!is_array($info)) {
throw new \Exception(
Expand Down
5 changes: 3 additions & 2 deletions lib/private/legacy/OC_App.php
Original file line number Diff line number Diff line change
Expand Up @@ -313,7 +313,8 @@ public static function findAppInDirectories(string $appId, bool $ignoreCache = f
* @deprecated 11.0.0 use \OCP\Server::get(IAppManager)->getAppPath()
*/
public static function getAppPath(string $appId, bool $refreshAppPath = false) {
if ($appId === null || trim($appId) === '') {
$appId = self::cleanAppId($appId);
if ($appId === '') {
return false;
}

Expand Down Expand Up @@ -346,7 +347,7 @@ public static function getAppWebPath(string $appId) {
*/
public static function getAppVersionByPath(string $path): string {
$infoFile = $path . '/appinfo/info.xml';
$appData = \OC::$server->getAppManager()->getAppInfo($infoFile, true);
$appData = \OCP\Server::get(IAppManager::class)->getAppInfoByPath($infoFile);
return $appData['version'] ?? '';
}

Expand Down
10 changes: 9 additions & 1 deletion lib/public/App/IAppManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,22 @@ interface IAppManager {
public const BACKEND_CALDAV = 'caldav';

/**
* Returns the app information from "appinfo/info.xml".
* Returns the app information from "appinfo/info.xml" for an app
*
* @param string|null $lang
* @return array|null
* @since 14.0.0
* @since 31.0.0 Usage of $path is discontinued and throws an \InvalidArgumentException, use {@see self::getAppInfoByPath} instead.
*/
public function getAppInfo(string $appId, bool $path = false, $lang = null);

/**
* Returns the app information from a given path ending with "/appinfo/info.xml"
*
* @since 31.0.0
*/
public function getAppInfoByPath(string $path, ?string $lang = null): ?array;

/**
* Returns the app information from "appinfo/info.xml".
*
Expand Down

0 comments on commit e90f9e3

Please sign in to comment.