Issues (4069)

Security Analysis    not enabled

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  Cross-Site Scripting
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Header Injection
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

ModuleInstall/PackageManager/PackageController.php (2 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
/*********************************************************************************
3
 * SugarCRM Community Edition is a customer relationship management program developed by
4
 * SugarCRM, Inc. Copyright (C) 2004-2013 SugarCRM Inc.
5
6
 * SuiteCRM is an extension to SugarCRM Community Edition developed by Salesagility Ltd.
7
 * Copyright (C) 2011 - 2014 Salesagility Ltd.
8
 *
9
 * This program is free software; you can redistribute it and/or modify it under
10
 * the terms of the GNU Affero General Public License version 3 as published by the
11
 * Free Software Foundation with the addition of the following permission added
12
 * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
13
 * IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY
14
 * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
15
 *
16
 * This program is distributed in the hope that it will be useful, but WITHOUT
17
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18
 * FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public License for more
19
 * details.
20
 *
21
 * You should have received a copy of the GNU Affero General Public License along with
22
 * this program; if not, see http://www.gnu.org/licenses or write to the Free
23
 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
24
 * 02110-1301 USA.
25
 *
26
 * You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road,
27
 * SW2-130, Cupertino, CA 95014, USA. or at email address [email protected].
28
 *
29
 * The interactive user interfaces in modified source and object code versions
30
 * of this program must display Appropriate Legal Notices, as required under
31
 * Section 5 of the GNU Affero General Public License version 3.
32
 *
33
 * In accordance with Section 7(b) of the GNU Affero General Public License version 3,
34
 * these Appropriate Legal Notices must retain the display of the "Powered by
35
 * SugarCRM" logo and "Supercharged by SuiteCRM" logo. If the display of the logos is not
36
 * reasonably feasible for  technical reasons, the Appropriate Legal Notices must
37
 * display the words  "Powered by SugarCRM" and "Supercharged by SuiteCRM".
38
 ********************************************************************************/
39
40
 require_once('ModuleInstall/PackageManager/PackageManagerDisplay.php');
41
 require_once('ModuleInstall/PackageManager/PackageManager.php');
42
 class PackageController{
43
        var $_pm;
44
45
        /**
46
         * Constructor: this class is called from the the ajax call and handles invoking the correct
47
         * functionality on the server.
48
         */
49
        function __construct(){
50
           $this->_pm = new PackageManager();
51
        }
52
53
    /**
54
     * @deprecated deprecated since version 7.6, PHP4 Style Constructors are deprecated and will be remove in 7.8, please update your code, use __construct instead
55
     */
56
    function PackageController(){
57
        $deprecatedMessage = 'PHP4 Style Constructors are deprecated and will be remove in 7.8, please update your code';
58
        if(isset($GLOBALS['log'])) {
59
            $GLOBALS['log']->deprecated($deprecatedMessage);
60
        }
61
        else {
62
            trigger_error($deprecatedMessage, E_USER_DEPRECATED);
63
        }
64
        self::__construct();
65
    }
66
67
68
        function performBasicSearch(){
69
            $json = getJSONobj();
70
            $search_term = '';
71
            $node_id = '';
72
             if(isset($_REQUEST['search_term'])) {
73
                $search_term = nl2br($_REQUEST['search_term']);
74
            }
75
             if(isset($_REQUEST['node_id'])) {
76
                $node_id = nl2br($_REQUEST['node_id']);
77
            }
78
            $xml = PackageManager::getPackages($node_id);
79
            echo 'result = ' . $json->encode(array('packages' => $xml));
80
        }
81
82
        /**
83
         * Retrieve a list of packages which belong to the corresponding category
84
         *
85
         * @param category_id   this is passed via POST and is the category id of packages
86
         *                      we wish to retrieve
87
         * @return packages     xml string consisting of the packages and releases which belong to
88
         *                      the category
89
         */
90
        function getPackages(){
91
            $json = getJSONobj();
92
            $category_id = '';
93
94
             if(isset($_REQUEST['category_id'])) {
95
                $category_id = nl2br($_REQUEST['category_id']);
96
            }
97
            $xml = PackageManager::getPackages($category_id);
98
            echo 'result = ' . $json->encode(array('package_output' => $xml));
99
        }
100
101
        /**
102
         * Obtain a list of releases from the server.  This function is currently used for generating the patches/langpacks for upgrade wizard
103
         * as well as during installation
104
         */
105
        function getReleases(){
106
            $json = getJSONobj();
107
            $category_id = '';
108
       		$package_id = '';
109
       		$types = '';
110
            if(isset($_REQUEST['category_id'])) {
111
                $category_id = nl2br($_REQUEST['category_id']);
112
            }
113
            if(isset($_REQUEST['package_id'])) {
114
                $package_id = nl2br($_REQUEST['package_id']);
115
            }
116
            if(isset($_REQUEST['types'])) {
117
                $types = nl2br($_REQUEST['types']);
118
            }
119
            $types = explode(',', $types);
120
121
            $filter = array();
122
          	$count = count($types);
123
          	$index = 1;
124
          	$type_str = '';
125
          	foreach($types as $type){
126
          		$type_str .= "'".$type."'";
127
          		if($index < $count)
128
          			$type_str .= ",";
129
          		$index++;
130
          	}
131
132
          	$filter = array('type' => $type_str);
133
          	$filter = PackageManager::toNameValueList($filter);
134
            $releases = PackageManager::getReleases($category_id, $package_id, $filter);
135
            $nodes = array();
136
            $release_map = array();
137
            foreach($releases['packages'] as $release){
138
            	$release = PackageManager::fromNameValueList($release);
139
				$nodes[] = array('description' => $release['description'], 'version' => $release['version'], 'build_number' => $release['build_number'], 'id' => $release['id']);
140
        		$release_map[$release['id']] = array('package_id' => $release['package_id'], 'category_id' => $release['category_id']);
141
        	}
142
        	$_SESSION['ML_PATCHES'] = $release_map;
143
            echo 'result = ' . $json->encode(array('releases' => $nodes));
144
        }
145
146
        /**
147
         * Obtain a promotion from the depot
148
         */
149
        function getPromotion(){
150
            $json = getJSONobj();
151
152
            $header = PackageManager::getPromotion();
153
154
            echo 'result = ' . $json->encode(array('promotion' => $header));
155
        }
156
157
        /**
158
         * Download the given release
159
         *
160
         * @param category_id   this is passed via POST and is the category id of the release we wish to download
161
         * @param package_id   this is passed via POST and is the package id of the release we wish to download
162
         * @param release_id   this is passed via POST and is the release id of the release we wish to download
163
         * @return bool         true is successful in downloading, false otherwise
164
         */
165
        function download(){
166
            global $sugar_config;
167
            $json = getJSONobj();
168
            $package_id = '';
169
            $category_id  = '';
170
            $release_id = '';
171
            if(isset($_REQUEST['package_id'])) {
172
                $package_id = nl2br($_REQUEST['package_id']);
173
            }
174
            if(isset($_REQUEST['category_id'])) {
175
                $category_id = nl2br($_REQUEST['category_id']);
176
            }
177
            if(isset($_REQUEST['release_id'])) {
178
                $release_id = nl2br($_REQUEST['release_id']);
179
            }
180
            $GLOBALS['log']->debug("PACKAGE ID: ".$package_id);
181
            $GLOBALS['log']->debug("CATEGORY ID: ".$category_id);
182
            $GLOBALS['log']->debug("RELEASE ID: ".$release_id);
183
            $result = $this->_pm->download($category_id, $package_id, $release_id);
184
            $GLOBALS['log']->debug("RESULT: ".print_r($result,true));
185
            $success = 'false';
186
            if($result != null){
0 ignored issues
show
It seems like you are loosely comparing $result of type string|null against null; this is ambiguous if the string can be empty. Consider using a strict comparison !== instead.
Loading history...
187
                $GLOBALS['log']->debug("Performing Setup");
188
                $this->_pm->performSetup($result, 'module', false);
189
                $GLOBALS['log']->debug("Complete Setup");
190
                $success = 'true';
191
            }
192
            echo 'result = ' . $json->encode(array('success' => $success));
193
        }
194
195
         /**
196
         * Retrieve a list of categories that are subcategories to the selected category
197
         *
198
         * @param id - the id of the parent_category, -1 if this is the root
199
         * @return array - a list of categories/nodes which are underneath this node
200
         */
201
        function getCategories(){
202
            $json = getJSONobj();
203
            $node_id = '';
204
             if(isset($_REQUEST['category_id'])) {
205
                $node_id = nl2br($_REQUEST['category_id']);
206
            }
207
            $GLOBALS['log']->debug("NODE ID: ".$node_id);
208
            $nodes = PackageManager::getCategories($node_id);
209
            echo 'result = ' . $json->encode(array('nodes' => $nodes));
210
        }
211
212
         function getNodes(){
213
            $json = getJSONobj();
214
            $category_id = '';
215
             if(isset($_REQUEST['category_id'])) {
216
                $category_id = nl2br($_REQUEST['category_id']);
217
            }
218
            $GLOBALS['log']->debug("CATEGORY ID: ".$category_id);
219
            $nodes = PackageManager::getModuleLoaderCategoryPackages($category_id);
220
            $GLOBALS['log']->debug(var_export($nodes, true));
221
            echo 'result = ' . $json->encode(array('nodes' => $nodes));
222
        }
223
224
        /**
225
         * Check the SugarDepot for updates for the given type as passed in via POST
226
         * @param type      the type to check for
227
         * @return array    return an array of releases for each given installed object if an update is found
228
         */
229
        function checkForUpdates(){
230
            $json = getJSONobj();
231
            $type = '';
232
             if(isset($_REQUEST['type'])) {
233
                $type = nl2br($_REQUEST['type']);
234
            }
235
            $pm = new PackageManager();
236
            $updates = $pm->checkForUpdates();
237
            $nodes = array();
238
			$release_map = array();
239
            if(!empty($updates)){
240
	            foreach($updates as $update){
241
	            	$update = PackageManager::fromNameValueList($update);
242
	            	$nodes[] = array('label' => $update['name'], 'description' => $update['description'], 'version' => $update['version'], 'build_number' => $update['build_number'], 'id' => $update['id'], 'type' => $update['type']);
243
					$release_map[$update['id']] = array('package_id' => $update['package_id'], 'category_id' => $update['category_id'], 'type' => $update['type']);
244
	            }
245
            }
246
           //patches
247
           $filter = array(array('name' => 'type', 'value' => "'patch'"));
248
            $releases = $pm->getReleases('', '', $filter);
249
            if(!empty($releases['packages'])){
250
            	foreach($releases['packages'] as $update){
251
	            	$update = PackageManager::fromNameValueList($update);
252
					$nodes[] = array('label' => $update['name'], 'description' => $update['description'], 'version' => $update['version'], 'build_number' => $update['build_number'], 'id' => $update['id'], 'type' => $update['type']);
253
					$release_map[$update['id']] = array('package_id' => $update['package_id'], 'category_id' => $update['category_id'], 'type' => $update['type']);
254
	            }
255
            }
256
			$_SESSION['ML_PATCHES'] = $release_map;
257
            echo 'result = ' . $json->encode(array('updates' => $nodes));
258
        }
259
260
        function getLicenseText(){
261
            $json = getJSONobj();
262
            $file = '';
263
            if(isset($_REQUEST['file'])) {
264
                $file = hashToFile($_REQUEST['file']);
265
            }
266
            $GLOBALS['log']->debug("FILE : ".$file);
267
            echo 'result = ' . $json->encode(array('license_display' => PackageManagerDisplay::buildLicenseOutput($file)));
268
        }
269
270
        /**
271
         *  build the list of modules that are currently in the staging area waiting to be installed
272
         */
273
        function getPackagesInStaging(){
274
            $packages = $this->_pm->getPackagesInStaging('module');
275
            $json = getJSONobj();
276
277
            echo 'result = ' . $json->encode(array('packages' => $packages));
278
        }
279
280
        /**
281
         *  build the list of modules that are currently in the staging area waiting to be installed
282
         */
283
        function performInstall(){
284
            $file = '';
285
             if(isset($_REQUEST['file'])) {
286
                $file = hashToFile($_REQUEST['file']);
287
            }
288
          	if(!empty($file)){
289
	            $this->_pm->performInstall($file);
290
			}
291
            $json = getJSONobj();
292
293
            echo 'result = ' . $json->encode(array('result' => 'success'));
294
        }
295
296
        function authenticate(){
297
            $json = getJSONobj();
298
            $username = '';
299
            $password = '';
300
            $servername = '';
301
            $terms_checked = '';
302
            if(isset($_REQUEST['username'])) {
303
                $username = nl2br($_REQUEST['username']);
304
            }
305
            if(isset($_REQUEST['password'])) {
306
                $password = nl2br($_REQUEST['password']);
307
            }
308
       		 if(isset($_REQUEST['servername'])) {
309
                $servername = $_REQUEST['servername'];
310
            }
311
            if(isset($_REQUEST['terms_checked'])) {
312
                $terms_checked = $_REQUEST['terms_checked'];
313
                if($terms_checked == 'on')
314
                	$terms_checked = true;
315
            }
316
317
            if(!empty($username) && !empty($password)){
318
                $password = md5($password);
319
                $result = PackageManager::authenticate($username, $password, $servername, $terms_checked);
320
                if(!is_array($result) && $result == true)
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
321
                    $status  = 'success';
322
                else
323
                    $status  = $result['faultstring'];
324
            }else{
325
                $status  = 'failed';
326
            }
327
328
            echo 'result = ' . $json->encode(array('status' => $status));
329
        }
330
331
        function getDocumentation(){
332
        	$json = getJSONobj();
333
            $package_id = '';
334
            $release_id = '';
335
336
            if(isset($_REQUEST['package_id'])) {
337
                $package_id = nl2br($_REQUEST['package_id']);
338
            }
339
            if(isset($_REQUEST['release_id'])) {
340
                $release_id = nl2br($_REQUEST['release_id']);
341
            }
342
343
            $documents = PackageManager::getDocumentation($package_id, $release_id);
344
            $GLOBALS['log']->debug("DOCUMENTS: ".var_export($documents, true));
345
            echo 'result = ' . $json->encode(array('documents' => $documents));
346
        }
347
348
        function downloadedDocumentation(){
349
        	$json = getJSONobj();
350
            $document_id = '';
351
352
            if(isset($_REQUEST['document_id'])) {
353
                $document_id = nl2br($_REQUEST['document_id']);
354
            }
355
             $GLOBALS['log']->debug("Downloading Document: ".$document_id);
356
            PackageManagerComm::downloadedDocumentation($document_id);
357
            echo 'result = ' . $json->encode(array('result' => 'true'));
358
        }
359
360
        /**
361
         * Remove metadata files such as foo-manifest
362
         * Enter description here ...
363
         * @param unknown_type $file
364
         * @param unknown_type $meta
365
         */
366
        protected function rmMetaFile($file, $meta)
367
        {
368
            $metafile = pathinfo($file, PATHINFO_DIRNAME)."/". pathinfo($file, PATHINFO_FILENAME)."-$meta.php";
369
            if(file_exists($metafile)) {
370
                unlink($metafile);
371
            }
372
        }
373
374
 		function remove(){
375
        	$json = getJSONobj();
376
            $file = '';
377
378
            if(isset($_REQUEST['file'])) {
379
                 $file = urldecode(hashToFile($_REQUEST['file']));
380
            }
381
            $GLOBALS['log']->debug("FILE TO REMOVE: ".$file);
382
            if(!empty($file)){
383
            	unlink($file);
384
            	foreach(array("manifest", "icon") as $meta) {
385
            	    $this->rmMetaFile($file, $meta);
386
            	}
387
            }
388
            echo 'result = ' . $json->encode(array('result' => 'true'));
389
        }
390
 }
391
?>
392