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

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

ただいまの
回答率

88.61%

phpでの値の受け渡しについて

解決済

回答 4

投稿

  • 評価
  • クリップ 1
  • VIEW 2,067

kakkydayo

score 16

現在。htmlで値を取得しphpでチェック処理しております。

name="password"はしっかり値が渡せて、phpでチェックができるのですが、
name="username"に関しては、値は渡せているのですがphpでカラのチェックや
hash化した際の突合せチェックができません。

またname="username"に1文字だけ入れて実行しても”idが入力されていません”
と出力されます。

name="username"はどうすればphpでチェックできまでしょうか??

宜しくお願い致します。

下記にコードを記載致します。

<form action="{$script}" method="POST">
      <p class="comment">ID パスワードを入力してください</p>
      ID<p class="input"><input type="text" name="username"/></p>
      pass<p class="input"><input type="password" name="password" /></p>
      <ul>
        <li><input type="submit" name="login_button" value="ログイン" /></li>
      </ul>
      {$login_error_message}
    </form>
global $admin_password;//config.phpのパス
  global $admin_id;
  global $login_error_message;

  $admin_id = htmlspecialchars($_POST['username'],ENT_QUOTES,'UTF-8');
  $input_password = htmlspecialchars($_POST['password'],ENT_QUOTES,'UTF-8');
  $admin_id_sha = hash('sha512',$admin_id);//idをハッシュ化
  $admin_password_sha = hash('sha512',$admin_password);//パスをハッシュ化


  if(empty($admin_id)){
    $login_error_message = '<p class="error_message">idが入力されていません</p>';
    show_login_form();
    exit;
  }

  if(empty($input_password)){
    $login_error_message = '<p class="error_message">パスワードが入力されていません</p>';
    show_login_form();
    exit;
  }

  if(hash('sha512',$admin_id) != $admin_id_sha){
    $login_error_message = '<p class="error_message">idが違います</p>';
    show_login_form();
    exit;
  }

  if(hash('sha512',$input_password) != $admin_password_sha){//ハッシュ化したpassの比較
    $login_error_message = '<p class="error_message">パスワードが違います</p>';
    show_login_form();
    exit;
  }
  • 気になる質問をクリップする

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 4

checkベストアンサー

+4

「PHPによる簡単なログイン認証いろいろ」を参考にどうぞ.実装サンプルがあるので多分これだけでも答えになるかと思います.


またname="username"に1文字だけ入れて実行しても”idが入力されていません” 
と出力されます。

ちょっとこの点だけがコードの内容と整合性が取れていない気がするのですが,まず最初に直すべき点をあげると,kei344さんがすでに仰られている通り,$admin_idへの代入を$input_idに直すことですね.global宣言が無意味になるのでおそらくミスです.

その他,気になったことを挙げると

  • $scriptをaction属性の値に使っているが,もしここに$_SERVER['PHP_SELF']を使っている場合XSS脆弱性となるので絶対にやめること.$_SERVER['SCRIPT_NAME']を使っている場合はセーフだが,そもそもaction属性の値を空文字列にした場合は自分自身に対してPOSTすることになるので,これが一番いい.

  • エラーが発生するリスクがあるので,変数の存在確認に関してノーチェックで$_POST['username']などを参照しない.最低限issetでの存在確認を行う.最善を求めるなら更に配列を弾くために文字列であるかどうかの検証も行う.この処理をfilter_inputを使うと1つにまとめることができる.
    備考: $_GET, $_POSTなどを受け取る際の処理

  • HTML出力以外の処理(ハッシュ生成など)を行うタイミングでhtmlspecialcharsの目的外使用をしない.これはテキストをHTMLとして埋め込む瞬間にのみ使うべき関数である.パスワードに「&」などの特殊文字が含まれていた場合,生成されるハッシュが誤ったものになってしまう.
    備考: 「何故htmlspecialcharsを通すのか?」を一言でどうぞ

  • SHA512はハッシュ関数としては十分な強度があるが,ソルト無しで使うとレインボーテーブル攻撃に弱いという欠点があるので,必ずソルトを入れる.更にソルトを毎回ランダムにしてくれるpassword_hash関数やそれに対応した検証関数のpassword_verifyを使うのが最もセキュリティが固くなるので,これを使うべき.
    備考: PHPによる簡単なログイン認証いろいろ

  • ユーザ名までハッシュ化してしまうと利便性の面で大きなディスアドバンテージがあるので,パスワードのハッシュ化が強力であればそれだけで十分.


【追記】

直すならこんな感じでしょうか. <input /> はHTMLとしては誤っているのでついでに <input> に直しておきます.また後から気づいたんですが,パスワードの方もハッシュ化が無意味になってる気がします. $admin_password_shaは最初から直接文字列で定義されているかと思いきや,平文の$admin_passwordから毎回生成されていますよね.平文でパスワードをスクリプトに書いてはいけません.それを避けるためにハッシュ関数があるんですから.

