Static code analysis in PHP (and GitLab)

Jan 12, 2020 by Thibault Debatty | 5921 views

PHP GitLab Secure Software Development

https://cylab.be/blog/51/static-code-analysis-in-php-and-gitlab

In the PHP toolbox for testing, you'll often find phpunit for unit testing, PHP_CodeSniffer for code style analysis, and here we present PHPStan for static code analysis.

Static code analysis tries to detect bugs by analyzing the source code of a program, without actually running it. At the opposite of PHPUnit, you don't need to write tests for your app.

In my opinion, static code analysis is particularly useful for an interpreted language like PHP, as it allows to detect "compile" errors in edge cases that are not covered by a unit test.

In the example below, PHPStan will immediately detect the missing `````` in front of Exception(...). With PHPUnit this would require an additional test to cover this single line of code:

namespace App;

class Foe
{
    public function bar() {
        $r = $this->doSomething();
        if ($r == null) {
            throw new Exception("Failed to do something...");
        }
    }
}

Installation and usage

PHPStan is best installed with composer:

composer require --dev phpstan/phpstan

You can run PHPStan directly from the command line, by using the command analyze and listing the directories to process:

vendor/bin/phpstan analyse src tests

However, it's easier to create a configuration file called phpstan.neon so you can omit the list of directories:

includes:
parameters:
  level: 1
  paths:
    - src
    - tests
  excludes_analyse:
  ignoreErrors:
  reportUnmatchedIgnoredErrors: false

The configuration file uses neon syntax, which is actually very similar to YAML.

Levels

As you can see in the configuration file, PHPStan has a configurable level for the analysis. In a nutshell, here is what each level will check:

  • level 0 : parse errors
  • level 1 : undefined variables
  • level 2 : correct type hints (but does not enforce the presence of type hints, see level 6)
  • level 3 : correct type of return values
  • level 4 : comparisons
  • level 5 : correct type of method parameters
  • level 6 : presence of type hints
  • level 7 : null returned values

The complete list of tests for each level is available on the GitHub page of PHPStan.

Integration in GitLab

To run phpstan at each push to GitLab, simply add this job to your .gitlab-ci.yml:

test:phpstan:
  image: cylab/php72
  before_script:
    - COMPOSER_CACHE_DIR=composer-cache composer install
  script:
    - vendor/bin/phpstan analyse

Additional rules

It is also possible to run additional rules in PHPStan. For example, to check for deprecated classes and methods, simply install the appropriate package:

composer require --dev phpstan/phpstan-deprecation-rules

Then add the rules to the includes section of your phpstan.neon:

includes:
    - vendor/phpstan/phpstan-deprecation-rules/rules.neon

PHPDoc

PHPStan takes advante of PHPDoc type annotations to derive parameters and return types. For example:

    /**
     * @param string $name
     * @return void
     */
    public function sayHello($name)
    {
    }

Here are the most common PHPDoc types:

  • int, integer
  • string
  • array-key
  • bool, boolean
  • true, false
  • null
  • float, double, scalar
  • array
  • iterable
  • callable
  • resource
  • void
  • object

Any class or interface can be used as a PHPDoc type. Finally, you can define the type as an array of other type:

  • Type[]
  • array<Type>
  • array<int, Type>
  • non-empty-array<Type>
  • non-empty-array<int, Type>

You can find the full list of PHPStan: https://phpstan.org/writing-php-code/phpdoc-types

Fully customizable emails using Laravel 9
With the release of Laravel 9, the Swift Mailer (that is no longer maintained) has been replaced by the Symfony Mailer. You can already find some useful information about this change along all the other ones in the Upgrade Guide from Laravel 8.x to 9.0. However this guide does not contain enough information if you want to send fully customized emails. This blog post proposes you a solution coming directly from the Symfony documentation!
SQL injection with SQLMap
Code injection is one of the most critical web application vulnerabilities. Indeed, the consequences of code injection can be dramatic (impact). Moreover, still today a lot of web applications are vulnerable to code injection (frequency). Finally, some tools like SQLMap allow to automatically detect and use these vulnerabilities (exploitation). For this reason, the vulnerability is listed in the top 10 published by the Open Web Application Security Project (OWASP) [1]. In this blog post, we will present one type of code injection, called SQL injection, and we will show how to perform a SQL injection attack with SQLMap.
Filter USB devices with udev (and some PHP code)
USB devices can be a liability : they can be used to exfiltrate data from a computer or server, to plug a hardware keylogger, or to plant a malware. Hence on a managed computer, USB devices should be filtered and whitelisted. In this blog post we show how this can be achieved thanks to udev, and some PHP code.
This website uses cookies. More information about the use of cookies is available in the cookies policy.
Accept