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

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

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

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

PHP

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

Q&A

4回答

2948閲覧

画像ファイルの受け取り方

ssk

総合スコア332

MySQL

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

PHP

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

0グッド

0クリップ

投稿2015/09/27 06:21

編集2015/09/27 06:36

PHPとMySQLを使用して、画像のアップロードを行っています。
独学のため、その際のセキュリティがわかりません。。

例えば、画像ファイルの語尾にダブルコーテーションやシングルコーテーション
など、不要なものがある場合、どのように処理しているのでしょうか?

画像ファイル名に対して、htmlspecialcharsですかね?
初歩的な質問ですが、ご教授願います><

追記

accept="image/gif, image/jpeg"

などを指定するだけで大丈夫なのでしょうか?

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

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

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

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

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

guest

回答4

0

画像のアップロードに限らずPHP開発者が知るべき
セキュリティ問題として以下のようなものがございます。

クロスサイト・スクリプティング(XSS)
SQL インジェクション
ディレクトリ・トラバーサル
OS コマンド・インジェクション
クロスサイト・リクエストフォージェリ(CSRF)
セッション・ハイジャック
HTTP ヘッダー・インジェクション
メールヘッダー・インジェクション

これらに対しては十分い対策がなされなければなりません。
セキュリティ対策例も含めて
https://blog.codecamp.jp/php_security
に色々と例が載っているので参考にされてはいかがでしょうか?

投稿2016/09/01 11:31

Yatsurugi

総合スコア1628

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

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

raccy

2016/09/01 13:08

上げていただいたセキュリティ問題について、今回は一体どれが問題になるとお考えなのでしょうか?
guest

0

アップロードされた画像ファイルをサーバー上に保存するときにどのようなファイル名にするか、また、直接アクセスするURL(許すかどうか別として)はどうなるかという話で良いでしょうか?

ファイル名に使える文字というのはサーバーが動いているOSによって変わってきます。単純に漢字や平仮名などがが使えないかも知れないという話だけではなく、":"や"/"、""などの記号もOSによって違います。例えば":"はWindowsでは使えませんが、Linuxでは使えると言ったようにです。ただ、少なくともアルファベット(a-b)と数字(0-9)おおび一部の記号(._)などは使えます。ただ、"."は拡張子の区切り文字以外に使われることはお勧めできません。"."と".."という特殊なファイル名が存在することと、UNIX/Linuxでは"."から始まる文字は隠しファイルになるという性質があるからです。

そこで採用するのが、そういった使える文字以外は削除してしまう、または、規則的に書き換えてしまうと言う方法があります。重複してしまった場合は後ろに連番をつけるなどの工夫をします。また、ファイルシステムによってはファイル名の大文字小文字を区別するのか区別しないのか分かれる場合があります。そのような場合の混乱を避けるため、全て小文字にするという処理します。今はLinuxだけしか考えてないから…ではなく、これってWindowsでも動くよね?と言われることに備えるというのも大事です。

また、文字数にも気をつけなければなりません。これもOSによってはファイルの文字数が決まっています。また、パスによっても変わってきます。

最後に、拡張子を考慮しましょう。アップできるのがjpegやpngなど決まっているのであれば、拡張子があっていなければ弾いても良いでしょう。

忘れるところでした。ファイル名にはそれまでのディレクトリへのパスがつけてあるかもしれません。階層構造は不要ですし、時にはセキュリティ上の問題が起きる場合がありますので、ディレクトリの部分はすべて切り捨てましょう。

まとめると一例として次のような処理になります。

  1. ファイル名を拡張子を除いたファイル名部分と拡張子に分解します。pathinfo()を使うと良いでしょう。ファイルパスのディレクトリの部分は無視します。
  2. 拡張子が想定のフォーマットで無ければ拒否します。なお、フロント側でJavaScriptを使って拒否する場合であっても、必ずPHP側にも拒否する処理を入れてください。フロント側のJavaScriptによるチェックを回避した悪意あるアクセスをすることで、想定外のファイルがアップロードされる可能性があります。
  3. 拡張子以外のファイル名部分について次のように書き換えます。

