- ベストアンサー
inputタグに入力された数値を安全にするには?
- inputタグに入力された数値や数式を安全に処理する方法を教えてください。
- 悪意のあるコードを防ぐために、入力情報をチェックする仕組みを実装する必要があります。
- ウイルスなどの被害を防ぐためには、信頼できる入力情報のみを正しく処理する必要があります。
- みんなの回答 (34)
- 専門家の回答
質問者が選んだベストアンサー
>回答No.32 amanojaku1 訂正です、括弧に対応していませんでした。 正規表現は下記の方が適切です。 超簡易式の処理です、要点は(式として成立しているかではなく)コマンドが実行されないようになっているか?、が重要です。 (断定はできませんが)これならJavaScriptのマクロのような構文も実行できないと思われます。 JavaScriptのマクロのような構文については分かりませんので、別の質問にしてみたら どうでしょうか? 「四則演算子、数字、括弧」以外は削除されます。<br> また式として成立しない文字列は計算できません。<br> <input type="text" name="gakunen" value="" onKeyPress="Calculator(this.value, event.keyCode)"> <script type="text/javascript"> <!-- function Calculator(a, kcode){ var r; if (!(13==kcode)){return;} // ↑「13:Enterキー」でない場合は「return」 r = a; r = r.replace(/[ ]*([\-\/\*\+])[ \-\/\*\+]*/g, '$1'); r = r.replace(/^([ ]*[\/\*\+][ \-\/\*\+]*)/g, ''); r = r.replace(/([^0-9\.\-\/\*\+\(\) ]+)/g, ' '); r = r.replace(/([ ]+)/g, ' '); try{ alert(r+' = '+eval(r)); }catch(ex){ alert(ex.message+' : '+r); } } // --> </script>
その他の回答 (33)
- amanojaku1
- ベストアンサー率54% (265/488)
>evalを使った処理のソースをコメントアウトします。これで大丈夫ですか? 基本的に、それで大丈夫です。 >もし改ざんされている場合は見覚えのないソースが追加されていると考えてよいでしょうか? 基本的に、そうです。 >ソースを隠すことはクラッカーでも不可能ですよね? クラッカーにサーバーが完全に乗っ取られたら、FTPに対するソースの隠蔽は可能です。 FTPからアクセスされたら、正常なソースを返し、httpサービスでアクセスされたらマルウェア・コードが実行されるように処理すれば良い訳です。 >一点気になったのはæ°ããããã¹ã ããã¥ã¡ã³ã.htm >というHTMLファイルがサーバ上にあったことです。 パーミッションは実行可能になってませんか? 実行可能になっているなら削除した方が良いでしょう。 ちなみにphpはセキュリティー的に甘いらしいので、セキュリティー的にはPerlの方がオススメです。 初心者にはphpの方が分かりやすいと言うメリットは有りますが…。
- H240S18B73
- ベストアンサー率65% (190/288)
XSSはサーバー上のデータの書き換えは伴いません ユーザーのブラウザに出力されるコードを書き換えるものです 先にも言いましたがXSS攻撃によって被害を被るのは 主にサイトではなくユーザーです 罠サイトに誘導されウィルスを仕込まれることになるのも 主にはユーザーということになるでしょう サイトのコード自体は改変されません XSS攻撃はまず他ユーザーに偽サイトやフィッシングメールによって 対象のサイトにおいて任意のスクリプトを 実行させるURLを踏ませるところから始まります それによって攻撃対象ユーザーのそのサイトにおける ユーザーのログイン情報を不正に取得したりあるいはのっとったり といったことを可能にするのがXSS攻撃です 詳しくは参考URLのクロスサイトスクリプティングの項目を一読ください
- H240S18B73
- ベストアンサー率65% (190/288)
先のスレでも言いましたが 単純なエスケープでは難読化されたコードには対応できません そして、タグのエスケープによるXSS対策というのは 「ユーザー入力をそのまま出力に使用する」際のXSS対策であって evalに値を渡す場合のXSS対策にはなりません evalにおけるXSS対策は「想定した入力であるか」をチェックすることです そしてその方法は正規表現での判定になるでしょう 加えておせっかいを言えば、 数式における()の対応の判定を正規表現により一度に行うのは ムダに難しいと思うので、()の対応の判定は(と)の数が同数であり かつ(より前に)がないということを判定するという形で 正規表現による判定とは別で判定する方が簡単かと思います 多分他ユーザーの回答も合わせれば十分なヒントは得られていますし ほぼ答えとなるサイトもご自分で見つけられているように思います
- H240S18B73
- ベストアンサー率65% (190/288)
JSのみによってXSSが成立しうるのは location.searchを使うなどしてURLパラメータから情報を取得し evalに渡していたり、そのまま出力に使っていたりする場合です 現状のURLパラメータから値を取得することはせず input要素から直接値を取得している仕様では XSSの心配をする必要はあまりありません ただ、先のスレで言っていたような、PHPなどによって 前回の入力を記憶しておくというような機能を追加しようとした場合は サーバーにURLパラメータを通して値を渡して記憶させておくなり することになるのでそのままevalを使うような形でやると XSSの脆弱性を生むことになる、ということです つまり、今はそれでも問題ないけど、 これからやろうとしてることはそのやり方のままじゃまずいよ ってことです
お礼
evalを使った自由に計算できる部分のみをコメントアウトしました。 これで大丈夫なのでしょうか? その他type="number"に数値のみ入れて計算する部分と、 ただの文字列を入れる部分は残っていますがここはevalを使っていないのと、alert()を入れても何の反応もなかったので大丈夫と考えてよいでしょうか? 一点気になったのはæ°ããããã¹ã ããã¥ã¡ã³ã.htm というHTMLファイルがサーバ上にあったことです。 恐らくPHP工房のファイルが文字化けしたのだと思いますがちょっと気持ち悪いので下記にソースを張り付けておきました。 もし改ざんされている場合は見覚えのないソースが追加されていると考えてよいでしょうか? ソースを隠すことはクラッカーでも不可能ですよね? <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja" lang="ja"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title><?php echo $confirmTitle;?></title> <style type="text/css"> /* 自由に編集下さい */ #formWrap { width:700px; margin:0 auto; color:#555; line-height:120%; font-size:90%; } table.formTable{ width:100%; margin:0 auto; border-collapse:collapse; } table.formTable td,table.formTable th{ border:1px solid #ccc; padding:10px; } table.formTable th{ width:30%; font-weight:normal; background:#efefef; text-align:left; } p.error_messe{ margin:5px 0; color:red; } </style> </head> <body> <!-- ▲ Headerやその他コンテンツなど ※自由に編集可 ▲--> <!-- ▼************ 送信内容表示部 ※編集は自己責任で ************ ▼--> <div id="formWrap"> <?php if($empty_flag == 1){ ?> <div align="center"> <h4><?php echo $requireCheckMesse;?></h4> <?php echo $errm; ?><br /><br /><input type="button" value=" <?php echo $returnBtnMesse;?> " onClick="history.back()"> </div> <?php }else{ ?> <h3><?php echo $confirmTitle;?></h3> <p align="center"><?php echo $confirmMesse;?></p> <form action="<?php echo h($_SERVER['SCRIPT_NAME']); ?>" method="POST"> <table class="formTable"> <?php echo confirmOutput($_POST);//入力内容を表示?> </table> <p align="center"><input type="hidden" name="mail_set" value="confirm_submit"> <input type="hidden" name="httpReferer" value="<?php echo h($_SERVER['HTTP_REFERER']);?>"> <input type="submit" value=" <?php echo $submitBtnMesse;?> "> <input type="button" value="<?php echo $returnBtnMesse;?>" onClick="history.back()"></p> </form> <?php copyright();} ?> </div><!-- /formWrap --> <!-- ▲ *********** 送信内容確認部 ※編集は自己責任で ************ ▲--> <!-- ▼ Footerその他コンテンツなど ※編集可 ▼--> </body> </html> <?php /* ▲▲▲送信確認画面のレイアウト ※オリジナルのデザインも適用可能▲▲▲ */ } if(($jumpPage == 0 && $sendmail == 1) || ($jumpPage == 0 && ($confirmDsp == 0 && $sendmail == 0))) { /* ▼▼▼送信完了画面のレイアウト 編集可 ※送信完了後に指定のページに移動しない場合のみ表示▼▼▼ */ ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja" lang="ja"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>完了画面</title> </head> <body> <div align="center"> <?php if($empty_flag == 1){ ?> <h4><?php echo $requireCheckMesse;?></h4> <div style="color:red"><?php echo $errm; ?></div> <br /><br /><input type="button" value=" <?php echo $returnBtnMesse;?> " onClick="history.back()"> </div> </body> </html> <?php }else{ ?> 送信ありがとうございました。<br /> 送信は正常に完了しました。<br /><br /> <a href="<?php echo $site_top ;?>">トップページへ戻る»</a> </div> <?php copyright(); ?> <!-- CV率を計測する場合ここにAnalyticsコードを貼り付け --> </body> </html>
補足
今はコメントアウトしていますが、問題が起きないように変換してから公開したいです。 function escapeHtml(str) { str = str.replace(/&/g, '&'); str = str.replace(/</g, '<'); str = str.replace(/>/g, '>'); str = str.replace(/"/g, '"'); str = str.replace(/'/g, '''); return str; } このようにエスケープしておけば大丈夫ですか? これを自由に計算ができるソースの前で実行すればよいのでしょうか ただこれだと無限にあるのでできればこの文字記号だけ許可するとしたいです 前回途中まで教えていただきましたが、上記のようにもう少し具体的なソースで教えていただければ幸いです。 何度も大変恐縮ですがどうぞよろしくお願い致します。 その後alert()を入れてもアラートが出てこなければセキュアと判断すれば良いのですね。 その他のinputにも入れてみましたが他ではalert()は実行されませんでした。 よって他はinnerHTMLを使っていても問題ないのですね。
- amanojaku1
- ベストアンサー率54% (265/488)
外部JSファイルを動的に読み込む事も可能なようです、これにより どんな複雑な処理でも可能になるでしょう。 JavaScriptファイルの動的読み込みと完了状態を取得する http://blog.yuhiisk.com/archive/2014/12/20/dynamic-loading-and-complete-processing-of-script.html
お礼
evalを使った自由に計算できる部分のみをコメントアウトしました。 これで大丈夫なのでしょうか? その他type="number"に数値のみ入れて計算する部分と、 ただの文字列を入れる部分は残っていますがここはevalを使っていないのと、alert()を入れても何の反応もなかったので大丈夫と考えてよいでしょうか? 一点気になったのはæ°ããããã¹ã ããã¥ã¡ã³ã.htm というHTMLファイルがサーバ上にあったことです。 恐らくPHP工房のファイルが文字化けしたのだと思いますがちょっと気持ち悪いので下記にソースを張り付けておきました。 もし改ざんされている場合は見覚えのないソースが追加されていると考えてよいでしょうか? ソースを隠すことはクラッカーでも不可能ですよね? <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja" lang="ja"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title><?php echo $confirmTitle;?></title> <style type="text/css"> /* 自由に編集下さい */ #formWrap { width:700px; margin:0 auto; color:#555; line-height:120%; font-size:90%; } table.formTable{ width:100%; margin:0 auto; border-collapse:collapse; } table.formTable td,table.formTable th{ border:1px solid #ccc; padding:10px; } table.formTable th{ width:30%; font-weight:normal; background:#efefef; text-align:left; } p.error_messe{ margin:5px 0; color:red; } </style> </head> <body> <!-- ▲ Headerやその他コンテンツなど ※自由に編集可 ▲--> <!-- ▼************ 送信内容表示部 ※編集は自己責任で ************ ▼--> <div id="formWrap"> <?php if($empty_flag == 1){ ?> <div align="center"> <h4><?php echo $requireCheckMesse;?></h4> <?php echo $errm; ?><br /><br /><input type="button" value=" <?php echo $returnBtnMesse;?> " onClick="history.back()"> </div> <?php }else{ ?> <h3><?php echo $confirmTitle;?></h3> <p align="center"><?php echo $confirmMesse;?></p> <form action="<?php echo h($_SERVER['SCRIPT_NAME']); ?>" method="POST"> <table class="formTable"> <?php echo confirmOutput($_POST);//入力内容を表示?> </table> <p align="center"><input type="hidden" name="mail_set" value="confirm_submit"> <input type="hidden" name="httpReferer" value="<?php echo h($_SERVER['HTTP_REFERER']);?>"> <input type="submit" value=" <?php echo $submitBtnMesse;?> "> <input type="button" value="<?php echo $returnBtnMesse;?>" onClick="history.back()"></p> </form> <?php copyright();} ?> </div><!-- /formWrap --> <!-- ▲ *********** 送信内容確認部 ※編集は自己責任で ************ ▲--> <!-- ▼ Footerその他コンテンツなど ※編集可 ▼--> </body> </html> <?php /* ▲▲▲送信確認画面のレイアウト ※オリジナルのデザインも適用可能▲▲▲ */ } if(($jumpPage == 0 && $sendmail == 1) || ($jumpPage == 0 && ($confirmDsp == 0 && $sendmail == 0))) { /* ▼▼▼送信完了画面のレイアウト 編集可 ※送信完了後に指定のページに移動しない場合のみ表示▼▼▼ */ ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja" lang="ja"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>完了画面</title> </head> <body> <div align="center"> <?php if($empty_flag == 1){ ?> <h4><?php echo $requireCheckMesse;?></h4> <div style="color:red"><?php echo $errm; ?></div> <br /><br /><input type="button" value=" <?php echo $returnBtnMesse;?> " onClick="history.back()"> </div> </body> </html> <?php }else{ ?> 送信ありがとうございました。<br /> 送信は正常に完了しました。<br /><br /> <a href="<?php echo $site_top ;?>">トップページへ戻る»</a> </div> <?php copyright(); ?> <!-- CV率を計測する場合ここにAnalyticsコードを貼り付け --> </body> </html>
- amanojaku1
- ベストアンサー率54% (265/488)
「Ajax」に加え「Comet」と言う手法も登場したようです(この記事「2006年09月11日」って随分前から登場してた訳ですな…) Ajaxの“彗星”とともに現われたチャットサービス“Lingr”を使ってみた http://ascii.jp/elem/000/000/355/355253/
- H240S18B73
- ベストアンサー率65% (190/288)
>ただサーバサイドのjsかhtmlを改ざんしないと無理ではないのですか? そんなことをせずともURLを踏ませるだけで スクリプトを実行させることができるから脆弱性なのです 任意のスクリプトを実行させることさえできれば 表示するhtmlなどいくらでも書き換えることができます 実行ボタンを罠サイトへのリンクに書き換えたりなどやりたい放題です クッキーについてはそれを参照できることよりも それを書き込めることに問題があります すなわちセッションIDとして使用されるCookieの値を攻撃者が意図した値に あらかじめ設定してしまうことで他のユーザーへのなりすましを可能にします これがセッションフィクセーションです セッションフィクセーションについてはXSS脆弱性に加えて サーバーサイドでのセッションIDの更新が十分な頻度で行われていない という問題も合わさることで可能になります
お礼
evalを使った処理のソースをコメントアウトします。これで大丈夫ですか?
補足
URLを踏ませるとは恐らくリンクをクリックさせるだけでウイルス配布サイトに誘導して感染させられるという意味だと思いますが、サーバ上のhtmlをいじれないのにどうやってリンクを他人のページに追加するのでしょうか? ajaxでPHP工房のファイルにリンクを埋め込む命令を送ってサーバ上のhtmlを換算すると、その後アクセスした人に改ざん後のファイルを見ることになるという事でしょうか?
- amanojaku1
- ベストアンサー率54% (265/488)
ちなみに(詳しくは知りませんが)「XMLHttpRequest」は「Ajax」などでも使われていますね。 Ajax https://ja.wikipedia.org/wiki/Ajax
お礼
evalを使った処理のソースをコメントアウトします。これで大丈夫ですか?
- amanojaku1
- ベストアンサー率54% (265/488)
>ただ先程も言った通りダウンロードしたjsでクラッカーが危険なソースを記載してもクラッカーのpcで実行されるので自分がやられるだけでわないのですか 詳しくは知りませんが「XMLHttpRequest」でサーバーと通信ができるようです。 XMLHttpRequest https://developer.mozilla.org/ja/docs/Web/API/XMLHttpRequest
- H240S18B73
- ベストアンサー率65% (190/288)
先のスレで書いたことの繰り返しになりますが XSS脆弱性というのはURLを踏んだだけで任意のスクリプトを 実行させることができてしまうということが要因です XSSというのはサイトへの攻撃というよりは 他のユーザーへの攻撃になります XSSによる被害はサイトよりは 主にユーザーに及びます サイトの改ざんなどの被害を起こす可能性があるのは CSRFあるいはディレクトリトランザクションなどです これらはサーバーサイドの脆弱性によって起こります できることは少ないとはいえ XSSはJSのみでも成立し得ます 何らかの情報を勝手に送信したり 罠サイトへの誘導程度はできるはずですし 将来同サイト内にサーバーサイドで何かのサービスを実装した際には そのサービスでのセッションフィクセーション攻撃の 足がかりにされたりすることになります XSS脆弱性によって被害を受けるのはユーザーの方です
お礼
下記にある通りという認識でよいということですかね? https://sp.okwave.jp/qa/q4957775.html?a_open=true javascriptはクライアント側のブラウザーで実行されているものであり、そもそもローカルなリソースにはアクセス出来ないし、ましてサーバー側に影響を及ぼすようなjavascriptとはどんなものなのでしょうか? クッキーを盗むといっても、本人のクッキーを盗んでも仕方ないし、他人のクッキーはみれないでしょう。XMLHttpRequestで他のサイトにポストするコードを実行されても、サーバー側で困る事はないと思うのですが。 つまりサーバサイドのファイルをいじれないのでサイトにウイルスを仕込まれるやクラッキングされる事はないのですネ。
補足
XSSというのはサイトへの攻撃というよりは 他のユーザーへの攻撃になります XSSによる被害はサイトよりは 主にユーザーに及びます 他の閲覧者のクッキーが盗まれたり、ウイルスサイトに誘導されたりするリスクがあるのですかね? ただサーバサイドのjsかhtmlを改ざんしないと無理ではないのですか?
お礼
サーバが乗っ取られると、ffftpからダウンロードされた情報のみ正常なものをダウンロードさせるなんてことができるのですね。 ただファイルを隠すことはできないので、別ファイルにしている場合は見覚えのないファイルが見えるのでしょうね。