Issues (287)

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.

Sniffs/Strings/DoubleQuoteUsageSniff.php (6 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
/**
4
 * CodeIgniter_Sniffs_Strings_DoubleQuoteUsageSniff.
5
 *
6
 * PHP version 5
7
 *
8
 * @category  PHP
9
 * @package   PHP_CodeSniffer
10
 * @author    Thomas Ernest <[email protected]>
11
 * @copyright 2011 Thomas Ernest
12
 * @license   http://thomas.ernest.fr/developement/php_cs/licence GNU General Public License
13
 * @link      http://pear.php.net/package/PHP_CodeSniffer
14
 */
15
16
namespace CodeIgniter\Sniffs\Strings;
17
18
use PHP_CodeSniffer\Sniffs\Sniff;
19
use PHP_CodeSniffer\Files\File;
20
21
/**
22
 * CodeIgniter_Sniffs_Strings_DoubleQuoteUsageSniff.
23
 *
24
 * Ensures that double-quoted strings are used only to parse variables,
25
 * to avoid escape characters before single quotes or for chars that need
26
 * to be interpreted like \r, \n or \t.
27
 * If a double-quoted string contain both single and double quotes
28
 * but no variable, then a warning is raised to encourage the use of
29
 * single-quoted strings.
30
 *
31
 * @category  PHP
32
 * @package   PHP_CodeSniffer
33
 * @author    Thomas Ernest <[email protected]>
34
 * @copyright 2011 Thomas Ernest
35
 * @license   http://thomas.ernest.fr/developement/php_cs/licence GNU General Public License
36
 * @link      http://pear.php.net/package/PHP_CodeSniffer
37
 */
38
class VariableUsageSniff implements Sniff
39
{
40
	/**
41
	 * Returns an array of tokens this test wants to listen for.
42
	 *
43
	 * @return array
44
	 */
45
	public function register()
46
	{
47
		/*
48
		return array(
49
			T_DOUBLE_QUOTED_STRING,
50
			T_CONSTANT_ENCAPSED_STRING,
51
		);
52
		*/
53
		return array();
54
	}//end register()
55
56
57
	/**
58
	 * Processes this test, when one of its tokens is encountered.
59
	 *
60
	 * @param File $phpcsFile The current file being scanned.
61
	 * @param int                  $stackPtr  The position of the current token
62
	 *                                        in the stack passed in $tokens.
63
	 *
64
	 * @return void
65
	 */
66
	public function process(File $phpcsFile, $stackPtr)
67
	{
68
		$tokens = $phpcsFile->getTokens();
69
		$string = $tokens[$stackPtr]['content'];
70
		// makes sure that it is about a double quote string,
71
		// since variables are not parsed out of double quoted string
72
		$openDblQtStr = substr($string, 0, 1);
73 View Code Duplication
		if (0 === strcmp($openDblQtStr, '"')) {
0 ignored issues
show
This code seems to be duplicated across 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...
74
			$this->processDoubleQuotedString($phpcsFile, $stackPtr, $string);
75
		} else if (0 === strcmp($openDblQtStr, "'")) {
76
			$this->processSingleQuotedString($phpcsFile, $stackPtr, $string);
77
		}
78
	}//end process()
79
80
81
	/**
82
	 * Processes this test, when the token encountered is a double-quoted string.
83
	 *
84
	 * @param File $phpcsFile   The current file being scanned.
85
	 * @param int                  $stackPtr    The position of the current token
86
	 *                                          in the stack passed in $tokens.
87
	 * @param string               $dblQtString The double-quoted string content,
88
	 *                                          i.e. without quotes.
89
	 *
90
	 * @return void
91
	 */
92
	protected function processDoubleQuotedString (File $phpcsFile, $stackPtr, $dblQtString)
93
	{
94
		$variableFound = FALSE;
95
		$strTokens = token_get_all('<?php '.$dblQtString);
96
		$strPtr = 1; // skip php opening tag added by ourselves
97
		$requireDblQuotes = FALSE;
98
		while ($strPtr < count($strTokens)) {
99
			$strToken = $strTokens[$strPtr];
100
			if (is_array($strToken)) {
101
				if (in_array($strToken[0], array(T_DOLLAR_OPEN_CURLY_BRACES, T_CURLY_OPEN))) {
102
					$strPtr++;
103
					try {
104
						$this->_parseVariable($strTokens, $strPtr);
105
					} catch (Exception $err) {
106
						$error = 'There is no variable, object nor array between curly braces. Please use the escape char for $ or {.';
107
						$phpcsFile->addError($error, $stackPtr);
108
					}
109
					$variableFound = TRUE;
110
					if ('}' !== $strTokens[$strPtr]) {
111
						$error = 'There is no matching closing curly brace.';
112
						$phpcsFile->addError($error, $stackPtr);
113
					}
114
					// don't move forward, since it will be done in the main loop
115
					// $strPtr++;
116 View Code Duplication
				} else if (T_VARIABLE === $strToken[0]) {
0 ignored issues
show
This code seems to be duplicated across 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...
117
					$variableFound = TRUE;
118
					$error = "Variable {$strToken[1]} in double-quoted strings should be enclosed with curly braces. Please consider {{$strToken[1]}}";
119
					$phpcsFile->addError($error, $stackPtr);
120
				}
121
			}
122
			$strPtr++;
123
		}
124
		return $variableFound;
125
	}//end processDoubleQuotedString()
126
127
128
	/**
129
	 * Processes this test, when the token encountered is a single-quoted string.
130
	 *
131
	 * @param File $phpcsFile   The current file being scanned.
132
	 * @param int                  $stackPtr    The position of the current token
133
	 *                                          in the stack passed in $tokens.
134
	 * @param string               $sglQtString The single-quoted string content,
135
	 *                                          i.e. without quotes.
136
	 *
137
	 * @return void
138
	 */
139
	protected function processSingleQuotedString (File $phpcsFile, $stackPtr, $sglQtString)
140
	{
141
		$variableFound = FALSE;
142
		$strTokens = token_get_all('<?php '.$sglQtString);
143
		$strPtr = 1; // skip php opening tag added by ourselves
144
		while ($strPtr < count($strTokens)) {
145
			$strToken = $strTokens[$strPtr];
146 View Code Duplication
			if (is_array($strToken)) {
0 ignored issues
show
This code seems to be duplicated across 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...
147
				if (T_VARIABLE === $strToken[0]) {
148
					$error = "Variables like {$strToken[1]} should be in double-quoted strings only.";
149
					$phpcsFile->addError($error, $stackPtr);
150
				}
151
			}
152
			$strPtr++;
153
		}
154
		return $variableFound;
155
	}//end processSingleQuotedString()
156
157
	/**
158
	 * Grammar rule to parse the use of a variable. Please notice that it
159
	 * doesn't manage the leading $.
160
	 *
161
	 * _parseVariable ::= <variable>
162
	 *     | <variable>_parseObjectAttribute()
163
	 *     | <variable>_parseArrayIndexes()
164
	 *
165
	 * @exception Exception raised if $strTokens starting from $strPtr
166
	 *                      doesn't matched the rule.
167
	 *
168
	 * @param array $strTokens Tokens to parse.
169
	 * @param int   $strPtr    Pointer to the token where parsing starts.
170
	 *
171
	 * @return array The attribute name associated to index 'var', an array with
172
	 * indexes 'obj' and 'attr' or an array with indexes 'arr' and 'idx'.
173
	 */
174
	private function _parseVariable ($strTokens, &$strPtr)
175
	{
176
		if ( ! in_array($strTokens[$strPtr][0], array(T_VARIABLE, T_STRING_VARNAME))) {
177
			throw new Exception ('Expected variable name.');
178
		}
179
		$var = $strTokens[$strPtr][1];
180
		$strPtr++;
181
		$startStrPtr = $strPtr;
182
		try {
183
			$attr = $this->_parseObjectAttribute($strTokens, $strPtr);
184
			return array ('obj' => $var, 'attr' => $attr);
185
		} catch (Exception $err) {
186
			if ($strPtr !== $startStrPtr) {
187
				throw $err;
188
			}
189
		}
190
		try {
191
			$idx = $this->_parseArrayIndexes($strTokens, $strPtr);
192
			return array ('arr' => $var, 'idx' => $idx);
193
		} catch (Exception $err) {
194
			if ($strPtr !== $startStrPtr) {
195
				throw $err;
196
			}
197
		}
198
		return array ('var' => $var);
199
	}//end _parseVariable()
200
201
202
	/**
203
	 * Grammar rule to parse the use of an object attribute.
204
	 *
205
	 * _parseObjectAttribute ::= -><attribute>
206
	 *     | -><attribute>_parseObjectAttribute()
207
	 *     | -><attribute>_parseArrayIndexes()
208
	 *
209
	 * @exception Exception raised if $strTokens starting from $strPtr
210
	 *                      doesn't matched the rule.
211
	 *
212
	 * @param array $strTokens Tokens to parse.
213
	 * @param int   $strPtr    Pointer to the token where parsing starts.
214
	 *
215
	 * @return mixed The attribute name as a string, an array with indexes
216
	 * 'obj' and 'attr' or an array with indexes 'arr' and 'idx'.
217
	 */
218
	private function _parseObjectAttribute ($strTokens, &$strPtr)
219
	{
220
		if (T_OBJECT_OPERATOR !== $strTokens[$strPtr][0]) {
221
			throw new Exception ('Expected ->.');
222
		}
223
		$strPtr++;
224
		if (T_STRING !== $strTokens[$strPtr][0]) {
225
			throw new Exception ('Expected an object attribute.');
226
		}
227
		$attr = $strTokens[$strPtr][1];
228
		$strPtr++;
229
		$startStrPtr = $strPtr;
230
		try {
231
			$sub_attr = $this->_parseObjectAttribute($strTokens, $strPtr);
232
			return array ('obj' => $attr, 'attr' => $sub_attr);
233
		} catch (Exception $err) {
234
			if ($strPtr !== $startStrPtr) {
235
				throw $err;
236
			}
237
		}
238
		try {
239
			$idx = $this->_parseArrayIndexes($strTokens, $strPtr);
240
			return array ('arr' => $attr, 'idx' => $idx);
241
		} catch (Exception $err) {
242
			if ($strPtr !== $startStrPtr) {
243
				throw $err;
244
			}
245
		}
246
		return $attr;
247
	}//end _parseObjectAttribute()
248
249
250
	/**
251
	 * Grammar rule to parse the use of one or more array indexes.
252
	 *
253
	 * _parseArrayIndexes ::= _parseArrayIndex()+
254
	 *
255
	 * @exception Exception raised if $strTokens starting from $strPtr
256
	 *                      doesn't matched the rule.
257
	 *
258
	 * @param array $strTokens Tokens to parse.
259
	 * @param int   $strPtr    Pointer to the token where parsing starts.
260
	 *
261
	 * @return array Indexes in the same order as in the string.
262
	 */
263
	private function _parseArrayIndexes ($strTokens, &$strPtr)
264
	{
265
		$indexes = array($this->_parseArrayIndex($strTokens, $strPtr));
266
		try {
267
			while (1) {
268
				$startStrPtr = $strPtr;
269
				$indexes [] = $this->_parseArrayIndex($strTokens, $strPtr);
270
			}
271
		} catch (Exception $err) {
272
			if (0 !== ($strPtr - $startStrPtr)) {
273
				throw $err;
274
			}
275
			return $indexes;
276
		}
277
	}//end _parseArrayIndexes()
278
279
280
	/**
281
	 * Grammar rule to parse the use of array index.
282
	 *
283
	 * _parseArrayIndex ::= [<index>]
284
	 *
285
	 * @exception Exception raised if $strTokens starting from $strPtr
286
	 *                      doesn't matched the rule.
287
	 *
288
	 * @param array $strTokens Tokens to parse.
289
	 * @param int   $strPtr    Pointer to the token where parsing starts.
290
	 *
291
	 * @return string Index between the 2 square brackets
292
	 */
293
	private function _parseArrayIndex ($strTokens, &$strPtr)
294
	{
295
		if ('[' !== $strTokens[$strPtr]) {
296
			throw new Exception ('Expected [.');
297
		}
298
		$strPtr++;
299
		if (! in_array($strTokens[$strPtr][0], array(T_CONSTANT_ENCAPSED_STRING, T_LNUMBER))) {
300
			throw new Exception ('Expected an array index.');
301
		}
302
		$index = $strTokens[$strPtr][1];
303
		$strPtr++;
304
		if (']' !== $strTokens[$strPtr]) {
305
			throw new Exception ('Expected ].');
306
		}
307
		$strPtr++;
308
		return $index;
309
	}//end _parseArrayIndex()
310
311
}//end class
312
313
/**
314
 * CodeIgniter_Sniffs_Strings_VariableUsageSniff.
315
 *
316
 * Ensures that variables parsed in double-quoted strings are enclosed with
317
 * braces to prevent greedy token parsing.
318
 * Single-quoted strings don't parse variables, so there is no risk of greedy
319
 * token parsing.
320
 *
321
 * @category  PHP
322
 * @package   PHP_CodeSniffer
323
 * @author    Thomas Ernest <[email protected]>
324
 * @copyright 2011 Thomas Ernest
325
 * @license   http://thomas.ernest.fr/developement/php_cs/licence GNU General Public License
326
 * @link      http://pear.php.net/package/PHP_CodeSniffer
327
 */
328
class DoubleQuoteUsageSniff extends VariableUsageSniff
329
{
330
    /**
331
     * Returns an array of tokens this test wants to listen for.
332
     *
333
     * @return array
334
     */
335
    public function register()
336
    {
337
        return array(
338
            T_DOUBLE_QUOTED_STRING,
339
            T_CONSTANT_ENCAPSED_STRING,
340
        );
341
    }//end register()
342
343
    /**
344
     * Processes this test, when one of its tokens is encountered.
345
     *
346
     * @param File $phpcsFile The current file being scanned.
347
     * @param int                  $stackPtr  The position of the current token
348
     *                                        in the stack passed in $tokens.
349
     *
350
     * @return void
351
     */
352
    public function process(File $phpcsFile, $stackPtr)
353
    {
354
        // no variable are in the string from here
355
        $tokens = $phpcsFile->getTokens();
356
        $qtString = $tokens[$stackPtr]['content'];
357
        // makes sure that it is about a double quote string,
358
        // since variables are not parsed out of double quoted string
359
        $open_qt_str = substr($qtString, 0, 1);
360
361
        // clean the enclosing quotes
362
        $qtString = substr($qtString, 1, strlen($qtString) - 1 - 1);
363
364 View Code Duplication
        if (0 === strcmp($open_qt_str, '"')) {
0 ignored issues
show
This code seems to be duplicated across 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...
365
            $this->processDoubleQuotedString($phpcsFile, $stackPtr, $qtString);
366
        } else if (0 === strcmp($open_qt_str, "'")) {
367
            $this->processSingleQuotedString($phpcsFile, $stackPtr, $qtString);
368
        }
369
    }//end process()
370
371
372
    /**
373
     * Processes this test, when the token encountered is a double-quoted string.
374
     *
375
     * @param File $phpcsFile The current file being scanned.
376
     * @param int                  $stackPtr  The position of the current token
377
     *                                        in the stack passed in $tokens.
378
     * @param string               $qtString  The double-quoted string content,
379
     *                                        i.e. without quotes.
380
     *
381
     * @return void
382
     */
383
    protected function processDoubleQuotedString (File $phpcsFile, $stackPtr, $qtString)
384
    {
385
        // so there should be at least a single quote or a special char
386
        // if there are the 2 kinds of quote and no special char, then add a warning
387
        $has_variable = parent::processDoubleQuotedString($phpcsFile, $stackPtr, '"'.$qtString.'"');
388
        $has_specific_sequence = $this->_hasSpecificSequence($qtString);
389
        $dbl_qt_at = strpos($qtString, '"');
390
        $smpl_qt_at = strpos($qtString, "'");
391
        if (false === $has_variable && false === $has_specific_sequence
392
            && false === $smpl_qt_at
393
        ) {
394
            $error = 'Single-quoted strings should be used unless it contains variables, special chars like \n or single quotes.';
395
            $phpcsFile->addError($error, $stackPtr);
396 View Code Duplication
        } else if (false !== $smpl_qt_at && false !== $dbl_qt_at
0 ignored issues
show
This code seems to be duplicated across 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...
397
            && false === $has_variable && false === $has_specific_sequence
398
        ) {
399
            $warning = 'It is encouraged to use a single-quoted string, since it doesn\'t contain any variable nor special char though it mixes single and double quotes.';
400
            $phpcsFile->addWarning($warning, $stackPtr);
401
        }
402
    }//end processDoubleQuotedString()
403
404
405
    /**
406
     * Processes this test, when the token encountered is a single-quoted string.
407
     *
408
     * @param File $phpcsFile The current file being scanned.
409
     * @param int                  $stackPtr  The position of the current token
410
     *                                        in the stack passed in $tokens.
411
     * @param string               $qtString  The single-quoted string content,
412
     *                                        i.e. without quotes.
413
     *
414
     * @return void
415
     */
416
    protected function processSingleQuotedString (File $phpcsFile, $stackPtr, $qtString)
417
    {
418
        // if there is single quotes without additional double quotes,
419
        // then user is allowed to use double quote to avoid having to
420
        // escape single quotes. Don't add the warning, if an error was
421
        // already added, because a variable was found in a single-quoted
422
        // string.
423
        $has_variable = parent::processSingleQuotedString($phpcsFile, $stackPtr, "'".$qtString."'");
424
        $dbl_qt_at = strpos($qtString, '"');
425
        $smpl_qt_at = strpos($qtString, "'");
426 View Code Duplication
        if (false === $has_variable && false !== $smpl_qt_at && false === $dbl_qt_at) {
0 ignored issues
show
This code seems to be duplicated across 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...
427
            $warning = 'You may also use double-quoted strings if the string contains single quotes, so you do not have to use escape characters.';
428
            $phpcsFile->addWarning($warning, $stackPtr);
429
        }
430
    }//end processSingleQuotedString()
431
432
    /**
433
     * Return TRUE, if a sequence of chars that is parsed in a specific way
434
     * in double-quoted strings is found, FALSE otherwise.
435
     *
436
     * @param string $string String in which sequence of special chars will
437
     * be researched.
438
     *
439
     * @return TRUE, if a sequence of chars that is parsed in a specific way
440
     * in double-quoted strings is found, FALSE otherwise.
441
     *
442
     * @link http://www.php.net/manual/en/language.types.string.php#language.types.string.syntax.double
443
     */
444
    private function _hasSpecificSequence($string)
445
    {
446
        $hasSpecificSequence = FALSE;
447
        $specialMeaningStrs = array('\n', '\r', '\t', '\v', '\f');
448
        foreach ($specialMeaningStrs as $splStr) {
449
            if (FALSE !== strpos($string, $splStr)) {
450
                $hasSpecificSequence = TRUE;
451
            }
452
        }
453
        $specialMeaningPtrns = array('\[0-7]{1,3}', '\x[0-9A-Fa-f]{1,2}');
454
        foreach ($specialMeaningPtrns as $splPtrn) {
455
            if (1 === preg_match("/{$splPtrn}/", $string)) {
456
                $hasSpecificSequence = TRUE;
457
            }
458
        }
459
        return $hasSpecificSequence;
460
    }//end _hasSpecificSequence()
461
462
}//end class
463
464
?>
465