Static Analysis of PHP Code – IPC Berlin 2016

Post on 08-Jan-2017

458 views 6 download

Transcript of Static Analysis of PHP Code – IPC Berlin 2016

Static Analysis of PHP

Code

How the Heck did I write so many Bugs?

International PHP Conference Berlin, June 2016

By Rouven Weßling ( ) Ecosystem Developer / Developer Evangelist, Contentful

@RouvenWesslingphoto credit: by Achim Fischer Brandenburg Gate Berlin (license)

What is StaticAnalysis?

Analysing software withoutexecuting it.

Dynamic Analysisxdebug

xhprof

PHP Analyzer

PHP Vulnerability Hunter

Assertions

Why use StaticAnalysis?

Spend less time on unit tests...

...and code review

class ClientTest extends \PHPUnit_Framework_TestCase { public function testGetSynchronizationManager() { $client = new Client('b4c0n73n7fu1', 'cfexampleapi');

$this->assertInstanceOf(Manager::class, $client->getSynchronizationManager()); } }

Easy to integrate in ContinuousIntegration

Find issues that can not be foundthrough unit tests

PHP 7

Abstract Syntax TreeScalar TypesStrict Types

PHP is dynamic �ReflectionVariable variablesReferencing classes/functions/properties by string

The more static your code is, theeasier it's to reason about.

Some tools

phpmd phan phpcs phpunit phploc phpcpd phpsa php7cc

Coupling Detector Mondrian PHP

Assumption PhpCodeAnalyzer PHPCodeFixer php7mar PHP

Semantic Versioning Checker PHP Inspection PHP

lint PHP Depend PhpMetrics PHPCheckstyle PHP

Reaper PHP vuln hunter RIPS Parse SonarQube Side

Channel

Analyzer TaintPHP Deptrac PhpDependencyAnalysis PHP

semver checker

phpmd phan phpcs phpunit phploc phpcpd phpsa php7cc

Coupling Detector Mondrian PHP

Assumption PhpCodeAnalyzer PHPCodeFixer php7mar PHP

Semantic Versioning Checker PHP Inspection PHP

lint PHP Depend PhpMetrics PHPCheckstyle PHP

Reaper PHP vuln hunter RIPS Parse SonarQube Side

Channel

Analyzer TaintPHP Deptrac PhpDependencyAnalysis PHP

semver checker

phpmd phan phpcs phpunit phploc phpcpd phpsa php7cc

Coupling Detector Mondrian PHP

Assumption PhpCodeAnalyzer PHPCodeFixer php7mar PHP

Semantic Versioning Checker PHP Inspection PHP

lint PHP Depend PhpMetrics PHPCheckstyle PHP

Reaper PHP vuln hunter RIPS Parse SonarQube Side

Channel

Analyzer TaintPHP Deptrac PhpDependencyAnalysis PHP

semver checker

phpmd phan phpcs phpunit phploc phpcpd phpsa php7cc

Coupling Detector Mondrian PHP

Assumption PhpCodeAnalyzer PHPCodeFixer php7mar PHP

Semantic Versioning Checker PHP Inspection PHP

lint PHP Depend PhpMetrics PHPCheckstyle PHP

Reaper PHP vuln hunter RIPS Parse SonarQube Side

Channel

Analyzer TaintPHP Deptrac PhpDependencyAnalysis PHP

semver checker

phpmd phan phpcs phpunit phploc phpcpd phpsa php7cc

Coupling Detector Mondrian PHP

Assumption PhpCodeAnalyzer PHPCodeFixer php7mar PHP

Semantic Versioning Checker PHP Inspection PHP

lint PHP Depend PhpMetrics PHPCheckstyle PHP

Reaper PHP vuln hunter RIPS Parse SonarQube Side

Channel

Analyzer TaintPHP Deptrac PhpDependencyAnalysis PHP

semver checker

phpmd phan phpcs phpunit phploc phpcpd phpsa php7cc

Coupling Detector Mondrian PHP

Assumption PhpCodeAnalyzer PHPCodeFixer php7mar PHP

Semantic Versioning Checker PHP Inspection PHP

lint PHP Depend PhpMetrics PHPCheckstyle PHP

Reaper PHP vuln hunter Parse SonarQube Side

Channel

Analyzer TaintPHP Deptrac PhpDependencyAnalysis PHP

semver checker

phpmd phan phpcs phpunit phploc phpcpd phpsa php7cc

Coupling Detector Mondrian PHP

Assumption PhpCodeAnalyzer PHPCodeFixer php7mar PHP

Semantic Versioning Checker PHP Inspection PHP

lint PHP Depend PhpMetrics PHPCheckstyle PHP

Reaper PHP vuln hunter Parse SonarQube Side

Channel

