Transcript
Page 1: Automated code audits

Automatic code audits

Rotterdam, Nederland, October 9th 010PHP

Page 2: Automated code audits

Definition

A kind of code analysis where the code is reviewed without running it.

Just like we would do ourselves!

Page 3: Automated code audits

Who is speaking?

Damien Seguy

CTO at exakat

Phather of the plush toy elePHPant

Back from China

Stepping up automated code audit services

Page 4: Automated code audits
Page 5: Automated code audits

Internals

Code

Analyze Report

AST

Page 6: Automated code audits
Page 7: Automated code audits

<?php!function x($a) {         return $a;} x(1, 2); ?>

Page 8: Automated code audits

Found

Dead code

Undefined structures

Unused structures

Illogical exp.

Slow code

Bad practices

Unsafe code

Maintainability

Bug issue

Ancient style

Uninitialized vars

Taint propagation

Page 9: Automated code audits

<?phpswitch ($this->consume()){     case "\x09":    case "\x0A":    case "\x0B":    case "\x0B":    case "\x0C":    case "\x20":    case "\x3C":    case "\x26":    case false:        break;    case "\x23":        switch ($this->consume())        {            case "\x78":            case "\x58":                $range = '0123456789ABCDEFabcdef';                $hex = true;                break;        }    }{?>

Page 10: Automated code audits

    protected function openString($end, &$out=null, $nestingOpen, $rejectStrs = null) {         $nestingLevel = $count = 0;        $content = array();        while ($this->match($patt, $m, false)) {             $tok = $m[2];            if ($tok == "@{" && $this->interpolation($inter)) {                 $content[] = $inter;                continue;            }            if (!empty($rejectStrs) && in_array($tok, $rejectStrs)) {                 $ount = null;                break;            }            $content[] = $tok;            $count += strlen($tok);        }        $this->eatWhiteDefault = $oldWhite;        if (count($content) == 0) return false;        $out = array("string", "", $content);        return true;    }

Page 11: Automated code audits

Spot bugs early

Code Test PreProd Production

Run it at commit Run it as audit

Page 12: Automated code audits

Static audit vs Unit test

No running

100% of the code

Symbolic testing

Little configuration

Has false positive

Mostly internal

Needs dedicated servers

Will only scan a part

Test only provided data

Write scenario

Has false negative

Can be handed to users

Page 13: Automated code audits

When does it help

Help port to a new system

Search for weak code fragments

Audit external libraries

Hint at refactoring

Page 14: Automated code audits

Report

Bugs

Useless code

Suggestions

Page 15: Automated code audits

Bugs

<?php !!  if($content = file_get_contents($file))    {        $content = trim($content);        $content = substr($content, -2) == '?>' ? substr($content, 0, -2) : $content;    } ! return true;!?> !

Page 16: Automated code audits

Useless code<?php!!// inside a legit class $this->module->xmlRequest;$_G['setting']['debug'];$post['usesig'] ? ($_G['setting']['sigviewcond'] ?  (strlen($post['message']) > $_G['setting']['sigviewcond'] ?!! ! ! !  $post['signature'] : '') !! ! ! ! ! : $post['signature']) : '';?> !

Page 17: Automated code audits

Suggestions

<?php !// Nested ternary should be turned into if then structures     $operation == 'ENCODE' ? sprintf('%010d', $expiry ? $expiry + time( ) : 0) . substr(md5($string . $egiskeys), 0, 16) . $string : base64_decode(substr($string, $key_length))    // Multiply by one is useless     SetCache($prefix, $key, $row, 60*60*1);

// Portable syntax     $bits = split('.', $string);    $y = $bits[0];     ! // Modern syntax     $y = split('.', $string)[0];?> !

Page 18: Automated code audits

Where it doesn’t help

Unit tests

Architecture

Old traditions that won’t change

Semantic errors

Page 19: Automated code audits

Architecture

No framework context

Conception is done before coding

Of course!

Static audit will report standards, not norms

Page 20: Automated code audits

Old traditions

<?php    $pna = explode(')(', $pn);    while (list($k, $v) = each($pna)) {        $lst = explode('"', $v);        if (isset($lst[3])) {            $pn[$lst[1]] = $lst[3];        } else {            $pn[$lst[1]] = '';        }    } ?>

10 % of current applications uses this instead of foreach()

Page 21: Automated code audits

Semantic errors

<?php     $babycarriage = new carriage();     $wheel1 = new Racingwheel();     $wheel2 = new Racingwheel();     $wheel3 = new Racingwheel();     $wheel4 = new Rhinoceros();         $babycarriage->installWheels($wheel1, ## # # # # # # # # # # # $wheel2, ## # # # # # # # # # $wheel3, ## # # # # # # # # # $wheel4);     ?>

Undefined classes : Vehicle, Racingwheel, Rhinoceros

Page 22: Automated code audits

Semantic errors

Page 23: Automated code audits

Available analyzers

PHP code sniffer

PHP MD

Scrutinizer-ci

Fortify

insight from Sensio

Page 25: Automated code audits

THE END

http://010php.nl/

http://www.meetup.com/010PHP/


Top Related