Completed
Push — development ( 6352e5...8bea34 )
by Nils
07:55
created

upgrade_ajax.php ➔ addColumnIfNotExist()   A

Complexity

Conditions 4
Paths 5

Size

Total Lines 15
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 12
nc 5
nop 3
dl 0
loc 15
rs 9.2
c 0
b 0
f 0
1
<?php
2
/**
3
 * @file          upgrade.ajax.php
4
 * @author        Nils Laumaillé
5
 * @version       2.1.27
6
 * @copyright     (c) 2009-2017 Nils Laumaillé
7
 * @licensing     GNU AFFERO GPL 3.0
8
 * @link          http://www.teampass.net
9
 *
10
 * This library is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13
 */
14
15
require_once('../sources/SecureHandler.php');
16
session_start();
17
error_reporting(E_ERROR | E_PARSE);
18
$_SESSION['db_encoding'] = "utf8";
19
$_SESSION['CPM'] = 1;
20
21
require_once '../includes/language/english.php';
22
require_once '../includes/config/include.php';
23
24
// manage settings.php file
25
if (!file_exists("../includes/config/settings.php")) {
26
    if (file_exists("../includes/settings.php")) {
27
        // since 2.1.27, this file has changed location
28
        if (copy("../includes/settings.php", "../includes/config/settings.php")) {
29
            unlink("../includes/settings.php");
30
        } else {
31
            echo 'document.getElementById("res_step1_error").innerHTML = '.
32
                '"Could not copy /includes/settings.php to /includes/config/settings.php! '.
33
                'Please do it manually and press button Launch.";';
34
            echo 'document.getElementById("loader").style.display = "none";';
35
            exit;
36
        }
37
    } else {
38
        echo 'document.getElementById("res_step1_error").innerHTML = '.
39
            '"File settings.php does not exist in folder includes/! '.
40
            'If it is an upgrade, it should be there, otherwise select install!";';
41
        echo 'document.getElementById("loader").style.display = "none";';
42
        exit;
43
    }
44
}
45
require_once '../includes/config/settings.php';
46
require_once '../sources/main.functions.php';
47
48
$_SESSION['settings']['loaded'] = "";
49
50
################
51
## Function permits to get the value from a line
52
################
53
/**
54
 * @param string $val
55
 */
56
function getSettingValue($val)
0 ignored issues
show
Best Practice introduced by
The function getSettingValue() has been defined more than once; this definition is ignored, only the first definition in api/functions.php (L149-159) is considered.

This check looks for functions that have already been defined in other files.

Some Codebases, like WordPress, make a practice of defining functions multiple times. This may lead to problems with the detection of function parameters and types. If you really need to do this, you can mark the duplicate definition with the @ignore annotation.

/**
 * @ignore
 */
function getUser() {

}

function getUser($id, $realm) {

}

See also the PhpDoc documentation for @ignore.

