• ベストアンサー

PHPやjavascriptを無効にする方法

PHP+MySQLで掲示板のようなものを作成しています。 投稿の際、HTML形式が利用できるようにしたいと思っています。 概ね完成したのですが、HTML形式で投稿できるということは、PHPやjavascriptのコードを投稿すれば、それらの機能も利用されてしまうことに気がつきました。 たとえば、投稿フォームから <?php //悪意のあるコード ?> と入力すれば、悪意のあるコードが実行されてしまいます。 そこで、投稿された部分のPHPやjavascriptだけを無効にする方法はないのでしょうか? あるいは$や{や;など、PHPやjavascriptなどで使用する記号を受け付けないようにすればいいのでしょうか? うまく説明できないので詳細は割愛しますが、「HTMLでの投稿をやめる」という選択ができないので悩んでいます。 どのような対処をすればいいのか、ご教授願います。 説明不足な点がありましたら、ご指摘いただければ補足します。 よろしくお願いいたします。

質問者が選んだベストアンサー

  • ベストアンサー
  • masa6272
  • ベストアンサー率66% (93/140)
回答No.3

属性に関してはチェックせず、タグそのものが許可されていれば、そのまま残ります。したがって、<button>などで、onClick属性とかにjavascriptのコードを入れられると、危ないですね。

ka-kichi
質問者

お礼

思い通りのことが実現できました!! ありがとうございました。 buttonなどは許可せず、divやpやspanなど、体裁を整えるものだけを許可したいと思います。

全文を見る
すると、全ての回答が全文表示されます。

その他の回答 (7)

  • SHlVA
  • ベストアンサー率48% (20/41)
回答No.8

HTML Purifier というライブラリが、ほとんど解決してくれます。 <script>はもちろん、属性(onclickなど)もちゃんと解析して排除してくれます。 セキュリティというものに完璧はないので、おそらく抜け道は存在するはずです。ただ自分で小手先の知識でやるよりは、こういう専門に作られた方が安全だとは思います。 他の方がおっしゃってるように、PHP側でeval()しない限りPHPコードは実行されないのでご安心を。

参考URL:
http://htmlpurifier.org/
ka-kichi
質問者

お礼

ありがとうございます。 便利なライブラリがたくさん出回っていてびっくりします。 前にも書きましたが、PHPの勉強を兼ねておりますので、自分で考えながら作ってみたいと思います。

全文を見る
すると、全ての回答が全文表示されます。
  • tany180sx
  • ベストアンサー率63% (239/379)
回答No.7

ググったらこんなのはありましたね。 function escapeJavascript_r($deep=false){ $search = array ('@<script[^>]*?>.*?</script>@si','@([\r\n])[\s]+@si'); $replace = array ('',''); if ($deep) { $search[] = '/[\s]+on[\w]{2,15}=[\"|\'][^>]*?[\"|\']/im'; $replace[] = ''; } return preg_replace($search, $replace, "".$this->v.""); }

ka-kichi
質問者

お礼

