From 65512ca984a86ac2c20eaf938d2d5f8cdf76ca29 Mon Sep 17 00:00:00 2001 From: bruno DA SILVA Date: Wed, 16 Oct 2019 18:00:54 +0200 Subject: [PATCH] 2498 - restrict access to module's assets - into env-* - into datamodels - into extensions --- datamodels/.htaccess | 13 +++ datamodels/web.config | 8 ++ extensions/.htaccess | 13 +++ extensions/web.config | 8 ++ setup/compiler.class.inc.php | 208 +++++++++++++++++++++++++++-------- 5 files changed, 206 insertions(+), 44 deletions(-) create mode 100644 datamodels/.htaccess create mode 100644 datamodels/web.config create mode 100644 extensions/.htaccess create mode 100644 extensions/web.config diff --git a/datamodels/.htaccess b/datamodels/.htaccess new file mode 100644 index 000000000..782472c78 --- /dev/null +++ b/datamodels/.htaccess @@ -0,0 +1,13 @@ +# Apache 2.4 + +Require all denied + + +# Apache 2.2 + +deny from all +Satisfy All + + +# Apache 2.2 and 2.4 +IndexIgnore * diff --git a/datamodels/web.config b/datamodels/web.config new file mode 100644 index 000000000..599a5f260 --- /dev/null +++ b/datamodels/web.config @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/extensions/.htaccess b/extensions/.htaccess new file mode 100644 index 000000000..782472c78 --- /dev/null +++ b/extensions/.htaccess @@ -0,0 +1,13 @@ +# Apache 2.4 + +Require all denied + + +# Apache 2.2 + +deny from all +Satisfy All + + +# Apache 2.2 and 2.4 +IndexIgnore * diff --git a/extensions/web.config b/extensions/web.config new file mode 100644 index 000000000..599a5f260 --- /dev/null +++ b/extensions/web.config @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/setup/compiler.class.inc.php b/setup/compiler.class.inc.php index 2fc52b3a9..4fb64227d 100644 --- a/setup/compiler.class.inc.php +++ b/setup/compiler.class.inc.php @@ -225,26 +225,49 @@ class MFCompiler $iStart = strlen(realpath(APPROOT)); $sRelFinalTargetDir = substr($sFinalTargetDir, strlen(APPROOT)); - $sModuleDesignHtaccessFileName = $sTempTargetDir.'/core/module_designs/.htaccess'; - // every xml files present in here must not be publicly accessible + $sModuleDesignDir = $sTempTargetDir.'/core/module_designs/'; + SetupUtils::builddir($sModuleDesignDir); + + $sModuleDesignHtaccessFileName = $sModuleDesignDir.'.htaccess'; $sModuleDesignHtaccessFileContent = << - Order deny,allow - Deny from all - +# This file was automatically generated by iTop. + +# Apache 2.4 + +Require all denied + + +# Apache 2.2 + +deny from all +Satisfy All + + +# Apache 2.2 and 2.4 +IndexIgnore * + EOF; - SetupUtils::builddir(dirname($sModuleDesignHtaccessFileName)); - $ret = file_put_contents($sModuleDesignHtaccessFileName, $sModuleDesignHtaccessFileContent); - if ($ret === false) - { - $iLen = strlen($sModuleDesignHtaccessFileContent); - $fFree = @disk_free_space(dirname($sModuleDesignHtaccessFileName)); - $aErr = error_get_last(); - throw new Exception("Failed to write '$sModuleDesignHtaccessFileName'. Last error: '{$aErr['message']}', content to write: $iLen bytes, available free space on disk: $fFree."); - } + $this->WriteFileIfNotExists($sModuleDesignHtaccessFileName, $sModuleDesignHtaccessFileContent); unset($sModuleDesignHtaccessFileContent, $sModuleDesignHtaccessFileName); + $sModuleDesignHtaccessFileName = $sModuleDesignDir.'web.config'; + $sModuleDesignHtaccessFileContent = << + + + + + + + + + +XML; + $this->WriteFileIfNotExists($sModuleDesignHtaccessFileName, $sModuleDesignHtaccessFileContent); + unset($sModuleDesignHtaccessFileContent, $sModuleDesignHtaccessFileName); + + foreach($aModules as $foo => $oModule) { $sModuleName = $oModule->GetName(); @@ -267,37 +290,10 @@ EOF; // Push the other module files SetupUtils::copydir($sModuleRootDir, $sTempTargetDir.'/'.$sRelativeDir, $bUseSymbolicLinks); - $sModuleHtaccessFileName = $sTempTargetDir.'/'.$sRelativeDir.'/.htaccess'; - if (!file_exists($sModuleHtaccessFileName)) - { - // if no .htaccess is present, add a generic one prohibiting access to potentially sensible files (ie: even if it is quite a bad practice, it may happen that a developer put a secret into the xml) - $sModuleHtaccessFileContent = << - Order deny,allow - Deny from all - + $this->WriteModuleHtaccess($sTempTargetDir, $sFinalTargetDir, $sRelativeDir, $sModuleName, $sModuleVersion); + $this->WriteModuleWebConfig($sTempTargetDir, $sFinalTargetDir, $sRelativeDir, $sModuleName, $sModuleVersion); - - Order deny,allow - Deny from all - - - Order deny,allow - Deny from all - - -EOF; - $ret = file_put_contents($sModuleHtaccessFileName, $sModuleHtaccessFileContent); - if ($ret === false) - { - $iLen = strlen($sModuleHtaccessFileContent); - $fFree = @disk_free_space(dirname($sModuleHtaccessFileName)); - $aErr = error_get_last(); - throw new Exception("Failed to write '$sModuleHtaccessFileName'. Last error: '{$aErr['message']}', content to write: $iLen bytes, available free space on disk: $fFree."); - } - SetupLog::Warning("Added a generic .htaccess into {$sFinalTargetDir}/{$sRelativeDir} during the compilation.");; - } } else { @@ -2938,4 +2934,128 @@ EOF; return $sPHP; } + + /** + * Write a file only if not exists + * Also add some informations in case of a write failleure + * @param $sFilename + * @param $sContent + * + * @return bool|int + * @throws \Exception + */ + protected function WriteFileIfNotExists($sFilename, $sContent) + { + if (file_exists($sFilename)) + { + return false; + } + + $ret = file_put_contents($sFilename, $sContent); + if ($ret === false) + { + $iLen = strlen($sContent); + $fFree = @disk_free_space(dirname($sFilename)); + $aErr = error_get_last(); + throw new Exception("Failed to write '$sFilename'. Last error: '{$aErr['message']}', content to write: $iLen bytes, available free space on disk: $fFree."); + } + + return $ret; +} + + /** + * if no ".htaccess" is present, add a generic one prohibiting access to potentially sensible files (ie: even if it is quite a bad practice, it may happen that a developer put a secret into the xml) + * + * @param $sTempTargetDir + * @param $sFinalTargetDir + * @param $sRelativeDir + * @param $sModuleName + * @param $sModuleVersion + * + * @throws \Exception + */ + protected function WriteModuleHtaccess($sTempTargetDir, $sFinalTargetDir, $sRelativeDir, $sModuleName, $sModuleVersion) + { + $sContent = << +Require all denied + + Require all granted + + + +# Apache 2.2 + +deny from all +Satisfy All + + Order Allow,Deny + Allow from all + + + +# Apache 2.2 and 2.4 +IndexIgnore * + +EOF; + + $sFilename = $sTempTargetDir.'/'.$sRelativeDir.'/.htaccess'; + + $bWritten = $this->WriteFileIfNotExists($sFilename, $sContent); + if ($bWritten) + { + SetupLog::Warning("Added a generic .htaccess into {$sFinalTargetDir}/{$sRelativeDir} during the compilation.");; + } + } + + /** + * if no "web.config" is present, add a generic one prohibiting access to potentially sensible files (ie: even if it is quite a bad practice, it may happen that a developer put a secret into the xml) + * + * @param $sTempTargetDir + * @param $sFinalTargetDir + * @param $sRelativeDir + * @param $sModuleName + * @param $sModuleVersion + * + * @throws \Exception + */ + protected function WriteModuleWebConfig($sTempTargetDir, $sFinalTargetDir, $sRelativeDir, $sModuleName, $sModuleVersion) + { + $sContent = << + + + + + + + + + + + + + + + + + + + + + + +EOF; + + $sFilename = $sTempTargetDir.'/'.$sRelativeDir.'/web.config'; + + $bWritten = $this->WriteFileIfNotExists($sFilename, $sContent); + if ($bWritten) + { + SetupLog::Warning("Added a generic web.config into {$sFinalTargetDir}/{$sRelativeDir} during the compilation.");; + } + } }