送受信_フォームデータの扱い-演習編

Problem1: 入力した文章をオウム返しに表示させてみよう

フォームから入力した文章をオウム返しに表示するCGIを作成してみてください

下記の手順でどうぞ

  1. 入力フォームのhtmlをGETメソッドで作成する(ファイル名 index.html )
    入力フォーム
  2. 入力された文章をテキスト平文で表示する CGI を作成する(ファイル名 parrot.cgi )
    ○
  3. 入力された文章を、入力フォームと一緒に html で表示する CGI を作成する(ファイル名 parrot.cgi )
    出力結果
  4. XSS 脆弱性対策を施した形で、入力された文章を html で表示する CGI を作成する(ファイル名 parrot.cgi )
    スクリプト入力
     ↓無事表示される
    無事表示される

⇒ ヒント

Hint

⇒ 答え

Solution

入力フォームhtmlの例

index.html:例えば、htmlファイルを下記のようにして、ファイル名 index.html とします。データの送り先は、parrot.cgi

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html lang="ja">
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS">
  <title>オウム返し</title>
</head>
<body>
<form action="parrot.cgi" method="GET">
入力:
<input type="text"   name="messe" value=""    tabindex="1" accesskey="1" size="72">
<input type="submit" name="botan" value="送信" tabindex="2" accesskey="2">
</form>
</body>
</html>

テキスト平文で表示させる場合

parrot.cgi:解説で使った例を、そのままコピーして使いました

#!/usr/local/bin/ruby -Ks
print <<HOGEHOGE
Content-Disposition: filename="parrot.txt"
Content-type: text/plain;charset=Shift_JIS

入力された文章:
HOGEHOGE
@in = Hash.new
for q in ENV['QUERY_STRING'].to_s.split(/[;&]/) do
  key,val = q.split(/=/,2)
  @in[key] = val.gsub(/\+/," ").gsub(/%[a-fA-F\d]{2}/){ $&[1,2].hex.chr } if val
end
print @in["messe"]

parrot.cgi:表示させるのは、一つの値だけで良いので、パターンマッチを使って簡略化できます

#!/usr/local/bin/ruby -Ks
print <<HOGEHOGE
Content-Disposition: filename="parrot.txt"
Content-type: text/plain;charset=Shift_JIS

入力された文章:
HOGEHOGE
if /messe=([^&]+)(&|\z)/ =~ ENV['QUERY_STRING'].to_s then
  print $1.gsub(/\+/," ").gsub(/%[a-fA-F\d]{2}/){ $&[1,2].hex.chr }
end

HTML で表示させる場合

parrot.cgi:index.htmlを読み込んで、受信した一文を</body>の直前に挟み込みます

#!/usr/local/bin/ruby -Ks
@in = Hash.new
for q in ENV['QUERY_STRING'].to_s.split(/[;&]/) do
  key,val = q.split(/=/,2)
  @in[key] = val.gsub(/\+/," ").gsub(/%[a-fA-F\d]{2}/){ $&[1,2].hex.chr } if val
end

html = open("index.html"){|f| f.read } rescue "<html><body><h1>Error!</h1></body></html>"
html.sub!(/<\/body>/){ "<p>出力: #{ @in["messe"] }</p>\n" + $& }

print <<HOGEHOGE
Content-Disposition: filename="parrot.html"
Content-Length: #{ html.length }
Content-type:   text/html;charset=Shift_JIS

HOGEHOGE
print html

HTML でセキュリティも考慮して表示させる場合

parrot.cgi:XSS脆弱性対策として、入力された文字列を、置換してから表示させます。

#!/usr/local/bin/ruby -Ks
@in = Hash.new
for q in ENV['QUERY_STRING'].to_s.split(/[;&]/) do
  key,val = q.split(/=/,2)
  @in[key] = val.gsub(/\+/," ").gsub(/%[a-fA-F\d]{2}/){ $&[1,2].hex.chr } if val
end

if @in["messe"] then
  @in["messe"].gsub!(/&/,"&amp;")
  @in["messe"].gsub!(/&amp;#(\d{2,4});/){ "&#" + $1 + ";" }
  @in["messe"].gsub!(/</,"&lt;")
  @in["messe"].gsub!(/>/,"&gt;")
  @in["messe"].gsub!(/"/,"&quot;")
  @in["messe"].gsub!(/'/,"&#39;")
end

html  = open("index.html"){|f| f.read } rescue "<html><body><h1>Error!</h1></body></html>"
html.sub!(/<\/body>/){ "<p>出力: #{ @in["messe"] }</p>\n" + $& }

print <<HOGEHOGE
Content-Disposition: filename="parrot.html"
Content-Length: #{ html.length }
Content-type:   text/html;charset=Shift_JIS

HOGEHOGE
print html

⇒ 次の問題に進む

以上です。

Last updated 30.Sep.2006 [ Home ] [ Up ] [ 質問メール ]
Copyright © 2005-2006 Shigeru Konno All Rights Reserved..