【PHP】画像アップローダのセキュリティ対策

このQ&Aのポイント
  • 画像アップローダのセキュリティについて考えます。サイトにおいて、画像をアップロードできる機能がある場合、セキュリティ上の課題が生じます。特に、画像の削除機能において、POSTやGET値の改ざんにより他の人がアップロードした画像データを消すリスクがあります。
  • これを防ぐためには、本人がアップロードしたもののみを削除できるようなロジックを組み立てる必要があります。具体的には、画像ファイルに対して一意な識別子(IDやハッシュ値)を付与し、削除リクエスト時にその識別子を使用することで、データベース上で正確に対象の画像を特定することができます。
  • また、セキュリティを高めるためには、POSTやGETなどのリクエストパラメータの改ざんが困難な形式でデータを送信することが重要です。たとえば、データベースにはハッシュ値を保存し、画像ファイル自体にはそのハッシュ値を含めないようにすることで、改ざんに対する防御策を取ることができます。
回答を見る
  • ベストアンサー

【php】画像アップローダのセキュリティ

マイページのプロフィール画像等、 画像をアップロードできる機能があるサイトを作成した場合 とあるディレクトリに、そのすべてのデータが入っていくとします。 image_22_00001.jpg image_02_00002.jpg image_45_00005.jpg というような感じで、あるルールにそってファイル名がついていくとして 削除ボタンのようなフォームで削除する場合、 「IDが02の 00002番目の画像をを削除しろ」  ↓ image_02_00002.jpg 削除 というプログラムを書くとします。 しかし、もし、POSTやGETでIDや番号を送ってしまうと、 POSTやGET値を改ざんするだけで ディレクトリに入ってる他の人がアップロードした画像データ等 どんな画像データでも消せてしまうことになります。 データベースに image_02_00002_XXXXXX(ハッシュ値) で登録するにしても、 データベースを呼び出すとき、どのレコードに入ってるデータを削除するか という指定をする時にデータベースのクエリで使うID等を改ざんすることで 好きなレコードの画像を削除することができます。 このようにPOST、GETの改ざんをされても 本人がアップしたもののみしか削除できないような ロジックはどのようにして組み立てたらよいものなのでしょうか?

  • PHP
  • 回答数1
  • ありがとう数1

質問者が選んだベストアンサー

  • ベストアンサー
  • shimix
  • ベストアンサー率54% (865/1590)
回答No.1

掲示板の記事編集・削除でも「最初に(その投稿に)設定したパスワード」を必須にしていることが多いですよね。 普通は「画像データ」とは別にテキストファイルやデータベースに「アップロードしたユーザ、パスワード、元ファイル名、保存したファイル名」などを記録しておくと思います。

yuzuru0024
質問者

お礼

回答有難うごいます。 なるほど、アップした本人しか知り得ない情報も 一緒に画像データの情報の入ったテーブルに保存しておくのですね。

