Чи безпечно передавати сирі кодовані рядки base64 через параметри GET?
Чи безпечно передавати сирі кодовані рядки base64 через параметри GET?
Відповіді:
Ні, вам потрібно буде кодувати URL, оскільки рядки base64 можуть містити символи "+", "=" та "/", які можуть змінити значення ваших даних - схожі на підпапку.
Дійсні базові символи нижче.
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=
Є додаткові специфікації base64. (Деталі див. У таблиці тут ). Але по суті вам потрібно 65 символів для кодування: 26 малих регістрів + 26 великих регістрів + 10 цифр = 62.
Вам потрібні ще два ['+', '/'] та 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, '._-', '+/='));
}
urlencode
, що пропонується у відповіді rodrigo-silveira. Створення двох нових функцій для збереження декількох символів у довжині URL-адреси - це як вхід у ваш будинок, що проходить через вікно, а не просто двері.
unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
,
слід звертатися до коду %2C
, я пропоную використовувати ._-
замість -_,
як єдиний варіант у en.wikipedia.org/wiki/Base64#Variants_summary_table, який зберігає
@joeshmo Або замість того, щоб написати допоміжну функцію, ви могли просто urlencode кодовану рядок base64. Це було б точно так само, як і ваша допоміжна функція, але без необхідності двох додаткових функцій.
$str = 'Some String';
$encoded = urlencode( base64_encode( $str ) );
$decoded = base64_decode( urldecode( $encoded ) );
/
символом, якщо ви передаєте його не як параметр GET, а як шлях у URL-адресі. Це змінить ваш шлях, якщо ви не заміните /
чимось іншим з обох сторін.
Вступне зауваження Я схильний опублікувати декілька роз'яснень, оскільки деякі відповіді тут були трохи оманливими (якщо не неправильними).
Відповідь "НІ" , ви не можете просто передати кодований параметр base64 у рядку запиту URL, оскільки знаки плюс перетворюються на SPACE всередині глобального масиву $ _GET. Іншими словами, якщо ви послали test.php? MYVAR = stringwith + знак , щоб
//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, оскільки + буде перетворено на пробіли.
Іншими словами , якщо я послав той же test.php? MYVAR = stringwith% 2Bsign до
//test.php
$string = urldecode($_GET['myVar']);
print $string;
результат несподіваний:
stringwith sign
Це було б безпечно для rawurldecode()
вхідних даних, однак це було б зайвим і, таким чином, непотрібним.
<br>
, тому не потрібно вводити багато HTML. Сподіваюся, це допомагає, я трохи відредагував вашу відповідь, щоб ще більше її покращити.
Так і ні.
Основна схема діапазону64 може в деяких випадках стикатися з традиційними умовами, що використовуються в URL-адресах. Але багато реалізацій base64 дозволяють вам змінити діаграму, щоб краще відповідати URL-адресам, або навіть поставитись із такою (як Python urlsafe_b64encode()
).
Ще одна проблема, з якою ви можете зіткнутися, - це обмеження довжини URL-адреси, а точніше - відсутність такого обмеження. Оскільки в стандартах не визначена максимальна довжина, браузери, сервери, бібліотеки та інше програмне забезпечення, що працює з протоколом HTTP, можуть визначати власні обмеження. Ви можете поглянути на цю статтю: FAQ WWW: Яка максимальна довжина URL-адреси?
Його базовий код 64url, який ви можете спробувати, його просто розширення коду 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-адреси / замовлення для клієнта чи сервера.
На практиці все може стати трохи складніше. Наприклад, це може запустити HttpRequestValidationException на ASP.NET, якщо значення має містити "on", і ви залишаєте в остаточному "==".
Для безпечного кодування URL, як base64.urlsafe_b64encode(...)
у Python код нижче, працює для мене на 100%
function base64UrlSafeEncode(string $input)
{
return str_replace(['+', '/'], ['-', '_'], base64_encode($input));
}
Так, це завжди безпечно. Звичайно, base64 містить:
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=
але рядки, кодовані base64, зазвичай не мають +
. +
буде перетворено у порожній простір, що призведе до неправильного розшифрованого рядка. /
безпечно в парі параметрів get. =
завжди знаходиться в кінці кодованого рядка base64 і сторона сервера може вирішуватись =
безпосередньо.