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

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

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

HTML5 (Hyper Text Markup Language、バージョン 5)は、マークアップ言語であるHTMLの第5版です。

PHP

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

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

Ajax

Ajaxとは、Webブラウザ内で搭載されているJavaScriptのHTTP通信機能を使って非同期通信を利用し、インターフェイスの構築などを行う技術の総称です。XMLドキュメントを指定したURLから読み込み、画面描画やユーザの操作などと並行してサーバと非同期に通信するWebアプリケーションを実現することができます。

Q&A

解決済

3回答

6257閲覧

フォームチェックをしajaxで送信する際のセキュリティについての質問です。

space_sss

総合スコア81

HTML5

HTML5 (Hyper Text Markup Language、バージョン 5)は、マークアップ言語であるHTMLの第5版です。

PHP

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

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

Ajax

Ajaxとは、Webブラウザ内で搭載されているJavaScriptのHTTP通信機能を使って非同期通信を利用し、インターフェイスの構築などを行う技術の総称です。XMLドキュメントを指定したURLから読み込み、画面描画やユーザの操作などと並行してサーバと非同期に通信するWebアプリケーションを実現することができます。

2グッド

1クリップ

投稿2016/12/27 18:20

フォームの必須項目を入力をチェックし大丈夫ならメールを送信するプログラムをajaxを使い作ってみました。
その際問題なくプログラムは動きやりたいことも問題なく出来ました。
がセキュリティに関してはこちらで問題がないのか?
といったところが不安になり今回はご質問させていただきました。

###こちらがフォームのhtmlのタグです

html

1<form action="" method="POST"> 2 <input type="text" name="name" placeholder="名前(必須)" /> 3 <input type="email" name="email" placeholder="Email(必須)" /> 4 <input type="tel" name="tel" placeholder="電話番号" /> 5 <textarea rows="7" name="free" placeholder="メッセージ(必須)"></textarea> 6 <input type="submit" name="send" id="aaaa" value="送信" /> 7</form>

###こちらがajaxとチェックが行われる部分です。

javascript