<form action="" method="post">
    <p class="comment">IDとパスワードを入力してください</p>
    ID<p class="input"><input type="text" name="username"></p>
    PW<p class="input"><input type="password" name="password"></p>
    <ul>
        <li><input type="submit" name="login_button" value="ログイン"></li>
    </ul>
    {$login_error_message}
</form>
global $admin_id; // 平文
global $admin_password_hash; // password_hash関数で生成しておいたBlowfishハッシュ
global $login_error_message;

$input_id = (string)filter_input(INPUT_POST, 'username');
$input_password= (string)filter_input(INPUT_POST, 'password');

if ($admin_id === '') {
    $login_error_message = '<p class="error_message">idが入力されていません</p>';
    show_login_form();
    exit;
}
if ($input_password === '') {
    $login_error_message = '<p class="error_message">パスワードが入力されていません</p>';
    show_login_form();
    exit;
}
if (($admin_id !== $input_id) | !password_verify($input_password, $admin_password_hash)) {
    $login_error_message = '<p class="error_message">IDまたはパスワードが違います</p>';
    show_login_form();
    exit;
}

こういうケースではIDもできれば隠蔽したいことでしょう.そのために「IDまたはパスワードが違います」というエラーメッセージでまとめたほうが望ましいです.また,password_verifyを確実に実行しないと実行時間の差から「最低限IDが間違っている」ということは推測されますので,論理演算子の||ではなく短絡評価のないビット演算子の|を敢えて使っています.

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/04/07 21:14

    回答ありがとうございます。
    idに1文字だけ入れて、チェックにかかってしまったのはemptyが0もカラ扱いにしてしまっていたせいでした。emptyを!issetに変更しました。
    またみなさんのご指摘通り$input_idに変えて行ったところ、今度はidがカラでも、
    ”idが入力されていません”が出力されなくなってしまいました。
    どなたか、ちょっとしたことでも良いのでご教授お願い致します。

    キャンセル

  • 2016/04/08 03:18

    そりゃ,未入力だとしても $_POST['username'] は空文字列として送信されてきますし,もしフォームのsubmitを使わずに独自のスクリプトで奇妙なPOSTリクエストが飛ばされてきて $_POST['username'] が未定義であったとしても (Noticeレベルのエラーを発生しながら)強引に htmlspecialchars の実行結果が $input_id に代入されることは確定しているので,当然の挙動です.

    キャンセル

  • 2016/04/08 03:40 編集

    修正例も提示しましたが,一応こちらにも目を通してください.CSRF攻撃対策についても実施されていないように思われますので.

    http://qiita.com/mpyw/items/bb8305ba196f5105be15

    キャンセル

0

ひとまず $input_id が無い状態なので、そこを修正されてはいかがでしょう。

//  $admin_id = htmlspecialchars($_POST['username'],ENT_QUOTES,'UTF-8');
//  ↓
  $input_id = htmlspecialchars($_POST['username'],ENT_QUOTES,'UTF-8');
  $input_password = htmlspecialchars($_POST['password'],ENT_QUOTES,'UTF-8');

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

皆さんの回答からいろいろ作法があるようですが、まずはusernameの件に特化して考えた方が良いでしょう。
PHP側でhtmlspecialchars関数で処理していますので、これを使わない場合はどうなりますか?
値が取れているようでしたら、htmlspecialchars関数の使い方に問題があることになります。
では問題があるとすれば?影響しそうなのは第三引数のencodingですね。
UTF8を指定していますが、HTML側で正しくUTF8で送る設定になっていますか?
PHP側とHTML側で文字コードの統一ができているか、確認してみてください。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/04/07 17:41

    「1文字だけ入れた」というのが日本語などのマルチバイト文字で,且つUTF-8以外の文字コードで書かれている,というケースであれば説明はつきますね.ただし半角英数字の場合は相変わらず原因不明です…

    キャンセル

  • 2016/04/08 03:14

    あ,"0" を入力されていたのが原因だったようですw (まさかのピンポイント一致

    キャンセル

-1

$admin_id は統一されてるので問題ないのでは…?
$input_password と $admin_password が混ざっているのが気になりました。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/04/07 00:56

    逆です,統一されているとこのスクリプトの目的が不明になります.

    $admin_id_sha = hash('sha512',$admin_id);
    if (hash('sha512', $admin_id) != $admin_id_sha) { }

    これはつまりこういうことです.

    if (hash('sha512', $admin_id) != hash('sha512',$admin_id)) { }

    このif文に何の意味があるのでしょうか.

    キャンセル

  • 2016/04/07 00:58 編集

    これは恥ずかしい勘違いでした…。場を汚してしまい申し訳ないです。ご指摘ありがとうございます。

    キャンセル

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

  • ただいまの回答率 88.61%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る