Perl についての質問です。


ごくごく初歩的な質問です。

自分の作ったサイト(仮にAサイトとします。)からPOSTを使い、データを以下のような感じで受け取るとします。

$data = $in_data{'data'};

ここで、ある疑問が頭をよぎったのですが、自分の作ったAサイト以外からも、POSTでデータを送る事ができるのでしょうか?

属性のあたりが関係してくるのでしょうか?

どなたか、わかりやすく教えて頂けないでしょうか?

回答の条件
  • URL必須
  • 1人2回まで
  • 登録:
  • 終了:2006/10/04 17:24:03
※ 有料アンケート・ポイント付き質問機能は2023年2月28日に終了しました。

ベストアンサー

id:TomCat No.4

回答回数5402ベストアンサー獲得回数215

ポイント100pt

postにせよgetにせよ、Webページから送信されるデータというのは、フォームのあるページが置かれているサーバが送信しているのではなく、実は送信ボタンを押した利用者のブラウザが送信しているんですよね。

 

ですから、どこのサイトに設置したページでも、あるいはPCのローカルに置かれたHTMLファイルでも、ブラウザがフォームを読み込んでいれば、そのブラウザは <form action="・・・・"> のactionで指示した先に、データを飛ばすことが出来るわけです。

 

この仕組みを使って、他サイトに設置されたフォームからデータを受け取って動作しているのが、たとえばGoogleなどの検索窓です。どこのサイトに設置された検索窓からでもGoogleはデータを受け取って、検索結果を表示します。Googleの場合、データの受け渡しはgetですが、考え方はpostと同じです。

 

とゆーことはどこからでもアクセスが可能で、掲示板などを作った場合、遠くから書き込めてしまうわけですね、、、みなさんはどうなさっているのでしょうか、、、?

掲示板などの場合、掲示板に付属する以外の書き込みフォームからのデータを受け付けてしまうと、勝手に書き込みフォームを作られてイタズラ書き込みをされたり、javascriptなどを使って大量に書き込みを送り付けられたりする恐れがありますから、この場合はデータを受け取る側のCGIで、ブラウザが読み込んでいたページがどこかということを示す「HTTP_REFERER」という変数を参照します。いわゆるリファラというやつです。そして、掲示板のURL以外のリファラが検出されたら、外部からの書き込みと判断して、エラーページに遷移させて処理を中断するなどして対処します。

 

2chなどの場合、ブラウザのリファラを送信しない設定にしていると「ブラウザ変ですよん」などと表示されて書き込めませんが、これは外部からの書き込みを遮断するためにリファラを参照していることの証拠で、そのため、リファラが検出されないブラウザからの書き込みも拒否しているわけです。

 

具体的な方法については、たとえばperlで書かれた掲示板CGIとして高いシェアを持つKENTさんのYY-BOARD

http://www.kent-web.com/bbs/yybbs.html

では、次のようにして外部からの書き込みを遮断しています。

# 他サイトからのアクセス排除
if ($baseUrl) {
	$ref = $ENV{'HTTP_REFERER'};
	$ref =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
	$baseUrl =~ s/(\W)/\\$1/g;
	if ($ref &amp;&amp; $ref !~ /$baseUrl/i) { &amp;error("不正なアクセスです"); }
}

$baseUrlが掲示板を設置するURL、$ENV{'HTTP_REFERER'}がデータを送信してきたブラウザのリファラです。これを照合して、外部からの書き込みかどうかを判断しています。

id:zachouR

詳しい解説ありがとうございます。

ソースまでつけて頂いて、すいません。

解説もわかりやすく、非常に参考になりました。2chを例にして頂いて、なんだか親近感?がわきました。

また、なにかありましたら、よろしくお願いいたします。

2006/10/04 17:23:19

その他の回答3件)

id:b-wind No.1

回答回数3344ベストアンサー獲得回数440

ポイント50pt

Perl に限らずすべての CGI に他サイトからの POST 送信は出来ます。

HTML の

<form action="http://example.com/form.cgi">

等とするだけです。

http://q.hatena.ne.jp/1159938166

id:zachouR

ありがとうございます、とゆーことはどこからでもアクセスが可能で、掲示板などを作った場合、遠くから書き込めてしまうわけですね、、、みなさんはどうなさっているのでしょうか、、、?

ありがとうございました。

b-WINDさん、いつもありがとうございます。お礼を送らせて頂きます!

2006/10/04 14:16:07
id:noboru No.2

回答回数94ベストアンサー獲得回数0

ポイント50pt

http://q.hatena.ne.jp/ (URLはダミーです)

特定のサイトからのみの POST しか受け付けないようにしたいということでしょうか? だったらその CGI の中で REMOTE_ADDR か REMOTE_HOST を見て判別するようにするとか、あるいはサーバの機能そのものを使って(ファイヤーウォールだとか tcp wrapper だとか)特定のホストからしか接続不可能にしてしまえば良いと思います。

id:zachouR

さっそく調べました。

これをやってみると、なんだかよさげな感じがします。(^^;)

ありがとうございました。

2006/10/04 17:21:08
id:ootatmt No.3

回答回数1307ベストアンサー獲得回数65

ポイント50pt

CGIでデータを送ってくるのはクライアント(ウェブページにアクセスしてきた人)です。

つまりどこからでもデータを送って掲示板等に書き込むことが出来ます。


最近は自動的に掲示板を巡回して宣伝等を書き込むボットが開発されているので、これを防ぐための対策をする必要があります。