関連するQ&A

  • 【php】画像のアップロードの方法

    画像のアップロードは大きく分けて以下の3つの方法があると思います (1) ●画像を (ユニークID).jpg の名前で保存 呼び出すときは、ユニークIDに紐付いた画像を呼び出す。 (2) ●画像を (任意のファイル名).jpg の名前で保存 同時に、画像のファイル名をデータベースに保存。 呼び出すときはデータベースに保存されたファイル名に紐付いた画像を呼び出す (3) ●画像データをデータベースに直接保存 呼び出すときは、データベースから呼び出す どの方法が一番いいでしょう?

    • ベストアンサー
    • PHP
  • RailsでRMagick不要の画像アップローダー

    タイトルのままになってしまいますが 現在作成中のサイトで画像のアップロード機能が必要なのですが 正直、環境構築時の鬼門のImageMagickで困っています 人に作ったものを見せるためには Cent,Ubuntu,Macのそれぞれの環境で比較的簡単に環境を作れる必要があるので ImageMagick不要の画像アップロードPlug-inを探しています * jpg,pngの画像拡大縮小だけ出来ればいい * データはDBか指定したディレクトリのどちらかだけにアップロード出来ればいい という条件なのですが、どなたかご存じないでしょうか?

    • ベストアンサー
    • Ruby
  • PHP 画像アップローダー作成について

    PHPの勉強をしている者です。 ローカル環境(XAMPP1.7.3)にて、画像アップローダーを動かそうと試みています。 が、一時ファイル名が取得できず、失敗に終わります。初歩的なミスかもしれません。 -------------------- 【upload.html】 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>画像ファイルアップロード</title> </head> <body> <h1>画像ファイルアップロード</h1> <p>アップロードする画像ファイル(JPEG形式)を選択して「アップロード」ボタンを押してください。</p> <form action="upload_image.php" method="POST" enctype="multipart/form-data"> <table> <tr> <th>画像ファイル選択</th> <td><input type="file" name="filename" size="50"></td> </tr> <tr> <td colspan="2"> <input type="submit" value="アップロード"> </td> </tr> </table> </form> </body> </html> -------------------- 【upload_image.php】 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>画像ファイルアップロード</title> </head> <body> <h1>アップロードファイル情報</h1> <p> <?php // ファイル名の取り出し $file_name = $_FILES['filename']['name']; // ファイル(MIME)タイプの取り出し $file_type = $_FILES['filename']['type']; // 一時ファイル名の取り出し $temp_name = $_FILES['filename']['temp_name']; // エラーコードの取り出し $upload_error = $_FILES["filename"]["error"]; // 保存先のディレクトリ $dir = 'uploads/'; // 保存先のファイル名 $upload_name = $dir . $file_name; // JPEG形式のファイルをアップロードする if (($file_type == "image/jpeg") || ($file_type == 'image/pjpeg')) { // アップロード(移動) $result = move_uploaded_file($temp_name,$upload_name); if ($result) { // アップロード成功時 echo '■アップロード成功'; } else { // アップロード失敗時 echo '■アップロード失敗'; } } else { // JPEG形式以外のファイルはアップロードしない echo '■JPEG形式の画像をアップロードしてください。'; } ?> </p> <table> <tr> <td colspan="2"><img src="<?php echo $upload_name; ?>" alt=""></td> </tr> <tr> <th>エラーコード</th> <td><?php echo $upload_error; ?></td> </tr> <tr> <th>画像ファイル名</th> <td><?php echo $file_name; ?></td> </tr> <tr> <th>MIMEタイプ</th> <td><?php echo $file_type; ?></td> </tr> <tr> <th>一時ファイル名</th> <td><?php echo $temp_name; ?></td> </tr> </table> </body> </html> -------------------- 【php.iniの一部】 ;;;;;;;;;;;;;;;; ; File Uploads ; ;;;;;;;;;;;;;;;; ; Whether to allow HTTP file uploads. ; http://php.net/file-uploads file_uploads = On ; Temporary directory for HTTP uploaded files (will use system default if not ; specified). ; http://php.net/upload-tmp-dir upload_tmp_dir = "C:\xampp\tmp" ; Maximum allowed size for uploaded files. ; http://php.net/upload-max-filesize upload_max_filesize = 128M -------------------- このように作っております。 結果は エラーコード→0 画像ファイル名→正常取得 MIMEタイプ→正常取得 一時ファイル名→空 どのような原因が考えられるか、教えて頂ければ幸いです。

    • ベストアンサー
    • PHP
  • 画像のアップについて

    画像のファイルは、フォルダにアップロードされているが、 画像のファイル名が、データベース上に 登録されません。データーベースにいれるソースがわかりません。フィールドにgazoを作成してあります。他のデーターはインサートします。$insertSQL = sprintf("INSERT INTO uru)・・・GetSQLValueString($HTTP_POST_VARS['daimei'], "text"),・・ではいります。よろしくご指導をお願いいたします。

  • PHPでajaxを利用してデータ更新の方法

    PHPでAJAX操作をしてデータ更新をしたいです。 たとえば削除ボタンが10個あって削除ボタンを押すとデータベースを更新して画像名をnoimage.jpg(デフォルト値)にします。 そして削除ボタンを無効化したいです。 こういうことってできるでしょうか? ボタンに割り振っているidはimage1からimage10としています。 JS側でどういうふうに受け取ってDBに渡せばいいか分かりません。 教えて下さい。 よろしくお願いします。

    • ベストアンサー
    • PHP
  • アップローダーの作製

    お世話になります。 アップローダーでmp4をUPしたいです。 下記の様なフォームを記述したところ、jpegはUP出来たのですが、mp4はアップできませんでした。 フォーム-------------------------------------------------------------------------------------- <?php //アップローダー function upload(){ $filename = $_GET["onamae"]; $max = 1024*1024*10; $array = array("01.jpg","02.jpg","03.jpg","pv.mp4"); for($i = 0; $i < count($array); ++$i){ ?> <div> <form method="post" enctype="multipart/form-data" action="uploader.php"> <input type="hidden" name="MAX_FILE_SIZE" value="<?php print $max; ?>"> <input name="userfile" type="file"> <input type="submit" value="アップロード" name="up"> <input name="filename" type="hidden" value="<?php print $array[$i]; ?>"> <input name="filemei" type="hidden" value="<?php print $filename; ?>"> </form> </div> <?php } } ?> uploader.php--------------------------------------------------------------------------------- <?php $filedir = "../girl/" . $_POST["filemei"] . "/" . $_POST["filename"]; $file_path = $filedir ; if(move_uploaded_file($_FILES['userfile']['tmp_name'], $file_path)){ ?> <div class="message">ファイルのアップロードに成功しました。</div> <?php } else{ ?> <div class="message">ファイルのアップロードに失敗しました</div> <?php } ?> ---------------------------------------------------------------------------------------------- 記述ミスあるかもです。すいません。

    • 締切済み
    • PHP
  • PHPでDBとディレクトリへの画像データ登録方法

    初めて質問させていただきますPHP初心者です。 画像投稿画面を作り、DB(imageフィールド)と任意のディレクトリ(member_picture)へ画像を保存するページを考えてます。 下記が作ったソースになるのですが、 id、message、titleフィールドにはちゃんと投稿内容が入るのですが、 どうしてもimageだけがフィールドにもディレクトリにも入りません。 アドバイスいただけますでしょうか。 <?php session_start(); if(!empty($_POST)) { //画像エラーの確認 $fileName = $_FILES['image']['name']; if(!empty($fileName)) { $ext = substr($fileName, -3); if($ext !='jpg') { $error['image'] = 'type'; } } if(empty($error)) { //画像をアップロードする $image = date('YmdHis') . $_FILES['image']['name']; move_uploaded_file($_FILES['image']['tmp_name'], '../member_picture/' . $image); $_SESSION['join'] = $_POST; $_SESSION['join']['image'] = $image; header('Location: content_upload.php'); } } //記録する if (!empty($_POST)) { if ($_POST['title'] !='') { $sql = sprintf('INSERT INTO post SET member_id=%d, message="%s", title="%s", image="%s", created=NOW()', mysql_real_escape_string($member['id']), mysql_real_escape_string($_POST['message']), mysql_real_escape_string($_POST['title']), mysql_real_escape_string($_POST['image']) ); mysql_query($sql) or die(mysql_error()); header('Location: content_upload.php'); } } ?> <!DOCTYPEうんぬん・・> <html うんぬん・・> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <link rel="stylesheet" type="text/css" href="style.css" /> <title>画像投稿ページ</title> </head> <body><div id="wrap"> <div id="head"><h1>画像投稿ページ</h1></div> <form action="" method="post" enctype="multipart/form-data"> <dl><dt>投稿画面</dt> <dd>画像<br> <input type="file" name="image" /> <?php if($error['image'] == 'type'): ?> <p class="error">* 画像は「.jpg」の画像を指定してください</p> <?php endif; ?> <?php if(!empty($error)): ?> <p class="error">* 恐れ入りますが、画像を改めて指定してください</p> <?php endif; ?> </dd> </dl> <div> <p><input type="submit" value="投稿する" /></p> </div> </form> </div> </div> </body> </html> 以上になります。 どこを注意したらいいのかもわからず困ってます! よろしくお願いいたします。

    • ベストアンサー
    • PHP
  • DBへの画像の挿入について

    現在filemakerPro6 windowsにて画像管理のデータベースを作成しているのですが、画像の挿入で不明に思った点があったので質問しました。 やろうとしていることは、 スクリプトでローカルのフォルダ内の画像(「レコードID」_a~f.jpgの名前で統一)を、ファイル名の_a~fで判別させて、各フィールド(画像a~f)に挿入 としたいのですが、 計算結果に "image:/D:/フォルダ名/" & レコードID & "_a.jpg" を試してみましたが上手く行かず(パスに変数が使えるのはver8から?) リレーションを使用すれば同じようなことが出来るのかと思いましたが、そこでも行き詰っている段階です。 (画像の一覧のデータベースからファイル名(1234_a.jpg)を参照してサムネイル画像をリレーションで表示できないものか…と) 上記と同等の処理を実現出来そうな方法が無いか、ご存知の方がいらっしゃればご教授お願いします。

  • PHPの画像アップ時の拡張子制限とエラー表記の方法

    PHP初心者です。画像をDBにアップロードする際jpgの場合のみアップできるようにして、 それ以外の場合エラーメッセージを表記させたいのですが、上手くいきません。 下記がソースになります。 if(!empty($_POST)) { if($_POST['image'] == '') { $error['image'] = 'blank'; } //画像エラーの確認 $fileName = $_FILES['image']['name']; if(!empty($fileName)) { $ext = substr($fileName, -3); if($ext !='jpg') { $error['image'] = 'type'; } } if(empty($error)) { //画像をアップロードする $image = date('YmdHis') . $_FILES['image']['name']; move_uploaded_file($_FILES['image']['tmp_name'], '../member_picture/' . $image); $_SESSION['join'] = $_POST; $_SESSION['join']['image'] = $image; header('Location: content_upload.php'); } } //メッセージを記録する if (!empty($_POST)) { if ($_SESSION['join']['image'] !='') { $sql = sprintf('INSERT INTO post SET member_id=%d,message="%s", title="%s", image="%s", created=NOW()', mysql_real_escape_string($member['id']), mysql_real_escape_string($_POST['message']), mysql_real_escape_string($_POST['title']), mysql_real_escape_string($_SESSION['join']['image']) ); mysql_query($sql) or die(mysql_error()); header('Location: content_upload.php'); } } (以下body) <form action="" method="post" enctype="multipart/form-data"> <dl> <dt>ログイン名:<?php echo $member['name']; ?>投稿画面<br><br>タイトル</dt> <dd> <input type="text" name="title" size="35" maxlength="255" value="<?php echo h($_POST['title']); ?>" /> </dd> <dt>メッセージ</dt> <dd> <input type="text" name="message" size="35" maxlength="255" value="<?php echo h($_POST['message']); ?>" /> </dd> <dt>写真 <span class="required">必須</span></dt> <dd> 画像<br> <input type="file" name="image" /> <?php if($error['image'] == 'type'): ?> <p class="error">* 画像は「.jpg」の画像を指定してください</p> <?php endif; ?> <?php if($error['image'] == 'blank'): ?> <p class="error">* 恐れ入りますが、画像を改めて指定してください</p> <?php endif; ?> </dd> </dl> <div><p><input type="submit" value="投稿する" /></p></div> </form> 「//メッセージを記録する」で画像がないと何もDBに入らないようにしたはずですがtitleとmessageは必ず入り、違う拡張子の画像を入れても「date('YmdHis')」部分だけは入ってしまいます。 エラーメッセージはどうしても出ません。初歩的なミスかもしれませんが宜しくお願いします

    • ベストアンサー
    • PHP
  • Ajaxで画像の削除

    Ajaxで画像を削除しようといろいろ試行錯誤しているのですが、 最終的なところで詰まっています。 $(function(){ $("input:button").click(function(){ //クリックされた画像のidを取得 var id = $(this).attr("id");   alert(id); //削除ボタンの無効化 $(this).attr("disabled",true); //idをサーバに送信(PHP側で削除処理)して結果を受け取る $.ajax({ url : "/test/delete_image", dataType : "json", data : {id:id}, type : "post", success : function(data){ if(data.id){ alert(data.id); $("#tblh img#image"+data.id).attr("src","/images/noimage.gif"); } }, error : function(){ alert("通信に失敗しました。"); } }); }); }); codeigniterというフレームワークを利用しPHP側では画像をディレクトリから削除しています。(こちらの動作は問題なし) <?php class Delete_image extends CI_Controller { function __construct(){ // Model クラスのコンストラクタを呼び出す parent::__construct(); $this->load->model('array_constant'); $this->load->helper(array('form', 'url')); $this->load->library('form_validation'); $this->load->library('form_ex'); } function index(){ if(!$this->input->post("id")){ return false; }else{            //画像の削除とDBの画像名称を更新 $arr = array('id' => $this->input->post("id")); } echo json_encode($arr); } } としています。 画像の削除とDBの画像名称は更新されてるのでPHP側は問題ないようです。 jsonの値を受け取って画像を置き換えようとしているのですが、エラー側のほうに 判断されてしまいます。「alert("通信に失敗しました。");」となります。 なぜか分からず困っています。 教えてください。

    • ベストアンサー
    • AJAX

専門家に質問してみよう