1function no_data() { 2 if(($('form span').length)){ 3 $('form span').html("必須項目を入力してください。"); 4 }else{ 5 $('textarea').after("<span>必須項目を入力してください。</span>"); 6 } 7} 8$(function(){ 9 $('form').submit(function(){ 10 if($('input[name="name"]').val() == '' || $('input[name="email"]').val() == '' || $('textarea').val() == '' || $('textarea').val().match(/^[ \r\n\t]*$/)){ 11 no_data(); 12 return false; 13 }else{ 14 $('form').fadeOut(600,function() { 15 //送信部分 16 var check; 17 check=$(this).serialize(); 18 $.ajax({ 19 url : 'inc/check.php', 20 type : 'post', 21 dataType : 'text', 22 data : check 23 }) 24 //受信部分 25 .done(function(response) { 26 if(response="ok"){ 27 $('form').html("<p>送信が完了いたしました</p>").fadeIn(600); 28 } 29 }) 30 .fail(function() {//エラーが起きた場合 31 alert('通信失敗') 32 }); 33 }); 34 return false; 35 } 36 }); 37});

###こちらがメールの送信する部分のプログラムとなります。

php

1<?php 2function test(array $arr){ 3 $data_box=array('name_box','email_box','tel_box','free_box'); 4 $title_box=array("\n名前\n\t","\nメールアドレス\n\t","\n電話番号\n\t","\nお問い合わせ内容\n\t"); 5 $i=0; 6 foreach($arr as $val){ 7 if($val!=""){ 8 $text_box[$data_box[$i]]=$title_box[$i].htmlspecialchars($val); 9 }else{ 10 $text_box[$data_box[$i]]=""; 11 } 12 ++$i; 13 } 14 mb_language( "ja"); 15 mb_internal_encoding( "UTF-8"); 16 $sub="確認メール"; 17 foreach($text_box as $val){ 18 $body.=$val; 19 } 20 $email=htmlspecialchars($arr["email"]); 21 $body="お問い合わせありがとうございます。".$body."\n上記で送信完了いたしました。"; 22 $from='From:'.mb_encode_mimeheader('私です。').'<送信元メールアドレス\nX-mailer:PHP>'; 23 //送信実行 24 mb_send_mail($email,$sub,$body,$from); 25 $check_box="ok"; 26 return $check_box; 27} 28header('Content-type: application/json'); 29$check_box=test(filter_input_array(INPUT_POST)); 30echo json_encode($check_box);

このプログラムではどういったところに問題があるかといったところをお答えいただけると幸いです。
解決策なども添えていただければ助かります。。。

またこれならこうやった方がいいといったところもあればご教授お願いしたいです。

お手数ですがどうぞ宜しくお願いいたします。

kyunta👍を押しています

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

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

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

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

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

guest

回答3

0

  1. メールヘッダに改行文字などが含まれていないかチェックして、str_replaceとかで改行文字を取り除く。
  2. メールアドレスの形式が正しいかPHPでもチェックする。
  3. htmlspecialcharsは出力時のみに使用する。(例: echo htmlspecialchars($_POST["name"]))
  4. CSRF対策としてトークンを生成してセッションに保存、Ajaxリクエスト時にトークンの値を検証する。

どうでもいいところかもしれませんが、メールの送信する部分のプログラムに書いてある19行目の$bodyは定義されてませんので一応定義しておいたほうが良いのでは。

投稿2016/12/27 19:22

編集2016/12/27 19:43
s8_chu

総合スコア14731

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

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

space_sss

2016/12/27 19:46 編集

ご解答ありがとうございます! >> メールヘッダに改行文字などが含まれていないかチェックして、str_replaceとかで改行文字を取り除く。 すぐに修正いたしました。 メールヘッダ部分というのはこの文ですとアドレスのみでよろしいのでしょうか? >> htmlspecialcharsは出力時のみに使用する。(例: echo htmlspecialchars($_POST["name"])) 今回に関しては現状やろうとしていることに対しては不要ということになるのでしょうか? >> CSRF対策としてトークンを生成してセッションに保存、Ajaxリクエスト時にトークンの値を検証する。 こちらはすぐに情報収集をし実行させていただきます! bodyに関しては完全に見落としていました… ご指摘ありがとうございます!
s8_chu

2016/12/27 19:57

メールヘッダには宛先や件名、送信者のアドレスなどが含まれます。また、htmlspecialcharsは不要だと思います。
space_sss

2016/12/28 06:35

返信ありがとうございます!そちらを含め更新させていただきます!
guest

0

ベストアンサー

ざっくりとソースコードを眺めた上で、気づいた点を指摘します。

・htmlspecialchars の使い方が間違っています。

・mb_send_mail の第一引数($email) が任意の値に設定可能です。第三者が任意のアドレスに対して送信可能なコードになっています。このことは、メール本文にURLを入れて受信者にウィルスを感染させる経路を提供することになります。

CSRFチェックがされていない。このことは、第三者が任意のリンクや偽装サイトからこの送信スクリプトを利用可能であるということです。SNSに短縮アドレスでリンクを作成し、ドメインを隠蔽した上で、任意のメッセージを任意のアドレスに対して送信可能であるということです。

またこれならこうやった方がいいといったところもあればご教授お願いしたいです。

設計からの見直しが必要なので、ソースコード全体の書き換えが必要となります。

投稿2016/12/27 18:34

編集2016/12/27 18:52
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

space_sss

2016/12/27 19:32

ご解答ありがとうございます。 >>・htmlspecialchars の使い方が間違っています。 htmlspecialcharsは出力する際に必要といった認識だったのですがメールを送信し文を表示させるので必要かと思っていましたが必要なかったのですね… もう一度htmlspecialcharsに関しては情報収集してみます。 >>・mb_send_mail の第一引数($email) が任意の値に設定可能です。第三者が任意のアドレスに対して送信可能なコードになっています。このことは、メール本文にURLを入れて受信者にウィルスを感染させる経路を提供することになります。 こちらに関してはユーザーが入力したアドレスにメールが届くようにしたかったのですが変数を直接書いてしまうのはダメといったことでしょうか? 別の方法で第1引数を決めるといったことでしょうか? 調べてみたのですが手段が見当たりませんでした… >>・CSRFチェックがされていない。このことは、第三者が任意のリンクや偽装サイトからこの送信スクリプトを利用可能であるということです。SNSに短縮アドレスでリンクを作成し、ドメインを隠蔽した上で、任意のメッセージを任意のアドレスに対して送信可能であるということです。 こちらに関しては完全に知らない内容でした。 内容を調べてすぐに実行してみます!
退会済みユーザー

退会済みユーザー

2016/12/27 19:35

> ユーザーが入力したアドレスにメールが届くようにしたかった これ自体は問題ありません。CSRFの問題とセットになると致命的な問題となります。
space_sss

2016/12/27 19:45

CSRFのチェックをすればこちらでも問題がなくなるといったことでしょうか?
退会済みユーザー

退会済みユーザー

2016/12/27 19:48 編集

そういうことです あと、JavaScriptの入力チェックもセキュリティ上は全く意味がありません。 PHPで行うべき処理です。
space_sss

2016/12/28 06:36

ご解答ありがとうございます!そちらを含め更新させていただきます!
guest

0

質問文のコードでも動くでしょうけれど、普通は
mb_language( "ja");
mb_internal_encoding( "UTF-8");
この二行は関数の中ではなく外に置くべきだと思います。

一般的にはrequireなどで読み込むファイルも含め、全てのコードの中での先頭付近(要するに最も早く実行される部分)に置いたほうがトラブルが減るかと。

投稿2016/12/28 03:06

zico_teratail

総合スコア907

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

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

space_sss

2016/12/28 06:35

ご解答ありがとうございます! そちらも含めて更新させていただきます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問