例えば、英数文字だけの書き込みは拒否するとか、書き込み時にパスワードを要求するとか、禁止ワードを設けて宣伝を防ぐとかですね。

公開されているCGIプログラムを参考にするといいと思います。

http://swanbay-web.hp.infoseek.co.jp/index.html

id:zachouR

URL、ありがとうございます。非常にたすかります!

2006/10/04 17:21:29
id:TomCat No.4

回答回数5402ベストアンサー獲得回数215ここでベストアンサー

ポイント100pt

postにせよgetにせよ、Webページから送信されるデータというのは、フォームのあるページが置かれているサーバが送信しているのではなく、実は送信ボタンを押した利用者のブラウザが送信しているんですよね。

 

ですから、どこのサイトに設置したページでも、あるいはPCのローカルに置かれたHTMLファイルでも、ブラウザがフォームを読み込んでいれば、そのブラウザは <form action="・・・・"> のactionで指示した先に、データを飛ばすことが出来るわけです。

 

この仕組みを使って、他サイトに設置されたフォームからデータを受け取って動作しているのが、たとえばGoogleなどの検索窓です。どこのサイトに設置された検索窓からでもGoogleはデータを受け取って、検索結果を表示します。Googleの場合、データの受け渡しはgetですが、考え方はpostと同じです。

 

とゆーことはどこからでもアクセスが可能で、掲示板などを作った場合、遠くから書き込めてしまうわけですね、、、みなさんはどうなさっているのでしょうか、、、?

掲示板などの場合、掲示板に付属する以外の書き込みフォームからのデータを受け付けてしまうと、勝手に書き込みフォームを作られてイタズラ書き込みをされたり、javascriptなどを使って大量に書き込みを送り付けられたりする恐れがありますから、この場合はデータを受け取る側のCGIで、ブラウザが読み込んでいたページがどこかということを示す「HTTP_REFERER」という変数を参照します。いわゆるリファラというやつです。そして、掲示板のURL以外のリファラが検出されたら、外部からの書き込みと判断して、エラーページに遷移させて処理を中断するなどして対処します。

 

2chなどの場合、ブラウザのリファラを送信しない設定にしていると「ブラウザ変ですよん」などと表示されて書き込めませんが、これは外部からの書き込みを遮断するためにリファラを参照していることの証拠で、そのため、リファラが検出されないブラウザからの書き込みも拒否しているわけです。

 

具体的な方法については、たとえばperlで書かれた掲示板CGIとして高いシェアを持つKENTさんのYY-BOARD

http://www.kent-web.com/bbs/yybbs.html

では、次のようにして外部からの書き込みを遮断しています。

# 他サイトからのアクセス排除
if ($baseUrl) {
	$ref = $ENV{'HTTP_REFERER'};
	$ref =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
	$baseUrl =~ s/(\W)/\\$1/g;
	if ($ref &amp;&amp; $ref !~ /$baseUrl/i) { &amp;error("不正なアクセスです"); }
}

$baseUrlが掲示板を設置するURL、$ENV{'HTTP_REFERER'}がデータを送信してきたブラウザのリファラです。これを照合して、外部からの書き込みかどうかを判断しています。

id:zachouR

詳しい解説ありがとうございます。

ソースまでつけて頂いて、すいません。

解説もわかりやすく、非常に参考になりました。2chを例にして頂いて、なんだか親近感?がわきました。

また、なにかありましたら、よろしくお願いいたします。

2006/10/04 17:23:19
  • id:ootatmt
    ちなみに、HTTP_REFERER は簡単に偽装できますし、実際スパムボットは偽装してきますので、これだけに頼らず、いくつかの方法を組み合わせて対策する必要がありますよ。
  • id:TomCat
    ああっ、ソース部分の & が &amp; に変換されてしまっていました。&amp; の部分は当然 & ですので、そう読み替えてくださいね。
    これはうまく書き込めるか不安なので、&は全角で書いてみました(^-^;
  • id:TomCat
    >>ootatmtさん
    その通りですよね。リファラの参照はあくまで外部に置かれたフォームからの不正な送信を拒絶するためのもので、スパム対策としてはこれでは不十分です。

    私の設置している掲示板では、逆引きできないホストからの書き込み、ポート80などが開いているホストからの書き込み、日本語2バイトコードが含まれない書き込み、スパムロボットであることが明らかなAgentからの書き込み、リンクの文字列が全体の書き込み量の指定割合以上の文字数の書き込み、URLが指定個数以上含まれた書き込み、エロスパムに使われやすい語彙を含んだ書き込みなども跳ねるようにしていますが、それでも完全には防ぎ切れません。

    今はスパムも山の賑わいと開き直って、見つけたら削除するでいいやということにしています(^-^;
  • id:zachouR
    お二人とも、ありがとうございます。少しですが、お礼をお送り致します。

    TOMCATさん、非常に詳しい方ではないでしょうか?

    そこまで、チェックを入れてもなお、防ぎきれないものなのですね、、、。非常に参考になりました、さっそく組み込む為の勉強を開始しようと思います。

    しかし、恐ろしいですね、、、。スパム、、、。
  • id:Mars
    spamに関して言えば、postされたものを弾くには限界があるのでとにかくロボットに拾われないようにする(通常のアンカーではなくjavascriptでジャンプさせるとか)のが割と有効なようです。詳しくは#3の参考URLで。

    フォームの安全性確保という点では
    http://www.ipa.go.jp/security/awareness/vendor/programming/intro.html
    こちらを一度読んで置く事をオススメします。
    (特に第1章、第4章)

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

回答リクエストを送信したユーザーはいません