分析不安全代码片段代码的好工具是什么?

时间:2011-02-28 10:00:38

标签: php code-analysis

我正在寻找一些可以对PHP脚本进行基本测试的工具。

这次我对复杂的测试解决方案不感兴趣,它需要为每一段代码编写测试。我对功能测试既不感兴趣。

我希望这个工具能够指出可能导致无效使用的代码片段:

  1. 变量;
  2. 函数参数;
  3. 函数返回值。
  4. 无效的用法是,例如,使用NULL作为对象或数组,或者将boolean传递为需要作为数组或对象(或NULL)的arguent。

    此外,它还可能会检查是否使用了“良好做法”,即它可能会警告使用if ( $condition ) $doSomething;是不安全的,如果它找到类似的东西。


    为了说明该工具应该检测为“不安全”的代码片段,这里有几个例子。

    在这种情况下,$filter可能是NULL,但它用作数组:

    <?php
        function getList(array $filter = null) { 
            $sql = '...';
            // ...
            foreach ( $filter as $field => $value ) {
                // ...
            }
            // ...
        }
    

    在这种情况下,$res可能是false,但它被用作resource

    <?php
        $res = mysql_query('...');
        while ( $row = mysql_fetch_assoc($res) ) {
            // ...
        }
        mysql_free_result($res);
    

    这里是相应的“安全”代码片段:

    // $filter is used only if it's non-empty; as list of arguments describes, it may be only NULL or array
    function getList(array $filter = null) { 
        $sql = '...';
        // ...
        if ( $filter ) {
            foreach ( $filter as $field => $value ) {
                // ...
            }
        }
        // ...
    }
    

    ...

    // $filter is forced to be an array
    function getList(array $filter = null) { 
        $filter = (array)$filter;
        $sql = '...';
        // ...
        foreach ( $filter as $field => $value ) {
            // ...
        }
        // ...
    }
    

    ...

    // if $res is false, mysql_fetch_assoc() and mysql_free_result() never executes
    $res = mysql_query('...');
    if ( $res === false ) {
        trigger_error('...');
        return;
    }
    while ( $row = mysql_fetch_assoc($res) ) {
        // ...
    }
    mysql_free_result($res);
    

    ...

    // if $res is false, mysql_fetch_assoc() and mysql_free_result() are skipped
    $res = mysql_query('...');
    if ( $res !== false ) {
        while ( $row = mysql_fetch_assoc($res) ) {
            // ...
        }
        mysql_free_result($res);
    }
    

3 个答案:

答案 0 :(得分:8)

这不是基本测试,但需要对令牌流进行非平凡的分析。

您可以使用

phpmd

  

扫描PHP源代码并查找潜在的问题,例如可能的错误,死代码,次优代码和过于复杂的表达式

phpcs

  

phpcs标记PHP,JavaScript和CSS文件,并检测违反一组已定义的编码标准。它是一种必不可少的开发工具,可确保您的代码保持清洁和一致。它还可以帮助防止开发人员出现一些常见的语义错误。

或 - 如果这还不够 - 用

查看字节码级别

bytekit-cli

  

bytekit-cli提供了一个命令行工具,它利用Bytekit扩展在PHP字节码级别上执行常见的代码分析任务。

你必须为此写自己的嗅觉。

更多工具和资源:

答案 1 :(得分:2)

一个好的IDE应该指出基本错误作为开发过程的一部分。

例如,我使用Netbeans,它突出显示常见的代码错误,例如定义但未使用的变量,或在if()条件中错误使用赋值运算符,其中等于运算符更正常(即写{ {1}}代替if($x = $y))。

这样的基本内容显示在Netbeans中,行号为黄色警告三角形。其他IDE将具有类似的功能。

我认为它没有找到你描述的特定错误条件,但它肯定会收集到相当多的错误,即使对于你所谈到的错误,这也是我希望这些事情发生的地方。标记,而不是单独的工具。

答案 2 :(得分:2)

您想要的是传统上称为静态分析工具。这些工具经常做什么, 确定代码中的每个点,它知道变量有哪些事实 (在X = NULL之后,工具知道X为NULL),然后沿着各种控制流路径传播它所知道的内容,以查看变量的状态是否与操作不一致(例如,在发现X为null之后,查找代码必须执行的尝试将X作为数组进行访问。)

要做到这一点,你需要一个完整的PHP解析器,生成AST,符号表至少告诉你PHP变量的范围,一些确定控制和数据流的方法,以及这组信息的一系列模式检测各种编码错误。

PHP的一个这样的工具是PHPSat。它似乎做了一些,你可以下载一个运行它(我没有具体经验)。构建它的技术Stratego至少适合于这项任务; Stratego可以生成AST并可以从中收集各种地方的事实,尽管我认为它并不擅长控制和数据流。这与只能访问PHP令牌的工具形成对比,例如在另一个答案中提到的PHPCS;来自令牌的计算控制和数据流是一场噩梦,实际上它根本无法完成。

正确的机器似乎隐藏在Paul Biggar的thesis中。我似乎无法找到任何人提到这一点的暗示并将其用作静态分析仪的基础。