ーに不正な値が入っていないかチェック」する箇所で質問...
確かに、条件式に、['c_id']['sort']['p']['p_id']があるかどうかたくさん指定しなくても、
「$viewDataがあるかどうかだけを調べる」方が効率がいいような気もしてきました。
ただ、その場合、逆に以下の条件式でも、「!empty($p_id) &&」は省略もできるのかなと考えましたが、こちらについては、意図ある差異だったでしょうか?
ーーーー
registProduct.php(35行目~)
「GETパラメータはあるが、改ざんされている(URLをいじくった)場合」
if(!empty($p_id) && empty($dbFormData)){
debug('GETパラメータの商品IDが違います。マイページへ遷移します。');
header("Location:mypage.php"); //マイページへ
}
ーーーー
②そして、お手数をおかけしますが、関連部分につきまして、もう一つ質問があります。
「GETパラメーターに不正な値が入っていないかチェック」する条件式について、理解があっているか、ご教示いただければ、と思います。
index.php 28行目付近「パラメーターに不正な値が入っていないかチェック」の部分で、
上記とは異なる方法(「is_int」)で「$currentPage」を調べる方法があるのですが、
(以下式です。)
ーーーーー
if(!is_int($currentPage)){
error_log('エラー発生:指定ページに不適切な値が入りました。');
header("Location:index.php");
}
ーーーーー
registProduct.phpなどと異なる方法の条件式「is_int」を使っている理由としては、
「・index.phpはだれでも見れるページだから(GETパラメーターの数字が他の整数に改ざんされたところで、プライベートなページではないので、問題ない)」
「・GETパラメーターに整数が入ったところで、個人情報を抜き取られる恐れがないから」
という理由でしょうか?
(あくまで、本等調べた中での当方の推測です。検索してみたのですが、詳しいページがありませんでした…。)
(試しに、条件部分を
if(!empty($p) && empty($dbProductData['data'])
と変えてみましたが、「productテーブルに登録のないcategoryで絞ったときに、全件表示されてしまう」というバグが発生してしまいました。)
しばらくの間、考えたり調べていたのですが、
「GETパラメーターへの挿入攻撃に関する条件式」について詳しいサイト等が見つかりませんでした。
これからWebサービスを作っていくにあたり、パラメーター情報改ざんで情報が洩れると怖いため、
以上に関しまして「どういった条件式を作成していけばいいのか」について、詳細を教えていただけますと幸いです。
たくさん質問してしまい、お手数をおかけしますが、どうぞよろしくお願いいたします。
まずregistProduct.phpで!empty($p_id)をチェックしているのは、このページが商品登録と編集を兼ねていて、
そのチェックでページが登録か編集か区別しているためです。
商品登録のときはGETパラメータは空なので、編集ページのときのみempty($dbFormData)をチェックしたいがために!empty($p_id)を確認しています。
(試しに!empty($p_id)という条件を消して商品登録ページにいこうとしてみてください。
mypage.phpにとばされることがわかると思います。)
一方でproductDetail.phpでは$p_idは必須なので!empty($p_id)を確認する必要はありません。
$p_idが空だと自動的にif(!empty($viewData))に引っかかるためです。
②なぜ違う方法(is_int)でチェックしているのか
index.phpのもう少し下の行を見てみましょう。
$currentPageNum-1など、計算をしていますね。
計算をするには数値でないといけないのでis_intでチェックしています。
>「・index.phpはだれでも見れるページだから(GETパラメーターの数字が他の整数に改ざんされたところで、プライベートなページではないので、問題ない)」
>「・GETパラメーターに整数が入ったところで、個人情報を抜き取られる恐れがないから」
上記の通り、GETパラメータは数値の必要があり、
他の整数に改ざんされても商品一覧ページが表示されるだけなので問題ありません。
続いて、GETパラメータの改ざんについてもう少し説明します。
GETパラメータを改ざんの問題は、そのパラメータにより見せてはいけないページが見えるなど期待していない動作が起きることです。
その問題を防ぐために、
まず、GETパラメータの値によってそのページの処理がどう変わるか場合分けして整理して、そのうちの望まない動作を把握します。
そして、その望まない動作が起こらないように、その望まない動作が起こる条件となるパラメータが入力されたときにその望まない動作を防ぐように、
おっしゃっている「GETパラメーターへの挿入攻撃に関する条件式」を考えて書いていきます。
ですから、何か決まった万能の関数の形があるわけではありません。
こちらについてregistProduct.phpで例えます。
GETパラメータを変えると、他の商品データを編集できることになります。
このページでは、他の商品とは「自分の登録した商品」と「他人が登録した商品」の二種類があります。
自分の登録した商品は編集できて当然なのでいいですが、他人が登録した商品を編集できるのは危険ですよね?
そこでregistProduct.phpの23行目あたりで、
$dbFormData = (!empty($p_id)) ? getProduct($_SESSION['user_id'], $p_id) : '';
ここではuser_idにひもづくproduct(商品)を取得しています。
ここでGETパラメータを改ざんして、他人の商品データを取得しようとしても、
getProduct($_SESSION['user_id'], $p_id)
の結果が空となります。
そのため、35行目付近で
if(!empty($p_id) && empty($dbFormData)){
と書いておけば、「GETパラメーターへの挿入攻撃」、今回の例でいう他人の商品の編集を防ぐことができます。
「GETパラメーターの挿入攻撃」には、何か決まった「型」があると思いこんでいたので、ドツボにはまっておりました。
今回のコーチのご回答で、当件につきより理解が深まったため、自信をもってコードを書いていくことができそうです。
今後とも、どうぞよろしくお願いいたします。
部活の学習一覧
Lesson 01
「WEBサービスと必要な機能」
Lesson 02
「画面を設計しよう!」
Lesson 03
「テーブルを設計しよう!part1」
Lesson 04
「テーブルを設計しよう!part2」
Lesson 05
「テーブルを設計しよう!part3」
Lesson 06
「DB作成」
Lesson 07
「画面を作ろう!」
Lesson 08
「画面を作ろう!part2」
Lesson 09
「ユーザー登録機能を作ろう!」
Lesson 10
「ユーザー登録機能を作ろう!part2」
コーヒーブレイク
「投資の小話」
Lesson 11
「ログイン機能を作ろう!」
Lesson 12
「ログアウト機能を作ろう!」
Lesson 13
「退会機能を作ろう!」
Lesson 14
「プロフィール編集機能を作ろう!」
コーヒーブレイク
「書いて書いて書きまくれ!」
Lesson 15
「パスワード変更機能を作ろう!」
Lesson 16
「パスワードリマインダー機能を作ろう!」
Lesson 17
「商品登録機能を作ろう!」
Lesson 18
「商品登録機能を作ろう!part2」
Lesson 19
「商品登録機能を作ろう!part3」
Lesson 20
「商品一覧表示機能を作ろう!」
Lesson 21
「商品詳細画面を作ろう!」
Lesson 22
「商品検索機能を作ろう!」
Lesson 23
「連絡掲示板機能を作ろう!」
Lesson 24
「お気に入り機能を作ろう!」
Lesson 25
「マイページ機能を作ろう!」
コーヒーブレイク
「はたらくプログラミング 第5話」
ご意見箱
productDetail.php(21行目~)にて、
if(empty($viewData)){
error_log('エラー発生:指定ページに不正な値が入りました');
header("Location:index.php"); //トップページへ
}
と、「$viewDataが空かどうか『のみ』」調べているのは何か理由がありますでしょうか?
というのも、registProduct.php(35行目~)に「GETパラメータはあるが、改ざんされている(URLをいじくった)場合」
if(!empty($p_id) && empty($dbFormData)){
debug('GETパラメータの商品IDが違います。マイページへ遷移します。');
header("Location:mypage.php"); //マイページへ
}
と「$_GET['p_id']がある場合」も指定されており、
productDetail.phpでも、以下のようになるのではないか?と考えたからです。
$p = (!empty($_GET['p'])) ? $_GET['p'] : '';
$p_id = (!empty($_GET['p_id'])) ? $_GET['p_id'] : '';
$viewData = getProductOne($p_id);
if(!empty($p) && !empty($p_id) && empty($viewData)){
error_log('不正な値がGETパラメーターに入りました');
header("Location:index.php");
}
ただ、$_GET['p_id']、$_GET['p']にデータが入っているかどうかにかかわらず、
「$viewDataにデータが入っていなければ、表示されない」というのも納得できます。
こちらにつきまして、何か意図があって変えてあるのか、自分の見落としているところがあるかと思い、「GETパラメーター 改ざん」など調べてみましたが、納得できる回答はありませんでした。
意図がある場合は、どういった理由か、ヒントをいただけますでしょうか。
どうぞよろしくお願いいたします。