У вас есть вопрос по рекламе в интернете и раскрутке сайтов? Задайте его здесь и вам ответят. Вы уже всё знаете? Помогите тем, кто знает пока не всё. Правила форума|
Сделать стартовой|Добавить в избранное.
02 Июн 2008 Пн 02:31 Безопасность в php - особенности условных конструкции со строками в PHP
Особенности условных конструкции со строками в PHP
Операции сравнения, операторы if и switch могут вести себя неожиданно в присутствии строковых переменных. Незнание поведения данных операторов может приводить к ошибкам безопасности приложения.
Что есть истина?
Какие строки истинны? Рассмотрим пример:
echo '"" is ' . (''?'true':'false') . "\n";
echo '"0" is ' . ('0'?'true':'false') . "\n";
echo '"-0" is ' . ('-0'?'true':'false') . "\n";
echo '"0.0" is ' . ('0.0'?'true':'false') . "\n";
echo '"00" is ' . ('00'?'true':'false') . "\n";
echo '"A" is ' . ('A'?'true':'false') . "\n";
Имеем:
"" is false
"0" is false
"-0" is true
"0.0" is true
"00" is true
"A" is true
Итак истинны все непустые строки, кроме строки "0". Логика такого поведения для меня не ясна. На практике часто с помощью оператора if проверяется заполнено ли поле формы, например:
if(isset($_GET['income']) && $_GET['income']) { .. }
Такая проверка примет поле, в котором указан 0 за незаполненное. Чтобы избежать возможного недоразумения, следует использовать проверку в виде:
if(isset($_GET['income']) && strlen($_GET['income'])) { .. }
Сравнение с участием строк
В PHP два оператора сравнения == и ===. Второй оператор сравнивает совпадение типов и значений, первый производит преобразование типа, а затем выполняет сравнение. Особенность оператора == в том, что при сравнении числа и строки, просходит преобразование строки в число. Если строка не представляет собой число, то она преобразуется в числовое значение 0. Рассмотрим пример:
echo '"A"==0 is ' . ('A'==0?'true':'false') . "\n";
echo '"A"===0 is ' . ('A'===0?'true':'false') . "\n";
echo '"A"==0.0 is ' . ('A'==0?'true':'false') . "\n";
echo '"A"===0.0 is ' . ('A'===0?'true':'false') . "\n";
Результат работы скрипта:
"A"==0 is true
"A"===0 is false
"A"==0.0 is true
"A"===0.0 is false
Если ваша функция сравнивает строку, переданную в качестве аргумента с заданной строкой, то следует предварительно проверить, что в качестве аргумента передана строка, а не число. Пример будет приведен далее, при рассмотрении оператора switch.
Оператор switch
Мы ожидаем, что оператор switch сравнивает переданное значение с заданными константами. Особенность реализации switch в php в том, что он производит сравнение с помощью оператора ==, то есть не производит сравнение типов. В качестве примера рассмотрим вымышленную функцию, которая возвращает зарплату сотрудника, получая его имя на входе:
<?php
function get_salary($name) {
switch($name) {
case 'John':
return 3400;
break;
case 'Mary':
return 4600;
break;
default:
return 0;
}
}
echo "John's salary is " . get_salary('John') . "\n";
echo "Mary's salary is " . get_salary('Mary') . "\n";
echo "Peter's salary is " . get_salary('Peter') . "\n";
echo "0's salary is " . get_salary(0) . "\n";
?>
Результат работы скрипта:
John's salary is 3400
Mary's salary is 4600
Peter's salary is 0
0's salary is 3400
На примере видно, что безопасность функции скомпрометирована путем передачи числового значения вместо строкового. Чтобы защитить функцию от нежелательного использования, требуется проверять тип входного значения.
<?php
function get_salary($name) {
if(!is_string($name)) return 0;
switch($name) {
case 'John':
return 3400;
break;
case 'Mary':
return 4600;
break;
default:
return 0;
}
}
echo "John's salary is " . get_salary('John') . "\n";
echo "Mary's salary is " . get_salary('Mary') . "\n";
echo "Peter's salary is " . get_salary('Peter') . "\n";
echo "0's salary is " . get_salary(0) . "\n";
?>
Результат работы скрипта:
John's salary is 3400
Mary's salary is 4600
Peter's salary is 0
0's salary is 0
Итак, некоторые операции сравнения ведут себя контринтуитивно.