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

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

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

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

Q&A

解決済

2回答

5114閲覧

PHPでURL直たたき対策の仕組みを作りたい

takuo5

総合スコア48

PHP

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

0グッド

0クリップ

投稿2020/04/03 02:40

編集2020/04/03 04:34

前提・実現したいこと

PHPで問い合わせフォームにURLの直たたき防止の機能を実装中です。
入力画面(contact.php)⇛確認画面(confirm.php)⇛完了画面(complete.php)という構造でこの順序でしかそれぞれの画面にアクセスできないようにしたいです。

現在confirm.phpにcontact.phpからでしかアクセスできませんというコードを下記のように作っておりますが、URL取得のコードをどのように書くべきかわかりません。
環境に応じた取得方法を記述するにはどのようにするべきでしょうか。

該当のソースコード

ソース// URL直たたき対策 $referer = $_SERVER["HTTP_REFERER"]; $url = 'https://3619dda849484d518eb5fda739e3e87d.vfs.cloud9.ap-northeast-1.amazonaws.com/contact_form/contact/contact.php'; if(!strstr($referer,$url)){ die("正規の画面からアクセスしてください"); exit; }

CSFR対策コード

//POSTされたデータをチェック $_POST = checkInput( $_POST ); //固定トークンを確認(CSRF対策) if ( isset( $_POST[ 'ticket' ], $_SESSION[ 'ticket' ] ) ) { $ticket = $_POST[ 'ticket' ]; if ( $ticket !== $_SESSION[ 'ticket' ] ) { //トークンが一致しない場合は処理を中止 die( 'Access Denied!' ); } } else { //トークンが存在しない場合は処理を中止(直接このページにアクセスするとエラーになる) die( 'Access Denied(直接このページにはアクセスできません)' ); }

補足情報(FW/ツールのバージョンなど)

AWS Cloud9
PHP 5.6.40

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

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

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

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

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

guest

回答2

0

ベストアンサー

リファラーは偽装可能であったり、ブラウザの設定で送信が無効化されたりするものなのでごく簡易的なチェックにしかなりません。
(特に、悪意を持って問い合わせを直POSTするようなケースにはほぼ効果がありません。)

かつ、おそらく多重POST等も防止する必要があるでしょうから
リファラーでチェックするのではなく
多重POST防止やCSRF対策として用いられるようなセッションとワンタイムトークンを使用して順番通りにアクセスであることを担保することをお勧めします。

具体的な実装はPHP CSRF対策あたりで調べてみてください。

個人的には、フレームワークを使わない場合だと
EasyCSRF
を使って実装するのが楽だった覚えがあります。

投稿2020/04/03 02:58

編集2020/04/03 03:22
tanat

総合スコア18727

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

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

takuo5

2020/04/03 04:43

上記にCSRF対策コード追加しましたのでご参照ください。 このコードでは最終的に”直接このページにはアクセスできません”というメッセージが出るようになっていますが、contact.phpのページにリダイレクトするようにしたいです。 そうするにはheader('Location: リダイレクト先のURL') を追加すればできると思うのですが、 URLを特定のURLをいれるのではなく環境に応じたものが入るようにしたいのですがどのように書けばよいでしょうか? 例:header('Location: https://3619dda849484d518eb5fda739e3e87d.vfs.cloud9.ap-northeast-1.amazonaws.com/contact_form/contact/contact.php') としてしまうと上記のわたしのAWSで動かしている環境でしかアクセスできないので、他の動作環境からでも対応できるようにしたいです。
tanat

2020/04/03 05:05

HTTPヘッダのLocationに関する仕様ですね。 https://teratail.com/questions/210809 が参考になるかと思います。 最近のクライアントなら、 /contact_form/contact/contact.php 部分だけ書けば行けると思います。(確認してみてください) どうしてもhttps://から書きたいなら $_SERVER['HTTP_HOST']にPHPが動いているドメインが格納されているので、 "https://".$_SERVER['HTTP_HOST']."/contact_form/contact/contact.php"みたいな感じで文字列連結すればPHPが動いている環境にあった形になります。 https://www.php.net/manual/ja/reserved.variables.server.php を参照してみてください。
takuo5

2020/04/03 05:22

ありがとうございます。 ご提案いただいた通り/contact_form/contact/contact.phpだけで入力フォームにリダイレクトすることができました。 また、いろいろと記事など調べていただきありがとうございます。 いただいたURLも確認して今後に活用させていただきます。
guest

0

直叩き=GETリクエスト
なので、$_SERVERよりREQUEST_METHODを確認するのが手っ取り早いです。
cURLやajaxなどの対策まで含むならこれにプラスでドメイン確認ですね。

投稿2020/04/03 02:44

m.ts10806

総合スコア80875

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問