Безопасно ли передавать необработанные строки с кодировкой base64 через параметры GET?
Нет, вам нужно будет его закодировать, поскольку строки base64 могут содержать символы «+», «=» и «/», которые могут изменить смысл ваших данных, – выглядят как подпапка.
Ниже приведены допустимые символы base64.
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=
Есть дополнительные спецификации base64. (См. Таблицу здесь для специфики). Но по существу вам нужно 65 символов для кодирования: 26 строчных букв + 26 прописных букв + 10 цифр = 62.
Вам нужно еще два ['+', '/'] и padding char '='. Но ни один из них не дружелюбен к URL, поэтому просто используйте разные символы для них, и вы настроены. Стандартными из приведенной выше диаграммы являются ['-', '_'], но вы можете использовать другие символы, пока вы их декодируете одинаково, и не нужно делиться с другими.
Я бы порекомендовал просто писать собственные помощники. Подобно этим из комментариев на странице руководства php для base64_encode :
function base64_url_encode($input) { return strtr(base64_encode($input), '+/=', '._-'); } function base64_url_decode($input) { return base64_decode(strtr($input, '._-', '+/=')); }
@joeshmo Или вместо написания вспомогательной функции вы можете просто ввести urlencode строку с кодировкой base64. Это будет делать то же самое, что и ваша вспомогательная функция, но без необходимости использования двух дополнительных функций.
$str = 'Some String'; $encoded = urlencode( base64_encode( $str ) ); $decoded = base64_decode( urldecode( $encoded ) );
Вводная записка Я склонен опубликовать несколько разъяснений, поскольку некоторые из ответов здесь были немного ошибочными (если не ошибочными).
Ответ НЕТ , вы не можете просто передать закодированный base64 параметр в строке запроса URL-адреса, поскольку знаки плюс преобразуются в SPACE внутри глобального массива $ _GET. Другими словами, если вы отправили test.php? MyVar = stringwith + sign to
//test.php print $_GET['myVar'];
результатом будет:
stringwith sign
Простым способом решения этой проблемы является просто urlencode()
ваша строка base64, прежде чем добавлять его в строку запроса, чтобы избежать кодов +, = и / символов в% ##. Например, urlencode("stringwith+sign")
возвращает stringwith%2Bsign
Когда вы обрабатываете действие, PHP тщательно обрабатывает строку запроса, когда заполняет глобальный $ _GET. Например, если я отправил test.php? MyVar = stringwith% 2Bsign для
//test.php print $_GET['myVar'];
результатом будет:
stringwith+sign
Вы не хотите, чтобы urldecode()
возвращал строку $ _GET, поскольку urldecode()
+ будут преобразованы в пробелы.
Другими словами, если я отправил тот же test.php? MyVar = stringwith% 2Bsign, чтобы
//test.php $string = urldecode($_GET['myVar']); print $string;
результат является неожиданным:
stringwith sign
Было бы безопасно использовать rawurldecode()
, но он был бы лишним и, следовательно, ненужным.
Да и нет.
Базовая кодировка base64 может в некоторых случаях сталкиваться с традиционными соглашениями, используемыми в URL-адресах. Но многие реализации base64 позволяют вам изменить кодировку для соответствия URL-адресам лучше или даже прийти с одним (например, urlsafe_b64encode()
Python).
Другой проблемой, с которой вы можете столкнуться, является ограничение длины URL или, скорее, отсутствие такого ограничения. Поскольку стандарты не указывают максимальную длину, браузеры, серверы, библиотеки и другое программное обеспечение, работающее с протоколом HTTP, могут определять свои собственные ограничения. Вы можете взглянуть на эту статью: Часто задаваемые вопросы по WWW: Какова максимальная длина URL-адреса?
Я не думаю, что это безопасно, потому что, например, символ «=» используется в исходной базе 64, а также используется для дифференциации параметров из значений в HTTP GET.
Его кодировка base64url вы можете попробовать, просто расширив код joeshmo выше.
function base64url_encode($data) { return rtrim(strtr(base64_encode($data), '+/', '-_'), '='); } function base64url_decode($data) { return base64_decode(str_pad(strtr($data, '-_', '+/'), strlen($data) % 4, '=', STR_PAD_RIGHT)); }
Теоретически, да, если вы не превысите максимальную длину строки запроса url и / oor для клиента или сервера.
На практике все может стать немного сложнее. Например, он может вызвать исключение HttpRequestValidationException на ASP.NET, если значение имеет значение «включено», и вы уходите в конечный «==».
Да, это всегда безопасно. Конечно, base64 содержит: ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=
но строка с кодировкой base64 обычно не имеет +
. +
будет преобразован в пустое пространство, что приведет к неправильной расшифровке строки. /
является безопасным в паре параметров получения. =
всегда находится в конце строки с кодировкой base64, и серверная сторона может разрешить =
напрямую.