Issues (1177)

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.

application/libraries/Update.php (5 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
use libraries\Backup;
0 ignored issues
show
This use statement conflicts with another class in this namespace, Backup.

Let’s assume that you have a directory layout like this:

.
|-- OtherDir
|   |-- Bar.php
|   `-- Foo.php
`-- SomeDir
    `-- Foo.php

and let’s assume the following content of Bar.php:

// Bar.php
namespace OtherDir;

use SomeDir\Foo; // This now conflicts the class OtherDir\Foo

If both files OtherDir/Foo.php and SomeDir/Foo.php are loaded in the same runtime, you will see a PHP error such as the following:

PHP Fatal error:  Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.php

However, as OtherDir/Foo.php does not necessarily have to be loaded and the error is only triggered if it is loaded before OtherDir/Bar.php, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias:

// Bar.php
namespace OtherDir;

use SomeDir\Foo as SomeDirFoo; // There is no conflict anymore.
Loading history...
4
5
/**
6
 * ImageCMS System Update Class
7
 * @copyright ImageCMS(c) 2013
8
 * @version 0.1 big start
9
 */
10
class Update
11
{
12
13
    private $arr_files;
14
15
    private $files_dates = [];
16
17
    private $restore_files = [];
18
19
    /**
20
     * update server
21
     * @var string
22
     */
23
    private $US = 'http://upd.imagecms.net/';
24
25
    /**
26
     * path to update server
27
     * @var string
28
     */
29
    private $pathUS;
30
31
    /**
32
     * папки, які не враховувати при обновлені
33
     * @var array
34
     */
35
    private $distinctDirs = [
36
                             '.',
37
                             '..',
38
                             '.git',
39
                             'uploads',
40
                             'cache',
41
                             'templates',
42
                             'tests',
43
                             'captcha',
44
                             'nbproject',
45
                             'uploads_site',
46
                             'backups',
47
                             'cmlTemp',
48
                            ];
49
50
    /**
51
     * файли, які не враховувати при обновлені
52
     * @var array
53
     */
54
    private $distinctFiles = [
55
                              'md5.txt',
56
                              '.htaccess',
57
                              'config.php',
58
                             ];
59
60
    /**
61
     * instance of ci
62
     * @var MY_Controller
63
     */
64
    public $ci;
65
66
    /**
67
     * SoapClient
68
     * @var SoapClient
69
     */
70
    public $client;
71
72
    /**
73
     *
74
     * @var array
75
     */
76
    public $settings;
77
78
    public function __construct() {
79
80
        $this->ci = &get_instance();
81
        $this->pathUS = $this->US . 'application/modules/update/UpdateService.wsdl';
82
        $this->client = new SoapClient($this->pathUS);
83
        $this->settings = $this->getSettings();
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->getSettings() of type string is incompatible with the declared type array of property $settings.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
84
    }
85
86
    /**
87
     * check new Version
88
     * @return mixed
89
     * @throws Exception
90
     */
91
    public function getStatus() {
92
93
        $domen = $this->ci->input->server('SERVER_NAME');
94
95
        $result = $this->client->getStatus($domen, BUILD_ID, IMAGECMS_NUMBER);
96
97
        if (mb_strlen($result) < 5 and $result == !0) {
98
            throw new Exception(lang('Cant get status', 'admin'));
99
        }
100
        $this->setSettings(['newVersion' => $result]);
101
        $this->setSettings(['checkTime' => time()]);
102
103
        return unserialize($result);
104
    }
105
106
    /**
107
     * getting hash from setting
108
     * @return array
109
     * @throws Exception
110
     */
111
    public function getHashSum() {
112
113
        $domen = $this->ci->input->server('SERVER_NAME');
114
        $key = $this->getSettings('careKey');
115
116
        $result = $this->client->getHashSum($domen, IMAGECMS_NUMBER, BUILD_ID, $key);
117
118
        $error = (array) json_decode($result);
119
        if ($error['error']) {
120
            throw new Exception($error['error']);
121
        }
122
123
        write_file(BACKUPFOLDER . 'md5.txt', $result);
124
        $result = (array) json_decode($result);
125
126
        $this->setSettings(['checkTime' => time()]);
127
128
        return $result;
129
    }
130
131
    public function getUpdate() {
132
133
        ini_set('soap.wsdl_cache_enabled', '0');
134
        $domain = $this->ci->input->server('SERVER_NAME');
135
136
        $href = $this->client->getUpdate($domain, IMAGECMS_NUMBER, $this->settings['careKey']);
137
        if (!$href) {
138
            throw new Exception(lang('Wrong generated hash code', 'admin'));
139
        }
140
141
        $all_href = $this->US . 'update/takeUpdate/' . $href . '/' . $domain . '/' . IMAGECMS_NUMBER . '/' . BUILD_ID;
142
        file_put_contents(BACKUPFOLDER . 'updates.zip', file_get_contents($all_href));
143
    }
144
145
    /**
146
     *
147
     * @param string $file
148
     * @return string
0 ignored issues
show
Should the return type not be array? Also, consider making the array more specific, something like array<String>, or String[].

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

If the return type contains the type array, this check recommends the use of a more specific type like String[] or array<String>.

Loading history...
149
     */
150
    public function getOldMD5File($file = 'md5.txt') {
151
152
        return (array) json_decode(read_file($file));
153
    }
154
155
    /**
156
     * zipping files
157
     * @param array $files
158
     * @return bool
0 ignored issues
show
Should the return type not be boolean|null?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
159
     * @throws Exception
160
     */
161
    public function add_to_ZIP($files = []) {
162
163
        if (empty($files)) {
164
            throw new Exception(lang('Nothing to create', 'admin'));
165
        }
166
167
        $zip = new ZipArchive();
168
        $filename = BACKUPFOLDER . 'backup.zip';
169
170
        if (file_exists($filename)) {
171
172
            $nameFolder = filemtime($filename);
173
            rename($filename, BACKUPFOLDER . "$nameFolder.zip");
174
            touch($filename, $nameFolder);
175
176
        }
177
178
        if ($zip->open($filename, ZipArchive::CREATE) !== true) {
179
            throw new Exception(lang('Dont have permissions folder backup', 'admin'));
180
        }
181
182
        foreach (array_keys($files) as $key) {
183
            if (!is_readable('.' . $key)) {
184
                continue;
185
            }
186
            $zip->addFile('.' . $key, $key);
187
        }
188
        $zip->close();
189
    }
190
191
    /**
192
     * @throws Exception
193
     */
194
    public function createBackUp() {
195
196
        $old = $this->getOldMD5File(BACKUPFOLDER . 'md5.txt');
197
        $array = $this->parse_md5();
198
        $diff = array_diff($array, $old);
199
        chmod(BACKUPFOLDER, 0755);
200
201
        if (!is_writable(BACKUPFOLDER)) {
202
            throw new Exception(lang('Dont have permissions folder backup', 'admin'));
203
        }
204
205
        $this->add_to_ZIP($diff);
206
207
        $filename = BACKUPFOLDER . 'backup.zip';
208
        $zip = new ZipArchive();
209
        $zip->open($filename);
210
211
        $db = $this->db_backup();
212
        $zip->addFile(BACKUPFOLDER . $db, $db);
213
        $zip->close();
214
215
        chmod(BACKUPFOLDER . $db, 0777);
216
        unlink(BACKUPFOLDER . $db);
217
    }
218
219
    /**
220
     * restore file to zip
221
     * @param string $file
222
     * @param mixed|string $destination
223
     * @return bool
224
     * @throws Exception
225
     */
226
    public function restoreFromZIP($file, $destination = FCPATH) {
227
228
        if (!$file) {
229
            $file = BACKUPFOLDER . 'backup.zip';
230
        }
231
232
        if (!file_exists($file) || substr(decoct(fileperms($destination)), 2) != '777') {
233
            throw  new Exception(lang('Dont have permissions folder backup', 'admin'));
234
        }
235
236
        $zip = new ZipArchive();
237
        $zip->open($file);
238
        $rez = $zip->extractTo($destination);
239
        $zip->close();
240
241
        if ($rez) {
242
            $this->db_restore($destination . '/backup.sql');
243
        }
244
245
        return $rez;
246
    }
247
248
    /**
249
     * Бере контрольні суми файлів текущих файлів і файлів старої теперішньої версії
250
     * Записує іх у відповідні файли з настройок, як серіалізований масив ключ - шлях до файлу, значення - контрольна сума
251
     * запускати два рази переоприділивши $this->path_parse
252
     * $this->path_parse = realpath('') текущі.
253
     * $this->path_parse = rtrim($this->dir_old_upd, '\')
254
     * @param null|string $directory
255
     * @return array
256
     */
257
    public function parse_md5($directory = null) {
258
259
        $dir = null === $directory ? realpath('') : $directory;
260
261
        $handle = opendir($dir);
262
        if ($handle) {
263
            while (FALSE !== ($file = readdir($handle))) {
264
                if (!in_array($file, $this->distinctDirs)) {
265
                    if (is_file($dir . DIRECTORY_SEPARATOR . $file) && !in_array($file, $this->distinctFiles)) {
266
                        $this->arr_files[str_replace(realpath(''), '', $dir) . DIRECTORY_SEPARATOR . $file] = md5_file($dir . DIRECTORY_SEPARATOR . $file);
267
                        $this->files_dates[str_replace(realpath(''), '', $dir) . DIRECTORY_SEPARATOR . $file] = filemtime($dir . DIRECTORY_SEPARATOR . $file);
268
                    }
269
                    if (is_dir($dir . DIRECTORY_SEPARATOR . $file)) {
270
                        $this->parse_md5($dir . DIRECTORY_SEPARATOR . $file);
271
                    }
272
                }
273
            }
274
        }
275
276
        return $this->arr_files;
277
    }
278
279
    /**
280
     * database backup
281
     * @return string
282
     */
283
    public function db_backup() {
284
285 View Code Duplication
        if (is_really_writable(BACKUPFOLDER)) {
286
            $this->ci->load->dbutil();
287
            $filePath = Backup::create()->createBackup('sql', 'backup', TRUE);
288
            return pathinfo($filePath, PATHINFO_BASENAME);
289
        } else {
290
            showMessage(langf('Can not create a database snapshot, Check the folder {0} on the ability to record', 'admin', [BACKUPFOLDER]));
291
        }
292
    }
293
294
    /**
295
     * database restore
296
     * @param string $file
297
     * @return boolean
298
     */
299
    public function db_restore($file) {
300
301
        if (empty($file)) {
302
            return FALSE;
303
        }
304
305
        if (is_readable($file)) {
306
            $restore = file_get_contents($file);
307
            return $this->query_from_file($restore);
308
        }
309
        return FALSE;
310
    }
311
312
    /**
313
     * Create restore files list
314
     * @return boolean|array
0 ignored issues
show
Consider making the return type a bit more specific; maybe use array|false.

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
315
     */
316
    public function restore_files_list() {
317
318
        if (is_readable(BACKUPFOLDER)) {
319
            $dh = opendir(BACKUPFOLDER);
320
            while ($filename = readdir($dh)) {
321
                if (filetype($filename) != 'dir') {
322
                    $file_type = '';
323
                    preg_match('/\.[a-z]{2,3}/', $filename, $file_type);
324
                    if ($file_type[0] == '.zip') {
325
                        $zip = new ZipArchive();
326
                        $zip->open(BACKUPFOLDER . $filename);
327
                        if ($zip->statName('backup.sql')) {
328
                            $this->restore_files[] = [
329
                                                      'name'        => $filename,
330
                                                      'size'        => round(filesize(BACKUPFOLDER . $filename) / 1024 / 1024, 2),
331
                                                      'create_date' => filemtime(BACKUPFOLDER . $filename),
332
                                                     ];
333
                        }
334
                        $zip->close();
335
                    }
336
                }
337
            }
338
            return $this->restore_files;
339
        } else {
340
            return FALSE;
341
        }
342
    }
343
344
    /**
345
     * remove dir recursive
346
     * @param string $dir - path to directory
347
     */
348
    public function removeDirRec($dir) {
349
350
        if ($objs = glob($dir . '/*')) {
351
            foreach ($objs as $obj) {
352
                is_dir($obj) ? $this->removeDirRec($obj) : unlink($obj);
353
            }
354
        }
355
        if (is_dir($dir)) {
356
            rmdir($dir);
357
        }
358
    }
359
360
    /**
361
     * db update
362
     * @param string $file_name
363
     * @return boolean
364
     */
365
    public function db_update($file_name = 'sql_19-08-2013_17.16.14.txt') {
366
367
        if (is_readable(BACKUPFOLDER . $file_name)) {
368
            $restore = file_get_contents(BACKUPFOLDER . $file_name);
369
            return $this->query_from_file($restore);
370
        } else {
371
            return FALSE;
372
        }
373
    }
374
375
    /**
376
     * ganerate sql query from file
377
     * @param string $file
378
     * @return boolean
379
     */
380
    public function query_from_file($file) {
381
382
        $string_query = rtrim($file, "\n;");
383
        $array_query = explode(";\n", $string_query);
384
385
        foreach ($array_query as $query) {
386
            if ($query) {
387
                if (!$this->ci->db->query($query)) {
388
                    echo 'Невозможно виполнить запрос: <br>';
389
                    return FALSE;
390
                }
391
            }
392
        }
393
        return TRUE;
394
    }
395
396
    public function get_files_dates() {
397
398
        if (!empty($this->files_dates)) {
399
            return $this->files_dates;
400
        } else {
401
            return FALSE;
402
        }
403
    }
404
405
    /**
406
     * @param bool|string $param
407
     * @return string
408
     */
409
    public function getSettings($param = false) {
410
411
        $settings = $this->ci->db
412
            ->get('settings')
413
            ->row_array();
414
        $settings = unserialize($settings['update']);
415
416
        if (!$param) {
417
            return $settings;
418
        } else {
419
            return $settings[$param];
420
        }
421
    }
422
423
    /**
424
     *
425
     * @param array $settings
426
     * @return bool
427
     */
428
    public function setSettings($settings) {
429
430
        if (!is_array($settings)) {
431
            return FALSE;
432
        }
433
        $s = (array) $this->getSettings();
434
435
        foreach ($settings as $key => $value) {
436
            $s[$key] = $value;
437
        }
438
439
        return $this->ci->db
440
            ->set('update', serialize($s))
441
            ->update('settings');
442
    }
443
444
}