GETパラメータを介して、base64でエンコードされた生の文字列を渡すことは安全ですか?
GETパラメータを介して、base64でエンコードされた生の文字列を渡すことは安全ですか?
回答:
いいえ、base64文字列には「+」、「=」、「/」の文字を含めることができるため、URLエンコードする必要があります。これは、データの意味を変える可能性があるため、サブフォルダーのように見えます。
有効なbase64文字は以下のとおりです。
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=
追加のbase64仕様があります。(詳細については、こちらの表をご覧ください)。ただし、基本的に、エンコードするには65文字が必要です(26小文字+ 26大文字+ 10桁= 62)。
さらに2つの['+'、 '/']とパディング文字 '='が必要です。しかし、それらはどれもURLフレンドリーではありません。したがって、それらに異なる文字を使用するだけで、設定は完了です。上記のチャートの標準的な文字は['-'、 '_']ですが、同じようにデコードし、他の文字と共有する必要がない限り、他の文字を使用できます。
独自のヘルパーを作成することをお勧めします。base64_encodeのphpマニュアルページのコメントからこれらのように:
function base64_url_encode($input) {
return strtr(base64_encode($input), '+/=', '._-');
}
function base64_url_decode($input) {
return base64_decode(strtr($input, '._-', '+/='));
}
urlencode
rodrigo-silveiraの回答で示唆されているように使用することをお勧めします。urlの長さで数文字を節約する2つの新しい関数を作成することは、ドアを使用するだけでなく、窓を通過して家に入るようなものです。
unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
,
にurlencodeする必要があるため、末尾を保持するen.wikipedia.org/wiki/Base64#Variants_summary_tableの唯一のバリアントの 代わりに%2C
使用._-
することをお勧めします=-_,
@joeshmoまたは、ヘルパー関数を作成する代わりに、base64エンコードされた文字列をurlencodeすることもできます。これはヘルパー関数とまったく同じことを行いますが、2つの追加関数は必要ありません。
$str = 'Some String';
$encoded = urlencode( base64_encode( $str ) );
$decoded = base64_decode( urldecode( $encoded ) );
/
GETパラメーターとしてではなく、URL内のパスとして渡す場合は、文字に注意してください。/
両側で何かを置き換えないと、パスが変更されます。
序論ここでの回答のいくつかは少し誤解を招くものだったので(不正確でないとしても)、私はいくつかの説明を投稿する傾向があります。
正解は $ _GETグローバル配列内のSPACEに変換されるため、答えはNOです。URLクエリ文字列内でbase64エンコードされたパラメーターを単純に渡すことはできません。つまり、test.php?myVar = stringwith + signを
//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
+はスペースに変換されるため、返される$ _GET文字列は必要ありませんurldecode()
。
つまり、同じtest.php?myVar = stringwith%2Bsignを
//test.php
$string = urldecode($_GET['myVar']);
print $string;
結果は予想外です:
stringwith sign
rawurldecode()
入力に対しては安全ですが、冗長であるため不要です。
<br>
、多くのHTMLを入力する必要はありません。これがお役に立てば幸いです。さらに改善するために、あなたの回答を少し編集しました。
はいといいえ。
base64の基本的な文字セットは、URLで使用される従来の規約と衝突する場合があります。しかし、base64実装の多くでは、URLに一致するように文字セットを変更したり、URLに(Pythonのようにurlsafe_b64encode()
)文字セットを追加したりできます。
直面している可能性のあるもう1つの問題は、URLの長さの制限、またはそのような制限の欠如です。標準では最大長が指定されていないため、ブラウザ、サーバー、ライブラリ、およびHTTPプロトコルで動作するその他のソフトウェアが独自の制限を定義する場合があります。次の記事をご覧ください。WWWFAQ:URLの最大長は?
あなたが試すことができるその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やクエリ文字列の最大長を超えない限り可能です。
実際には、物事は少しトリッキーになる可能性があります。たとえば、値に "on"が含まれている場合、ASP.NETでHttpRequestValidationExceptionをトリガーし、最後に "=="を残すことができます。
はい、常に安全です。もちろん、base64には以下
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=
が含まれます。
ただし、base64でエンコードされた文字列には通常はありません+
。+
空白に変換され、誤った文字列がデコードされます。/
getパラメータのペアでは安全です。=
常にbase64エンコードされた文字列の最後にあり、サーバー側は=
直接解決できます。