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
This commit is contained in:
Frank Karlitschek 2012-04-21 22:47:56 +02:00
parent 6bfe2289be
commit a86d89f5ca
2 changed files with 57 additions and 3 deletions

View File

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

View File

@ -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;
}
}
}