Тут смысл в том что передавая скрипту параметр pass в виде script.php?pass[]=dsdsfsd
на стороне сервера в переменную $pass кладется массив array ( 'dsdsfsd'), но многие стандартные функции ожидают вполне конкретных типов и не готовы к приему массива. В данном случае функция если принимает массив возвращает NULL, а при сравнении типа NULL == 0 возвращается 1 (если бы было NULL === 0, то было бы иначе).
Выложил скрипт для примера тут
slus.name/hackme.php?pass[]=1
Главная проблема даже не в этой конкретной функции, многие функции могут вести себя нестандартно, выложил задачку чтобы напомнить еще раз о необходимости фильтровать все входные параметры из вне, даже если на первый взгляд они не могут нанести вреда. (даже раскрытие пути по сути своей опасно)
PS. Хабрапарсер в скрипте заменил кавычки на свои, может поэтому Ваш скрипт не отработал, а может в разных версиях по разному ведут себя скрипты.
Проверил у себя, — есть варнинг, и var_dump(strcasecmp( $_GET['pass'], $pass )); возвращает int(-10).
Т.к. приведение массива к строке даёт строку «Array», т.е. фактически выполняется strcasecmp( «Array», $pass );
Задача не решена. Key не получен. (хотя пути раскрыты, если display_errors=1, у себя всегда отключаю в первую очередь, от греха подальше)
PHP это обёртка над когда-то перловыми, а нынче сишными библиотеками, так что билиберды с параметрами и названиями во многом тянется ещё оттуда, чтобы сишникам было проще входить в php. Собственно быстрая популяризация языка во многом с этим и связана. Так что здесь язык никому ничего не должен.
С типизацией стоит разобраться, в доке всё хорошо расписанно, но так как много заморочек остаётся, нужно самому явно приводить к нужному типу, тем более что во входных данных может быть ещё куча мусора, например, пробелы в начале и конце и т.д.
Вы ошибаетесь. В Си нету типа данных boolean и нету значения false. Это именно ошибка в проектировании функции. В особенностях преобразования типов в PHP я разбираюсь, но мне эта система простой и логичной не кажется.
Кстати тоже интересный вопрос.
Я часто делаю что-то типа $i=(int)$_GET['i'];
Но в исходниках одного программиста увидел конструкцию приблизительно такую
$id = (is_numeric($id))? (int)$id: false;
Неспроста ведь…
Просто решил (или было сказано в ТЗ), что комбинация '123456qwerty' должна приводиться к false, а не к 123456, а 'qwerty' тоже к false, а не к 0. И, вероятно, где-то есть проверка if (false === $id) {} .
Всё просто. Есди $id не false, значит оно было введено как число и можно работать. Если бы был передан тот же массив, то (int)array() вернёт 0, а 0 может быть валидным $id.
Где-то такие дополнительные проверки имеют смысл, где-то нет.
Это вопрос или тут в тоже есть уязвимость? Если второе буду ломать голову, а вообще интересный вопрос :)
Вообще я везде как минимум привожу к нужному типу из соображений «Береженого бог бережет», затраты минимальные а нервов сбережет много.
The case expression may be any expression that evaluates to a simple type, that is, integer or floating-point numbers and strings. Arrays or objects cannot be used here unless they are dereferenced to a simple type.
Кстати, в комментариях на странице www.php.net/manual/en/control-structures.switch.php я наткнулся на код, который показывает, как можно наколоться со switch при $_GET['pass'] == 0 или $_GET['pass'] == true (допустим, мы привели $_GET['pass'] к int или bool):