再度ご回答ありがとうございます。 残念ながら、複雑すぎて今の私には理解不能です。(^^ゞ 今回は、strip_tagsを使って必要なものだけを許可する、という方針で進めようと思っています。 ありがとうございました。

全文を見る
すると、全ての回答が全文表示されます。
  • tany180sx
  • ベストアンサー率63% (239/379)
回答No.6

適当に書いてみましたが動作の保証はありません。 XSSについて理解が漠然としすぎな感もしますし もしお仕事なら htmlspecialchars 使っとくのが無難な気がします。 function escapeJavaScript($html) { $html = preg_replace('/((?:\G|<)[^>]*?)(javascript:)/i', '\\1_\\2', $html); $html = preg_replace('/((?:\G|<)[^>]*?)([^a-zA-Z])(on[a-zA-Z]+)/i', '\\1\\2_\\3', $html); $html = preg_replace('/<(script)/i', '&lt;\\1', $html); return $html; }

ka-kichi
質問者

お礼

ご回答ありがとうございます。 XSS(クロスサイトスクリプティング)というのですね。(^^ゞ これをキーワードに探してみれば、よりよい方法がみつかるかもしれません。 ソースまで作っていただきありがとうございました。 ちなみにPHPの勉強をかねて、趣味でやってます。(^^ゞ

全文を見る
すると、全ての回答が全文表示されます。
  • BellBell
  • ベストアンサー率54% (327/598)
回答No.5

お礼の中で、気になる点がいくつかあったので書かせて貰います。 <?php $hoge = '<?php echo"hogehoge";?>'; echo $hoge; ?> 上のPHPコードを実行すると、どうなるでしょう? 2行目のecho $hoge;はサーバー上で実行されますが、その変数$hogeに格納されている<?php echo"hogehoge";?>は、ただの文字列です。 そのままブラウザに渡されますが、ブラウザ上ではPHPは動作しません。 HTML内にただ<?php echo"hogehoge";?>が残るだけです(表示はされず、コメントとして扱われると思います)。 $hogeに入れる値は、ファイルやDBから取得した場合でも同様です。 通常の掲示板の作り方では、ユーザーがPHPコードらしき文字列を投稿することはできますが、その文字列をPHPコードとして動かすことはできません。 わざわざ、(少々苦心した上で)ユーザーが投稿した文字列をPHPコードとして動作するように作り込みすることは可能です。 可能ですが、わざわざそんなことします? 普通に作れば、ユーザーの投稿した文字列がPHPコードとして動作することはありません。 というのが、No.4の方の最後の2行の意味ですね。 ま、strip_tagsで<?php ~ ?>も削除でしょうけど。 mb_eregiで、大文字小文字を区別しないマッチもできますよ。 http://jp.php.net/manual/ja/function.mb-eregi.php 他には、いくつかHTMLタグを使った嫌がらせを紹介。 開始タグのみを書いて終了タグを書かずに、以降のレイアウトを崩す嫌がらせ。 <font size=100> 大きいサイズを指定してレイアウトを崩す <font color=#FFFFFF> 背景色と同一の色で書いて、文字を見えなくする 縦横のサイズを大きく指定して、レイアウトを崩す嫌がらせ <div style="width:1000px;"></div> 幅指定を大きくして、レイアウトを崩す <p><p><p><p><p><p><p><p><p><p><p><p><p><p><p>たくさん改行することで、無駄に縦に長い空白を作成する。 HTMLタグを許可するって事は、色々なHTMLタグを使った嫌がらせにも対応する必要があるって事で御注意。

ka-kichi
質問者

お礼

ご指摘ありがとうございます。 説明不足&知識不足でうまく伝わらない部分もあると思いますがご容赦ください。 先ほど、投稿フォームから <?php $hoge = '<?php echo"hogehoge";?>'; echo $hoge; ?> を送信したところ、ブラウザには何も表示されませんでした。 ソースを見れば4行のコードがそのまま記述されていますが、ブラウザには表示されません。 このコードが実行されてしまうかもしれないと、私が勘違いをしていたようです。(^^ゞ PHPやjavascriptなどは、HTML内に埋め込んで動作させることができるので、PHPなどを含むHTMLが投稿された記事を表示させると、PHPなどが実行されてしまう・・・と思っていました。 > 普通に作れば、ユーザーの投稿した文字列がPHPコードとして動作することはありません。 たぶん、普通に作っているはずです・・・。(^^ゞ 後半に記述されたような「消去すれば解決できる嫌がらせ」は気にしていません。 PHPなどが実行され、DBのデータを抜き取られたり、公開ディレクトリより上に置いてある設定ファイルを覗かれたり、といった情報漏洩や、無限ループを仕掛けられてサーバーに高付加をかけるといった、取り返しのつかない事態を避けたいと考えています。 実ファイルに書き込んだコードと、スクリプトで自動生成したコードでは挙動が違うことがわかりました。 私が気にしていた「悪意のあるコード」は実行されないようですね。 ありがとうございました。

全文を見る
すると、全ての回答が全文表示されます。
  • tany180sx
  • ベストアンサー率63% (239/379)
回答No.4

入力が予定されるHTMLの内容にもよるかと思います。 日記投稿レベルであればJavaScriptのダイアログなどを利用して 独自のフォーマットで保存してやるとか。 リンク [link=http://domain.dom/]サイト名[/link] 文字色 [color=red]文字[/color] 様々なHTMLが入力されるのであれば、 <script></script> <* on[a-zA-Z] .. <a href="javascript: .. あたりを正規表現なりで除去する必要があります。 もしくは上記のような記述が見受けられれば 「悪意のあるコードが記述されている可能性があります。」 と1回警告を出したのち自己責任で見てもらうとか・・・ > <?php 悪意のあるコード ?> print などで出力する分には実行されませんが、ファイルを書き出して phpで走らせたりphpのコードとして評価させるのでしょうか?

ka-kichi
質問者

お礼

ご回答ありがとうございます。 独自フォーマットも考えましたが、今の自分の知識レベルでは難しいので断念しました。(^^ゞ また、<Script>や<sCrIpT>などと大文字小文字を混在させるパターンや、<script >などと余分なスペースを入れるパターンなど、工夫をすれば無限大の可能性があると思い、現実的ではないような気がします。 最後の二行の意味がわかりませんが、ユーザーがPHPコードを投稿できるということはとんでもないことだと思いました。 一番怖いのは、公開ディレクトリより上の階層に入り込まれたり、DBを覗かれたりする可能性も出てくることです。 説明不足でもうしわけありません。

全文を見る
すると、全ての回答が全文表示されます。
  • masa6272
  • ベストアンサー率66% (93/140)
回答No.2

umotaさんの回答だと、HTMLも禁止されてしまいますね。 strip_tagsという関数があります。 これは、許可するタグ以外をすべて消します。 問題は、許可するタグをすべて列挙する必要があることです。 たとえば、<p>、<strong>、<font>だけを許すのでしたら、 $strippedString = strip_tags($inputString, '<p><strong><font>'); のように書きます。 HTMLのタグもフォームなど危険なものもありますので、記述が面倒かもしれませんが、この方法で許可するものだけを残すことをお勧めします。

ka-kichi
質問者

お礼

ご回答ありがとうございます。 なるほど。便利な関数があるものですね。 下記のようにclassやidを追加したタグはどうなるのでしょうか? <p class="midashi"> strip_tagsについて調べてテストしてみようと思います。

全文を見る
すると、全ての回答が全文表示されます。
  • umota
  • ベストアンサー率46% (150/324)
回答No.1

phpを使っているならば htmlentities 関数で変換する。 例えば "<?php" は "&lt;?php" となるので実行できません。

参考URL:
http://jp2.php.net/manual/ja/function.htmlentities.php
ka-kichi
質問者

お礼

ご回答ありがとうございます。 htmlentitiesを通すとHTMLタグも使えなくなるので、残念ながら今回の主旨からはずれてしまうんです・・・。

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • html,javascript,php,mysqlの発音

     英語でHtml,javascript,php,mysqlはそのままで呼びます。日本語でどうのような発音するんですか?  よく言われる言い方は教えてください。  よろしくお願いいたします。

    • ベストアンサー
    • MySQL
  • php と JavaScript(HTML??)

    どうかお願いします。 まず私がやりたい事は、 phpプログラムによってファイル名を入所し、HTMLのコンボボックスとして表示。 それを二つ作る。 その際、一つ目のコンボボックスで選ばれたディレクトリの中に入っているファイルを2つ目のコンボボックスで表示するようにする。 つまり (1)利用者はディレクトリを一つ目のコンボボックスで選択 (2)そのディレクトリに入っているファイル名(TEXTファイル)などを2つ目のコンボボックスで選択 このような事をしたいと考えています。 一つ目のコンボボックスはできました。 しかし、二つ目ができません。 まず私は$dir = opendir("./");としてディレクトリを開いています。 一つ目は上でいいのですが、2つ目が$dir = opendir("./???"); ??の部分に一つ目で選ばれた物を入れなくてはなりません。 しかし、HTMLやJavaScriptからPHPに変数を渡す方法がわからないのでできないんです・・・。。 どのようにしたらよいでしょうか。 長くなりましたがお願いします。

    • ベストアンサー
    • PHP
  • Javascriptの関数をPHPで作りましたが戻値を得る方法がわかりません。

    はじめまして。xpにxamppの環境で利用してます。 PHPをjavascriptの関数に出来ると知り、 geturl.php <?php header("Content-type: application/x-javascript"); echo "function picturl() {"; ~ MySQLを特定の条件で検索し、画像の保存先URLを$urlへ格納 ~ echo "}"; ?> showpict.html <html> <head> <meta http-equiv="content-type" content="text/html;charset=shift_jis"> <title>photo</title> <script type="text/javascript" src="geturl.php"></script> <script type="text/javascript"> ~以下でたとえば、  var url = picturl(); とすれば url に 値が入るかと思って作成して見ました。 PHPの$urlには、 ./data/001.png のような値が入ります。 私が参考にしたPHP文では戻値は変数ではなく生のテキストで echo "document.write(\"文章\")"; となっており、これは実行できました。 変数を使用して上記のような値を求めようとしたところ、 echo "document.write(\"$url\")"; echo "retuen $url"; などを試してみましたがうまくいきません。 この様な方法では利用できないものなのでしょうか?。 それともecho文が以外の方法で行うものなのでしょうか?。 よろしくご協力のほどお願いいたします。

    • ベストアンサー
    • PHP
  • JavaScriptからPHP呼び出しHTML出力で…

    現在phpにてブログのカテゴリリストを取得して、投稿ページ (HTML)上にカテゴリのプルダウンを表示しようと試みている のですが、JS(JavaScript)からPHPを呼び出しHTML上に出力する 際にPHPファイルにincludeがあるとjavascriptエラーとなって しまいます。 ちなみに参考にしたホームページはこちらです。 http://www.res-system.com/item/383 PHPソース(init.php)↓ <?php include_once('entry.php'); // ←エラーの箇所 // ヘッダ header("Content-Type: application/x-javascript; charset=UTF-8"); // インスタンス生成 $obj = new XMLComm(); // 初期設定 $obj->XMLComm(); // カテゴリ取得 echo "document.write(\"$obj->getCategories()\")"; ?> HTMLソース(entry.html)↓ <HTML> <HEAD> <TITLE>BLOG ENTRY</TITLE> </HEAD> <BODY> ブログエントリー</br> <script type="text/javascript" src="/init.php"></script> </BODY> </HTML> ちなみに、include等が無い状態で任意の文字で試したのですが こちらはきちんと表示されます。 javascriptでincludeなど呼び出しているphpを起動することは できないのでしょうか… 解決策、別案などありましたらご教授いただけたら幸いです。 phpを始めたばかりの初心者で、質問自体おかしい点があるかも しれませんが、、どうぞよろしくお願いいたします。

    • ベストアンサー
    • PHP
  • phpとjavascriptで画像を切り替える

    こんにちは。phpで掲示板を作っているんですが、画像差し替えのためのjavascriptを入れると上手く動作しません。どなたかお手数ですがご教授いただけませんでしょうか?以下がスクリプトです。 <?php require_once("****.php"); $con = mysql_connect($DBSERVER, $DBUSER, $DBPASSWORD); $selectdb = mysql_select_db($DBNAME, $con); $sql = "select * from stock where no = '$no'"; $rst = mysql_query($sql,$con); $body =""; while($col = mysql_fetch_array($rst)) { $img = $col["imgfilename"]; $img1 = $col["imgfilename1"]; $body .= "<p style='text-align: center;'> <img src ='upload/$img' name='imgs' alt='*'><br> <a href ='#' onClick='roimg('upload/$img1'); return false;'>差し替え画像</a> </p>"; } $con= mysql_close($con); ?> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <HTML> <HEAD> <META http-equiv="Content-Type" content="text/html; charset=Shift_JIS"> <META http-equiv="Content-Style-Type" content="text/css"> <script type="text/javascript"> <!-- function roimg(i){ if (document.images){ document.imgs.src=i; } } //--> </script> </HEAD> <center> <?= $body ?> </center> </BODY> </HTML>

    • ベストアンサー
    • PHP
  • php、MySQL、javascriptで

    php MySQL javascriptを使ったウェブアプリを作っています。 商品コードを入力すると、隣の欄にその商品コードに対応する商品名と価格が表示され、それにより入力した商品コードを確認しながら、さらにその隣の個数欄に個数を入力し、その下の登録ボタンをクリックして、注文票に商品を追加していきます。 数品のレコードを登録し、登録が完了したら、最下部の「この内容で注文票を確定する」ボタンをクリックすることにより、注文票が確定されるという内容の部分があります。 その上手な作り方があるでしょうか。 とりあえず、力技で何とか作って動いてはいますが、あまりスマートでないと感じています。 Submitボタンが2つと、商品コードを入力した後に、onBlurで処理ページに移動し、そこからLocationで戻ってくるという作りで、変数の受け渡しにPOSTやMySQLを使い、強引な感じです。 getElementByIdを使うといいかなと思いましたが、phpに値を渡すなど、いくつか難しい箇所があり、断念しました。 コードでなく、言葉でも結構ですから、こういう流れで作ったら?というヒントなどいただければ幸いです。 同様なことを実現しているページや解説ページも大歓迎です。 もちろん、コードによる説明は大歓迎です。 よろしくお願いいたします。

    • ベストアンサー
    • PHP
  • MySQL,PHP,javascript,mapへ

    MySQLのデータベースレコードにある住所をGoogle Mapsに表示させたいです。 手順1) 住所を検索するphpを実行し,結果を JavaScript に渡す。 手順2) JavaScriptで Google Map API を呼び出す。 上記の方法を考えたのですが、 MySQLの接続や、データを検索するプログラムが分かりません。 以下のコードのどこにどのように入れれば宜しいでしょうか? <?php $txt = $_POST['txt']; $txt = mb_xxx ( $txt ); ?> <script type="text/javascript"> <!-- function hoge () { var txt = "<?= $txt ?>"; } //--> </script> プログラム参考にしたサイト http://d.hatena.ne.jp/ese-se/20070823/1187870469 ご回答よろしくお願いします。

  • mysqlの設定&php+javascript(ajax)

    今javascript(ajax)とphpとmysqlで多言語チャットを作っているんですが退出するときにwindowを消したら退出しデータを消したいんですがmysqlにどのような設定をすればmysqlのデータを消していいのかわかりません。 htmlに<body onUnload="window.location='logout.php'">というコードを書いてlogout.phpは作ったんですが、mysqlのデータを消すのに個人に絞ることがどうやるのかという事がわかりません。 ちなみにmysqlで自分はchat(nick(入ったときのニックネーム)、time(入った時間)、words(チャットのコメント))というテーブルとmembers(nick(入ったときのニックネーム)、time(入った時間)というテーブルを使っています。

  • phpとjavascript ・・・・ について

    授業評価アンケートのデータ収集システムの開発を行っています。 科目及び科目コードを入力させるページ(page1.php)があります。 その入力について、入力ミスをなくすために、「参照」ページ(kamoku.html)をつくり、 そこには予め「科目/科目コード」という項目のある表が用意されており、 そのページ(kamoku.html)へジャンプし、そこで入力したい項目をクリックすると、 page1.phpの科目及び科目コード、各々のテキストボックスに入力したいものを代入することに成功しました。 このような構造にする前は、 手入力した後、 「次ページへ」 をクリックすると、次ページへジャンプするようになっていました。 <FORM method="post" action="page2.php" enctype="application/x-www-form-urlencoded"> javascript を利用したのですが、 これが原因なのでしょうか? javascriptを利用したページの拡張子は必ずhtmlじゃないといけないのでしょうか? (page1.phpをただ単にpage1.htmlにしてもダメでしたが・・・) URLについて、 http://----/page1.php 次ページをクリックすると http://----/page1.php?nendo=6&gakunen=1&class=1&kamokumei=&kamokucode=&kind=1&people=&sub=次ページへ のようになり、昔のように次ページをジャンプせず、入力項目が空になったりします。 どなたか解決法を教えてください!!! お願いします><

    • ベストアンサー
    • PHP
  • PHPからjavascriptへGETで値を渡すとき

    初歩的な質問で失礼いたします。 PHPからjavascriptへGETで値を渡すときにマルチバイト文字が文字化けしてしまいます。 javascriptのjQueryというライブラリを利用しています。 具体的には、 -------------- test.js -------------- var url = 'test.php?code=' + code; $.get(url, function(data){ alert(data); } -------------------------------------- --------------- test.php ------------- $input = $_GET['code'];  ・・・mysqlの処理・・・ echo $output; --------------------------------------- という処理をしています。 test.js → test.phpへ渡す値はマルチバイトではないので問題ないのですが、 test.php → test.jsへ返す値はマルチバイトで文字化けしてしまいます。 php側でrawurlencode関数でエンコードしてから、javascript側でdecodeURI関数を使用してデコードしたのですが、うまくデコードできませんでした。 恐らくデコードの仕方が悪いんだと思うんですが。。。 分かりにくい説明で恐縮ではございますが、ご回答をお願いいたします。 宜しくお願いいたします。

    • ベストアンサー
    • PHP