É seguro transmitir strings codificadas em base64 brutas através de parâmetros GET?
É seguro transmitir strings codificadas em base64 brutas através de parâmetros GET?
Respostas:
Não, você precisaria codificá-lo por URL, pois as cadeias base64 podem conter os caracteres "+", "=" e "/" que podem alterar o significado dos seus dados - parecendo uma subpasta.
Os caracteres base64 válidos estão abaixo.
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=
Existem especificações base64 adicionais. (Veja a tabela aqui para detalhes). Mas essencialmente você precisa de 65 caracteres para codificar: 26 em minúscula + 26 em maiúscula + 10 dígitos = 62.
Você precisa de mais dois ['+', '/'] e um caractere de preenchimento '='. Mas nenhum deles é compatível com URL, portanto, use caracteres diferentes para eles e pronto. Os padrões do gráfico acima são ['-', '_'], mas você pode usar outros caracteres desde que os decodifique da mesma forma e não precise compartilhar com outros.
Eu recomendo apenas escrever seus próprios ajudantes. Assim como nos comentários na página de manual do php para base64_encode :
function base64_url_encode($input) {
return strtr(base64_encode($input), '+/=', '._-');
}
function base64_url_decode($input) {
return base64_decode(strtr($input, '._-', '+/='));
}
urlencode
como sugerido pela resposta de rodrigo-silveira. Criando duas novas funções para economizar alguns caracteres no tamanho da URL, é como entrar na sua casa passando pela janela em vez de apenas usar a porta.
unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
,
devem ser urlencoded para %2C
, eu sugiro usar ._-
em vez de -_,
ser a única variante em en.wikipedia.org/wiki/Base64#Variants_summary_table que mantém o arrasto =
@joeshmo Ou, em vez de escrever uma função auxiliar, você pode simplesmente codificar a string codificada em base64. Isso faria exatamente a mesma coisa que sua função auxiliar, mas sem a necessidade de duas funções extras.
$str = 'Some String';
$encoded = urlencode( base64_encode( $str ) );
$decoded = base64_decode( urldecode( $encoded ) );
/
caractere se você o transmitir não como um parâmetro GET, mas como um caminho na URL. Isso mudará seu caminho se você não substituir /
por outra coisa nos dois lados.
Nota introdutória Estou inclinado a postar alguns esclarecimentos, já que algumas das respostas aqui foram um pouco enganadoras (se não incorretas).
A resposta é NÃO , você não pode simplesmente passar um parâmetro codificado em base64 em uma sequência de consulta de URL, pois os sinais de adição são convertidos em um ESPAÇO dentro da matriz global $ _GET. Em outras palavras, se você enviou test.php? MyVar = stringwith + sign para
//test.php
print $_GET['myVar'];
o resultado seria:
stringwith sign
A maneira mais fácil de resolver isso é simplesmente urlencode()
sua string base64 antes de adicioná-la à string de consulta para escapar dos caracteres +, = e / / aos códigos% ##. Por exemplo, urlencode("stringwith+sign")
retornastringwith%2Bsign
Quando você processa a ação, o PHP cuida da decodificação automática da string de consulta quando preenche o global $ _GET. Por exemplo, se eu enviei test.php? MyVar = stringwith% 2Bsign para
//test.php
print $_GET['myVar'];
o resultado seria:
stringwith+sign
Você não deseja a urldecode()
string $ _GET retornada, pois os + serão convertidos em espaços.
Em outras palavras, se eu enviar o mesmo test.php? MyVar = stringwith% 2Bsign para
//test.php
$string = urldecode($_GET['myVar']);
print $string;
o resultado é inesperado:
stringwith sign
Seria seguro para rawurldecode()
a entrada, no entanto, seria redundante e, portanto, desnecessário.
<br>
, portanto, não é necessário digitar muito HTML. Espero que isso ajude, editei sua resposta um pouco para melhorá-la ainda mais.
Sim e não.
O conjunto de caracteres básico de base64 pode, em alguns casos, colidir com convenções tradicionais usadas em URLs. Porém, muitas das implementações de base64 permitem alterar o conjunto de caracteres para corresponder melhor às URLs ou até mesmo com uma (como a do Python urlsafe_b64encode()
).
Outro problema que você pode estar enfrentando é o limite do tamanho do URL ou melhor - a falta desse limite. Como os padrões não especificam tamanho máximo, navegadores, servidores, bibliotecas e outros softwares que trabalham com o protocolo HTTP podem definir seus próprios limites. Você pode dar uma olhada neste artigo: WWW FAQs: Qual é o tamanho máximo de um URL?
É uma codificação base64url que você pode experimentar, é apenas uma extensão do código do joeshmo acima.
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));
}
Em teoria, sim, desde que você não exceda o comprimento máximo da URL e / ou da consulta para o cliente ou servidor.
Na prática, as coisas podem ficar um pouco mais complicadas. Por exemplo, ele pode disparar uma HttpRequestValidationException no ASP.NET se o valor contiver um "on" e você deixar no final "==".
Para codificação segura de URL, como base64.urlsafe_b64encode(...)
em Python, o código abaixo, funciona para mim 100%
function base64UrlSafeEncode(string $input)
{
return str_replace(['+', '/'], ['-', '_'], base64_encode($input));
}
Sim, é sempre seguro. é claro que base64 contém:
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=
mas uma string codificada em base64 geralmente não possui +
. +
será convertido em um espaço em branco, resultando em uma string decodificada incorreta. /
é seguro em um par de parâmetros get. =
está sempre no final da cadeia codificada em base64 e o lado do servidor pode resolver =
diretamente.