質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

セキュリティー

このタグは、コンピューターシステムの安全性やデータの機密性に関連したトピックの為に使われます。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

Ajax

Ajaxとは、Webブラウザ内で搭載されているJavaScriptのHTTP通信機能を使って非同期通信を利用し、インターフェイスの構築などを行う技術の総称です。XMLドキュメントを指定したURLから読み込み、画面描画やユーザの操作などと並行してサーバと非同期に通信するWebアプリケーションを実現することができます。

Q&A

解決済

3回答

1391閲覧

画像アプロードにおけるセキュリティ対策が、なぜ大変なのかわかりません。

kikijiji

総合スコア3

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

セキュリティー

このタグは、コンピューターシステムの安全性やデータの機密性に関連したトピックの為に使われます。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

Ajax

Ajaxとは、Webブラウザ内で搭載されているJavaScriptのHTTP通信機能を使って非同期通信を利用し、インターフェイスの構築などを行う技術の総称です。XMLドキュメントを指定したURLから読み込み、画面描画やユーザの操作などと並行してサーバと非同期に通信するWebアプリケーションを実現することができます。

0グッド

5クリップ

投稿2020/06/08 07:36

編集2020/06/08 07:39

前提・実現したいこと

画像アップロード機能を実装しています。調べているとセキュリティ周りを組むのが大変そうで腰が引けたのですが、ふと次の方法でいいのではないかと思いました。問題やセキュリティリスクがないか知りたいです。

###考えた方法
■保存フロー

  1. JSで画像をbase64にし、
  2. AJAXで送り、
  3. 送られたbase64のテキストについて以下検証し

➀タグがあるか?
➁画像かどうか?
4. base64のテキストのままデータベースに保存する

■表示フロー

  1. データベースにあるbase64のテキストを取得
  2. htmlspecialchars()をかけて出力

###ソースコード
上の流れなら、通常のコメントを受け付けるのと同じ検証でいいですよね?

ただのテキストの検証なので、唯一やるべき検証である3の➀と➁は、次のコードで済むと思います。

そのように思ったのですが、base64のテキストで送るこの方法には、何か問題あるのでしょうか?

PHP

1<?php 2// AJAXでbase64化された画像を受け取る 3$base64 = $_POST['base64'] ?? ''; // "data:image/jpeg;base64,/9j/ABCDEFG" など 4 5// ➀と➁が問題あれば終了 6if( isHtml($base64) || ! isImg($base64) ) { 7 echo '問題が発生しました'; 8}else{ 9 $sql = "INSERT INTO images (ID, base64, created) VALUES (:base64, now())"; 10 $stmt = $dbh->prepare($sql); 11 $params = array(':base64' => $base64); 12 $stmt->execute($params); 13 echo '登録完了しました'; 14} 15 16// ➀タグがあるか? 17function isHtml( $base64 ) { 18 $result = false; 19 if ( preg_match("/<(\"[^\"]*\"|'[^']*'|[^'\">])*>/", $base64) ) $result = true; 20 return $result; 21} 22 23// ➁画像かどうか? 24function isImg( $v ){ 25 $result = false; 26 if ( preg_match("#^data:image/jpeg;base64#", $v) ) $result = true; 27 if ( preg_match("#^data:image/jpg;base64#", $v) ) $result = true; 28 if ( preg_match("#^data:image/png;base64#", $v) ) $result = true; 29 return $result; 30}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

m.ts10806

2020/06/08 07:46

なにか問題があるような点はどこからきた懸念点でしょうか。出典明示してください
kikijiji

2020/06/08 07:54

ざっくり言いますと「こんな簡単な方法がネットに載ってないということは、何か問題があるのだろうか?」という懸念です。
Lhankor_Mhy

2020/06/08 08:51

data:image/jpeg;base64" onclick=alert() という文字列がチェック通るからあまり意味がないような……? もちろん、出力時の htmlspecialchars で潰せますが、それに頼るなら①の入力時サニタイズする意味はあまりないのではないかな、と。 ②は必要だと思いますが。
kikijiji

2020/06/08 09:06

なるほど画像チェックはこれではいけませんね。もう少し調べてみます。
guest

回答3

0

ベストアンサー

// ➁画像かどうか?

このチェックでは不適切なものを弾ききれません。data:で送ってくるContent-typeはクライアント側が設定するものですので、攻撃者が送信する場合はいくらでも詐称可能です。

