PHP+MySQLで作られたWEBサイトの「セキュリティ」に関する質問です。


とりあえず今持っている知識で以下の対応をしました。

ユーザーからの入力データをextract($_POST)で受け取らない。

ユーザーからの入力データをSQLに渡す場合は全てmysql_real_escape_string処理をする。

ユーザーからの入力データを画面に表示する場合はhtmlspecialchars処理をする。


この3点のみ対処しました。


ただ、もちろん他にも様々な穴があると思います。そこで「こんな対処もしないとダメだよ」といったアドバイスをお願いします。

私の作っているサイト情報を実際に見ないと難しいのは重々承知しておりますが、「一般論」で構いません。総合的に技術を理解している方からのご意見をお待ちしております。

回答の条件
  • 1人2回まで
  • 登録:
  • 終了:2007/04/17 16:55:03
※ 有料アンケート・ポイント付き質問機能は2023年2月28日に終了しました。

回答3件)

id:kidd-number5 No.1

回答回数117ベストアンサー獲得回数15

ポイント27pt

Zend社が指針として出しているレベルは最低限おさえておくと良いのではないかなと思います。

http://www.zend.co.jp/tech/index.php?%A5%BB%A5%AD%A5%E5%A5%EA%A5...

(Zendの認定試験にはこの程度の内容が出題されてましたし)

id:tokyosmash

ありがとうございます。とりあえず3までは自分で意識しているつもりです。(もちろん穴はあると思いますが)

それより下はほとんど初めてみますね。これから勉強したいと思います。

2007/04/10 17:11:52
id:studioes No.2

回答回数523ベストアンサー獲得回数61

ポイント27pt

 範囲チェックを行う。

 例えば、1ページの表示数で10~50等のリストフォームがあって、これを元に項目を表示する場合、リスト値を書き換えられてマイナスであるとか、大きい数値を送られた場合に、膨大な処理を行うことでシステムの応答速度が低下する恐れがあります(DoS攻撃)

 ですので、範囲が10~50などと決まっているのならば、

if($val<1 or 50<$val) die();

 等のようにして、想定外の範囲を除去します。

id:tokyosmash

DoS攻撃ってよく見かけますがそういう事なんですね。検索結果をPear Pagerで制御しようと思っていたのですが、アドバイスを頭に入れて作ります。

もう古い話になるかもしれませんが、WEB2.0の基本的な概念として「ユーザーを信頼する」ってあると思います。とことん性善説ですよね。

でもサイトのバックエンドは全く逆の考え方で作らないといけないんだと認識してきました。アドバイスありがとうございます。

2007/04/10 17:24:38
id:kidd-number5 No.3

回答回数117ベストアンサー獲得回数15

ポイント26pt

PHPの界隈でセキュリティといえばこの人(と勝手に思ってます)

http://blog.ohgaki.net/

Pear::Auth使っているとの事ですが、

そしたらついでに(?)DB関連もPEAR::DBにしてみたらどうですか?

PEAR::DBのmysqlのクラスでは、内部的にこんな処理が入ってます。

明示的にescapeしなくても、ここを自然に通るようになっています。

    function escapeSimple($str)
    {
        if (function_exists('mysql_real_escape_string')) {
            return @mysql_real_escape_string($str, $this->connection);
        } else {
            return @mysql_escape_string($str);
        }
    }

(というわけで回答二回終わり~)

id:tokyosmash

なるほど、PEAR::DBはそんなに親切な事をやってくれるんですね。イマイチPEAR::DBを使うメリットというか意味がよくわかってなかったのですが、色々と便利な機能があるのでしょうか。ちょっと探ってみようと思います。

2007/04/10 17:30:11
  • id:tokyosmash
    追記させてもらいます。
    PHPとMySQLのバージョンは様々です。
    4も5も使っています。

    register_globalsはonです。
    これはちょっと危険みたいですね。

    メールフォームは設置していません。
    Pear Authで会員制サイトにしています。

    どのようなサイトか?という事を全く書いていませんでした。
    ・商品などにユーザーがレビューする。
    ・フォームから入力したレビューデータはMySQLに格納。
    ・検索はユーザー入力データをGETで飛ばします。

    このようなサイトです。漠然とし過ぎですね。

    セキュリティ関係がよくまとまっているサイトを紹介して頂くだけでも構いません。
    http://www.ipa.go.jp/security/awareness/vendor/programming/a01_02.html
    今はこちらのサイトを上から順番に読んでいる状態です。
  • id:studioes
    >もう古い話になるかもしれませんが、WEB2.0の基本的な概念として「ユーザーを信頼する」ってあると思います。とことん性善説ですよね。
    >でもサイトのバックエンドは全く逆の考え方で作らないといけないんだと認識してきました。アドバイスありがとうございます。
     そうですね。 利用者どころか、管理側も信頼せずに作ることもあります。
     例えば、最近問題になっている機密情報持ち出し問題などは、外部というより内部からの流出です。
     ですので、ECショップのシステムでも情報を扱えるレベル毎に分ける(発送係は宛先だけ、受注受付は注文内容とメールアドレスだけ等。 拘ってくると、メールも%KOKYAKU_SHIMEI等の様にタグを使って担当者に入力させて、送信システム内でお客様の情報に置き換えることで、情報を保護する等)もあります。

     ところで・・・
    >register_globalsはonです。
    >これはちょっと危険みたいですね。
     ちょっとではありません。 これは、
    extract($_POST)
     しているのと同意です。
    フォームとして<input type='text' name='i' value='10'>等と送られてくれば、PHPが実行された時点で$i=10です。 意図しない動作を起こす可能性があります。
  • id:tokyosmash
    >管理側も信頼せず

    確かに大きなニュースになってよくとりあげられていますよね。まあ自分の作るサイトは自分で管理しているのでその辺は心配ないですが。

    それから本名や住所・電話番号などはDBに入れないようにしています。できればメールアドレスも持ちたくないのですが、それだとメール認証が使えなくなるので困りものです。

    register_globalsがonの状態とoffの状態で何が違ってくるのかきちんと調べてみることにします。offにしたからと言って特に問題が発生するとは思えないので(勝手な推測ですけど)なるべくセキュリティ重視の設定にしようと思っています。

    ご丁寧にありがとうございます。
  • id:kidd-number5
    > フォームとして<input type='text' name='i' value='10'>等と送られてくれば、PHPが実行された時点で$i=10です。 

    「$iをプログラムの先頭で初期化していなければ」そうなります。
    これもZend認定試験対策本に出てきますよ。

    php.iniの設定によらないプログラムを書くことが脆弱性対策には有効になるわけなので、自分でini_setしてregister_globalsをoffにする、プログラム内で利用する変数はすべて初期化する。($i=""など)とかしておいたほうが良いかも。

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

回答リクエストを送信したユーザーはいません