web-dev-qa-db-fra.com

Passage de chaînes encodées en base64 dans une URL

Est-il prudent de transmettre des chaînes brutes encodées en base64 via des paramètres GET?

224
Alix Axel

Non, vous devez le coder en URL, car les chaînes en base64 peuvent contenir les caractères "+", "=" et "/" qui pourraient modifier le sens de vos données. Cela ressemble à un sous-dossier.

Les caractères valides en base64 sont ci-dessous.

ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=
193
Thiyagaraj

Il existe des spécifications supplémentaires en base64. (Voir le tableau ici pour plus de détails). Mais vous avez essentiellement besoin de 65 caractères pour coder: 26 minuscules + 26 majuscules + 10 chiffres = 62.

Vous avez besoin de deux autres ['+', '/'] et d'un caractère de remplissage '='. Mais aucun d’eux n’est convivial, donc utilisez simplement des caractères différents pour eux et vous êtes prêt. Les caractères standard du tableau ci-dessus sont ['-', '_'], mais vous pouvez utiliser d'autres caractères tant que vous les décodez de la même façon et que vous n'avez pas besoin de les partager avec d'autres.

Je recommanderais simplement d'écrire vos propres aides. Comme ceux des commentaires sur le page de manuel php pour base64_encode :

function base64_url_encode($input) {
 return strtr(base64_encode($input), '+/=', '._-');
}

function base64_url_decode($input) {
 return base64_decode(strtr($input, '._-', '+/='));
}
256
Joe Flynn

@ joeshmo Ou au lieu d'écrire une fonction d'assistance, vous pouvez simplement encoder la chaîne encodée en base64. Cela ferait exactement la même chose que votre fonction d'assistance, mais sans la nécessité de deux fonctions supplémentaires.

$str = 'Some String';

$encoded = urlencode( base64_encode( $str ) );
$decoded = base64_decode( urldecode( $encoded ) );
70
rodrigo-silveira

Note introductive Je suis enclin à publier quelques éclaircissements car certaines des réponses fournies ici sont un peu trompeuses (si ce n’est pas incorrect).

La réponse est NON , vous ne pouvez pas simplement passer un paramètre codé en base64 dans une chaîne de requête d'URL, car les signes plus sont convertis en ESPACE dans le tableau global $ _GET. . En d'autres termes, si vous avez envoyé test.php? MyVar = stringwith + sign à

//test.php
print $_GET['myVar'];

le résultat serait:
stringwith sign

Le moyen le plus simple de résoudre ce problème consiste à simplement urlencode() votre chaîne base64 avant de l’ajouter à la chaîne de requête pour échapper aux caractères +, = et/dans les codes% ##. Par exemple, urlencode("stringwith+sign") renvoie stringwith%2Bsign

Lorsque vous traitez l'action, PHP prend en charge le décodage automatique de la chaîne de requête lorsqu'elle remplit le champ $ _GET global. Par exemple, si j'ai envoyé test.php? MyVar = stringwith% 2Bsign à

//test.php
print $_GET['myVar'];

le résultat serait:
stringwith+sign

Vous ne voulez pas vouloir urldecode() la chaîne $ _GET renvoyée car les caractères + seront convertis en espaces.
En d’autres termes, si j’envoyais le même test.php? MyVar = stringwith% 2Bsign à

//test.php
$string = urldecode($_GET['myVar']);
print $string;

le résultat est inattendu:
stringwith sign

Il serait prudent de rawurldecode() l'entrée, cependant, elle serait redondante et donc inutile.

38
Jeffory J. Beckers

Oui et non.

Le jeu de caractères de base de base64 peut dans certains cas entrer en conflit avec les conventions traditionnelles utilisées dans les URL. Cependant, de nombreuses implémentations en base64 vous permettent de modifier le jeu de caractères pour qu'il corresponde mieux aux URL, voire qu'il en vienne à un (comme avec Python urlsafe_b64encode() ).

Un autre problème auquel vous pouvez être confronté est la limite de longueur d'URL ou plutôt l'absence de cette limite. Comme les normes ne spécifient aucune longueur maximale, les navigateurs, serveurs, bibliothèques et autres logiciels fonctionnant avec le protocole HTTP peuvent définir leurs propres limites. Vous pouvez consulter cet article: WWW FAQs: Quelle est la longueur maximale d'une URL?

13
Michał Górny

C’est un encodage base64url que vous pouvez essayer, sa juste extension du code de joeshmo ci-dessus.

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));
}
8
Andy

Je ne pense pas que cela soit sans danger parce que, par exemple, le caractère "=" est utilisé dans la base brute 64 et sert également à différencier les paramètres des valeurs d'un HTTP GET.

4
Mischa

En théorie, oui, tant que vous ne dépassez pas l'URL maximale et/ou la longueur de la chaîne de requête pour le client ou le serveur.

En pratique, les choses peuvent devenir un peu plus compliquées. Par exemple, il peut déclencher une exception HttpRequestValidationException sur ASP.NET s'il se trouve que la valeur contient un "on" et que vous laissez le dernier "==".

1
Nicole Calinoiu