static analysis saved my code tonight

36
STATIC ANALYSIS SAVED MY CODE TONIGHT PHP UK, LONDON, FEBRUARY 2017.

Upload: damien-seguy-

Post on 11-Apr-2017

61 views

Category:

Technology


2 download

TRANSCRIPT

Page 1: Static analysis saved my code tonight

STATIC ANALYSIS SAVED MY CODE TONIGHT

PHP UK, LONDON, FEBRUARY 2017.

Page 2: Static analysis saved my code tonight

PHPUK 2017

AGENDA

‣ Under the hood of a static analyzer

‣ What can analyzers do for you

‣ Adopt them now!

Page 3: Static analysis saved my code tonight

‣ Damien Seguy

‣ CTO at exakat

‣ Static code analysis for PHP

‣ Retiring house for oldest elephpant

PHPUK 2017

SPEAKER

Elephpant in the death valley

Page 4: Static analysis saved my code tonight

‣ 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?

Page 5: Static analysis saved my code tonight

PHPUK 2017

STATIC ANALYSIS IS AN EXTRA STEP

EXECUTION

TEXT FILE

OPCODE

CODING CONVENTIONS

Page 6: Static analysis saved my code tonight

PHPUK 2017

STATIC ANALYSIS IS AN EXTRA STEP

EXECUTION

TEXT FILE

OPCODE STATIC ANALYSIS

Page 7: Static analysis saved my code tonight

OPCODE

PHPUK 2017

STATIC ANALYSIS IS AN EXTRA STEP

EXECUTION

TEXT FILE

STATIC ANALYSIS

Page 8: Static analysis saved my code tonight

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

Page 9: Static analysis saved my code tonight

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;    }   

Page 10: Static analysis saved my code tonight

PHPUK 2017

STATIC ANALYSIS UNDER THE HOOD

PHP 5 / 7 Calisthenics ClearPHP Performance Metrics Couplings

Page 11: Static analysis saved my code tonight

PHPUK 2017

PHP TOKENS [248] => Array ( [0] => 382 [1] => [2] => 167 )

[249] => Array ( [0] => 319 [1] => define [2] => 167 )

[250] => ( [251] => Array ( [0] => 323 [1] => 'EXT' [2] => 167 )

[252] => , [253] => Array ( [0] => 382 [1] => [2] => 167 )

‣ Comments, Doc, whitespace

‣ Delimiters : " () {} [] `

‣ 2/3 of the tokens are removed

<?php //....     define('EXT', '.php');

Page 12: Static analysis saved my code tonight

PHPUK 2017

AST

‣ PHP 7.0 : ext/ast

‣ nikic/php-parser

Page 13: Static analysis saved my code tonight

PHPUK 2017

AST

<?php

class Foo {     function bar($arg) {         return \StrToUpper($arg + 2);     } }

$foo = new Foo(); $foo->bar(__FILE__);

Page 14: Static analysis saved my code tonight

TEXTE

<?php     $x = source();          if ($x < 10) {         $y = $x + 1;         $x = corrige($y);     } else {         $y = $x;     }

FLOW CONTROL

Page 15: Static analysis saved my code tonight

TEXTE

FLOW CONTROL GRAPH

$x = source();

if ($x < 10) 

$y = $x + 1;

$x = corrige($y);

$y = $x;

PHP

Exit

ElseThen

<?php     $x = source();          if ($x < 10) {         $y = $x + 1;         $x = corrige($y);     } else {         $y = $x;     }

Page 16: Static analysis saved my code tonight

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;     }

Page 17: Static analysis saved my code tonight

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

Page 18: Static analysis saved my code tonight

PHPUK 2017

STATIC ANALYSIS TOOLS

▸ Migration tools

▸ Code quality

▸ Security tools

▸ Metrics

▸ Inventories

Page 19: Static analysis saved my code tonight

PHPUK 2017

MIGRATION TOOLS

‣ Exakat

‣ php7mar

‣ php7cc

Page 20: Static analysis saved my code tonight

EXAKAT REPORT FOR PHP 7.2 COMPATIBILITY

Page 21: Static analysis saved my code tonight

PHPUK 2017

CODE QUALITY

‣ PHPstan

‣ Phan

‣ Psalm

‣ Exakat

Page 22: Static analysis saved my code tonight

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

Page 23: Static analysis saved my code tonight

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

Page 24: Static analysis saved my code tonight

PSECIO REPORT55) 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("danger", _("Invalid widget"), true); }

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/import.csv') or die ($this->Result->show("danger", _('Cannot open 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: ".create_link("error","400")); die(); }

For more information execute 'psecio-parse rules SetHeaderWithInput'

Page 25: Static analysis saved my code tonight

PHPUK 2017

METRICS

‣ PHP Metrics

‣ PHP MD

‣ PHP LOC

Page 26: Static analysis saved my code tonight

PHPMETRICS REPORT

Page 27: Static analysis saved my code tonight

PHPMETRICS REPORT

Page 28: Static analysis saved my code tonight

PHPUK 2017

INVENTORIES

‣ Collection of names, literals, features

‣ Magic number syndrome

‣ PHP compilation directives

‣ Error messages check

‣ Spelling, consistency…

‣ Exakat

Page 29: Static analysis saved my code tonight

INVENTORY REPORT

Page 30: Static analysis saved my code tonight

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] --with-openssl[=DIR]

; Duration of time (in seconds) for which to cache realpath information for a ; given file or directory. If the application's code doesn't change too often, you ; 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 value as low ; 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 recommended to set ; 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 request. It ; has to be higher or equal to upload_max_filesize. For security reasons, it ; should be as low as possible, to prevent PHP using too much memory. post_max_size = 2M

PHP DIRECTIVES CHECKLIST

Page 31: Static analysis saved my code tonight

PHPUK 2017

OTHER USAGE

▸ Dependency graph

▸ Namespaces graph

▸ Deptrack

▸ Taint analysis

Page 32: Static analysis saved my code tonight
Page 33: Static analysis saved my code tonight

PHPUK 2017

WRITE YOUR OWN STATIC ANALYSER

▸ ext/ast : Access the internal AST

▸ nikic/php-parser : for PHP 7

▸ BetterReflection

▸ Fork an existing tool

▸ Use regex

Page 34: Static analysis saved my code tonight

PHPUK 2017

MORE IDEAS

▸ Static analysis for frameworks

▸ Class diagram extractors

▸ Definition / usage paradigm

▸ More coding references

▸ East-programming, SOLID

▸ ~40% of PHP code is static

Page 35: Static analysis saved my code tonight

TEXTE

NEVER CODE ALONE AGAIN

▸ Use experience from others

▸ Use some one else point of view

▸ Prepare for the future

▸ Learn, Find, Capitalize

Page 36: Static analysis saved my code tonight

THANKS

@EXAKAT / EXAKAT.IO