電子書籍の厳選無料作品が豊富!

自分なりにいろいろ試してみたのですが出来なかったので、お教えいただきたいと思い、質問させていただきます。

現在、perlを使ってCGIを組んでいます。
(というよりは組まれていたCGIを編集しています)
その中で、外部から入力された文字列データを変数に格納し
それをprintで書き出しています。
以下のような形です。

--------------------------------------------------
open(IN,"$datfile");
while (<IN>) {
my ($no,$date,$name,$comment,$ip) = split(/<>/);
print "<div class=\"line_wrap\">";
print "<div class=\"line_left\">$date</div>";
print "<div class=\"line_right\">$comment</div>";
print "</div>";


}
close(IN);
--------------------------------------------------

なんとなくでしか理解できてないのに編集したのでおかしい部分もあるとは思いますが・・・。

今回お伺いしたいのは

$comment

という変数内に、HTMLタグが入っていた場合、そのままの状態で吐き出されてしまうことになり困っています。
変数内の文字列に記載されているHTMLを、HTMLとして認識して実行したいのですが(要はリンクを貼りたい)可能でしょうか?
外部から入力されているものですので、HTMLがあったりなかったりします。
何か方法があれば、教えていただきたいです。
よろしくお願い致します。

A 回答 (3件)

まず、



 my($no,$date,$name,$comment,$ip) = split(/<>/);

~の部分ですが…。
区切り文字が「split(/<>/)」で“<>”となっていますので、“\t”とかに変更して。最初に読み込んでくるDATA(この場合は「$datfile」です)にコメントが書き込まれる処理の時に、区切り文字が“\t”で処理される様に書き直す必要があります。

HTMLタグに必要な“<>”を区切り文字に使っているので。
コメント中にHTMLタグが含まれていた場合、予期せぬ箇所でコメントが分断されたりしているせいだと思われます。恐らくは元になったCGIプログラムのオリジナル製作者が、安易にHTMLタグをコメント文に含まない様にセキュリティの意味でそうしてるのだと思われます。

またHTMLタグをコメント文中に許可する場合。
HREFタグに偽装して悪意あるコードを実行されない様に、かなりコメント文を慎重に精査して変換処理を加える必要があると思います。またPerlで実行するので、Perl特有の「冗長なエンコードの問題」を付かれない様に注意する必要もあります。

この回答への補足

ありがとうございます。
“<>”を“\t”に変えて、吐き出しをさせることが出来ました。

しかしながら、まだタグは有効ではないようです。
でも、<>で区切るよりは、個人的にもこちらが好きですし、とても勉強になりました。
ありがとうございました!

補足日時:2009/07/09 11:57
    • good
    • 0
この回答へのお礼

回答ありがとうございます。

なるほど~・・・と納得しました。
区切り文字が<>だということに気づいていながら、それがHTMLタグで混乱させているということに気づけず申し訳ないです。

まずは外部から入力したときに使用している区切りを“<>”から“\t”に変更しなければならないということですね。
掲示板のようなところから、第三者に入力してもらい、それをdatファイルに書き出して、そのデータ区切りが“<>”になっているので、それが“<>”になるよう指定しているcgi部分を探りたいと思います。

いろいろ試してみましたが(関係している3つのcgi内の“<>”をすべて“\t”に置換するとか・・・)、まだ理解力が足りないようで解決できませんでしたが、糸口が見つかりました。ありがとうございます!

お礼日時:2009/07/09 11:43

なるほど。


既に

$comment =~ s/&amp;/&/g;
$comment =~ s/&lt;/</g;
$comment =~ s/&gt;/>/g;

これと同じ処理がされているのですね。
それを外せばタグはタグとして実行されますが、XSSなどの危険性は覚悟してください。
    • good
    • 0
この回答へのお礼

再びありがとうございます。

--------------------
$val =~ s/&/&amp;/g;
$val =~ s/"/&quot;/g;
$val =~ s/</&lt;/g;
$val =~ s/>/&gt;/g;
$val =~ s/\r\n/<br>/g;
$val =~ s/\r/<br>/g;
$val =~ s/\n/<br>/g;
----------------------

多分?これがその役目を果たしているのだと思い、消してみましたが、特に変わりはありませんでした。

皆様の意見を聞いていると、やはりHTMLを使えるようにすることはかなりのリスクがあるようですね。皆様がそう注意をしてくださる中、まだやろうとするのも申し訳ないのですが、もう少し研究してみます。
ありがとうございました!

お礼日時:2009/07/09 11:56

タグがタグとして実行されるなら、そのままリンクタグも有効です。


タグを文字列として表示したいなら、

$comment =~ s/&amp;/&/g;
$comment =~ s/&lt;/</g;
$comment =~ s/&gt;/>/g;

として変換し、
http://と書かれていたら自動リンクするならば、
$comment =~ s/(http?\:[\w\.\~\-\/\?\&\=\;\#\:\%\*\+]+)/&autoexg($1)/eg;

sub autoexg{
$local = $_[0];
$output = "<A href=\"$local\" target=\"$target\">";
$output .= "リンクです→$local";
return($output);
}

とでも行えばいいような気がしますが。
(あくまでも例なのでご質問者さまの要求に合わせて変更してください)
    • good
    • 0
この回答へのお礼

早速のご回答ありがとうございます!

回答を参考にいろいろ試してみましたが、望む結果が得られませんでした。

>タグがタグとして実行されるなら、そのままリンクタグも有効です。
cgi内にprintで記述しているタグはそのまま実行されるのですが
変数($comment)内のタグは実行されません。
下記のように、そのまま表示されてしまいます。
---------------------------------------------------
<a href="http://www.yahoo.co.jp">あいうえお</a>
---------------------------------------------------
外部から入力する際に、「"」を「\"」として入力し、エスケープさせてみましたが、その場合も
---------------------------------------------------
<a href=\"http://www.yahoo.co.jp\">あいうえお</a>
---------------------------------------------------
とそのまま出力されてしまいます。
タグ部分を表示せず、
「あいうえお」
と表示され、そこにリンクをつけた状態にするにはどうしたらよいのでしょうか・・・。

お礼日時:2009/07/09 11:17

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!