Статический анализ PHP кода
AppChecker позволяет проводить статический анализ PHP кода. В первую очередь он нацелен на поиск таких опасных дефектов, как:
- SQL injection;
- cross-site scripting;
- eval injection;
- PHP remote file inclusion;
- жестко заданные пароли и закладки.
Но, помимо поиска таких дефектов, статический анализатор AppChecker выявляет и другие типы ошибок в коде, которые возникают в результате опечаток, невнимательности и тому подобное.
К примеру, AppChecker может находить в php коде использование переменной, которая не была проинициализирована (т.е. этой переменной не было присвоено значение). PHP, в отличие от других языков, например, C/C++/Python, разрешает использовать неинициализированные переменные.
Справедливости ради надо отметить, что при использовании таких переменных интерпретатор PHP выдает предупреждение уровня “Notice”, но часто вывод предупреждений такого уровня отключен посредством директив error_reporting и/или display_errors.
Использование непроинициализированной переменной может являться следствием ошибки при написании кода, в качестве примера приведем такой код:
$ldapuser = extldap_authenticate($login, 'nopass', true);
if ($ldap_user !== false) {
$chamilo_user = extldap_get_chamilo_user($ldapuser);
}
Здесь информация об аутентификации пользователя записывается в переменную $ldapuser, она же в последствии используется и в других местах, но в условном операторе проверяется другая переменная, по названию очень схожая с первой — $ldap_user.
Причем до этого данная переменная нигде не фигурировала. Очевидно, что и в условии должна быть переменная $ldapuser.
Другой пример:
function SmartEllipses($text, $attr = NULL, $ctx = NULL) {
# Paramaters:
$text; # text to be parsed
$attr; # value of the smart_ellipses=»» attribute
$ctx; # MT context object (unused)
if ($attr == NULL) $attr = $smartypants_attr;
..
}
Здесь используется необъявленная переменная $smartypants_attr
Но если посмотреть другие подобные функции, то можно обнаружить, что в них эта переменная объявленная как глобальная:
function SmartDashes($text, $attr = NULL, $ctx = NULL) {
global $smartypants_attr, $sp_tags_to_skip;
..
}
Понятно, что в функции SmartEllipses переменную smartypants_attr тоже надо объявить как глобальную.
Конечно, возникают сложности при обнаружении такого типа дефектов, ведь переменные могут появиться в результате выполнения функции extract или eval, в результате выполнения директив include/require и т.д., но AppChecker старается охватить все эти ньюансы.
Так же статический анализатор кода AppChecker способен обнаруживать выражения, которые не производят никакого эффекта. В большинстве случаев в таких выражениях была допущена ошибка. Например:
function edit_announcement_attachment_file() {
..
if (!filter_extension($new_file_name)) {
$return — 1;
}
..
return $return;
}
Здесь из переменной $return вычитается единица, но этот результат никуда не записывается. С уверенностью можно сказать, что строчка этого кода должна быть такой:
$return = -1;
Или такой пример:
$wpdb>update( $wpdb->categories,
array(‘category_nicename’ => $newtitle),
array(‘cat_ID’ => $category->cat_ID) );
В данном случае $wpdb — это объект, соответственно, вместо оператора сравнения “>” надо использовать оператор доступа к методу класса “->”
Вот еще пример ошибки:
foreach ($promotion_list as $item) {
$total_count += $item[‘count’];
$total_goods_net + $item[‘sum_goods_net’];
..
}
Выражение “$total_goods_net + $item[‘sum_goods_net’];” не производит никакого эффекта, вместо “+” следует использовать “+=”.
При подготовке статьи использовались следующие проекты с открытым исходным текстом:
chamilo-lms
Wolf CMS
WorPress
onxshop
Ссылки:
Статический анализатор кода AppChecker
Static code analyzer AppСheker
Блог облачного аудита кода
http://www.php.net/
Common Weakness Enumeration