• ベストアンサー

セキュリティ

プログラム初心者です PDOやる前にmysqliの手続き型で勉強中です 手続き型でフォームから入力された値をこんな感じにするのは危険でしょうか? 悪意を持ったユーザーに簡単に突破されますか? if(!empty($_POST['name'])){ $sql = sprintf('SELECT * FROM hoge WHERE name="%s"', mysqli_real_escape_string($link,$_POST['name']) ); } 更新するとき if(!empty($_POST['name'])){ mysqli_query($link,sprintf('UPDATE hoge SET name="%s" WHERE id=%d', mysqli_real_escape_string($name), mysqli_real_escape_string($link,10) )); } よろしくお願いします

  • flash0
  • お礼率97% (297/306)
  • PHP
  • 回答数1
  • ありがとう数1

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

  • ベストアンサー
noname#244856
noname#244856
回答No.1

セキュリティ上の危険はないと思いますが、普通はプリペアドステートメントを使います。 http://php.net/manual/ja/mysqli.prepare.php 【習得難易度】 [○] Mysql関数(非推奨) < PDOクラス < Mysqli関数 = Mysqliクラス [△] 【おすすめ度】 [○] PDOクラス > Mysqliクラス > Mysqli関数 > Mysql関数(非推奨) [△] Mysqliから入ってもいいですが、かえって足かせになるような気がしないでもないですね・・・Mysqliをわざわざ選ぶ人と言えば「チューニングに拘るベテラン」か「クラスとオブジェクトを毛嫌いする初心者」ぐらいしかいないでしょう・・・ 以下蛇足 emptyはissetの機能に加えて空文字列を弾くようにもなっていますが、空文字列だけでなく文字列「0」を弾いてしまいますので、一般的にはあまり用いられません。 http://php.net/manual/ja/types.comparisons.php 厳密に「空でない文字列」だけを許容するようにしたければ if ( ____isset($_POST['name']) && ____is_string($_POST['name']) && ____$_POST['name'] !== '' ) { .... .... } という条件になります。 http://qiita.com/mpyw/items/2f9955db1c02eeef43ea 各項目に対して毎回このように記述するのが煩わしかったり、配列をフォームから受け取る必要があって子要素までの厳密なチェックが手に負えなくなると感じる場合、こういった関数を用意しておくのも1つの手です。 http://qiita.com/mpyw/items/c39b9ee695a5c2e74627 「ここまで厳密にしなくても本番環境ではどうせdisplay_errors=Offだからいいじゃん」と言われればそれまでですが、気になるならばここまでやっておいても損はないでしょう。

flash0
質問者

お礼

回答ありがとうございます 手続き型でもプリペアドステートメント使えるんですね。勉強になりました emptyも使い方を気を付けます。

