Press "Enter" to skip to content

Taint-0.3.0(A XSS codes sniffer) released

最近几天忙里偷闲, 一直在完善taint, 今天我觉得终于算做到了80%的满意了, 根据80:20原则, 我觉得可以做为一个里程碑的版本了 :).

什么是Taint? An extension used for detecting XSS codes(tainted string), And also can be used to spot sql injection vulnerabilities, shell inject, etc.

经过我实际测试, Taint-0.3.0能检测出实际的一些开源产品的(别问是什么)隐藏的XSS code, SQL注入, Shell注入等漏洞, 并且这些漏洞如果要用静态分析工具去排查, 将会非常困难, 比如对于如下的例子:

<?php
   $name = $_GET["name"];
   $value = strval($_GET["tainted"]);

   echo $$name;

对于请求:

http://****.com/?name=value&tainted=xxx

静态分析工具, 往往无能为力, 而Taint却可以准确无误的爆出这类型问题.

Warning: main() [function.echo]:
     Attempt to echo a string that might be tainted in %s.php on line %d

现在0.3.0已经发布, 我想短时间内, 我不会再添加新功能了. enjoy, PHP Taint.

另外, 多说一句, Taint可以说是, 我完成的扩展中最为复杂的一个, 使用了各种tricky技巧, 大家如果有兴趣做扩展开发, 可以用来作为一个很好的高级教材.

附录:

A. Tainted String

所有来自$_GET, $_POST, $_COOKIE的变量, 都被认为是Tainted String

B. taint检测的函数/语句列表, 当这些函数使用tainted string参数的时候, taint会给出警告:

1. 输出函数/语句系列

echo
print
printf
file_put_contents

2. 文件系统函数

fopen
opendir
basename
dirname
file
pathinfo

3. 数据库系列函数/方法

mysql_query
mysqli_query
sqlite_query
sqlite_single_query
oci_parse
Mysqli::query
SqliteDataBase::query
SqliteDataBase::SingleQuery
PDO::query
PDO::prepare

4. 命令行系列

system
exec
proc_open
passthru
shell_exec

5. 语法结构

eval
include(_once)
require(_once)

C. 消除tainted信息的函数, 调用这些函数以后, tainted string就会变成合法的string:

escapeshellcmd
htmlspecialchars
escapeshellcmd
addcslashes
addslashes
mysqli_escape_string
mysql_real_escape_string
mysql_escape_string
sqlite_escape_string
PDO::quote
Mysqli::escape_string
Mysql::real_escape_string

D. 调用中保持tainted信息的函数/语句, 调用这些函数/语句时, 如果输入是tainted string, 则输出也为tainted string:

= (assign)
. (concat)
"{$var}" (variable substitution)
.= (assign concat)
strval
explode
implode
sprintf
vsprintf
trim(as of 0.4.0)
rtrim(as of 0.4.0)
ltrim(as of 0.4.0)

E. 链接:

70 Comments

  1. mruse
    mruse 2013-06-16

    @laruence,我在安装的时候编译过程没有出错,是php+nginx环境的,编辑完成,重启php-fpm后报以下错误,可能是什么问题呢?google了一下貌似没有跟我的情况类似的,求指点

    版本:
    php5.2.14
    zend v3.3.9

  2. yliang_1987
    yliang_1987 2013-05-10

    是不是说这个 扩展 就是为了防止 在代码中出现有 打印url参数啊?

  3. grom
    grom 2013-04-21

    $_GET[‘a’]的值被过滤了

    <script>alert(1);</script>

  4. grom
    grom 2013-04-21

    centos 6.3 + php 5.4.12 下测试
    $_GET[‘a’]的值为alert(1);
    然后我调用addslashes,然后echo,正确弹出对话框,另外is_tainted返回 false。

  5. allen
    allen 2013-02-07

    PHP Version 5.4.11-1~precise+1
    Ubuntu 12.04

    编译过程无错误, 加载扩展时报以下错误

    PHP Warning: PHP Startup: Unable to load dynamic library ‘/usr/lib/php5/20100525+lfs/taint.so’ – /usr/lib/php5/20100525+lfs/taint.so: undefined symbol: MAKE_REAL_ZVAL_PTR in Unknown on line 0

    请问这个怎么解决?

  6. little
    little 2012-11-21

    不同的场合也许会用 htmlentities、urlencode、urlrawencode、http_build_query 这些

  7. 闪电客
    闪电客 2012-08-05

    不错哦!!加油改进

  8. chenggang
    chenggang 2012-06-15

    这种似乎抓不出来:
    $a = $_GET[‘name’];
    $arr[‘key’] = $a;
    extract($arr);
    echo $key;

  9. WPS2000
    WPS2000 2012-05-21

    这个相当的不错,试着在公司推行安装了。还没发现它提示出错,当然,这是对我们之前工作的肯定。
    我编译的windows 版本放在这里 http://82.165.131.79/php_taint.dll ,5.3系列,VC9的,有需要的可以尝尝鲜
    另外,博主能否让这个扩展默认就 enable?而不是需要到 配置文件里去通过配置 taint.enable 启用?

  10. virgins
    virgins 2012-05-13

    我觉得这个网站的内容真心好

  11. shirne
    shirne 2012-05-09

    但是,我还是想问问,是什么–!

  12. liut
    liut 2012-04-16

    请问有没有编译好win32 dll,我本人用mac,但组员大部分用windows

  13. skybyte
    skybyte 2012-04-11

    这个不能记录日志到文件啊,我这样设置日志里面没得
    error_reporting = E_ALL & ~E_NOTICE
    error_log=php.log
    display_errors=Off

    改成display_errors=on就直接显示到浏览器了

  14. liut
    liut 2012-04-11

    在lion下编译失败:

    /Users/liutao/.macports/opt/local/var/macports/build/_Users_liutao_DarwinPorts_local-sources_www_php5-taint/php5-taint/work/taint-0.5.1/taint.c:1056:16: warning:
    passing ‘long *’ to parameter of type ‘unsigned long *’ converts between pointers
    to integer types with different sign [-Wpointer-sign]
    …switch (zend_hash_get_current_key(ht, &key, &idx, 0)) {
    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    /opt/local/include/php/Zend/zend_hash.h:201:52: note: instantiated from:
    zend_hash_get_current_key_ex(ht, str_index, NULL, num_index, duplicate, NULL)
    ^
    /Users/liutao/.macports/opt/local/var/macports/build/_Users_liutao_DarwinPorts_local-sources_www_php5-taint/php5-taint/work/taint-0.5.1/taint.c:1056:52: note: instantiated from:
    …switch (zend_hash_get_current_key(ht, &key, &idx, 0)) {
    ^~~~
    /opt/local/include/php/Zend/zend_hash.h:179:107: note: passing argument to parameter
    ‘num_index’ here
    …uint *str_length, ulong *num_index, zend_bool duplicate, HashPosition *pos);
    ^
    /Users/liutao/.macports/opt/local/var/macports/build/_Users_liutao_DarwinPorts_local-sources_www_php5-taint/php5-taint/work/taint-0.5.1/taint.c:1260:22: error:
    expression is not assignable
    Z_REFCOUNT_PP(op1) = refcount;
    ~~~~~~~~~~~~~~~~~~ ^
    /Users/liutao/.macports/opt/local/var/macports/build/_Users_liutao_DarwinPorts_local-sources_www_php5-taint/php5-taint/work/taint-0.5.1/taint.c:1517:30: warning:
    ‘zend_get_parameters_ex’ is deprecated [-Wdeprecated-declarations]
    if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &arg) == FAILURE) {
    ^
    2 warnings and 1 error generated.
    make: *** [taint.lo] Error 1

  15. test
    test 2012-04-07

    在条件error_reporting = E_ALL ^ E_NOTICE,display_errors = On下,看不到taint warning,这有问题吗?

  16. essay
    essay 2012-03-29

    大虾无敌啊!从chinaz过来看到您的blog;内容比较高深,看不大明白。但该顶,呵呵。

  17. Sunny
    Sunny 2012-03-27

    很多开源系统,对$_GET和$_POST参数的获取,都封装有自己的函数。类似G_GET(),G_POST()这类预转移过的函数。
    这样的数据是否也能监控到XSS呢?

  18. achun
    achun 2012-03-19

    这种问题够复杂,对于严格的产品,taint 会起到很大作用

  19. 雪候鸟
    雪候鸟 2012-03-11

    @count 恩, 是的, 所以建议是在开发/测试的时候启用这个扩展.

  20. count
    count 2012-03-11

    很不错的东东

    我的理解是这样,这种检测方式是一种线上检测,前提是要知道php文件的所有输入参数url,去触发这个检测逻辑;

    静态语法分析没这个问题,但在某些方面没这种方式准确了

  21. glone
    glone 2012-03-07

    这么热闹

  22. fifsky
    fifsky 2012-03-02

    不知道能不能配置某个虚拟机检测,现在打开这个同一台服务器的老系统全都挂掉了,我只想针对新的项目使用,老的项目不关心这些

  23. 雪候鸟
    雪候鸟 2012-02-29

    @李枨煊 奇怪了, 我这边没问题, 等我回头再验证下2.14,(目前我是2.17), thanks

  24. 李枨煊
    李枨煊 2012-02-29

    开了,直接这样写就会报错
    echo $_GET[‘b’];

  25. 雪候鸟
    雪候鸟 2012-02-28

    @李枨煊 你用的是那个版本? 我这里没问题, 试试最新的.

  26. 李枨煊
    李枨煊 2012-02-28

    hi~鸟哥:

    今天在开发机装了一个试了一下,发现有这么一个问题,如果参数这样接收,taint就不会报错,这算是BUG吗?

    $b = isset($_GET[‘b’]) ? $_GET[‘b’] : ”;
    echo $b;

  27. helloki
    helloki 2012-02-24

    能否提供5.3.6 nts的.dll呢 ^^

  28. toms
    toms 2012-02-22

    高深……………………..

  29. laruence
    laruence 2012-02-20

    @hello 恩, 看起来有的版本的PHP没有暴露出这些符号, 我换个方法. 回头0.3.1修复这个问题

  30. hello
    hello 2012-02-20

    有一个测试失败
    [root@localhost taint]# make test

    Build complete.
    Don’t forget to run ‘make test’.

    /usr/local/bin/php: symbol lookup error: /root/Downloads/php-5.3.10/ext/taint/modules/taint.so: undefined symbol: zif_implode

    =====================================================================
    PHP : /usr/local/bin/php
    PHP_SAPI : cli
    PHP_VERSION : 5.3.10
    ZEND_VERSION: 2.3.0
    PHP_OS : Linux – Linux localhost.localdomain 2.6.33.6-147.fc13.i686 #1 SMP Tue Jul 6 22:30:55 UTC 2010 i686
    INI actual : /root/Downloads/php-5.3.10/ext/taint/tmp-php.ini
    More .INIs :
    CWD : /root/Downloads/php-5.3.10/ext/taint
    Extra dirs :
    VALGRIND : Not used
    =====================================================================
    TIME START 2012-02-20 14:19:14
    =====================================================================
    PASS Check for taint presence [tests/001.phpt]
    PASS Check Taint function [tests/002.phpt]
    PASS Check Taint with ternary [tests/003.phpt]
    PASS Check Taint with eval [tests/004.phpt]
    PASS Check Taint with separation [tests/005.phpt]
    PASS Check Taint with send_var/send_ref [tests/006.phpt]
    FAIL Check Taint with functions [tests/007.phpt]
    =====================================================================
    TIME END 2012-02-20 14:19:15

  31. 雪候鸟
    雪候鸟 2012-02-20

    @enjoy 恩,, trim应该加入到函数链表中…

  32. enjoy
    enjoy 2012-02-20

    $username = $_POST[‘UserName’];
    echo $username;
    提示:Attempt to echo a string that might be tainted
    测试后发现,不管magic_quotes_gpc是On还是Off,加个trim就不报错了。
    $username = trim($_POST[‘UserName’]);
    好像有点不对?

  33. majl
    majl 2012-02-20

    yum安装的,就打了这一个补丁!

  34. 雪候鸟
    雪候鸟 2012-02-19

    @majl 你的PHP是从哪里下载的, 另外, 是否打了其他的什么patch?

  35. majl
    majl 2012-02-19

    为什么我用5.3.10报错呢..
    Warning: PHP Startup: Unable to load dynamic library /usr/lib/php/modules/taint.so’ – /usr/lib/php/modules/taint.so: undefined symbol: zif_user_sprintf in Unknown on line 0

Leave a Reply

Your email address will not be published. Required fields are marked *