(1) 英数字および""の記号以外は全ての文字を""にします。
(2) 英大文字は英子文字にします。
(3) 文字数が60文字(この文字数は適当にきめてください)を越える場合は60文字まで切り詰めます。
4. 処理したファイル名と拡張子(これも小文字化しておく)でファイル名を作ります。
5. もし、同じファイル名が存在する場合は、"ファイル名_1.拡張子"とつけます。_1もあれば_2、_3と増やしていきます。

細部は異なりますが、Drupalが上記のような方法を取っています。Drupalはアップロードされたファイルを直接見に行くURLになるため、ファイル名はなるべく変わらないようにしたいという配慮のようです。


さて、上の方法はあくまでアップロードされたファイルのファイル名をなるべく残したい場合です。特にそのような事情が無ければ、アップロードされたときのファイル名を無視して、サーバに保存するファイル名を決めた方が良いでしょう。ファイル名を変換していくという面倒な処理も少なくてすみます。

その1 連番

連番でつけるのは最も簡単に思えるかも知れません。しかし、あまりお勧めできません。なぜなら、重複しないように連番を管理している所(DB内のどこかのレコードになるでしょうか)について排他ロック処理をしなければたちまち重複しておかしくなってしまいます。もう一つ気をつけるのが番号から他のファイルの存在が知られることです。もし、URLで直接アクセス可能にしている場合、番号をずらして他のファイルに簡単にアクセスできるようになってしまうかも知れません。何をアップロードするかによりますが、セキュリティ上の不具合と見なされる場合があります。

その2 タイムスタンプ

現在時刻からファイル名を作る方法です。この方法の利点は排他ロックという重い処理が不要なことです。ただ、本当に同時にアップロードされてファイル名が重複する可能性はあります。fopen()に"x"オプションをつけるなど、重複したときはわざと書き込みが失敗するなどの工夫が必要です。連番よりは他のファイルは推測しにくいですが、完全ではありません。

その3 ランダム

十分な長さのランダムな英数字にします。ファイル名が重なる可能性が極僅かに存在しますが「その2」と同じ対策を行えば十分でしょう。他のファイルのファイル名を推測することはほぼ不可能です。乱数に暗号論的擬似乱数(PHPではopenssl_random_pseudo_bytes()などを使います)を使えばさらに推測は不可能になり、より安全です。


以上になりますが、他サービスがどのようになっているかを見てみるのもいいかもしれません。例えば、このteratailのユーザーのアイコン画像はランダムな英数字のファイル名になっています。アップロードされたときのファイル名をなるべく保ちたいという事情が無ければ、ランダムにするのが一番良いのではないかと思います。

投稿2016/09/01 12:51

編集2016/09/01 13:04
raccy

総合スコア21735

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

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

0

例えば、画像ファイルの語尾にダブルコーテーションやシングルコーテーション

アップロードの時に、ファイル名を指定させると言うことでしょうか?

ファイル名に使える文字を決めて、それ以外の文字があったら、自動的に削除や置換するので無く、エラーで再入力させるのがいいかと思います。
ユーザーの利便性を考えると、JavaScriptでそもそも決めた文字しか入力できないというのが優しいです。
その場合でもサーバー側でのチェックは必要です。

画像ファイル名に対して、htmlspecialcharsですかね?

htmlspecialcharsは、データをHTMLとして画面出力するときに使う関数なので、全く関係ありません。

投稿2015/09/27 10:20

編集2015/09/27 10:22
otn

総合スコア84538

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

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

ssk

2015/09/28 03:02

javascriptで指定して、サーバー側でもチェックさせる形、、、 ざっくりとした参考コードをいただけますでしょうか? イメージができず、、、、><すいません。
guest

0

入力チェックで不都合なファイル名は弾いてしまうか、
アップロードされた時点で、システム連番にファイル名を変えてしまうのはいかがでしょうか。

ファイル名をそのまま使う懸念は、マルチバイトだった時の文字化けです。

投稿2015/09/27 07:07

TetsujiMiwa

総合スコア1124

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

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

ssk

2015/09/28 03:04

>ファイル名をそのまま使う懸念は、マルチバイトだった時の文字化け たしかにそうですね!そこを考慮していませんでした。ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問