]> source.dussan.org Git - nextcloud-server.git/commitdiff
Add a static code checker for evil patterns in apps.
authorFrank Karlitschek <karlitschek@kde.org>
Sat, 21 Apr 2012 20:47:56 +0000 (22:47 +0200)
committerFrank Karlitschek <karlitschek@kde.org>
Sat, 21 Apr 2012 20:47:56 +0000 (22:47 +0200)
Disabled by default for now.
We will check for private api calls here later once the public api is in place

config/config.sample.php
lib/installer.php

index 9f6d674fc0e4c68887ac8968bd4b6c362d511789..0900937c690db60a9925a5c9b875ca4030456705 100755 (executable)
@@ -24,6 +24,7 @@ $CONFIG = array(
 "mail_smtpauth" => "false",
 "mail_smtpname" => "",
 "mail_smtppassword" => "",
+"appcodechecker" => "",
 // "datadirectory" => ""
 );
 ?>
index 6edf4ce1b74f5c86fa5b438249580630116253fa..d5592273815199fc63721c4e5b82b28e04a55221 100644 (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;
+               }
+        }
+
+
 }