web-dev-qa-db-ja.com

URLにbase64エンコード文字列を渡す

GETパラメータを介して生のbase64エンコード文字列を渡すのは安全ですか?

213
Alix Axel

いいえ、あなたはそれをURLエンコードする必要があるでしょう、base64文字列はあなたのデータの意味を変える可能性がある "+"、 "="そして "/"文字を含むことができるからです。

有効なbase64文字は以下のとおりです。

ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=
182
Thiyagaraj

追加のbase64仕様があります。 (詳しくは表 ここ を参照してください)。しかし、基本的にはエンコードするのに65文字が必要です:26小文字+ 26大文字+ 10桁= 62。

さらに2つの['+'、 '/']と1つの埋め込み文字 '='が必要です。しかし、それらのどれもURLフレンドリーではないので、それらのために異なる文字を使うだけですそしてあなたは設定されています。上の表の標準的なものは[' - '、 '_']ですが、同じようにデコードしさえすれば他の文字を使用することができ、他の人と共有する必要はありません。

私はあなた自身のヘルパーを書くことをお勧めします。 base64_encodeのphpマニュアルページ のコメントからこれらのように:

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

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

@joeshmoあるいは、ヘルパー関数を書く代わりに、base64でエンコードされた文字列を単にurlencodeすることもできます。これはあなたのヘルパー関数と全く同じことをするでしょうが、2つの追加関数を必要としません。

$str = 'Some String';

$encoded = urlencode( base64_encode( $str ) );
$decoded = base64_decode( urldecode( $encoded ) );
68

はじめにここでの答えのいくつかは少し誤解を招く可能性があったので、私はいくつかの説明を投稿する傾向があります(正しくない場合を除く)。

答えはNOです。プラス記号は$ _GETグローバル配列内のSPACEに変換されるため、URLクエリ文字列内でbase64エンコードパラメータを単純に渡すことはできません。 。言い換えれば、test.php?myVar=stringwith+signをあなたに送信した場合

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

結果は次のようになります。
stringwith sign

これを解決する簡単な方法は、クエリ文字列に追加して+、=、および/の各文字を%##コードにエスケープする前に、単純にbase64文字列をurlencode()することです。たとえば、urlencode("stringwith+sign")stringwith%2Bsignを返します。

アクションを処理するとき、PHPは、クエリ文字列が$ _GETグローバルに入力されると自動的にデコードされます。たとえば、test.php?myVar=stringwith%2Bsignと送信した場合

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

結果は次のようになります。
stringwith+sign

notのように、返された$ _GET文字列をurldecode()にすると、+がスペースに変換されます。
言い換えれば、私が同じtest.php?myVar=stringwith%2Bsignを送った場合

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

結果は予想外です。
stringwith sign

入力を rawurldecode() しても安全ですが、冗長であるため不要です。

38

はいといいえ。

Base64の基本文字セットは、場合によっては、URLで使用される従来の規則と衝突する可能性があります。しかし、base64の実装の多くでは、文字セットをURLとよりよく一致するように、またはURLと一致するように変更することができます(Pythonの urlsafe_b64encode() のように)。

あなたが直面しているかもしれないもう一つの問題はURLの長さの制限かむしろそのような制限の欠如です。規格では最大長を指定していないため、ブラウザ、サーバー、ライブラリ、およびHTTPプロトコルを使用するその他のソフトウェアで独自の制限が定義されている場合があります。あなたはこの記事を見てみることができます: WWWのFAQ:URLの最大長はいくつですか?

13
Michał Górny

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

これは安全だとは思わない。 "="文字は生の基数64で使用され、HTTP GETの値とパラメーターを区別するのにも使用されます。

4
Mischa

理論上は、クライアントまたはサーバーの最大URLおよび/またはクエリ文字列の長さを超えない限り、可能です。

実際には、物事は少しトリッキーになることがあります。たとえば、値に "on"が含まれていて末尾の "=="のままにした場合、ASP.NETでHttpRequestValidationExceptionが発生する可能性があります。

1
Nicole Calinoiu