diff options
Diffstat (limited to 'plugins')
-rw-r--r-- | plugins/API/API.php | 26 | ||||
-rw-r--r-- | plugins/CorePluginsAdmin/Controller.php | 7 | ||||
-rw-r--r-- | plugins/CorePluginsAdmin/PluginInstaller.php | 6 | ||||
-rw-r--r-- | plugins/CoreUpdater/Controller.php | 32 | ||||
-rw-r--r-- | plugins/ImageGraph/API.php | 7 | ||||
-rw-r--r-- | plugins/Installation/Controller.php | 20 | ||||
-rw-r--r-- | plugins/Installation/FormDatabaseSetup.php | 12 | ||||
-rw-r--r-- | plugins/Installation/ServerFilesGenerator.php | 134 | ||||
-rw-r--r-- | plugins/LanguagesManager/API.php | 5 |
9 files changed, 196 insertions, 53 deletions
diff --git a/plugins/API/API.php b/plugins/API/API.php index d26b46db47..19cade72f1 100644 --- a/plugins/API/API.php +++ b/plugins/API/API.php @@ -10,19 +10,19 @@ */ namespace Piwik\Plugins\API; -use Piwik\API\Request; use Piwik\API\Proxy; +use Piwik\API\Request; +use Piwik\Config; use Piwik\DataTable\Filter\ColumnDelete; use Piwik\DataTable\Row; +use Piwik\DataTable; +use Piwik\Date; +use Piwik\Filesystem; use Piwik\Metrics; use Piwik\Piwik; -use Piwik\Common; -use Piwik\Config; -use Piwik\Date; -use Piwik\DataTable; use Piwik\Tracker\GoalManager; -use Piwik\Version; use Piwik\Translate; +use Piwik\Version; require_once PIWIK_INCLUDE_PATH . '/core/Config.php'; @@ -284,14 +284,14 @@ class API { $logo = 'plugins/Zeitgeist/images/logo.png'; if (Config::getInstance()->branding['use_custom_logo'] == 1 - && file_exists(Common::getPathToPiwikRoot() . '/misc/user/logo.png') + && file_exists(Filesystem::getPathToPiwikRoot() . '/misc/user/logo.png') ) { $logo = 'misc/user/logo.png'; } if (!$pathOnly) { return Piwik::getPiwikUrl() . $logo; } - return Common::getPathToPiwikRoot() . '/' . $logo; + return Filesystem::getPathToPiwikRoot() . '/' . $logo; } /** @@ -304,14 +304,14 @@ class API { $logo = 'plugins/Zeitgeist/images/logo-header.png'; if (Config::getInstance()->branding['use_custom_logo'] == 1 - && file_exists(Common::getPathToPiwikRoot() . '/misc/user/logo-header.png') + && file_exists(Filesystem::getPathToPiwikRoot() . '/misc/user/logo-header.png') ) { $logo = 'misc/user/logo-header.png'; } if (!$pathOnly) { return Piwik::getPiwikUrl() . $logo; } - return Common::getPathToPiwikRoot() . '/' . $logo; + return Filesystem::getPathToPiwikRoot() . '/' . $logo; } /** @@ -325,14 +325,14 @@ class API { $logo = 'plugins/Zeitgeist/images/logo.svg'; if (Config::getInstance()->branding['use_custom_logo'] == 1 - && file_exists(Common::getPathToPiwikRoot() . '/misc/user/logo.svg') + && file_exists(Filesystem::getPathToPiwikRoot() . '/misc/user/logo.svg') ) { $logo = 'misc/user/logo.svg'; } if (!$pathOnly) { return Piwik::getPiwikUrl() . $logo; } - return Common::getPathToPiwikRoot() . '/' . $logo; + return Filesystem::getPathToPiwikRoot() . '/' . $logo; } /** @@ -346,7 +346,7 @@ class API /* We always have our application logo */ return true; } else if (Config::getInstance()->branding['use_custom_logo'] == 1 - && file_exists(Common::getPathToPiwikRoot() . '/misc/user/logo.svg') + && file_exists(Filesystem::getPathToPiwikRoot() . '/misc/user/logo.svg') ) { return true; } diff --git a/plugins/CorePluginsAdmin/Controller.php b/plugins/CorePluginsAdmin/Controller.php index d5ae70cf41..867a645953 100644 --- a/plugins/CorePluginsAdmin/Controller.php +++ b/plugins/CorePluginsAdmin/Controller.php @@ -10,12 +10,13 @@ */ namespace Piwik\Plugins\CorePluginsAdmin; -use Piwik\Piwik; use Piwik\Common; use Piwik\Config; +use Piwik\Filesystem; +use Piwik\Piwik; use Piwik\Plugin; -use Piwik\View; use Piwik\Url; +use Piwik\View; /** * @@ -195,7 +196,7 @@ class Controller extends \Piwik\Controller\Admin $pluginName = $this->initPluginModification(); $uninstalled = \Piwik\PluginsManager::getInstance()->uninstallPlugin($pluginName); if (!$uninstalled) { - $path = Common::getPathToPiwikRoot() . '/plugins/' . $pluginName . '/'; + $path = Filesystem::getPathToPiwikRoot() . '/plugins/' . $pluginName . '/'; $messagePermissions = Piwik::getErrorMessageMissingPermissions($path); $messageIntro = Piwik_Translate("Warning: \"%s\" could not be uninstalled. Piwik did not have enough permission to delete the files in $path. ", diff --git a/plugins/CorePluginsAdmin/PluginInstaller.php b/plugins/CorePluginsAdmin/PluginInstaller.php index 0fa791c795..eb7cf7095c 100644 --- a/plugins/CorePluginsAdmin/PluginInstaller.php +++ b/plugins/CorePluginsAdmin/PluginInstaller.php @@ -9,7 +9,7 @@ * @package CorePluginsAdmin */ namespace Piwik\Plugins\CorePluginsAdmin; -use Piwik\Http; +use Piwik\Filesystem; use Piwik\Piwik; use Piwik\Unzip; @@ -93,7 +93,7 @@ class PluginInstaller $pluginTargetPath = PIWIK_USER_PATH . self::PATH_TO_EXTRACT . $this->pluginName; $this->removeFolderIfExists($pluginTargetPath); - Piwik::copyRecursive($tmpPluginFolder, $pluginTargetPath); + Filesystem::copyRecursive($tmpPluginFolder, $pluginTargetPath); } /** @@ -102,7 +102,7 @@ class PluginInstaller private function removeFolderIfExists($pathExtracted) { if (file_exists($pathExtracted)) { - Piwik::unlinkRecursive($pathExtracted, true); + Filesystem::unlinkRecursive($pathExtracted, true); } } diff --git a/plugins/CoreUpdater/Controller.php b/plugins/CoreUpdater/Controller.php index 6853dc3cc9..ae48b8e8ce 100644 --- a/plugins/CoreUpdater/Controller.php +++ b/plugins/CoreUpdater/Controller.php @@ -13,19 +13,19 @@ namespace Piwik\Plugins\CoreUpdater; use Exception; use Piwik\API\Request; use Piwik\ArchiveProcessor\Rules; -use Piwik\Config; -use Piwik\Piwik; use Piwik\Common; +use Piwik\Config; +use Piwik\Filesystem; use Piwik\Http; +use Piwik\Piwik; +use Piwik\Plugins\LanguagesManager\LanguagesManager; +use Piwik\Unzip; +use Piwik\UpdateCheck; use Piwik\Updater; -use Piwik\View; +use Piwik\Updater_UpdateErrorException; use Piwik\Version; -use Piwik\UpdateCheck; -use Piwik\Unzip; +use Piwik\View; use Piwik\View\OneClickDone; -use Piwik\Plugins\CoreUpdater\CoreUpdater; -use Piwik\Plugins\LanguagesManager\LanguagesManager; -use Piwik\Updater_UpdateErrorException; /** * @@ -138,7 +138,7 @@ class Controller extends \Piwik\Controller $this->pathRootExtractedPiwik = $pathExtracted . 'piwik'; if (file_exists($this->pathRootExtractedPiwik)) { - Piwik::unlinkRecursive($this->pathRootExtractedPiwik, true); + Filesystem::unlinkRecursive($this->pathRootExtractedPiwik, true); } $archive = Unzip::factory('PclZip', $this->pathPiwikZip); @@ -173,7 +173,7 @@ class Controller extends \Piwik\Controller { $configFileBefore = PIWIK_USER_PATH . '/config/global.ini.php'; $configFileAfter = PIWIK_USER_PATH . self::CONFIG_FILE_BACKUP; - Piwik::copy($configFileBefore, $configFileAfter); + Filesystem::copy($configFileBefore, $configFileAfter); } private function oneClick_Copy() @@ -189,7 +189,7 @@ class Controller extends \Piwik\Controller * Copy all files to PIWIK_INCLUDE_PATH. * These files are accessed through the dispatcher. */ - Piwik::copyRecursive($this->pathRootExtractedPiwik, PIWIK_INCLUDE_PATH); + Filesystem::copyRecursive($this->pathRootExtractedPiwik, PIWIK_INCLUDE_PATH); /* * These files are visible in the web root and are generally @@ -206,23 +206,23 @@ class Controller extends \Piwik\Controller ); foreach ($specialCases as $file) { - Piwik::copy($this->pathRootExtractedPiwik . $file, PIWIK_DOCUMENT_ROOT . $file); + Filesystem::copy($this->pathRootExtractedPiwik . $file, PIWIK_DOCUMENT_ROOT . $file); } /* * Copy the non-PHP files (e.g., images, css, javascript) */ - Piwik::copyRecursive($this->pathRootExtractedPiwik, PIWIK_DOCUMENT_ROOT, true); + Filesystem::copyRecursive($this->pathRootExtractedPiwik, PIWIK_DOCUMENT_ROOT, true); } /* * Config files may be user (account) specific */ if (PIWIK_INCLUDE_PATH !== PIWIK_USER_PATH) { - Piwik::copyRecursive($this->pathRootExtractedPiwik . '/config', PIWIK_USER_PATH . '/config'); + Filesystem::copyRecursive($this->pathRootExtractedPiwik . '/config', PIWIK_USER_PATH . '/config'); } - Piwik::unlinkRecursive($this->pathRootExtractedPiwik, true); + Filesystem::unlinkRecursive($this->pathRootExtractedPiwik, true); if (function_exists('apc_clear_cache')) { apc_clear_cache(); // clear the system (aka 'opcode') cache @@ -289,7 +289,7 @@ class Controller extends \Piwik\Controller private function doWelcomeUpdates($view, $componentsWithUpdateFile) { $view->new_piwik_version = Version::VERSION; - $view->commandUpgradePiwik = "<br /><code>php " . Common::getPathToPiwikRoot() . "/index.php -- \"module=CoreUpdater\" </code>"; + $view->commandUpgradePiwik = "<br /><code>php " . Filesystem::getPathToPiwikRoot() . "/index.php -- \"module=CoreUpdater\" </code>"; $pluginNamesToUpdate = array(); $coreToUpdate = false; diff --git a/plugins/ImageGraph/API.php b/plugins/ImageGraph/API.php index 6266bf9ed2..8cf9850ce1 100644 --- a/plugins/ImageGraph/API.php +++ b/plugins/ImageGraph/API.php @@ -11,12 +11,13 @@ namespace Piwik\Plugins\ImageGraph; use Exception; +use Piwik\Common; +use Piwik\Filesystem; use Piwik\Period; use Piwik\Piwik; -use Piwik\Common; -use Piwik\Translate; use Piwik\Plugins\API\API as MetaAPI; use Piwik\Plugins\ImageGraph\StaticGraph; +use Piwik\Translate; /** * The ImageGraph.get API call lets you generate beautiful static PNG Graphs for any existing Piwik report. @@ -510,7 +511,7 @@ class API $fileName = self::$DEFAULT_PARAMETERS[$graphType][self::FILENAME_KEY] . '_' . $apiModule . '_' . $apiAction . $idGoal . ' ' . str_replace(',', '-', $date) . ' ' . $idSite . '.png'; $fileName = str_replace(array(' ', '/'), '_', $fileName); - if (!Common::isValidFilename($fileName)) { + if (!Filesystem::isValidFilename($fileName)) { throw new Exception('Error: Image graph filename ' . $fileName . ' is not valid.'); } diff --git a/plugins/Installation/Controller.php b/plugins/Installation/Controller.php index 5df88f94f4..106023195d 100644 --- a/plugins/Installation/Controller.php +++ b/plugins/Installation/Controller.php @@ -18,6 +18,7 @@ use Piwik\Config; use Piwik\DataAccess\ArchiveTableCreator; use Piwik\Db\Adapter; use Piwik\Db; +use Piwik\Filesystem; use Piwik\Http; use Piwik\Piwik; use Piwik\Plugins\LanguagesManager\LanguagesManager; @@ -63,6 +64,16 @@ class Controller extends \Piwik\Controller\Admin Piwik_PostEvent('InstallationController.construct', array($this)); } + protected static function initServerFilesForSecurity() + { + if (Common::isIIS()) { + ServerFilesGenerator::createWebConfigFiles(); + } else { + ServerFilesGenerator::createHtAccessFiles(); + } + ServerFilesGenerator::createWebRootFiles(); + } + /** * Get installation steps * @@ -720,12 +731,7 @@ class Controller extends \Piwik\Controller\Admin $infos['can_auto_update'] = Piwik::canAutoUpdate(); - if (Common::isIIS()) { - Piwik::createWebConfigFiles(); - } else { - Piwik::createHtAccessFiles(); - } - Piwik::createWebRootFiles(); + self::initServerFilesForSecurity(); $infos['phpVersion_minimum'] = $piwik_minimumPHPVersion; $infos['phpVersion'] = PHP_VERSION; @@ -858,7 +864,7 @@ class Controller extends \Piwik\Controller\Admin } // check if filesystem is NFS, if it is file based sessions won't work properly - $infos['is_nfs'] = Piwik::checkIfFileSystemIsNFS(); + $infos['is_nfs'] = Filesystem::checkIfFileSystemIsNFS(); // determine whether there are any errors/warnings from the checks done above $infos['has_errors'] = false; diff --git a/plugins/Installation/FormDatabaseSetup.php b/plugins/Installation/FormDatabaseSetup.php index 71f4643c8a..84efb6e698 100644 --- a/plugins/Installation/FormDatabaseSetup.php +++ b/plugins/Installation/FormDatabaseSetup.php @@ -10,14 +10,14 @@ */ namespace Piwik\Plugins\Installation; -use Piwik\Db\Adapter; -use Piwik\Piwik; -use Piwik\Common; -use Piwik\QuickForm2; use Exception; -use HTML_QuickForm2_Rule; use HTML_QuickForm2_DataSource_Array; use HTML_QuickForm2_Factory; +use HTML_QuickForm2_Rule; +use Piwik\Db\Adapter; +use Piwik\Filesystem; +use Piwik\Piwik; +use Piwik\QuickForm2; use Zend_Db_Adapter_Exception; /** @@ -309,7 +309,7 @@ class FormDatabaseSetup_Rule_checkValidFilename extends HTML_QuickForm2_Rule { $prefix = $this->owner->getValue(); return empty($prefix) - || Common::isValidFilename($prefix); + || Filesystem::isValidFilename($prefix); } } diff --git a/plugins/Installation/ServerFilesGenerator.php b/plugins/Installation/ServerFilesGenerator.php new file mode 100644 index 0000000000..2fbf591a21 --- /dev/null +++ b/plugins/Installation/ServerFilesGenerator.php @@ -0,0 +1,134 @@ +<?php +/** + * Piwik - Open source web analytics + * + * @link http://piwik.org + * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later + * + * @category Piwik_Plugins + * @package Installation + */ +namespace Piwik\Plugins\Installation; + +use Piwik\Filesystem; + +class ServerFilesGenerator +{ + + /** + * Generate Apache .htaccess files to restrict access + */ + public static function createHtAccessFiles() + { + // deny access to these folders + $directoriesToProtect = array( + '/config', + '/core', + '/lang', + '/tmp', + ); + foreach ($directoriesToProtect as $directoryToProtect) { + Filesystem::createHtAccess(PIWIK_INCLUDE_PATH . $directoryToProtect, $overwrite = true); + } + + // Allow/Deny lives in different modules depending on the Apache version + $allow = "<IfModule mod_access.c>\nAllow from all\n</IfModule>\n<IfModule !mod_access_compat>\n<IfModule mod_authz_host.c>\nAllow from all\n</IfModule>\n</IfModule>\n<IfModule mod_access_compat>\nAllow from all\n</IfModule>\n"; + $deny = "<IfModule mod_access.c>\nDeny from all\n</IfModule>\n<IfModule !mod_access_compat>\n<IfModule mod_authz_host.c>\nDeny from all\n</IfModule>\n</IfModule>\n<IfModule mod_access_compat>\nDeny from all\n</IfModule>\n"; + + // more selective allow/deny filters + $allowAny = "<Files \"*\">\n" . $allow . "Satisfy any\n</Files>\n"; + $allowStaticAssets = "<Files ~ \"\\.(test\.php|gif|ico|jpg|png|svg|js|css|swf)$\">\n" . $allow . "Satisfy any\n</Files>\n"; + $denyDirectPhp = "<Files ~ \"\\.(php|php4|php5|inc|tpl|in|twig)$\">\n" . $deny . "</Files>\n"; + + $directoriesToProtect = array( + '/js' => $allowAny, + '/libs' => $denyDirectPhp . $allowStaticAssets, + '/vendor' => $denyDirectPhp . $allowStaticAssets, + '/plugins' => $denyDirectPhp . $allowStaticAssets, + '/misc/user' => $denyDirectPhp . $allowStaticAssets, + ); + foreach ($directoriesToProtect as $directoryToProtect => $content) { + Filesystem::createHtAccess(PIWIK_INCLUDE_PATH . $directoryToProtect, $overwrite = true, $content); + } + } + + /** + * Generate IIS web.config files to restrict access + * + * Note: for IIS 7 and above + */ + public static function createWebConfigFiles() + { + @file_put_contents(PIWIK_INCLUDE_PATH . '/web.config', + '<?xml version="1.0" encoding="UTF-8"?> +<configuration> + <system.webServer> + <security> + <requestFiltering> + <hiddenSegments> + <add segment="config" /> + <add segment="core" /> + <add segment="lang" /> + <add segment="tmp" /> + </hiddenSegments> + <fileExtensions> + <add fileExtension=".tpl" allowed="false" /> + <add fileExtension=".twig" allowed="false" /> + <add fileExtension=".php4" allowed="false" /> + <add fileExtension=".php5" allowed="false" /> + <add fileExtension=".inc" allowed="false" /> + <add fileExtension=".in" allowed="false" /> + </fileExtensions> + </requestFiltering> + </security> + <directoryBrowse enabled="false" /> + <defaultDocument> + <files> + <remove value="index.php" /> + <add value="index.php" /> + </files> + </defaultDocument> + </system.webServer> +</configuration>'); + + // deny direct access to .php files + $directoriesToProtect = array( + '/libs', + '/vendor', + '/plugins', + ); + foreach ($directoriesToProtect as $directoryToProtect) { + @file_put_contents(PIWIK_INCLUDE_PATH . $directoryToProtect . '/web.config', + '<?xml version="1.0" encoding="UTF-8"?> +<configuration> + <system.webServer> + <security> + <requestFiltering> + <denyUrlSequences> + <add sequence=".php" /> + </denyUrlSequences> + </requestFiltering> + </security> + </system.webServer> +</configuration>'); + } + } + + /** + * Generate default robots.txt, favicon.ico, etc to suppress + * 404 (Not Found) errors in the web server logs, if Piwik + * is installed in the web root (or top level of subdomain). + * + * @see misc/crossdomain.xml + */ + public static function createWebRootFiles() + { + $filesToCreate = array( + '/robots.txt', + '/favicon.ico', + ); + foreach ($filesToCreate as $file) { + @file_put_contents(PIWIK_DOCUMENT_ROOT . $file, ''); + } + } +}
\ No newline at end of file diff --git a/plugins/LanguagesManager/API.php b/plugins/LanguagesManager/API.php index eccb98050a..c7bee7603a 100644 --- a/plugins/LanguagesManager/API.php +++ b/plugins/LanguagesManager/API.php @@ -11,9 +11,10 @@ */ namespace Piwik\Plugins\LanguagesManager; -use Piwik\Piwik; use Piwik\Common; use Piwik\Db; +use Piwik\Filesystem; +use Piwik\Piwik; /** * The LanguagesManager API lets you access existing Piwik translations, and change Users languages preferences. @@ -54,7 +55,7 @@ class API public function isLanguageAvailable($languageCode) { return $languageCode !== false - && Common::isValidFilename($languageCode) + && Filesystem::isValidFilename($languageCode) && in_array($languageCode, $this->getAvailableLanguages()); } |