Static analysis tools checks PHP code without running them. Fully automated, they bring expertise to review the code, enforce good practices when programming, keep code ready for the next PHP version. PHP 7 has developed tremendously our capacity to audit code - thanks to AST and return types, it is possible to go deeper and prevent more bugs. During this session, we'll review the current state of static analysis tools, learn what they can find for us, and how to integrate it in the development cycle - security bugs, migration incompatibilities, directives recommendations. Simply said, better PHP coding.
2. PHPUK 2017
AGENDA
‣ Under the hood of a static analyzer
‣ What can analyzers do for you
‣ Adopt them now!
3. ‣ Damien Seguy
‣ CTO at exakat
‣ Static code analysis for PHP
‣ Retiring house for oldest
elephpant
PHPUK 2017
SPEAKER
Elephpant in the death valley
4. ‣ IS IT FAST?
‣ IS THIS BACKWARD COMPATIBLE?
‣ IS THIS SECURE? ‣ IS THIS COMPATIBLE WITH PHP 7?
‣ SHOULD I USE ++$I OR ARRAY_MERGE_RECURSIVE() ?
‣ IS IT TIME FOR LUNCH ?
‣ WHY NOT USE A FRAMEWORK?
8. PHPUK 2017
SWITCH STATEMENTS MAY ONLY CONTAIN ONE DEFAULT CLAUSE
<?php
switch($x) {
case '1' :
break;
default :
break;
default :
break;
case '2' :
break;
}
PHP Lint
9. PHPUK 2017
SWITCH STATEMENTS MAY ONLY CONTAIN ONE DEFAULT CLAUSE
switch($x) {
case 1 :
break;
case 0+1 :
break;
case '1' :
break;
case true :
break;
case 1.0 :
break;
case $y :
break;
}
16. PHPUK 2017
PROGRAM DEPENDENCY GRAPH
$x = source();
if ($x < 10)
$y = $x + 1;
$x = corrige($y);
$y = $x;
Depend de $x
Depend de $x
Depend de $y
Depend de $x
Depend de $x
Depend de $x
<?php
$x = source();
if ($x < 10) {
$y = $x + 1;
$x = corrige($y);
} else {
$y = $x;
}
17. PHPUK 2017
PHP AS A CODE DATABASE
‣ Source code is a highly organized dataset
‣ We need a way to query it
‣ There are over 68 static analysis tools for PHP
‣ https://github.com/exakat/php-static-analysis-tools
22. PHPSTAN REPORT
------ ---------------------------------------------
Line code/functions/scripts/pingCheck.php
------ ---------------------------------------------
362 Instantiated class phpipam_mail not found.
415 Function create_link not found.
446 Catched class phpmailerException not found.
------ ------------------------------------
Line code/index.php
------ ------------------------------------
228 Undefined variable: $heredoc
------ ----------------------------------------
Line library/Exakat/Tasks/Files.php
------ ----------------------------------------
197 Undefined variable: $toRemoveFromFiles
------ ------------------------------------------------
Line code/functions/scripts/resolveIPaddresses.php
------ ------------------------------------------------
236 Undefined variable: $returnPath
[ERROR] Found 1846 errors
23. PHPUK 2017
SECURITY TOOLS
‣ psecio:parse
‣ php vuln hunter
‣ RIPS 0.5 / Ripstech saas
$x = source();
if ($x < 10)
$y = $x + 1;
$x = corrige($y);
$y = $x;
Depend de $x
Depend de $x
Depend de $y
Depend de $x
Depend de $x
Depend de $x
24. PSECIO REPORT
55) projects/phpipam/code/app/dashboard/widgets/inactive-hosts.php on line 40
Avoid the use of $_REQUEST (know where your data comes from)
> if(!$widget = $Tools->fetch_object ("widgets", "wfile", $_REQUEST['section'])) { $Result->show(
For more information execute 'psecio-parse rules RequestUse'
296) functions/classes/class.Tools.php on line 2762
Avoid the use of `exit` or `die` with strings as it could lead to injection issues (direct output)
> $outFile = file_get_contents(dirname(__FILE__) . '/../../app/subnets/import-subnet/upload/i
upload/import.csv'), true));
For more information execute 'psecio-parse rules ExitOrDie'
448) index.php on line 284
'header()' calls should not use concatenation directly
> if (!in_array($_GET['section'], $tools_menu_items)) { header("Location:
For more information execute 'psecio-parse rules SetHeaderWithInput'
30. PHP COMPILE SCRIPT
;;;;;;;;;;;;;;;;;;;;;;;;
; PHP configure list ;
;;;;;;;;;;;;;;;;;;;;;;;;
./configure
--with-apxs2
--enable-bcmath
--with-curl=DIR
--disable-dom
--enable-exif
--disable-fileinfo
--with-gd
--with-jpeg-dir=DIR
--with-png-dir=DIR
--with-xpm-dir=DIR
--with-vpx-dir=DIR
--with-freetype-dir=DIR
--enable-gd-native-ttf
--with-gettext=DIR
--with-gmp
--with-ldap[=DIR]
--with-ldap-sasl[=DIR]
--disable-libxml
--enable-mbstring
--with-libmbfl=DIR
--enable-mbstr-enc-trans
--disable-mbregex
--with-mcrypt=[DIR]
; Duration of time (in seconds) for which to cache realpath information
; given file or directory. If the application's code doesn't change too o
; may set this directive to 3600 (one hour) or even more.
realpath_cache_ttl = 3600
; More information about file :
;http://php.net/manual/en/filesystem.configuration.php
[File Upload]
; This is the maximum uploaded size. It is recommended to keep this
; as possible.
upload_max_filesize = 2M
; This is the maximum number of uploaded files in a single request.
max_file_uploads = 1
; Upload directory where PHP stores the temporary files. It is recomm
; this value, and separate it from other temporary directories.
upload_tmp_dir = /tmp/php_upload
; This is the maximum amount of data that PHP will accept in a POST r
; has to be higher or equal to upload_max_filesize. For security reason
; should be as low as possible, to prevent PHP using too much memo
post_max_size = 2M
PHP DIRECTIVES CHECKLIST