Analyzer TaintPHP Deptrac PhpDependencyAnalysis PHP

semver checker

phpmd phan phpcs phpunit phploc phpcpd phpsa PHP

Coupling Detector Mondrian PHP

Assumption PhpCodeAnalyzer PHPCodeFixer php7mar PHP

Semantic Versioning Checker PHP Inspection PHP

lint PHP Depend PhpMetrics PHPCheckstyle PHP

Reaper PHP vuln hunter Parse SonarQube Side

Channel

Analyzer TaintPHP Deptrac PhpDependencyAnalysis PHP

semver checker

PHP lint

php -l

Compiles PHP script with the actual PHP compiler

It's already installed on your computer

Can be used to test compatibility with multiple PHP

versions

<?php

namespace Contentful\Log

use Psr\Http\Message\RequestInterface;

use Psr\Http\Message\ResponseInterface;

class NullLogger implements LoggerInterface

{

public function getTimer()

{

return new NullTimer;

}

public function log($api, RequestInterface $request, StandardTimer $timer, ResponseInterface $response = null, \Exception $exception = null)

{

}

}

PHP 7.0.3 | 10 parallel jobs

.................................X...... 40/40 (100 %)

Checked 40 files in 0.5 seconds

Syntax error found in 1 file

------------------------------------------------------------

Parse error: src/Log/NullLogger.php:9

7| namespace Contentful\Log

8|

> 9| use Psr\Http\Message\RequestInterface;

10| use Psr\Http\Message\ResponseInterface;

11|

Unexpected 'use' (T_USE), expecting '{'

Make your life easierUse PHP-Parallel-Lint

Deptrac

Software has layersThere should be rules about those layersRules are easily broken

1. Define the layers of your architecture2. Define what layers another layer can access3. Profit!!!

layers: - name: Controller collectors: - type: className regex: .*Controller.* - name: Entity collectors: - type: className regex: AstaRwth\\VorkursticketBundle\\Entity\\.*

ruleset: Controller: - Service - Entity - Form Service: - Repository Command: - Entity Entity: - Validator

How it works

Parses all files in your codeStores which classes access which others classesChecks the graph for rule violations

deptrac is alpha, not production ready.

please help us and report feedback / bugs.

Start to create an AstMap for 24 Files.

........................

AstMap created.

start emitting dependencies "InheritanceDependencyEmitter"

start emitting dependencies "BasicDependencyEmitter"

end emitting dependencies

start flatten dependencies

end flatten dependencies

collecting violations.

formatting dependencies.

[...]\Services\PdfOrder::5 must not depend on [...]\Entity\Vorkursticket (Service on Entity)

[...]\Services\PdfOrder::23 must not depend on [...]\Entity\Vorkursticket (Service on Entity)

Found 2 Violations

phan

Type safety for PHP

Checks docblocks

Signature mismatches

Unused code

How it works

Makes 2 passes over the codebase1. Build a list of all classes, functions, methods, etc.2. Go trough each function and follow the type ofeach variable

/** * @param Locale|string|null $locale * * @return string */ public function getDescription($locale = null) { $localeCode = $this->getLocaleFromInput($locale);

// This checks happens after the call to getLocaleFromInput to make sure // the Exception for invalid locales is still thrown. if ($this->description === null) { return null; }

return $this->description->$localeCode; }

src/Delivery/Asset.php:74 PhanTypeMismatchReturn Returning type null but getDescription() is declared to return string

class ContentType { /** * The fields, keyed by ID. * * @var object */ private $fields = []; }

src/Delivery/ContentType.php:34 PhanTypeMismatchProperty Assigning array to property but \contentful\delivery\contenttype::fields is object

public function __call($name, $arguments) { // Lots of code here

if ($result instanceof Link) { return $client->resolveLink($result); }

return array_map(function ($value) use ($client) { if ($value instanceof Link) { return $client->resolveLink($value); }

return $value; }, $result); }

src/Delivery/DynamicEntry.php:126 PhanTypeMismatchArgumentInternal Argument 2 (input1) is \contentful\delivery\link but \array_map() takes array

Not a bug

Not a bug

Don't trust blindly

Bad news?Requires php-astNot easy to deal with library codeNoisy - not easily integrated in CI.

The future

phan is using brute force for type checkingRoughly as good as the compiler for a staticallytyped languageWorks, but a Control Flow Graph could give evendeeper insight

int foo(int length) { int x = 0; for (int i = 0; i < length; i++) x += 1

return length/x; }

Bottom lineThere are dozens of tools - pick what's necessary foryouMake them part of your Continuous Integration setupNever trust. Make sure you understand where theerror is coming from.

Slides available on Slideshare:http://www.slideshare.net/rwessling/static-analysis-of-

php-code-ipc-berlin-2016