imgのsrcにbase64でエンコードされたユーザーデータを入れるのは安全ですか?

base64でエンコードされた画像データを 使用する POST データを受け入れ、 src img

Obviously, with no filtering one could easily break out of the src attribute and the img tag and insert malicious <script /> or other tags, so my idea is to

base64_decode($rawPostData)

デコードされていることを確認してからOK

base64_encode($decodedData)

これを src 属性に挿入します。

このアプローチでは、脆弱性(XSS、おそらくバッファオーバーフローなど)がありますか?

バックグラウンド

JavaScriptを使ってサードパーティ製の svg canvas から base64 に変換したページに必要です( "canvg"を使って正確)。イメージを使用して他のいくつかのタスクを実行するために、イメージをサーバー側のスクリプトに渡す必要がありますが、イメージをユーザー/クライアントに表示する必要もあります。

2
それを base64_decode()することができれば誰でも可能です。
追加された 著者 BoltClock,
さて、非エンコードされたデータを受け取ってから、イメージを検証し、バックエンドで自分自身でエンコードしてみてはどうでしょうか。 Base64エンコーディングは実際にはデータのサイズを増やし、低速のアップロード(およびダウンロード)は遅くなります:)
追加された 著者 Leigh,
@BoltClockあなたは精巧にできますか?私は base64_encode を使用してデータを暗号化/復号化するつもりはないので、ユーザーランドからデータを取得してイメージとして表示するだけです。私の質問は、このアプローチの結果としてXSSなどの脆弱性があることです。
追加された 著者 bububaba,
@Leigh:これは明白なことですが、サードパーティ製の svg canvas base64 に変換するページに必要です> JavaScript( canvg プロジェクト)を使用してエンコードされたデータ
追加された 著者 bububaba,

3 答え

イメージをイメージとして受け取り、それから base64_encode します。それは期待通りに提出されたことを確認し、XSSを引き起こすことを不可能にするという、あなたの中途半端なステップを節約します。

base64を画像のように検証する必要がある場合は、imgタグ内に埋め込むだけでbase64文字だけをチェックするだけで十分です(base64ではタグ区切り文字は使用できません)。

組み込み関数を使用する:

if (base64_decode($mystring, true)) {
   //is valid
} else {
   //not valid
}
2
追加された
もちろん。そのため、受け取った厳密な base64_decode の戻り値をチェックする必要があります。
追加された 著者 deed02392,
問題はJavaScriptコードからbase64でエンコードされたデータを受け取っていることです。それは有効ですが、誰かがスクリプトやデータを改ざんしていたら、私は安全でありたいです。
追加された 著者 bububaba,

データの内容を確認しないと安全ではありません。

例:

$data= '"/><script>alert("hi");</script>';

print '';

$ data のみ有効であることを確認するのは非常に簡単ですベース64文字。いずれもあなたのタグを破ることはありません。

編集:

次のようにすると、単純にイメージが破損します。

$data= '"/><script>alert("hi");</script>';

$data64 = base64_encode($data);

print '';
1
追加された
@bububaba:編集された答え。実際のbase64でエンコードされたデータを供給すると、imgタグを破ることができないため、ブラウザによって画像データとして内部的にデコードされます。 (引用符やタグの終わりは含まれません)。あなたが最初にbase64データを受け取ったことを確認するために私がリンクしている他のSOの質問をチェックしてください。
追加された 著者 Leigh,
@bububaba:理論上は、誰かが最初にデータを改ざんした場合、または画像フォーマットが無効であった場合にのみ、画像が壊れてしまいます。とにかくアップロードを確認する必要があります。過去には、画像処理ルーチン(例えば、IEのGDI +)に依存するブラウザエクスプロイトがありましたが、
追加された 著者 Leigh,
あなたのご意見ありがとうございます。 $ data はデコードして再エンコードしても有害でしょうか?
追加された 著者 bububaba,
セキュリティ上のリスクがある場合を除いて、腐敗は私にとっては問題ありません
追加された 著者 bububaba,

主なセキュリティ上の問題は、このタイプのデータにクリーンなXSSを適用できないことです。 "data:image/png; base64"という文字列の一部は、クリーンXSSが適用され、画像を汚す場合削除されます。

これを念頭に置いて、私は私によく答えた解決策を設定しました:

  1. We know that the beginning of a base64 image follows a pattern similar to "data:image/png;base64,", so the following code could capture this beginning

    $data = substr($imageBase64, 0, strpos($imageBase64, ",") + 1);
  2. Okay, but we're only relying on the first comma found, that does not provide any security. So let's use preg_replace() to make sure the string we've captured is really what we expect.

    $data = preg_replace('#^data:image/[^;]+;base64,#', '', $data);
  3. If everything goes as planned the result stored in $data will be an empty string. Otherwise our image is no longer valid here. Now we need to validate what is after the first comma, so we will simply use the base64_decode.

    $img = preg_replace('#^data:image/[^;]+;base64,#', '', $imageBase64);
    if(base64_decode($img, true)) {
     //is valid
    } else {
     //not valid
    }
  4. We use the same preg_replace to replace the beginning of the string, and then we test the rest to see if it matches a valid base64 data. If positive you can already store the original string in the database without worries because its string is really clean, if negative again we have an invalid image.

1
追加された
なぜdownvote?あなたが否定的なフィードバックを与えるたびに、その人が将来訂正する機会があるというコメントの理由を説明してください。
追加された 著者 Pedro Souza,
PHP - 日本のコミュニティ [ja]
PHP - 日本のコミュニティ [ja]
4 参加者の

このグループではPHPについて話します。 パートナー:kotaeta.com