У нас есть URL:
http://site.com/index.php?action=show
$_GET['action']
используется в шаблонах для проверки значения ?action=
:
switch ($_GET['action']) { case = "show" { $match_show = true; } }
и в другом месте:
echo $_GET['action'];
Безопасно ли использовать эти конструкции?
Как сделать их безопасными?
Благодарю.
Переключатель в порядке, потому что вы сравниваете его с жестко запрограммированным значением (однако, это case "show":
btw).
Как отмечает @Bruce в комментариях, вы должны добавить случай по default:
также, чтобы поймать значения, отсутствующие в списке, или пустые значения:
switch ($_GET['action']) { case "show": $match_show = true; break; default: // value is not on the list. React accordingly. echo "Unknown value for 'action'". }
Во-вторых, это потенциально опасно, так как можно было бы добавить HTML и, что более важно, JavaScript в тело документа. Вы должны применить htmlspecialchars()
к переменной, прежде чем повторять ее.
$_GET
по умолчанию небезопасно, так как оно может содержать специальные или закодированные символы и другие нежелательные текстовые последовательности.
Вы можете использовать встроенную функцию PHP filter_input
для дезинфекции строки в соответствии с несколькими стандартными фильтрами (см. Список фильтров для представления того, что возможно).
Пример:
if (!($action = filter_input(INPUT_GET, 'action', FILTER_SANITIZE_STRING))) { $action = 'some-default'; }
Преимущества:
Опирается на встроенную фильтрацию санитаза, которая обеспечивает:
Недостатки:
filter_input
если вы модифицируете суперглобальный $_GET
(которого вы, вероятно, не должны делать в любом случае). Примечание
Вы также можете проверить, что поле является одним из наборов с использованием in_array
, который является более динамичным методом проверки, если у вас есть один из наборов.
$search = in_array($search, array('show', 'hide')) ? $search : 'some-default';
Динамический подход позволяет вам безопасно выполнять или искать целевое действие, сохраняя множество возможных вариантов в структуре данных по сравнению с статическим кодом.
Да, как уже упоминалось, вы должны проверить значение любой переменной $_GET
прежде чем использовать ее вслепую. Но…
Вы также должны проверить, что он существует даже до его использования. В зависимости от того, как вы устанавливаете error_reporting () на своем сервере, если вы пытаетесь использовать $_GET['action']
и ?action=something
не указано в URL-адресе, вы получите E_NOTICE-Undefined index: действие , которые либо загрязнят ваши журналы ошибок, либо хуже, появятся в браузере.
$urlAction = isset($_GET['action']) ? $_GET['action'] : null; if (isset($urlAction)) { // Rest of validation... }
Иногда, когда у меня много начинающих, вы создаете плагины или модули для сайта, я использую что-то вроде …
foreach($_GET as $key=>$value) { if(functions_exists('clean_get_'.$key)) { $_GET[$key]=call_user_func('clean_get_'.$key,$value); } else { unset($_GET[$key]; } }
сforeach($_GET as $key=>$value) { if(functions_exists('clean_get_'.$key)) { $_GET[$key]=call_user_func('clean_get_'.$key,$value); } else { unset($_GET[$key]; } }
… и все значения get и post «волшебным образом» очищаются или удаляются, поэтому мне не нужно беспокоиться о том, что у кого-то elses sql-injectable plugin.
Или, если вы поклонник ленивой загрузки …
foreach($_GET as $key=>$value) { if(is_file('clean_get_'.$key.'.php')) { include_once('clean_get_'.$key.'.php'); if(functions_exists('clean_get_'.$key)) { $_GET[$key]=call_user_func('clean_get_'.$key,$value); } else { unset($_GET[$key]); } } else { unset($_GET[$key]; } }
сforeach($_GET as $key=>$value) { if(is_file('clean_get_'.$key.'.php')) { include_once('clean_get_'.$key.'.php'); if(functions_exists('clean_get_'.$key)) { $_GET[$key]=call_user_func('clean_get_'.$key,$value); } else { unset($_GET[$key]); } } else { unset($_GET[$key]; } }
сforeach($_GET as $key=>$value) { if(is_file('clean_get_'.$key.'.php')) { include_once('clean_get_'.$key.'.php'); if(functions_exists('clean_get_'.$key)) { $_GET[$key]=call_user_func('clean_get_'.$key,$value); } else { unset($_GET[$key]); } } else { unset($_GET[$key]; } }
пс. код был написан здесь напрямую, возможны ошибки!
PHP $_GET
сам по себе небезопасен, его можно использовать в нескольких областях, для хорошего чтения и примеров я рекомендую вам прочитать эту статью
Чтобы заменить пустые (не заданные) значения по умолчанию, попробуйте это:
$variable = isset($_GET['get_variable']) ? $_GET['get_variable'] : 'some-default';