Loading history...
57
{
58
    $val = trim(strstr($val, "="));
59
    return trim(str_replace('"', '', substr($val, 1, strpos($val, ";") - 1)));
60
}
61
62
################
63
## Function permits to check if a column exists, and if not to add it
64
################
65
function addColumnIfNotExist($db, $column, $columnAttr = "VARCHAR(255) NULL")
66
{
67
    global $dbTmp;
68
    $exists = false;
69
    $columns = mysqli_query($dbTmp, "show columns from $db");
70
    while ($c = mysqli_fetch_assoc($columns)) {
71
        if ($c['Field'] == $column) {
72
            $exists = true;
73
            break;
74
        }
75
    }
76
    if (!$exists) {
77
        return mysqli_query($dbTmp, "ALTER TABLE `$db` ADD `$column`  $columnAttr");
78
    }
79
}
80
81 View Code Duplication
function addIndexIfNotExist($table, $index, $sql)
0 ignored issues
show
Duplication introduced by
This function seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
82
{
83
    global $dbTmp;
84
85
    $mysqli_result = mysqli_query($dbTmp, "SHOW INDEX FROM $table WHERE key_name LIKE \"$index\"");
86
    $res = mysqli_fetch_row($mysqli_result);
87
88
    // if index does not exist, then add it
89
    if (!$res) {
90
        $res = mysqli_query($dbTmp, "ALTER TABLE `$table` ".$sql);
91
    }
92
93
    return $res;
94
}
95
96 View Code Duplication
function tableExists($tablename)
0 ignored issues
show
Duplication introduced by
This function seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
97
{
98
    global $dbTmp;
99
100
    $res = mysqli_query(
101
        $dbTmp,
102
        "SELECT COUNT(*) as count
103
        FROM information_schema.tables
104
        WHERE table_schema = '".$_SESSION['database']."'
105
        AND table_name = '$tablename'"
106
    );
107
108
    if ($res > 0) {
109
        return true;
110
    } else {
111
        return false;
112
    }
113
}
114
115
//define pbkdf2 iteration count
116
define('ITCOUNT', '2072');
117
118
if (isset($_POST['type'])) {
119
    switch ($_POST['type']) {
120
        case "step0":
121
            // erase session table
122
            $_SESSION = array();
123
            setcookie('pma_end_session');
124
            session_destroy();
125
126
            echo 'document.getElementById("res_step0").innerHTML = "";';
127
            require_once 'libs/aesctr.php';
128
            require_once "../includes/config/settings.php";
129
130
            // check if path in settings.php are consistent
131
            if (!is_dir(SECUREPATH)) {
132
                echo 'document.getElementById("but_next").disabled = "disabled";';
133
                echo 'document.getElementById("res_step0").innerHTML = "Error in settings.php file!<br>Check correctness of path indicated in file `includes/config/settings.php`.<br>Reload this page and retry.";';
134
                echo 'document.getElementById("loader").style.display = "none";';
135
                break;
136
            }
137
            if (!file_exists(SECUREPATH."/sk.php")) {
138
                echo 'document.getElementById("but_next").disabled = "disabled";';
139
                echo 'document.getElementById("res_step0").innerHTML = "Error in settings.php file!<br>Check that file `sk.php` exists as defined in `includes/config/settings.php`.<br>Reload this page and retry.";';
140
                echo 'document.getElementById("loader").style.display = "none";';
141
                break;
142
            }
143
144
            $_SESSION['settings']['cpassman_dir'] = "..";
145
            require_once '../includes/libraries/PasswordLib/Random/Generator.php';
146
            require_once '../includes/libraries/PasswordLib/Random/Source.php';
147
            require_once '../includes/libraries/PasswordLib/Random/Source/MTRand.php';
148
            require_once '../includes/libraries/PasswordLib/Random/Source/Rand.php';
149
            require_once '../includes/libraries/PasswordLib/Random/Source/UniqID.php';
150
            require_once '../includes/libraries/PasswordLib/Random/Source/URandom.php';
151
            require_once '../includes/libraries/PasswordLib/Random/Source/MicroTime.php';
152
            require_once '../includes/libraries/PasswordLib/Random/Source/CAPICOM.php';
153
            require_once '../includes/libraries/PasswordLib/Random/Mixer.php';
154
            require_once '../includes/libraries/PasswordLib/Random/AbstractMixer.php';
155
            require_once '../includes/libraries/PasswordLib/Random/Mixer/Hash.php';
156
            require_once '../includes/libraries/PasswordLib/Password/AbstractPassword.php';
157
            require_once '../includes/libraries/PasswordLib/Password/Implementation/Hash.php';
158
            require_once '../includes/libraries/PasswordLib/Password/Implementation/Crypt.php';
159
            require_once '../includes/libraries/PasswordLib/Password/Implementation/SHA256.php';
160
            require_once '../includes/libraries/PasswordLib/Password/Implementation/SHA512.php';
161
            require_once '../includes/libraries/PasswordLib/Password/Implementation/PHPASS.php';
162
            require_once '../includes/libraries/PasswordLib/Password/Implementation/PHPBB.php';
163
            require_once '../includes/libraries/PasswordLib/Password/Implementation/PBKDF.php';
164
            require_once '../includes/libraries/PasswordLib/Password/Implementation/MediaWiki.php';
165
            require_once '../includes/libraries/PasswordLib/Password/Implementation/MD5.php';
166
            require_once '../includes/libraries/PasswordLib/Password/Implementation/Joomla.php';
167
            require_once '../includes/libraries/PasswordLib/Password/Implementation/Drupal.php';
168
            require_once '../includes/libraries/PasswordLib/Password/Implementation/APR1.php';
169
            require_once '../includes/libraries/PasswordLib/PasswordLib.php';
170
            $pwdlib = new PasswordLib\PasswordLib();
171
172
            //connect to db and check user is granted
173
            $link = mysqli_connect(
174
                $server,
175
                $user,
176
                $pass,
177
                $database,
178
                $port
179
            );
180
181
            $user_info = mysqli_fetch_array(
182
                mysqli_query(
183
                    $link,
184
                    "SELECT pw, admin FROM ".$pre."users
185
                    WHERE login='".mysqli_escape_string($link, stripslashes($_POST['login']))."'"
186
                )
187
            );
188
189
            if (empty($user_info['pw']) || $user_info['pw'] === null) {
190
                echo 'document.getElementById("but_next").disabled = "disabled";';
191
                echo 'document.getElementById("res_step0").innerHTML = "This user is not allowed!";';
192
                echo 'document.getElementById("user_granted").value = "0";';
193
                $_SESSION['user_granted'] = false;
194
            } else {
195
                if ($pwdlib->verifyPasswordHash(Encryption\Crypt\aesctr::decrypt(base64_decode($_POST['pwd']), "cpm", 128), $user_info['pw']) === true && $user_info['admin'] === "1") {
0 ignored issues
show
Documentation introduced by
base64_decode($_POST['pwd']) is of type string, but the function expects a object<Encryption\Crypt\source>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
Documentation introduced by
'cpm' is of type string, but the function expects a object<Encryption\Crypt\the>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
196
                    echo 'document.getElementById("but_next").disabled = "";';
197
                    echo 'document.getElementById("res_step0").innerHTML = "User is granted.";';
198
                    echo 'document.getElementById("step").value = "1";';
199
                    echo 'document.getElementById("user_granted").value = "1";';
200
                    $_SESSION['user_granted'] = true;
201
                } else {
202
                    echo 'document.getElementById("but_next").disabled = "disabled";';
203
                    echo 'document.getElementById("res_step0").innerHTML = "This user is not allowed!";';
204
                    echo 'document.getElementById("user_granted").value = "0";';
205
                    $_SESSION['user_granted'] = false;
206
                }
207
            }
208
209
            echo 'document.getElementById("loader").style.display = "none";';
210
            break;
211
212
        case "step1":
213
            if ($_SESSION['user_granted'] !== "1") {
214
                echo 'document.getElementById("res_step1").innerHTML = "User not connected anymore!";';
215
                echo 'document.getElementById("loader").style.display = "none";';
216
                break;
217
            }
218
219
            $_SESSION['fullurl'] = $_POST['fullurl'];
220
            $abspath = str_replace('\\', '/', $_POST['abspath']);
221
            $_SESSION['abspath'] = $abspath;
222 View Code Duplication
            if (substr($abspath, strlen($abspath) - 1) == "/") {
223
                $abspath = substr($abspath, 0, strlen($abspath) - 1);
224
            }
225
            $okWritable = true;
226
            $okExtensions = true;
227
            $txt = "";
228
            $x = 1;
229
            $tab = array(
230
                $abspath."/includes/config/settings.php",
231
                $abspath."/includes/libraries/csrfp/libs/",
232
                $abspath."/install/",
233
                $abspath."/includes/",
234
                $abspath."/includes/config/",
235
                $abspath."/includes/avatars/",
236
                $abspath."/files/",
237
                $abspath."/upload/"
238
            );
239
            foreach ($tab as $elem) {
240
                // try to create it if not existing
241
                if (substr($elem, -1) === '/' && !is_dir($elem)) {
242
                    mkdir($elem);
243
                }
244
                // check if writable
245
                if (is_writable($elem)) {
246
                    $txt .= '<span style=\"padding-left:30px;font-size:13pt;\">'.
247
                        $elem.'&nbsp;&nbsp;<img src=\"images/tick-circle.png\"></span><br />';
248
                } else {
249
                    $txt .= '<span style=\"padding-left:30px;font-size:13pt;\">'.
250
                        $elem.'&nbsp;&nbsp;<img src=\"images/minus-circle.png\"></span><br />';
251
                    $okWritable = false;
252
                }
253
                $x++;
254
            }
255
256
            if (!extension_loaded('mcrypt')) {
257
                $okExtensions = false;
258
                $txt .= '<span style=\"padding-left:30px;font-size:13pt;\">PHP extension \"mcrypt\"'.
259
                    '&nbsp;&nbsp;<img src=\"images/minus-circle.png\"></span><br />';
260
            } else {
261
                $txt .= '<span style=\"padding-left:30px;font-size:13pt;\">PHP extension \"mcrypt\"'.
262
                    '&nbsp;&nbsp;<img src=\"images/tick-circle.png\"></span><br />';
263
            }
264
            if (!extension_loaded('openssl')) {
265
                //$okExtensions = false;
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
266
                $txt .= '<span style=\"padding-left:30px;font-size:13pt;\">PHP extension \"openssl\"'.
267
                    '&nbsp;&nbsp;<img src=\"images/minus-circle.png\"></span><br />';
268
            } else {
269
                $txt .= '<span style=\"padding-left:30px;font-size:13pt;\">PHP extension \"openssl\"'.
270
                    '&nbsp;&nbsp;<img src=\"images/tick-circle.png\"></span><br />';
271
            }
272
            if (!extension_loaded('gd')) {
273
                //$okExtensions = false;
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
274
                $txt .= '<span style=\"padding-left:30px;font-size:13pt;\">PHP extension \"gd\"'.
275
                    '&nbsp;&nbsp;<img src=\"images/minus-circle.png\"></span><br />';
276
            } else {
277
                $txt .= '<span style=\"padding-left:30px;font-size:13pt;\">PHP extension \"gd\"'.
278
                    '&nbsp;&nbsp;<img src=\"images/tick-circle.png\"></span><br />';
279
            }
280
            if (!extension_loaded('mbstring')) {
281
                //$okExtensions = false;
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
282
                $txt .= '<span style=\"padding-left:30px;font-size:13pt;\">PHP extension \"mbstring\"'.
283
                    '&nbsp;&nbsp;<img src=\"images/minus-circle.png\"></span><br />';
284
            } else {
285
                $txt .= '<span style=\"padding-left:30px;font-size:13pt;\">PHP extension \"mbstring\"'.
286
                    '&nbsp;&nbsp;<img src=\"images/tick-circle.png\"></span><br />';
287
            }
288
            if (!extension_loaded('bcmath')) {
289
                //$okExtensions = false;
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
290
                $txt .= '<span style=\"padding-left:30px;font-size:13pt;\">PHP extension \"bcmath\"'.
291
                    '&nbsp;&nbsp;<img src=\"images/minus-circle.png\"></span><br />';
292
            } else {
293
                $txt .= '<span style=\"padding-left:30px;font-size:13pt;\">PHP extension \"bcmath\"'.
294
                    '&nbsp;&nbsp;<img src=\"images/tick-circle.png\"></span><br />';
295
            }
296
            if (!extension_loaded('iconv')) {
297
                //$okExtensions = false;
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
298
                $txt .= '<span style=\"padding-left:30px;font-size:13pt;\">PHP extension \"iconv\"'.
299
                    '&nbsp;&nbsp;<img src=\"images/minus-circle.png\"></span><br />';
300
            } else {
301
                $txt .= '<span style=\"padding-left:30px;font-size:13pt;\">PHP extension \"iconv\"'.
302
                    '&nbsp;&nbsp;<img src=\"images/tick-circle.png\"></span><br />';
303
            }
304 View Code Duplication
            if (!extension_loaded('xml')) {
305
                //$okExtensions = false;
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
306
                $txt .= '<span style=\"padding-left:30px;font-size:13pt;\">PHP extension \"xml\"'.
307
                    '&nbsp;&nbsp;<img src=\"images/minus-circle.png\"></span><br />';
308
            } else {
309
                $txt .= '<span style=\"padding-left:30px;font-size:13pt;\">PHP extension \"xml\"'.
310
                    '&nbsp;&nbsp;<img src=\"images/tick-circle.png\"></span><br />';
311
            }
312 View Code Duplication
            if (!extension_loaded('curl')) {
313
                $txt .= '<span style=\"padding-left:30px;font-size:13pt;\">PHP extension \"curl\"'.
314
                    '&nbsp;&nbsp;<img src=\"images/minus-circle.png\"></span><br />';
315
            } else {
316
                $txt .= '<span style=\"padding-left:30px;font-size:13pt;\">PHP extension \"curl\"'.
317
                    '&nbsp;&nbsp;<img src=\"images/tick-circle.png\"></span><br />';
318
            }
319
            if (ini_get('max_execution_time') < 60) {
320
                $txt .= '<span style=\"padding-left:30px;font-size:13pt;\">PHP \"Maximum '.
321
                    'execution time\" is set to '.ini_get('max_execution_time').' seconds.'.
322
                    ' Please try to set to 60s at least until Upgrade is finished.&nbsp;'.
323
                    '&nbsp;<img src=\"images/minus-circle.png\"></span> <br />';
324
            } else {
325
                $txt .= '<span style=\"padding-left:30px;font-size:13pt;\">PHP \"Maximum '.
326
                    'execution time\" is set to '.ini_get('max_execution_time').' seconds'.
327
                    '&nbsp;&nbsp;<img src=\"images/tick-circle.png\"></span><br />';
328
            }
329
            if (version_compare(phpversion(), '5.5.0', '<')) {
330
                $okVersion = false;
331
                $txt .= '<span style=\"padding-left:30px;font-size:13pt;\">PHP version '.
332
                    phpversion().' is not OK (minimum is 5.5.0) &nbsp;&nbsp;'.
333
                    '<img src=\"images/minus-circle.png\"></span><br />';
334
            } else {
335
                $txt .= '<span style=\"padding-left:30px;font-size:13pt;\">PHP version '.
336
                    phpversion().' is OK&nbsp;&nbsp;<img src=\"images/tick-circle.png\">'.
337
                    '</span><br />';
338
            }
339
340
            //get infos from SETTINGS.PHP file
341
            $filename = "../includes/config/settings.php";
342
            $events = "";
343 View Code Duplication
            if (file_exists($filename)) {
344
                //copy some constants from this existing file
345
                $settingsFile = file($filename);
346
                while (list($key, $val) = each($settingsFile)) {
347
                    if (substr_count($val, 'charset') > 0) {
348
                        $_SESSION['charset'] = getSettingValue($val);
349
                    } elseif (substr_count($val, '@define(') > 0 && substr_count($val, 'SALT') > 0) {
350
                        $_SESSION['encrypt_key'] = substr($val, 17, strpos($val, "')") - 17);
351
                    } elseif (substr_count($val, '$smtp_server') > 0) {
352
                        $_SESSION['smtp_server'] = getSettingValue($val);
353
                    } elseif (substr_count($val, '$smtp_auth') > 0) {
354
                        $_SESSION['smtp_auth'] = getSettingValue($val);
355
                    } elseif (substr_count($val, '$smtp_auth_username') > 0) {
356
                        $_SESSION['smtp_auth_username'] = getSettingValue($val);
357
                    } elseif (substr_count($val, '$smtp_auth_password') > 0) {
358
                        $_SESSION['smtp_auth_password'] = getSettingValue($val);
359
                    } elseif (substr_count($val, '$smtp_port') > 0) {
360
                        $_SESSION['smtp_port'] = getSettingValue($val);
361
                    } elseif (substr_count($val, '$smtp_security') > 0) {
362
                        $_SESSION['smtp_security'] = getSettingValue($val);
363
                    } elseif (substr_count($val, '$email_from') > 0) {
364
                        $_SESSION['email_from'] = getSettingValue($val);
365
                    } elseif (substr_count($val, '$email_from_name') > 0) {
366
                        $_SESSION['email_from_name'] = getSettingValue($val);
367
                    } elseif (substr_count($val, '$server') > 0) {
368
                        $_SESSION['server'] = getSettingValue($val);
369
                    } elseif (substr_count($val, '$user') > 0) {
370
                        $_SESSION['user'] = getSettingValue($val);
371
                    } elseif (substr_count($val, '$pass') > 0) {
372
                        $_SESSION['pass'] = getSettingValue($val);
373
                    } elseif (substr_count($val, '$port') > 0) {
374
                        $_SESSION['port'] = getSettingValue($val);
375
                    } elseif (substr_count($val, '$database') > 0) {
376
                        $_SESSION['database'] = getSettingValue($val);
377
                    } elseif (substr_count($val, '$pre') > 0) {
378
                        $_SESSION['pre'] = getSettingValue($val);
379
                    } elseif (substr_count($val, "define('SECUREPATH',") > 0) {
380
                        $_SESSION['sk_file'] = substr($val, 23, strpos($val, ');')-24)."/sk.php";
381
                    }
382
                }
383
            }
384
            if (isset($_SESSION['sk_file']) && !empty($_SESSION['sk_file'])
385
                && file_exists($_SESSION['sk_file'])
386
            ) {
387
                $txt .= '<span style=\"padding-left:30px;font-size:13pt;\">sk.php file'.
388
                    ' found in \"'.addslashes($_SESSION['sk_file']).'\"&nbsp;&nbsp;<img src=\"images/tick-circle.png\">'.
389
                    '</span><br />';
390
                //copy some constants from this existing file
391
                $skFile = file($_SESSION['sk_file']);
0 ignored issues
show
Security File Exposure introduced by
$_SESSION['sk_file'] can contain request data and is used in file inclusion context(s) leading to a potential security vulnerability.

2 paths for user data to reach this point

  1. Path: Read from $_POST, and $_SESSION is assigned in install/upgrade_ajax.php on line 219
  1. Read from $_POST, and $_SESSION is assigned
    in install/upgrade_ajax.php on line 219
  2. $_SESSION is assigned
    in install/upgrade_ajax.php on line 221
  2. Path: Read from $_POST, and $_POST['abspath'] is passed through str_replace(), and $abspath is assigned in install/upgrade_ajax.php on line 220
  1. Read from $_POST, and $_POST['abspath'] is passed through str_replace(), and $abspath is assigned
    in install/upgrade_ajax.php on line 220
  2. $_SESSION is assigned
    in install/upgrade_ajax.php on line 221

General Strategies to prevent injection

In general, it is advisable to prevent any user-data to reach this point. This can be done by white-listing certain values:

if ( ! in_array($value, array('this-is-allowed', 'and-this-too'), true)) {
    throw new \InvalidArgumentException('This input is not allowed.');
}

For numeric data, we recommend to explicitly cast the data:

$sanitized = (integer) $tainted;
Loading history...
392
                while (list($key, $val) = each($skFile)) {
393
                    if (substr_count($val, "@define('SALT'") > 0) {
394
                        $_SESSION['encrypt_key'] = substr($val, 17, strpos($val, "')") - 17);
395
                        echo '$("#session_salt").val("'.$_SESSION['encrypt_key'].'");';
0 ignored issues
show
Security Cross-Site Scripting introduced by
'$("#session_salt").val(...['encrypt_key'] . '");' can contain request data and is used in output context(s) leading to a potential security vulnerability.

2 paths for user data to reach this point

  1. Path: Read from $_POST, and $_SESSION is assigned in install/upgrade_ajax.php on line 219
  1. Read from $_POST, and $_SESSION is assigned
    in install/upgrade_ajax.php on line 219
  2. $_SESSION is assigned
    in install/upgrade_ajax.php on line 221
  3. $_SESSION is assigned
    in install/upgrade_ajax.php on line 394
  2. Path: Read from $_POST, and $_POST['abspath'] is passed through str_replace(), and $abspath is assigned in install/upgrade_ajax.php on line 220
  1. Read from $_POST, and $_POST['abspath'] is passed through str_replace(), and $abspath is assigned
    in install/upgrade_ajax.php on line 220
  2. $_SESSION is assigned
    in install/upgrade_ajax.php on line 221
  3. $_SESSION is assigned
    in install/upgrade_ajax.php on line 394

Preventing Cross-Site-Scripting Attacks

Cross-Site-Scripting allows an attacker to inject malicious code into your website - in particular Javascript code, and have that code executed with the privileges of a visiting user. This can be used to obtain data, or perform actions on behalf of that visiting user.

In order to prevent this, make sure to escape all user-provided data:

// for HTML
$sanitized = htmlentities($tainted, ENT_QUOTES);

// for URLs
$sanitized = urlencode($tainted);

General Strategies to prevent injection

In general, it is advisable to prevent any user-data to reach this point. This can be done by white-listing certain values:

if ( ! in_array($value, array('this-is-allowed', 'and-this-too'), true)) {
    throw new \InvalidArgumentException('This input is not allowed.');
}

For numeric data, we recommend to explicitly cast the data:

$sanitized = (integer) $tainted;
Loading history...
396
                    }
397
                }
398
            }
399
400
            if (!isset($_SESSION['encrypt_key']) || empty($_SESSION['encrypt_key'])) {
401
                // check if 2.1.27 already installed
402
                $defuse_file = substr($_SESSION['sk_file'], 0, strrpos($_SESSION['sk_file'], "/"))."/teampass-seckey.txt";
403
                if (file_exists($defuse_file)) {
404
                    $okEncryptKey = true;
405
                    $_SESSION['tp_defuse_installed'] = true;
406
                    $txt .= '<span style=\"padding-left:30px;font-size:13pt;\">Defuse encryption key is defined&nbsp;&nbsp;<img src=\"images/tick-circle.png\">'.
407
                        '</span><br />';
408
                } else {
409
                    $okEncryptKey = false;
410
                    $_SESSION['tp_defuse_installed'] = false;
411
                    $txt .= '<span style=\"padding-left:30px;font-size:13pt;\">Encryption Key (SALT) '.
412
                        ' could not be recovered &nbsp;&nbsp;'.
413
                        '<img src=\"images/minus-circle.png\"></span><br />';
414
                }
415
            } else {
416
                $okEncryptKey = true;
417
                $txt .= '<span style=\"padding-left:30px;font-size:13pt;\">Encryption Key (SALT) is available&nbsp;&nbsp;<img src=\"images/tick-circle.png\">'.
418
                    '</span><br />';
419
            }
420
421
            if ($okWritable === true && $okExtensions === true && $okEncryptKey === true) {
422
                echo 'document.getElementById("but_next").disabled = "";';
423
                echo 'document.getElementById("res_step1").innerHTML = "Elements are OK.";';
424
            } else {
425
                echo 'document.getElementById("but_next").disabled = "disabled";';
426
                echo 'document.getElementById("res_step1").innerHTML = "Correct the shown '.
427
                    'errors and click on button Launch to refresh";';
428
            }
429
430
            echo 'document.getElementById("res_step1").innerHTML = "'.$txt.'";';
0 ignored issues
show
Security Cross-Site Scripting introduced by
'document.getElementById...HTML = "' . $txt . '";' can contain request data and is used in output context(s) leading to a potential security vulnerability.

2 paths for user data to reach this point

  1. Path: Read from $_POST, and $_SESSION is assigned in install/upgrade_ajax.php on line 219
  1. Read from $_POST, and $_SESSION is assigned
    in install/upgrade_ajax.php on line 219
  2. $_SESSION is assigned
    in install/upgrade_ajax.php on line 221
  3. $_SESSION['sk_file'] is escaped by addslashes() for sql, xpath context(s)
    in install/upgrade_ajax.php on line 388
  4. $txt is assigned
    in install/upgrade_ajax.php on line 387
  2. Path: Read from $_POST, and $_POST['abspath'] is passed through str_replace(), and $abspath is assigned in install/upgrade_ajax.php on line 220
  1. Read from $_POST, and $_POST['abspath'] is passed through str_replace(), and $abspath is assigned
    in install/upgrade_ajax.php on line 220
  2. $_SESSION is assigned
    in install/upgrade_ajax.php on line 221
  3. $_SESSION['sk_file'] is escaped by addslashes() for sql, xpath context(s)
    in install/upgrade_ajax.php on line 388
  4. $txt is assigned
    in install/upgrade_ajax.php on line 387

Preventing Cross-Site-Scripting Attacks

Cross-Site-Scripting allows an attacker to inject malicious code into your website - in particular Javascript code, and have that code executed with the privileges of a visiting user. This can be used to obtain data, or perform actions on behalf of that visiting user.

In order to prevent this, make sure to escape all user-provided data:

// for HTML
$sanitized = htmlentities($tainted, ENT_QUOTES);

// for URLs
$sanitized = urlencode($tainted);

General Strategies to prevent injection

In general, it is advisable to prevent any user-data to reach this point. This can be done by white-listing certain values:

if ( ! in_array($value, array('this-is-allowed', 'and-this-too'), true)) {
    throw new \InvalidArgumentException('This input is not allowed.');
}

For numeric data, we recommend to explicitly cast the data:

$sanitized = (integer) $tainted;
Loading history...
431
            echo 'document.getElementById("loader").style.display = "none";';
432
            break;
433
434
            #==========================
435
        case "step2":
436
            $res = "";
437
438
            if ($_SESSION['user_granted'] !== "1") {
439
                echo 'document.getElementById("res_step2").innerHTML = "User not connected anymore!";';
440
                echo 'document.getElementById("loader").style.display = "none";';
441
                break;
442
            }
443
            //decrypt the password
444
            // AES Counter Mode implementation
445
            require_once 'libs/aesctr.php';
446
447
            // connexion
448
            if (mysqli_connect(
449
                $_SESSION['server'],
450
                $_SESSION['user'],
451
                $_SESSION['pass'],
452
                $_SESSION['database'],
453
                $_SESSION['port']
454
            )
455
            ) {
456
                $dbTmp = mysqli_connect(
457
                    $_SESSION['server'],
458
                    $_SESSION['user'],
459
                    $_SESSION['pass'],
460
                    $_SESSION['database'],
461
                    $_SESSION['port']
462
                );
463
                $res = "Connection is successful";
464
                echo 'document.getElementById("but_next").disabled = "";';
465
466
                // check in db if previous saltk exists
467
                if ($_POST['no_previous_sk'] === "false" || $_POST['no_previous_sk'] === "previous_sk_sel") {
468
                    $db_sk = mysqli_fetch_row(mysqli_query($dbTmp, "SELECT count(*) FROM ".$_SESSION['pre']."misc
469
                    WHERE type='admin' AND intitule = 'saltkey_ante_2127'"));
470
                    if (!empty($_POST['previous_sk']) || !empty($_POST['session_salt'])) {
471
                        // get sk
472
                        if (!empty($_POST['session_salt'])) {
473
                            $sk_val = filter_var($_POST['session_salt'], FILTER_SANITIZE_STRING);
474
                        } else {
475
                            $sk_val = filter_var($_POST['previous_sk'], FILTER_SANITIZE_STRING);
476
                        }
477
478
                        // Update
479
                        if (!empty($db_sk[0])) {
480
                            mysqli_query(
481
                                $dbTmp,
482
                                "UPDATE `".$_SESSION['pre']."misc`
0 ignored issues
show
Security SQL Injection introduced by
'UPDATE `' . $_SESSION['... \'saltkey_ante_2127\'' can contain request data and is used in sql context(s) leading to a potential security vulnerability.

2 paths for user data to reach this point

  1. Path: Read from $_POST, and $_POST['session_salt'] is passed through filter_var(), and $sk_val is assigned in install/upgrade_ajax.php on line 473
  1. Read from $_POST, and $_POST['session_salt'] is passed through filter_var(), and $sk_val is assigned
    in install/upgrade_ajax.php on line 473
  2. Path: Read from $_POST, and $_POST['previous_sk'] is passed through filter_var(), and $sk_val is assigned in install/upgrade_ajax.php on line 475
  1. Read from $_POST, and $_POST['previous_sk'] is passed through filter_var(), and $sk_val is assigned
    in install/upgrade_ajax.php on line 475

Preventing SQL Injection

There are two options to prevent SQL injection. Generally, it is recommended to use parameter binding:

$stmt = mysqli_prepare("SELECT * FROM users WHERE name = ?");
$stmt->bind_param("s", $taintedUserName);

An alternative – although generally not recommended – is to escape your data manually:

$mysqli = new mysqli('localhost', 'user', 'pass', 'dbname');

$escaped = $mysqli->real_escape_string($taintedUserName);
$mysqli->query("SELECT * FROM users WHERE name = '".$escaped."'");

General Strategies to prevent injection

In general, it is advisable to prevent any user-data to reach this point. This can be done by white-listing certain values:

if ( ! in_array($value, array('this-is-allowed', 'and-this-too'), true)) {
    throw new \InvalidArgumentException('This input is not allowed.');
}

For numeric data, we recommend to explicitly cast the data:

$sanitized = (integer) $tainted;
Loading history...
483
                                SET `valeur` = '".$sk_val."'
484
                                WHERE type = 'admin' AND intitule = 'saltkey_ante_2127'"
485
                            );
486
                        } else {
487
                            mysqli_query(
488
                                $dbTmp,
489
                                "INSERT INTO `".$_SESSION['pre']."misc`
0 ignored issues
show
Security SQL Injection introduced by
'INSERT INTO `' . $_SESS...\'saltkey_ante_2127\')' can contain request data and is used in sql context(s) leading to a potential security vulnerability.

2 paths for user data to reach this point

  1. Path: Read from $_POST, and $_POST['session_salt'] is passed through filter_var(), and $sk_val is assigned in install/upgrade_ajax.php on line 473
  1. Read from $_POST, and $_POST['session_salt'] is passed through filter_var(), and $sk_val is assigned
    in install/upgrade_ajax.php on line 473
  2. Path: Read from $_POST, and $_POST['previous_sk'] is passed through filter_var(), and $sk_val is assigned in install/upgrade_ajax.php on line 475
  1. Read from $_POST, and $_POST['previous_sk'] is passed through filter_var(), and $sk_val is assigned
    in install/upgrade_ajax.php on line 475

Preventing SQL Injection

There are two options to prevent SQL injection. Generally, it is recommended to use parameter binding:

$stmt = mysqli_prepare("SELECT * FROM users WHERE name = ?");
$stmt->bind_param("s", $taintedUserName);

An alternative – although generally not recommended – is to escape your data manually:

$mysqli = new mysqli('localhost', 'user', 'pass', 'dbname');

$escaped = $mysqli->real_escape_string($taintedUserName);
$mysqli->query("SELECT * FROM users WHERE name = '".$escaped."'");

General Strategies to prevent injection

In general, it is advisable to prevent any user-data to reach this point. This can be done by white-listing certain values:

if ( ! in_array($value, array('this-is-allowed', 'and-this-too'), true)) {
    throw new \InvalidArgumentException('This input is not allowed.');
}

For numeric data, we recommend to explicitly cast the data:

$sanitized = (integer) $tainted;
Loading history...
490
                                (`valeur`, `type`, `intitule`)
491
                                VALUES ('".$sk_val."', 'admin', 'saltkey_ante_2127')"
492
                            );
493
                        }
494
                    } elseif (empty($db_sk[0])) {
495
                        $res = "Please provide Teampass instance history.";
496
                        echo 'document.getElementById("but_next").disabled = "disabled";';
497
                        echo 'document.getElementById("res_step2").innerHTML = "'.$res.'";';
498
                        echo 'document.getElementById("loader").style.display = "none";';
499
                        echo 'document.getElementById("no_encrypt_key").style.display = "";';
500
                    }
501
                } else {
502
                    // user said that database has not being used for an older version
503
                    // no old sk is available
504
                        $tmp = mysqli_num_rows(mysqli_query(
505
                            $dbTmp,
506
                            "SELECT * FROM `".$var['tbl_prefix']."misc` WHERE type = 'admin' AND intitule = 'saltkey_ante_2127'"
507
                        ));
508
                    if ($tmp == 0) {
509
                        mysqli_query(
510
                            $dbTmp,
511
                            "INSERT INTO `".$_SESSION['pre']."misc`
512
                            (`valeur`, `type`, `intitule`)
513
                            VALUES ('none', 'admin', 'saltkey_ante_2127')"
514
                        );
515
                    } else {
516
                        mysqli_query(
517
                            $dbTmp,
518
                            "INSERT INTO `".$_SESSION['pre']."misc`
519
                            (`valeur`, `type`, `intitule`)
520
                            VALUES ('none', 'admin', 'saltkey_ante_2127')"
521
                        );
522
                    }
523
                    $_SESSION['tp_defuse_installed'] = true;
524
                }
525
526
                //What CPM version
527
                if (mysqli_query(
528
                    $dbTmp,
529
                    "SELECT valeur FROM ".$_POST['tbl_prefix']."misc
0 ignored issues
show
Security SQL Injection introduced by
'SELECT valeur FROM ' . ...= \'cpassman_version\'' can contain request data and is used in sql context(s) leading to a potential security vulnerability.

1 path for user data to reach this point

  1. Read from $_POST
    in install/upgrade_ajax.php on line 529

Preventing SQL Injection

There are two options to prevent SQL injection. Generally, it is recommended to use parameter binding:

$stmt = mysqli_prepare("SELECT * FROM users WHERE name = ?");
$stmt->bind_param("s", $taintedUserName);

An alternative – although generally not recommended – is to escape your data manually:

$mysqli = new mysqli('localhost', 'user', 'pass', 'dbname');

$escaped = $mysqli->real_escape_string($taintedUserName);
$mysqli->query("SELECT * FROM users WHERE name = '".$escaped."'");

General Strategies to prevent injection

In general, it is advisable to prevent any user-data to reach this point. This can be done by white-listing certain values:

if ( ! in_array($value, array('this-is-allowed', 'and-this-too'), true)) {
    throw new \InvalidArgumentException('This input is not allowed.');
}

For numeric data, we recommend to explicitly cast the data:

$sanitized = (integer) $tainted;
Loading history...
530
                    WHERE type='admin' AND intitule = 'cpassman_version'"
531
                )) {
532
                    $tmpResult = mysqli_query(
533
                        $dbTmp,
534
                        "SELECT valeur FROM ".$_POST['tbl_prefix']."misc
0 ignored issues
show
Security SQL Injection introduced by
'SELECT valeur FROM ' . ...= \'cpassman_version\'' can contain request data and is used in sql context(s) leading to a potential security vulnerability.

1 path for user data to reach this point

  1. Read from $_POST
    in install/upgrade_ajax.php on line 534

Preventing SQL Injection

There are two options to prevent SQL injection. Generally, it is recommended to use parameter binding:

$stmt = mysqli_prepare("SELECT * FROM users WHERE name = ?");
$stmt->bind_param("s", $taintedUserName);

An alternative – although generally not recommended – is to escape your data manually:

$mysqli = new mysqli('localhost', 'user', 'pass', 'dbname');

$escaped = $mysqli->real_escape_string($taintedUserName);
$mysqli->query("SELECT * FROM users WHERE name = '".$escaped."'");

General Strategies to prevent injection

In general, it is advisable to prevent any user-data to reach this point. This can be done by white-listing certain values:

if ( ! in_array($value, array('this-is-allowed', 'and-this-too'), true)) {
    throw new \InvalidArgumentException('This input is not allowed.');
}

For numeric data, we recommend to explicitly cast the data:

$sanitized = (integer) $tainted;
Loading history...
535
                        WHERE type='admin' AND intitule = 'cpassman_version'"
536
                    );
537
                    $cpmVersion = mysqli_fetch_row($tmpResult);
538
                    echo 'document.getElementById("actual_cpm_version").value = "'.
0 ignored issues
show
Security Cross-Site Scripting introduced by
'document.getElementById.... $cpmVersion[0] . '";' can contain request data and is used in output context(s) leading to a potential security vulnerability.

1 path for user data to reach this point

  1. Read from $_POST, and ``'SELECT valeur FROM ' . $_POST['tbl_prefix'] . 'misc WHERE type=\'admin\' AND intitule = \'cpassman_version\''`` is passed through mysqli_query()
    in install/upgrade_ajax.php on line 534
  2. $tmpResult is assigned
    in install/upgrade_ajax.php on line 532
  3. $tmpResult is passed through mysqli_fetch_row(), and $cpmVersion is assigned
    in install/upgrade_ajax.php on line 537

Preventing Cross-Site-Scripting Attacks

Cross-Site-Scripting allows an attacker to inject malicious code into your website - in particular Javascript code, and have that code executed with the privileges of a visiting user. This can be used to obtain data, or perform actions on behalf of that visiting user.

In order to prevent this, make sure to escape all user-provided data:

// for HTML
$sanitized = htmlentities($tainted, ENT_QUOTES);

// for URLs
$sanitized = urlencode($tainted);

General Strategies to prevent injection

In general, it is advisable to prevent any user-data to reach this point. This can be done by white-listing certain values:

if ( ! in_array($value, array('this-is-allowed', 'and-this-too'), true)) {
    throw new \InvalidArgumentException('This input is not allowed.');
}

For numeric data, we recommend to explicitly cast the data:

$sanitized = (integer) $tainted;
Loading history...
539
                        $cpmVersion[0].'";';
540
                } else {
541
                    echo 'document.getElementById("actual_cpm_version").value = "0";';
542
                }
543
544
                //Get some infos from DB
545
                if (@mysqli_fetch_row(
546
                    mysqli_query(
547
                        $dbTmp,
548
                        "SELECT valeur FROM ".$_POST['tbl_prefix']."misc
0 ignored issues
show
Security SQL Injection introduced by
'SELECT valeur FROM ' . ...ule = \'utf8_enabled\'' can contain request data and is used in sql context(s) leading to a potential security vulnerability.

1 path for user data to reach this point

  1. Read from $_POST
    in install/upgrade_ajax.php on line 548

Preventing SQL Injection

There are two options to prevent SQL injection. Generally, it is recommended to use parameter binding:

$stmt = mysqli_prepare("SELECT * FROM users WHERE name = ?");
$stmt->bind_param("s", $taintedUserName);

An alternative – although generally not recommended – is to escape your data manually:

$mysqli = new mysqli('localhost', 'user', 'pass', 'dbname');

$escaped = $mysqli->real_escape_string($taintedUserName);
$mysqli->query("SELECT * FROM users WHERE name = '".$escaped."'");

General Strategies to prevent injection

In general, it is advisable to prevent any user-data to reach this point. This can be done by white-listing certain values:

if ( ! in_array($value, array('this-is-allowed', 'and-this-too'), true)) {
    throw new \InvalidArgumentException('This input is not allowed.');
}

For numeric data, we recommend to explicitly cast the data:

$sanitized = (integer) $tainted;
Loading history...
549
                        WHERE type='admin' AND intitule = 'utf8_enabled'"
550
                    )
551
                )
552
                ) {
553
                    $cpmIsUTF8 = mysqli_fetch_row(
554
                        mysqli_query(
555
                            $dbTmp,
556
                            "SELECT valeur FROM ".$_POST['tbl_prefix']."misc
0 ignored issues
show
Security SQL Injection introduced by
'SELECT valeur FROM ' . ...ule = \'utf8_enabled\'' can contain request data and is used in sql context(s) leading to a potential security vulnerability.

1 path for user data to reach this point

  1. Read from $_POST
    in install/upgrade_ajax.php on line 556

Preventing SQL Injection

There are two options to prevent SQL injection. Generally, it is recommended to use parameter binding:

$stmt = mysqli_prepare("SELECT * FROM users WHERE name = ?");
$stmt->bind_param("s", $taintedUserName);

An alternative – although generally not recommended – is to escape your data manually:

$mysqli = new mysqli('localhost', 'user', 'pass', 'dbname');

$escaped = $mysqli->real_escape_string($taintedUserName);
$mysqli->query("SELECT * FROM users WHERE name = '".$escaped."'");

General Strategies to prevent injection

In general, it is advisable to prevent any user-data to reach this point. This can be done by white-listing certain values:

if ( ! in_array($value, array('this-is-allowed', 'and-this-too'), true)) {
    throw new \InvalidArgumentException('This input is not allowed.');
}

For numeric data, we recommend to explicitly cast the data:

$sanitized = (integer) $tainted;
Loading history...
557
                            WHERE type='admin' AND intitule = 'utf8_enabled'"
558
                        )
559
                    );
560
                    echo 'document.getElementById("cpm_isUTF8").value = "'.$cpmIsUTF8[0].'";';
0 ignored issues
show
Security Cross-Site Scripting introduced by
'document.getElementById... . $cpmIsUTF8[0] . '";' can contain request data and is used in output context(s) leading to a potential security vulnerability.

1 path for user data to reach this point

  1. Read from $_POST, and ``'SELECT valeur FROM ' . $_POST['tbl_prefix'] . 'misc WHERE type=\'admin\' AND intitule = \'utf8_enabled\''`` is passed through mysqli_query()
    in install/upgrade_ajax.php on line 556
  2. ``mysqli_query($dbTmp, 'SELECT valeur FROM ' . $_POST['tbl_prefix'] . 'misc WHERE type=\'admin\' AND intitule = \'utf8_enabled\'')`` is passed through mysqli_fetch_row()
    in install/upgrade_ajax.php on line 554
  3. $cpmIsUTF8 is assigned
    in install/upgrade_ajax.php on line 553

Preventing Cross-Site-Scripting Attacks

Cross-Site-Scripting allows an attacker to inject malicious code into your website - in particular Javascript code, and have that code executed with the privileges of a visiting user. This can be used to obtain data, or perform actions on behalf of that visiting user.

In order to prevent this, make sure to escape all user-provided data:

// for HTML
$sanitized = htmlentities($tainted, ENT_QUOTES);

// for URLs
$sanitized = urlencode($tainted);

General Strategies to prevent injection

In general, it is advisable to prevent any user-data to reach this point. This can be done by white-listing certain values:

if ( ! in_array($value, array('this-is-allowed', 'and-this-too'), true)) {
    throw new \InvalidArgumentException('This input is not allowed.');
}

For numeric data, we recommend to explicitly cast the data:

$sanitized = (integer) $tainted;
Loading history...
561
                    $_SESSION['utf8_enabled'] = $cpmIsUTF8[0];
562
                } else {
563
                    echo 'document.getElementById("cpm_isUTF8").value = "0";';
564
                    $_SESSION['utf8_enabled'] = 0;
565
                }
566
567
                // put TP in maintenance mode or not
568
                @mysqli_query(
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
569
                    $dbTmp,
570
                    "UPDATE `".$_SESSION['pre']."misc`
0 ignored issues
show
Security SQL Injection introduced by
'UPDATE `' . $_SESSION['...intenance_mode'] . '\'' can contain request data and is used in sql context(s) leading to a potential security vulnerability.

2 paths for user data to reach this point

  1. Path: Read from $_POST, and ``'SELECT valeur FROM ' . $_POST['tbl_prefix'] . 'misc WHERE type=\'admin\' AND intitule = \'utf8_enabled\''`` is passed through mysqli_query() in install/upgrade_ajax.php on line 556
  1. Read from $_POST, and ``'SELECT valeur FROM ' . $_POST['tbl_prefix'] . 'misc WHERE type=\'admin\' AND intitule = \'utf8_enabled\''`` is passed through mysqli_query()
    in install/upgrade_ajax.php on line 556
  2. ``mysqli_query($dbTmp, 'SELECT valeur FROM ' . $_POST['tbl_prefix'] . 'misc WHERE type=\'admin\' AND intitule = \'utf8_enabled\'')`` is passed through mysqli_fetch_row()
    in install/upgrade_ajax.php on line 554
  3. $cpmIsUTF8 is assigned
    in install/upgrade_ajax.php on line 553
  4. $_SESSION is assigned
    in install/upgrade_ajax.php on line 561
  2. Path: Read from $_POST in install/upgrade_ajax.php on line 572
  1. Read from $_POST
    in install/upgrade_ajax.php on line 572

Preventing SQL Injection

There are two options to prevent SQL injection. Generally, it is recommended to use parameter binding:

$stmt = mysqli_prepare("SELECT * FROM users WHERE name = ?");
$stmt->bind_param("s", $taintedUserName);

An alternative – although generally not recommended – is to escape your data manually:

$mysqli = new mysqli('localhost', 'user', 'pass', 'dbname');

$escaped = $mysqli->real_escape_string($taintedUserName);
$mysqli->query("SELECT * FROM users WHERE name = '".$escaped."'");

General Strategies to prevent injection

In general, it is advisable to prevent any user-data to reach this point. This can be done by white-listing certain values:

if ( ! in_array($value, array('this-is-allowed', 'and-this-too'), true)) {
    throw new \InvalidArgumentException('This input is not allowed.');
}

For numeric data, we recommend to explicitly cast the data:

$sanitized = (integer) $tainted;
Loading history...
571
                    SET `valeur` = 'maintenance_mode'
572
                    WHERE type = 'admin' AND intitule = '".$_POST['no_maintenance_mode']."'"
573
                );
574
575
                echo 'document.getElementById("dump").style.display = "";';
576
            } else {
577
                $res = "Impossible to get connected to server. Error is: ".addslashes(mysqli_connect_error());
578
                echo 'document.getElementById("but_next").disabled = "disabled";';
579
            }
580
581
            echo 'document.getElementById("res_step2").innerHTML = "'.$res.'";';
582
            echo 'document.getElementById("loader").style.display = "none";';
583
            break;
584
585
            #==========================
586
        case "step3":
587
            if ($_SESSION['user_granted'] !== "1") {
588
                echo 'document.getElementById("res_step3").innerHTML = "User not connected anymore!";';
589
                echo 'document.getElementById("loader").style.display = "none";';
590
                break;
591
            }
592
593
            mysqli_connect(
594
                $_SESSION['server'],
595
                $_SESSION['user'],
596
                $_SESSION['pass'],
597
                $_SESSION['database'],
598
                $_SESSION['port']
599
            );
600
            $dbTmp = mysqli_connect(
601
                $_SESSION['server'],
602
                $_SESSION['user'],
603
                $_SESSION['pass'],
604
                $_SESSION['database'],
605
                $_SESSION['port']
606
            );
607
            $status = "";
608
609
            //rename tables
610
            if (isset($_POST['prefix_before_convert']) && $_POST['prefix_before_convert'] == "true") {
611
                $tables = mysqli_query($dbTmp, 'SHOW TABLES');
612
                while ($table = mysqli_fetch_row($tables)) {
613
                    if (tableExists("old_".$table[0]) != 1 && substr($table[0], 0, 4) != "old_") {
614
                        mysqli_query($dbTmp, "CREATE TABLE old_".$table[0]." LIKE ".$table[0]);
615
                        mysqli_query($dbTmp, "INSERT INTO old_".$table[0]." SELECT * FROM ".$table[0]);
616
                    }
617
                }
618
            }
619
620
            //convert database
621
            mysqli_query(
622
                $dbTmp,
623
                "ALTER DATABASE `".$_SESSION['database']."`
624
                DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci"
625
            );
626
627
            //convert tables
628
            $res = mysqli_query($dbTmp, "SHOW TABLES FROM `".$_SESSION['database']."`");
629
            while ($table = mysqli_fetch_row($res)) {
630
                if (substr($table[0], 0, 4) != "old_") {
631
                    mysqli_query(
632
                        $dbTmp,
633
                        "ALTER TABLE ".$_SESSION['database'].".`{$table[0]}`
634
                        CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci"
635
                    );
636
                    mysqli_query(
637
                        $dbTmp,
638
                        "ALTER TABLE".$_SESSION['database'].".`{$table[0]}`
639
                        DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci"
640
                    );
641
                }
642
            }
643
644
            echo 'document.getElementById("res_step3").innerHTML = "Done!";';
645
            echo 'document.getElementById("loader").style.display = "none";';
646
            echo 'document.getElementById("but_next").disabled = "";';
647
            echo 'document.getElementById("but_launch").disabled = "disabled";';
648
649
            mysqli_close($dbTmp);
650
            break;
651
652
            #==========================
653
654
655
            //=============================
656
        case "step5":
657
            if ($_SESSION['user_granted'] !== "1") {
658
                echo 'document.getElementById("res_step5").innerHTML = "User not connected anymore!";';
659
                echo 'document.getElementById("loader").style.display = "none";';
660
                break;
661
            }
662
663
            $filename = "../includes/config/settings.php";
664
            $events = "";
665
            if (file_exists($filename)) {
666
                //Do a copy of the existing file
667
                if (!copy(
668
                    $filename,
669
                    $filename.'.'.date(
670
                        "Y_m_d",
671
                        mktime(0, 0, 0, date('m'), date('d'), date('y'))
672
                    )
673
                )) {
674
                    echo 'document.getElementById("res_step5").innerHTML = '.
675
                        '"Setting.php file already exists and cannot be renamed. '.
676
                        'Please do it by yourself and click on button Launch.";';
677
                    echo 'document.getElementById("loader").style.display = "none";';
678
                    break;
679
                } else {
680
                    $events .= "The file $filename already exist. A copy has been created.<br />";
681
                    unlink($filename);
682
                }
683
684
                //manage SK path
685
                if (isset($_POST['sk_path']) && !empty($_POST['sk_path'])) {
686
                    $skFile = str_replace('\\', '/', $_POST['sk_path'].'/sk.php');
687
                    $securePath = str_replace('\\', '/', $_POST['sk_path']);
688
                } else {
689
                    echo 'document.getElementById("res_step5").innerHTML = '.
690
                        '"<img src=\"images/exclamation-red.png\"> The SK path must be indicated.";
691
                        document.getElementById("loader").style.display = "none";';
692
                    break;
693
                }
694
695
                //Check if path is ok
696
                if (is_dir($securePath)) {
697
                    if (is_writable($securePath)) {
0 ignored issues
show
Unused Code introduced by
This if statement is empty and can be removed.

This check looks for the bodies of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These if bodies can be removed. If you have an empty if but statements in the else branch, consider inverting the condition.

if (rand(1, 6) > 3) {
//print "Check failed";
} else {
    print "Check succeeded";
}

could be turned into

if (rand(1, 6) <= 3) {
    print "Check succeeded";
}

This is much more concise to read.

Loading history...
698
                        //Do nothing
699
                    } else {
700
                        echo 'document.getElementById("res_step5").innerHTML = '.
701
                            '"<img src=\"images/exclamation-red.png\"> The SK path must be writable!";
702
                            document.getElementById("loader").style.display = "none";';
703
                        break;
704
                    }
705
                } else {
706
                    echo 'document.getElementById("res_step5").innerHTML = '.
707
                        '"<img src=\"images/exclamation-red.png\"> '.
708
                        'Path for SK is not a Directory!";
709
                    document.getElementById("loader").style.display = "none";';
710
                    break;
711
                }
712
713
                $fh = fopen($filename, 'w');
714
715
                //prepare smtp_auth variable
716
                if (empty($_SESSION['smtp_auth'])) {
717
                    $_SESSION['smtp_auth'] = 'false';
718
                }
719
                if (empty($_SESSION['smtp_auth_username'])) {
720
                    $_SESSION['smtp_auth_username'] = 'false';
721
                }
722
                if (empty($_SESSION['smtp_auth_password'])) {
723
                    $_SESSION['smtp_auth_password'] = 'false';
724
                }
725
                if (empty($_SESSION['email_from_name'])) {
726
                    $_SESSION['email_from_name'] = 'false';
727
                }
728
729
                $result1 = fwrite(
730
                    $fh,
731
                    utf8_encode(
0 ignored issues
show
Security File Manipulation introduced by
utf8_encode('<?php globa.../ Don\'t change this.') can contain request data and is used in file manipulation context(s) leading to a potential security vulnerability.

1 path for user data to reach this point

  1. Read from $_POST, and $_POST['sk_path'] . '/sk.php' is passed through str_replace(), and $skFile is assigned
    in install/upgrade_ajax.php on line 686
  2. ``'$lang, $txt, $k, $pathTeampas, $urlTeampass, $pwComplexity, $mngPages; global $server, $user, $pass, $database, $pre, $db, $port, $encoding; ### DATABASE connexion parameters ### $server = "' . filter_var($_SESSION['server'], FILTER_SANITIZE_STRING) . '"; $user = "' . filter_var($_SESSION['user'], FILTER_SANITIZE_STRING) . '"; $pass = "' . str_replace('$', '\\$', filter_var($_SESSION['pass'], FILTER_SANITIZE_STRING)) . '"; $database = "' . filter_var($_SESSION['database'], FILTER_SANITIZE_STRING) . '"; $port = ' . filter_var($_SESSION['port'], FILTER_SANITIZE_STRING) . '; $pre = "' . filter_var($_SESSION['pre'], FILTER_SANITIZE_STRING) . '"; $encoding = "' . filter_var($_SESSION['db_encoding'], FILTER_SANITIZE_STRING) . '"; @date_default_timezone_set($_SESSION[\'settings\'][\'timezone\']); @define(\'SECUREPATH\', \'' . substr($skFile, 0, strlen($skFile) - 7) . '\'); if (file_exists("' . $skFile . '")) { require_once "' . $skFile . '"; } @define(\'COST\', \'13\'); // Don\'t change this.'`` is passed through utf8_encode()
    in install/upgrade_ajax.php on line 732

General Strategies to prevent injection

In general, it is advisable to prevent any user-data to reach this point. This can be done by white-listing certain values:

if ( ! in_array($value, array('this-is-allowed', 'and-this-too'), true)) {
    throw new \InvalidArgumentException('This input is not allowed.');
}

For numeric data, we recommend to explicitly cast the data:

$sanitized = (integer) $tainted;
Loading history...
732
                        "<?php
733
global \$lang, \$txt, \$k, \$pathTeampas, \$urlTeampass, \$pwComplexity, \$mngPages;
734
global \$server, \$user, \$pass, \$database, \$pre, \$db, \$port, \$encoding;
735
736
### DATABASE connexion parameters ###
737
\$server = \"".filter_var($_SESSION['server'], FILTER_SANITIZE_STRING)."\";
738
\$user = \"". filter_var($_SESSION['user'], FILTER_SANITIZE_STRING)."\";
739
\$pass = \"". str_replace("$", "\\$", filter_var($_SESSION['pass'], FILTER_SANITIZE_STRING))."\";
740
\$database = \"". filter_var($_SESSION['database'], FILTER_SANITIZE_STRING)."\";
741
\$port = ". filter_var($_SESSION['port'], FILTER_SANITIZE_STRING).";
742
\$pre = \"". filter_var($_SESSION['pre'], FILTER_SANITIZE_STRING)."\";
743
\$encoding = \"".filter_var($_SESSION['db_encoding'], FILTER_SANITIZE_STRING)."\";
744
745
@date_default_timezone_set(\$_SESSION['settings']['timezone']);
746
@define('SECUREPATH', '".substr($skFile, 0, strlen($skFile) - 7)."');
747
if (file_exists(\"".$skFile."\")) {
748
    require_once \"".$skFile."\";
749
}
750
@define('COST', '13'); // Don't change this."
751
                    )
752
                );
753
754
                fclose($fh);
755
                if ($result1 === false) {
756
                    echo 'document.getElementById("res_step5").innerHTML = '.
757
                        '"Setting.php file could not be created. '.
758
                        'Please check the path and the rights.";';
759
                } else {
760
                    echo 'document.getElementById("step5_settingFile").innerHTML = '.
761
                        '"<img src=\"images/tick.png\">";';
762
                }
763
764
                //Create sk.php file
765
                if (!file_exists($skFile)) {
766
                    $fh = fopen($skFile, 'w');
767
768
                    $result2 = fwrite(
769
                        $fh,
770
                        utf8_encode(
771
                            "<?php
772
@define('COST', '13'); // Don't change this.
773
@define('AKEY', '');
774
@define('IKEY', '');
775
@define('SKEY', '');
776
@define('HOST', '');
777
?>"
778
                        )
779
                    );
780
                    fclose($fh);
781
                }
782
783
                // update CSRFP TOKEN
784
                $csrfp_file_sample = "../includes/libraries/csrfp/libs/csrfp.config.sample.php";
785
                $csrfp_file = "../includes/libraries/csrfp/libs/csrfp.config.php";
786
                if (file_exists($csrfp_file)) {
787
                    if (!copy($filename, $filename.'.'.date("Y_m_d", mktime(0, 0, 0, date('m'), date('d'), date('y'))))) {
788
                        echo '[{"error" : "csrfp.config.php file already exists and cannot be renamed. Please do it by yourself and click on button Launch.", "result":"", "index" : "'.$_POST['index'].'", "multiple" : "'.$_POST['multiple'].'"}]';
0 ignored issues
show
Security Cross-Site Scripting introduced by
'[{"error" : "csrfp.conf...OST['multiple'] . '"}]' can contain request data and is used in output context(s) leading to a potential security vulnerability.

1 path for user data to reach this point

  1. Read from $_POST
    in install/upgrade_ajax.php on line 788

Preventing Cross-Site-Scripting Attacks

Cross-Site-Scripting allows an attacker to inject malicious code into your website - in particular Javascript code, and have that code executed with the privileges of a visiting user. This can be used to obtain data, or perform actions on behalf of that visiting user.

In order to prevent this, make sure to escape all user-provided data:

// for HTML
$sanitized = htmlentities($tainted, ENT_QUOTES);

// for URLs
$sanitized = urlencode($tainted);

General Strategies to prevent injection

In general, it is advisable to prevent any user-data to reach this point. This can be done by white-listing certain values:

if ( ! in_array($value, array('this-is-allowed', 'and-this-too'), true)) {
    throw new \InvalidArgumentException('This input is not allowed.');
}

For numeric data, we recommend to explicitly cast the data:

$sanitized = (integer) $tainted;
Loading history...
789
                        break;
790
                    } else {
791
                        $events .= "The file $csrfp_file already exist. A copy has been created.<br />";
792
                    }
793
                }
794
                unlink($csrfp_file); // delete existing csrfp.config file
795
                copy($csrfp_file_sample, $csrfp_file); // make a copy of csrfp.config.sample file
796
                $data = file_get_contents("../includes/libraries/csrfp/libs/csrfp.config.php");
797
                $newdata = str_replace('"CSRFP_TOKEN" => ""', '"CSRFP_TOKEN" => "'.bin2hex(openssl_random_pseudo_bytes(25)).'"', $data);
798
                $newdata = str_replace('"tokenLength" => "25"', '"tokenLength" => "50"', $newdata);
799
                $jsUrl = $_SESSION['fullurl'].'/includes/libraries/csrfp/js/csrfprotector.js';
800
                $newdata = str_replace('"jsUrl" => ""', '"jsUrl" => "'.$jsUrl.'"', $newdata);
801
                $newdata = str_replace('"verifyGetFor" => array()', '"verifyGetFor" => array("*page=items&type=duo_check*")', $newdata);
802
                file_put_contents("../includes/libraries/csrfp/libs/csrfp.config.php", $newdata);
803
804
805
                // finalize
806
                if (isset($result2) && $result2 === false) {
807
                    echo 'document.getElementById("res_step5").innerHTML = '.
808
                        '"$skFile could not be created. Please check the path and the rights.";';
809
                } else {
810
                    echo 'document.getElementById("step5_skFile").innerHTML = '.
811
                        '"<img src=\"images/tick.png\">";';
812
                }
813
814
                //Finished
815
                if ($result1 !== false
816
                    && (!isset($result2) || (isset($result2) && $result2 !== false))
817
                ) {
818
                    echo 'document.getElementById("but_next").disabled = "";';
819
                    echo 'document.getElementById("res_step5").innerHTML = '.
820
                        '"Operations are successfully completed.";';
821
                    echo 'document.getElementById("loader").style.display = "none";';
822
                    echo 'document.getElementById("but_launch").disabled = "disabled";';
823
                }
824
            } else {
825
                //settings.php file doesn't exit => ERROR !!!!
826
                echo 'document.getElementById("res_step5").innerHTML = '.
827
                        '"<img src=\"images/error.png\">&nbsp;Setting.php '.
828
                        'file doesn\'t exist! Upgrade can\'t continue without this file.<br />'.
829
                        'Please copy your existing settings.php into the \"includes\" '.
830
                        'folder of your TeamPass installation ";';
831
                echo 'document.getElementById("loader").style.display = "none";';
832
            }
833
834
            break;
835
836
        case "perform_database_dump":
837
            $filename = "../includes/config/settings.php";
838
839
            $mtables = array();
840
841
            $mysqli = new mysqli($_SESSION['server'], $_SESSION['user'], $_SESSION['pass'], $_SESSION['database'], $_SESSION['port']);
842
            if ($mysqli->connect_error) {
843
                die('Error : ('.$mysqli->connect_errno.') '.$mysqli->connect_error);
844
            }
845
846
            $results = $mysqli->query("SHOW TABLES");
847
848
            while ($row = $results->fetch_array()) {
849
                $mtables[] = $row[0];
850
            }
851
852
            foreach ($mtables as $table) {
853
                $contents .= "-- Table `".$table."` --\n";
854
855
                $results = $mysqli->query("SHOW CREATE TABLE ".$table);
856
                while ($row = $results->fetch_array()) {
857
                    $contents .= $row[1].";\n\n";
858
                }
859
860
                $results = $mysqli->query("SELECT * FROM ".$table);
861
                $row_count = $results->num_rows;
862
                $fields = $results->fetch_fields();
863
                $fields_count = count($fields);
864
865
                $insert_head = "INSERT INTO `".$table."` (";
866
                for ($i = 0; $i < $fields_count; $i++) {
867
                    $insert_head .= "`".$fields[$i]->name."`";
868
                    if ($i < $fields_count - 1) {
869
                        $insert_head .= ', ';
870
                    }
871
                }
872
                $insert_head .= ")";
873
                $insert_head .= " VALUES\n";
874
875
                if ($row_count > 0) {
876
                    $r = 0;
877
                    while ($row = $results->fetch_array()) {
878
                        if (($r % 400) == 0) {
879
                            $contents .= $insert_head;
880
                        }
881
                        $contents .= "(";
882
                        for ($i = 0; $i < $fields_count; $i++) {
883
                            $row_content = str_replace("\n", "\\n", $mysqli->real_escape_string($row[$i]));
884
885
                            switch ($fields[$i]->type) {
886
                                case 8: case 3:
887
                                    $contents .= $row_content;
888
                                    break;
889
                                default:
890
                                    $contents .= "'".$row_content."'";
891
                            }
892
                            if ($i < $fields_count - 1) {
893
                                $contents .= ', ';
894
                            }
895
                        }
896
                        if (($r + 1) == $row_count || ($r % 400) == 399) {
897
                            $contents .= ");\n\n";
898
                        } else {
899
                            $contents .= "),\n";
900
                        }
901
                        $r++;
902
                    }
903
                }
904
            }
905
906
            $backup_file_name = "sql-backup-".date("d-m-Y--h-i-s").".sql";
907
908
            $fp = fopen("../files/".$backup_file_name, 'w+');
909
            if (($result = fwrite($fp, $contents))) {
910
                echo '[{ "error" : "" , "file" : "files/'.$backup_file_name.'"}]';
911
            } else {
912
                echo '[{ "error" : "Backup fails - please do it manually."}]';
913
            }
914
            fclose($fp);
915
916
            break;
917
    }
918
}
919