Add a static code checker for evil patterns in apps.

Disabled by default for now.
We will check for private api calls here later once the public api is in place
remotes/origin/stable4
Frank Karlitschek 2012-04-21 22:47:56 +07:00
parent 6bfe2289be
commit a86d89f5ca
2 changed files with 57 additions and 3 deletions

@ -24,6 +24,7 @@ $CONFIG = array(
"mail_smtpauth" => "false",
"mail_smtpname" => "",
"mail_smtppassword" => "",
"appcodechecker" => "",
// "datadirectory" => ""
);
?>

@ -47,6 +47,7 @@ class OC_Installer{
* This function works as follows
* -# fetching the file
* -# unzipping it
* -# check the code
* -# installing the database at appinfo/database.xml
* -# including appinfo/install.php
* -# setting the installed version
@ -91,6 +92,7 @@ class OC_Installer{
//extract the archive in a temporary folder
$extractDir=OC_Helper::tmpFolder();
OC_Helper::rmdirr($extractDir);
mkdir($extractDir);
if($archive=OC_Archive::open($path)){
$archive->extract($extractDir);
@ -102,7 +104,7 @@ class OC_Installer{
}
return false;
}
//load the info.xml file of the app
if(!is_file($extractDir.'/appinfo/info.xml')){
//try to find it in a subdir
@ -125,6 +127,12 @@ class OC_Installer{
}
$info=OC_App::getAppInfo($extractDir.'/appinfo/info.xml',true);
$basedir=OC::$APPSROOT.'/apps/'.$info['id'];
// check the code for not allowed calls
if(!OC_Installer::checkCode($info['id'],$extractDir)){
OC_Helper::rmdirr($extractDir);
return false;
}
//check if an app with the same id is already installed
if(self::isInstalled( $info['id'] )){
@ -151,8 +159,8 @@ class OC_Installer{
}
//copy the app to the correct place
if(!mkdir($basedir)){
OC_Log::write('core','Can\'t create app folder ('.$basedir.')',OC_Log::ERROR);
if(@!mkdir($basedir)){
OC_Log::write('core','Can\'t create app folder. Please fix permissions. ('.$basedir.')',OC_Log::ERROR);
OC_Helper::rmdirr($extractDir);
if($data['source']=='http'){
unlink($path);
@ -300,4 +308,49 @@ class OC_Installer{
OC_Appconfig::setValue($app,'installed_version',OC_App::getAppVersion($app));
return $info;
}
/**
* check the code of an app with some static code checks
* @param string $folder the folder of the app to check
* @returns true for app is o.k. and false for app is not o.k.
*/
public static function checkCode($appname,$folder){
$blacklist=array(
'fopen(',
'eval('
// more evil pattern will go here later
// will will also check if an app is using private api once the public api is in place
);
// is the code checker enabled?
if(OC_Config::getValue('appcodechecker', false)){
// check if grep is installed
$grep = exec('which grep');
if($grep=='') {
OC_Log::write('core','grep not installed. So checking the code of the app "'.$appname.'" was not possible',OC_Log::ERROR);
return true;
}
// iterate the bad patterns
foreach($blacklist as $bl) {
$cmd = 'grep -ri '.escapeshellarg($bl).' '.$folder.'';
$result = exec($cmd);
// bad pattern found
if($result<>'') {
OC_Log::write('core','App "'.$appname.'" is using a not allowed call "'.$bl.'". Installation refused.',OC_Log::ERROR);
return false;
}
}
return true;
}else{
return true;
}
}
}