投稿2020/06/08 08:13

maisumakun

総合スコア146018

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

maisumakun

2020/06/08 08:31

それこそ「精神的ブラクラ」(コンピューターのシステム上は至って正常なファイルだけど、見る人間の精神にダメージを与えるような画像)なんてものもありますので、完璧というのは困難です。
kikijiji

2020/06/08 09:07

ありがとうございます。画像チェックはもっと考えないといけないですね。
guest

0

既に解決されたようですが、追加で。
この手の方法は使われてなくもないようですが、あまり見かけない理由の一つは、ブラウザおよびサーバーり両方で画像がメモリ上で処理されるので、あまり大きな画像(または他のアップロードデータ)は使いにくいというのがあると思います。$_FILESだと、アップロードデータはファイルとして扱われ、それがセキュリティ上の問題を生みやすい原因の一つになっています。

小さな画像であれば、base64でデータサイスが1.3倍程度になるオーバーヘッドを除けば、あまり問題にはならないかと。

投稿2020/06/08 22:41

ockeghem

総合スコア11705

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kikijiji

2020/06/09 00:11

ありがとうございます。base64の方のそういった事情を知りたかったです。確かにLazyLoadなどができなそうですね。 ファイルの方ですが以下に便利なライブラリがございまして、こちらネットに問題点もなかったようですが、専門家の方からしますとこういったライブラリはいかがでしょうか。 使い方参考サイトにあるように「$handle = new Upload($_FILES['image_file']);」だけでセキュリティをばっちりチェックしてくれるようです。 「class.upload.php」 (使い方参考サイト) http://webtech-walker.com/archive/2007/06/11210929.html (Github) https://github.com/verot/class.upload.php/blob/master/src/class.upload.php
ockeghem

2020/06/09 00:13

そういった既存のライブラリのセキュリティチェックはお仕事なので、こちらでの回答は控えたいと思います
kikijiji

2020/06/09 07:36

そうですよね、専門家なら簡単かと思いましたが、専門家だからこそ安易な回答をしてはいけませんでしたね。大変失礼いたしました。YouTubeの方で期待しています(笑)
guest

0

普通にファイルをsubmitして、ファイルはファイルとして保持しておけば
大した手間ではありません。
ただimgで参照されたときになんらかの不正な動きをする可能性は否定できません。
(その昔そういう攻撃があった記憶があります)

投稿2020/06/08 07:51

yambejp

総合スコア116724

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yambejp

2020/06/08 07:54 編集

いまはその辺りブラウザ側である程度セキュアな処理がされている んじゃないでしょうか? どうしても怖い場合は、サーバー側で一度画像をフルカラーに展開して 保存し直すという手もないことはないでしょう。 (画像によっては再保存時に劣化します) ただそこまで作りこんでも運用上の費用対効果があるかどうかは微妙です。
kikijiji

2020/06/08 08:10

ありがとうございます。ご意見参考にさせて頂きます。 しかしながらやや抽象的で「普通にやれば大丈夫」「ブラウザ側がうまくやってくれる」などと言われてしまいますと、さすがプロは違うなという印象は受けますが… このたびの質問には、考えた方法に問題やセキュリティリスクがないか知りたいという内容でございますので、できればそのあたりについてのご意見がございましたらコメント頂けるとありがたく存じます。 仮に考えた方法にセキュリティリスクがないとしても、$_POSTで受け取ったテキストを簡易な検証を通してbase64で保存するより、$_FILESで受け取ったものをあれこれ大変な検証してでもurlを保存した方が、データベースに保存される量が少なくてすむ(base64の文字数とただのurlの文字数)という点で、考えた方法には問題があったりしそうにも思えましたので。
yambejp

2020/06/08 08:16

逆にbase64だなんだはどうでもいいです。 ポイントは受け取ったファイルをシステムが参照したり ユーザーのブラウザ上で表示したときに致命的なセキュリティ問題を 起こすか否かだけ気にしてください。 たとえばウィルスやトロイの木馬だってファイルのアップロード時には 紛れ込む可能性はあるわけです
hentaiman

2020/06/08 09:19

画像が大変=なぜ画像じゃなければ(画像と比べると)簡単なの?と逆の考え方した方がスッと思いつきやすいような。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問