関連するQ&A

  • チェックする方法

    プログラム初心者です $nameと$mailをDBに登録してあるか調べたいのですが sqlを一回だけ発行で調べる方法はありますか? //名前とメールを取得して重複チェック $name2 = mysqli_query($link,sprintf('SELECT name FROM table WHERE name="%s"', mysqli_real_escape_string($link,$name) )); $data = mysqli_fetch_assoc($name2); if(isset($data['name'])==$name){ throw new Exception('noname'); } $name3 = mysqli_query($link,sprintf('SELECT mail FROM table WHERE mail="%s"', mysqli_real_escape_string($link,$mail) )); $data2 = mysqli_fetch_assoc($name3); if(isset($data2['mail'])==$mail){ throw new Exception('nomail'); } よろしくお願いします

    • ベストアンサー
    • PHP
  • 空文字のアップデート

    mysql初心者です phpとmysqliを使っています テーブルhogeにid、gifとカラムがあります gifのカラムを空にしたいのですがこんな感じでいいでしょうか? mysqli_query($link,sprintf('UPDATE hoge SET gif="%s" WHERE id=%d', "", mysqli_real_escape_string($link,$id) )); よろしくお願いします

    • ベストアンサー
    • MySQL
  • テストdataの作成について

    プログラム初心者です テスト用にmysqlのテストdataをつくりたいです PHPでダミーDATA10万件をinsertする方法を教えてください カラムはuser_id gif_id tag の三つです user_id gif_idはなにも記入しなくてもいいです。(数字が入る予定です) tagはあ~お、か~こまで1文字をランダムに値を変化させながら入れられますか?(無理なら同じタグでいいです) XAMPP(ローカル)で作るので負荷かかってもかまいません mysqli_query($link,sprintf('INSERT INTO tag(user_id,gif_id,tag) VALUES(%d,%d,"%s"),(%d,%d,"%s","%s")', mysqli_real_escape_string($link,$id), mysqli_real_escape_string($link,$gif_id), mysqli_real_escape_string($link,$tag), mysqli_real_escape_string($link,$id), mysqli_real_escape_string($link,$gif_id), mysqli_real_escape_string($link,$tag2) )); よろしくお願いします

    • ベストアンサー
    • PHP
  • パスワードの暗号化

    php+mysqlでシンプルな会員登録を作りたいのですがパスワードは暗号化したほうがいいですか? パスワードを簡単に暗号化できる方法はありますか? postされたpassと暗号化されたpassのチェック方法がわかりません ログイン if ($_POST['id'] !='' && $_POST['pass'] !='') { $sql = sprintf('SELECT * FROM hoge WHERE id="%s" AND pass="%s"', mysql_real_escape_string($_POST['id']), mysql_real_escape_string($_POST['pass']) ); $record = mysql_query($sql) or die(mysql_error()); if ($table = mysql_fetch_assoc($record)) { $_SESSION['id'] = $table['id']; $_SESSION['name'] = $table['name']; } else { //エラー }

    • ベストアンサー
    • MySQL
  • mysql危険回避(1 OR effective)

    mysqlの危険回避の質問です。 (私がした1つ前に質問したものでは、解決しなかったので再度表現を変えて行います。) mysqlでwhere句の値に 1 OR effective=0 が入ると危険であり、シングルクオテーションで回避できる、とあるサイトでみました。 それを踏まえ、それまで以下の(1)で動いていたものを(2)にしたら、動かなくなりました。 そこで質問です。 (初めてphpに触れた人に教えるレベルで、かなり噛み砕いて教えていただけたら幸いです。) ■(1)はそのままでは危険という認識でよろしいですか? ■(2)はなぜ動かないのでしょうか? ■(1)を危険のない(もしくは可能な限り危険のない)書き方をするとしたらどうしたら いいでしょうか?(PDOで書く事!やmysqliがいい、というのは知っています。 どうしてもmysql_real_escape_stringを使わなくてはいけないという条件があったと 想定して強引にやるとしたらどうか、という事でお答えをいただければと思います。) (1) $sql = sprintf("SELECT id , password FROM `adminDatabase` where id = '%s' and password = '%s' order by id", mysql_real_escape_string($id), mysql_real_escape_string($password)); (2) $id = "'" . mysql_real_escape_string($id) . "'"; $password = "'". mysql_real_escape_string($password) . "'"; $sql = sprintf("SELECT id , password FROM `adminDatabase` where id = '%s' and password = '%s' order by id",$id , $password ); よろしくお願いします。

    • ベストアンサー
    • MySQL
  • 重複が

    新規登録の時の重複をチェックしたいです テーブルのカラムはシンプルにidとnameとpassだけです nameに同じ名前の人がいると困るので、HTMLフォームから送られた名前と登録してある名前の重複がないかチェックするようにできますか? やってみましたが動きません(ーー;; $name = mysql_real_escape_string($_POST['name']); $name3=array(); $name2 = mysql_query('SELECT name FROM hoge2 WHERE name=$name'); while($data = mysql_fetch_assoc($name2)) { array_push($name3, $data['name']); } if(isset($name3)){ print "重複があります"; }else{ //ここからsql $sql = sprintf('INSERT INTO hoge2 SET name="%s", pass="%s"', $name, mysql_real_escape_string($_POST['pass']) ); //ここまで mysql_query($sql) or die(mysql_error()); }

    • ベストアンサー
    • MySQL
  • phpのif文について

    phpでログイン処理のif文を書いています。 nameとpasswordのフィールドが記入されているのかをチェックするif文を書いたのですが、機能してくれません。何かが間違っているのでしょうか。 何も入力しないor間違った情報を入力する ということをしてもログインが出来てしまいます。 どなたかテェックお願い致します。 <?php require('dbconnect.php'); session_start(); if ($_COOKIE['name'] != '') { $_POST['name'] = $_COOKIE['name']; $_POST['password'] = $_COOKIE['password']; $_POST['save'] = 'on'; } if (!empty($_POST)) { // ログインの処理 if ($_POST['name'] != '' && $_POST['password'] != '') { $sql = sprintf('SELECT * FROM members WHERE name="%s" AND password="%s"', mysql_real_escape_string($_POST['name']), sha1(mysql_real_escape_string($_POST['password'])) ); $record = mysql_query($sql) or die(mysql_error()); if ($table = mysql_fetch_assoc($record)) { // ログイン成功 $_SESSION['id'] = $table['id']; $_SESSION['time'] = time(); // ログイン情報を記録する if ($_POST['save'] == 'on') { setcookie('name', $_POST['name'], time()+60*60*24*14); setcookie('password', $_POST['password'], time()+60*60*24*14); } header('Location: index.php'); exit(); } else { $error['login'] = 'failed'; } } else { $error['login'] = 'blank'; } } ?>

    • ベストアンサー
    • PHP
  • PHPのSQLインジェクションはsprintf?

    PHPのSQLインジェクションですが、sprintf内でクォートをしてあるとそれで大丈夫なのでしょうか? 以下のようなコードがあり、nameは画面入力なのでSQLインジェクションが起こるのでは? と作成者に確認したところ、"%s"してあるから大丈夫との返事をもらいました。 ネット調べるとmysql_real_escape_stringでエスケープしてから"%s"で変換すれば大丈夫といった内容は見つけたのですが、mysql_real_escape_stringなど不要との返事をもらいました。 なぜ?と聞くとそういうものだとしか回答がありません。 sprintf('UPDATE users SET name = "%s" WHERE id = %d', name, id); 結局上記のコードでSQLインジェクションは解消されているのでしょうか?

    • ベストアンサー
    • PHP
  • 画像削除機能を付けたい

    php初心者です 以前教えていただいたサンプルを元に phpとmysqliの手続き型で画像アップ機能を作りたいです サンプルでは削除機能がないので、削除機能を付けたいと思いました 付けたい機能 1.画像削除機能 2.画像一覧表示(そのひとがアップしている画像を取得して一覧表示、その画像のしたに削除チェックを付けたい) 以前教えていただいたサンプル http://qiita.com/mpyw/items/73ee77a9535cc65eff1e 素人なりに考えてみましたが頭パンクしました 失敗作 フォーム失敗作 しかし、DBから取得した画像と、削除チェックの位置を合わせられませんでした <div> <p>画像表示一覧</p> <form method="POST" action=""> ここに画像1(gif) 削除チェック<input type="checkbox" name="deletefile[]" value="1"> ここに画像2(jpg) 削除チェック<input type="checkbox" name="deletefile[]" value="2"> <input type="submit" value="削除ボタン" name="btn"> </form> </div> DBのgifのテーブルのカラムはidとuser_idとgif(画像名)にしています どんどんINSERTで登録していく感じになっています(テーブル設計も自信ありません・・・) 受け取るphpの上のほうに記述したもの ※セッションidから会員の画像名を取得 session_start(); $id = $_SESSION['id']; $sql= mysqli_query($link,sprintf('SELECT * FROM gif WHERE user_id=%d', mysqli_real_escape_string($link,$id) )); $data = mysqli_fetch_assoc($sql); if(isset($_POST["deletefile"])){ if(isset($data['gif'])){ if(unlink("img/".画像名 )){ mysqli_query($link,sprintf('DELETE FROM gif WHERE id=%d', mysqli_real_escape_string($link,画像の番号) )); $mes = "削除しました"; }else{ $mes = "削除失敗"; } } } 新しくサンプルいただけると助かります よろしくお願いします

    • ベストアンサー
    • PHP
  • PHPのPDOについて

    例えば手続き型でしたら、値をデータベースに追加するとき $sql = sprintf( 'INSERT INTO member SET id=%d, message="%s" ', mysql_real_escape_string($id), mysql_real_escape_string($message) ); mysql_query($sql) or die(mysql_error()); など「mysql_real_escape_string」を使って多少なりともセキュリティーをかけると思うのですが、PDOですと下記に書かれている以外に見たことないのですが、「mysql_real_escape_string」などはやらなくても大丈夫ということなのでしょうか? PDOの場合 $sql = 'INSERT INTO member SET id=?, message=?'; $stmt = $db->prepare($sql); $stmt->execute(array($id, $message)); 色々調べてみたのですがいまいち分からないためよろしくお願いします。

    • ベストアンサー
    • PHP