トップページphp
1001コメント360KB

Perlコーディング初心者質問スレ Part 52

■ このスレッドは過去ログ倉庫に格納されています
0001nobodyさん2006/09/15(金) 14:01:51ID:gobry0n2
Perlのコーディングで困ってる人のスレです。

【投稿する際の注意】
質問するときは内容をよく吟味してから投稿してください。
「コマンドの意味がわかんない」とかはマニュアル見ましょう。
回答者さんは何でも屋じゃありません。

1: 自分はこういう事がしたい。
2: それでこんな風にやってみたが・・・
3: こんなエラーが出て上手く行かなかった。

最低でも1と3が無いと誰も答えられないよ。
ソース貼る時は、全角スペースでインデント忘れずに。
良い回答は良い質問から。一緒に勉強しましょう。

お勧めサイトは >>2-10

前スレ http://pc8.2ch.net/test/read.cgi/php/1153987463/
過去ログ倉庫 ttp://user.ftth100.com/mirrorhenkan/perl/
0010nobodyさん2006/09/16(土) 11:37:13ID:vjnDDSY/
>>9
ありがとうございます。
0011nobodyさん2006/09/16(土) 22:23:36ID:???
一行にしたいなら:
chomp(@list = sort <STDIN>);
0012nobodyさん2006/09/18(月) 19:19:34ID:???
STDINに直接sort指定できるんだ。
その発想は無かった。
0013nobodyさん2006/09/18(月) 22:14:51ID:???
そりゃsortが要求するのはLISTであってARRAYじゃないしね。
普段はあんまり意識しないけど、LISTとARRAYの違いは重要。
0014nobodyさん2006/09/18(月) 22:14:58ID:???
>>12
STDIN を直接ソートしてるわけじゃなくて、
リストコンテキストで評価することでファイルの中身をソートしてるだけ。
0015nobodyさん2006/09/18(月) 22:32:44ID:???
なるへそ。
そういう動作の仕方を知ってると色々応用できるし参考になるよ。
0016nobodyさん2006/09/19(火) 06:52:45ID:???
Shift_JIS でコーディングをする場合のセキュリティについての質問です。

例えば、次のようにユーザ入力の値をダブルクォート内に代入したとします。
この時エスケープする文字列は、 & と < と > と " と ' です。

<a href="http://$hoge";>

バイナリエディタで解析した " (ダブルクォート) の 16進表記は、"22" です。
ここで、$hoge に バイナリレベルで "82" をいれてみるとどうなるかやってみました。(バイナリファイルを一般のテキストエディタで表示したときの、"・"(半角) と表示されるあれです。)
それを出力して、IE と Firefox と Opera で表示したところ、 "82 22" で 1つの不正な文字 "・"(全角) として表示され、ダブルクォートが消えうせていました。

当然、掲示板のURL欄にこういう文字列をいれられたら、それ以降のデータがダブルクォート内のものと扱われますし、
その後の投稿内容の一部が " (ダブルクォート) 外にすることも可能で、"onload" イベントなどを使った、XSS攻撃も可能になるわけです。

大手CGI配布サイトのCGIで実験してみたところ、なんと実際にXSS攻撃が可能でした。

つまり、下記の条件を満たしてるPerlには脆弱性があることになります。

・文字コードとしてShift_JISを使っている。
・ダブルクォート内に正規表現などで入力内容を規制していない文字列が代入される。
 (所謂、< とか > とか " のサニタイズをしていてもこの攻撃は可能。)
・Shift_JIS に存在しないコードを含む文字列が存在しないかの確認をしてない。
0017162006/09/19(火) 06:56:55ID:???
上の脆弱性を要約すると、

「"(ダブルクォート) は 1バイト文字だけど、ユーザが送る文字列の最後に不正な1バイトコードをいれることで、
その1バイトコードと、ダブルクォートが合体した、不正な文字化けした2バイトデータと扱われ、ダブルクォートが消失してしまう(文字化けした・になる)」ということです。

こういった「文字化けを悪用した攻撃」に関する解説サイトはなかなか見つからず困っています。(上の情報は自分で検証した結果です。)
これの対処についていくつか質問があります。


・ユーザから送られてきた文字列が、Shift_JIS として正当であることを確認する、モジュールなどはないでしょうか?
それができたら、文字化けを悪用した攻撃は防げるかと思います。


・EUC-JP や UFT-8 ではこのような問題は発生しないのでしょうか?
参考: http://www2d.biglobe.ne.jp/~msyk/cgi-bin/charcode/bbs.cgi?past=1&c=r&n=82

 ・もし、EUC-JP などなら問題が生じないのであれば、スクリプトの文字コードの変換をやろうかと思います。
  Shift_JIS の駄目文字を "\" でエスケープしているコードを自動的に変換するソフトはないでしょうか?


ご教示お願い致します。

0018162006/09/19(火) 06:58:25ID:???
>>16 の <a href="http://$hoge";> が2chブラウザで見ると、
実体参照化される場合があるようです。

<a href=”http://$hoge”> です。
0019nobodyさん2006/09/19(火) 12:24:14ID:???
XSSはブラウザ依存だからなぁ。
「このサイトはテキストブラウザ専用です」と書いておけばおk。
完全に排除したいなら最後に半角スペースを入れるくらいしかないと思う。
なぜならクライアントはページ製作者の指定したエンコードで表示するとは限らないから。
0020nobodyさん2006/09/19(火) 12:38:09ID:???
>"onload" イベントなど
s/=/?/g;

>Shift_JIS として正当であることを確認
正規表現
0021nobodyさん2006/09/19(火) 12:39:43ID:???
表示されてない…
s/=/&#61;/g;
0022nobodyさん2006/09/19(火) 15:40:09ID:???
>>16
てーか普通URLに \x7f 以上の文字あるときはそれ全部エスケープするだろ?
あのくだらない日本語ドメインかなんかですか?(^ω^;
0023nobodyさん2006/09/19(火) 17:02:06ID:???
>>17
> ・ユーザから送られてきた文字列が、Shift_JIS として正当であることを確認する、モジュールなどはないでしょうか?
正規表現一行で実現できるよ。
0024nobodyさん2006/09/19(火) 18:25:23ID:???
if構文でandとorなんですが、
AでかつBでかつCの場合、のような全部andというわけではなく
AでかつBかCの場合、という混合の書き方はありますでしょうか?
現在は
if($foo eq 'A'){
if($bar eq 'B' or $bench eq 'C'){
print $foobar;
}
}
みたいに入れ子にしてます。
0025nobodyさん2006/09/19(火) 18:27:03ID:tgpbfNw0
>>24
($foo eq 'A') && ($bar eq 'B' or $bench eq 'C')
0026nobodyさん2006/09/19(火) 18:28:07ID:???
>>25
即答有難う御座いました。
使っていきます。
0027nobodyさん2006/09/19(火) 18:39:53ID:LgUjbLc5

http://www.technorati.jp/home.html

テクノラティで任豚が発狂中〜〜www
ここの左側で「踊っているマリオ」のところが任豚ブログだ。
任豚パワーは凄まじい〜〜。
0028nobodyさん2006/09/19(火) 20:00:03ID:???
>>23
kwsk
0029nobodyさん2006/09/19(火) 20:10:20ID:???
>>28
$str = qr/^([\n\x20-\x7e\xa1-\xdf]|[\x81-\x9f\xe0-\xfc][\x40-\x7e\x80-\xfc])*$/;
実際に使ってるのはこんな感じ。
0030nobodyさん2006/09/19(火) 20:29:05ID:???
>>29
サンクス。
使ってみる。
0031nobodyさん2006/09/21(木) 03:42:14ID:???
Perlでのセッション管理で汎用的に使用されているような
モジュール・ライブラリがあれば教えていただきたい次第
です。

CGI::SessionやWalrus::Session::Lite等が検索で出てきま
すが、環境によって動作する・しないというものもあるみた
いなので一番安全で手軽に導入できるものがあれば
有り難いです。
0032nobodyさん2006/09/21(木) 06:44:43ID:31FpoYel
CGIで使うんならCGI::Sessionが無難と思われ
0033nobodyさん2006/09/21(木) 08:00:46ID:???
foreach構文についてなのですが、
1万行に渡るデータを、一行ずつ拾って、という処理をさせていると、
foreach構文の後ろを実行せずブラウザが完了と返してきます。
1万行が多いのか、foreach構文の中身の処理が多いのか、判別つきませんが、
ちゃんときっちり完了させる書き方ってありますでしょうか?
(タイムアウトなのでしょうか?)

foreachに送る@配列を1000ずつとかに切って、それの処理が終わるのを待ってから次の1000を処理する、とか、
いろいろ考えたのですがその待たせるという処理の仕方も思いつかなかったです。
なにか方法ありませんでしょうか?
お教えくださいますようお願いいたします。
0034332006/09/21(木) 08:04:08ID:???
ちなみに、
foreachの中で行ってる処理も途中で中断されてるみたいです。
出力結果は途中まででした。

これはコーディングで解決できるような問題なのでしょうか?
@配列の行を20行ほどにして試してみたら普通に処理されたので、
構文ミスではないと思います。
0035nobodyさん2006/09/21(木) 08:38:30ID:???
>>33-34
高負荷(実行時間が長すぎる)なので途中で実行停止されるように
鯖で設定されているのでは。
0036332006/09/21(木) 08:50:05ID:???
>>35
なるほどやはりタイムアウトのような感じの処理をされているんですね。
ありがとうございます。

foreach $foo(@foo[0...200])
とかぶつ切りにすればそれぞれの処理は軽くなるような気がしますが、
それを
for ($bar = 0; $bar < 10000; $bar+200){

}
内で処理させたら同じになっちゃいますでしょうか。
($john = $bar+200;
foreach $foo( @foo[$bar...$john])
のような切り方にして)

テスト環境がもろいので、あまり何度も試す事ができなくて困ってます。

何か方法御座いませんでしょうか?
0037nobodyさん2006/09/21(木) 09:05:15ID:???
実行時間で切られてるんだからどう切っても全体の処理量が変わらなければ
何の効果もない。1回あたりの処理が短い時間で終わるようにがんばって書き
直すしかないだろう
0038nobodyさん2006/09/21(木) 09:08:43ID:???
>>33
ループ回数だけで言うと、10000回くらいなら一瞬で終わるよ、こんなのなら
my $i;
foreach (0..9999) { $i++ }
print $i;
なのでループの回数そのものの問題ではないでしょう。
起動時から完了までどのくらい時間がかかっているのですか?
ループの中の処理はどんなことをしているのですか?
子プロセス起動させてバックグラウンド処理ができるなら、そのようにするとか。
小分けにして、処理後にリダイレクトさせるようにして、続けるとか。
do.cgi→do.cgi?1000→do.cgi?2000→…
0039332006/09/21(木) 09:12:56ID:???
>37
やはり、一回の処理にはかわりはないんですね。
ありがとうございます。

>38
会員制サイトのメールマガジンのシステムなんですが、
1万件のアドレスを切って、メール送信、次のアドレス、という風に処理してるんです。
以前この質問をしたとき、なにに使ってるかを最初に書いたら「スパム業者に力は貸せない」と一蹴されてしまったので、書くのを躊躇してしまいました。
やはりsendmailの処理が重いのでしょうか。
0040nobodyさん2006/09/21(木) 09:20:46ID:???
>>39
メールマガジンなら BCC で1回で送るのでは不都合あるかな?
0041nobodyさん2006/09/21(木) 09:26:05ID:???
制限はずせばいいんじゃないの? 制限を自分でいじれない貸し鯖なら
そもそもやるべきではない。
0042332006/09/21(木) 09:28:54ID:???
>>40

最近携帯ばっか触ってたので、bccが4つまでしか使えないと勝手に脳内で設定されてました。
ありがとうございます。それでやってみます。

みなさま有難う御座いました。
0043332006/09/21(木) 10:58:40ID:???
えと、初歩的なことのような気もするんですが、

foreach $mail(@mail){
print MAIL "Bcc: $mail\n";
(受け取った$mailに配信)
}
とループしてたのを、

print MAIL "Bcc: $mail\n";
($mailにBCCの内容を)
とするつもりなんですが、

BCCの区切り子って,(カンマ)じゃないんですか?
$mail = join(/,/,@mail);
とすると、

open(MAIL,"| $sendmail -t");
print MAIL "Bcc: $mail\n";
print MAIL "From: $from\n";
print MAIL "Subject: $title\n\n";
print MAIL "$message\n";
close(MAIL);
のデータのsubject、Fromが空になって、本文に表示されるようになってしまいました。
本文に、ずれ込んだ件名なども表示されてます。

なんか根本的に間違ってるのでしょうか?
0044nobodyさん2006/09/21(木) 11:24:13ID:???
根本的な間違い: 事故の元だからBccで送るな。
0045332006/09/21(木) 11:46:43ID:???
$mail =~ tr/\r\n//d;
で改行したらいけました。
有難う御座いました。
0046nobodyさん2006/09/21(木) 11:48:09ID:???
1万のメルマガをBCCで送るなんて怖くてできねーww
0047332006/09/21(木) 11:50:02ID:???
>>46
すみません、後学のためにBCCの恐怖をお教えいただけないでしょうか?
他に軽く出来る処理のヒントになるかもしれないですし。
0048462006/09/21(木) 12:00:24ID:???
>>47
BCCで送るつもりがCCになっててメルアド流出ってニュース聞いたことないですか?
「事故の元」って>>44が言ってるのもそういうことだと思いますよ
0049332006/09/21(木) 12:04:51ID:???
>>48
あー、そっちの意味ですか。
それは大丈夫です。
>>44
>Bccで送るな。
と言ってますからBccで送ってはいけない、って意味なので違う事を危惧してくださっていると思います。
0050nobodyさん2006/09/21(木) 12:23:58ID:???
大丈夫大丈夫って飲酒運転して人を轢き殺すタイプだな
0051nobodyさん2006/09/21(木) 12:24:45ID:???
これはとあるシリアル制御機器にコマンドを送る命令である


$test->printf("%c%c",0x1b,0x40);

これでは問題なく動いてくれるが、
ちょっとコマンドを長めに投入するとだめ。
原因はなんだろう

×
$test->printf("%c%c%c%c%c%c",0x1b,0x40,0x1f,0x03,0x1b,0x40);
0052332006/09/21(木) 12:30:16ID:???
>>50
お前>>48で46を名乗って「>>44が言ってるのも」と他人の振りをしてるのはなぜだ?
>>44=>>46=>>48=>>50
答えれねーならしゃしゃんじゃねーよクズが。
0053462006/09/21(木) 12:34:25ID:xRtMaydf
はいはい妄想乙。
0054nobodyさん2006/09/21(木) 12:46:46ID:rVJ008ap
>>52 != >>33
だろ
0055nobodyさん2006/09/21(木) 12:50:01ID:rVJ008ap
  |    |    |  /-------------石綿-------------
  |    |    |/|           ∧   | lllllllllll |
▲|  schindler /  |    シュレッダー  |雪|   | パロマ | l| ̄ ̄ ̄|
▽|    |  //l . |    |アイリス |  |印|   | O。O | ||___| アメリカ産牛肉
  |    |// │ |    |オーヤマ|    ̄  `┬┬_´ ..||ε(;; ;)3|\  __
  |    /..│   | |  __ ̄ ̄ ___ . / ┌┘/l . ||ε(;; ;)3|.  || |#|イトーヨーカドー電気ストーブ
_|_/  │   | |  |Mac ||_  |:|デル|:| lニニニl/  .||ε(;; ;)3|.  || ~~~
.  / .     |   | | /__/l|:.. : |ニニニ|.::.:.:.||.:..:::..::..:  ̄ ̄ ̄\||            _/ ̄ ̄\_三菱
./ .       |0,  | |::_||.::..:...||:..::.SH902iS::::.[PS2]::::: /\\ : | | .           └-○--○- ┘
 設計     |   |/.::.↓>>52.:..::::./ヽ-、.:(PSP): .| \| ̄|=| |コ=      /\\ :  _/ ̄ ̄\_トヨタ
姉歯事務所|  ./.::..:..:<⌒/     ヽ.::..:..:◎..:...::.. .| \|  |: | | 松下|  .| \| ̄| └-○--○- ┘
.       |/.::..:..:..::::.<_/____/.::.: ソニーBMG:..\.|_|: | | FF式 .  .| \|  |  ファイヤストンタイヤ
      ____   ___    _____  ________...\.|_|:サンヨー石油ファンヒーター

0056nobodyさん2006/09/21(木) 13:03:19ID:???
>>47
メールアドレスに改行仕込まれるとそれ以降のアドレスが駄々漏れになる。
sendmailの引数で指定すれば(シェルに解釈させないように注する)、その心配はまったく無くなる。

付録:
一行の長さの制限とか考えてないでしょ。
0057nobodyさん2006/09/21(木) 13:43:19ID:???
>>56
Sendmail の引数で指定するのは、一般的にはやっちゃいけない方法と言われてるね

リスクとしては、

OSインジェクション >>> メールアドレス漏洩 だし、

シェルに解釈されないようにする&RFC準拠のメルアドを全て使えるようにする手間 >>> 改行コードとカンマとスペースを排除する手間

シェルコマンドは色々あるからね。
まぁシェルコマンドを全部エスケープすればすむだけだとは思うけど。
0058nobodyさん2006/09/21(木) 13:46:31ID:???
そもそもメールマガジンで1万って考えられないな。
スパムじゃないの?
0059nobodyさん2006/09/21(木) 13:47:40ID:???
>53

>54

>55

おいおいいきなりID出して別人工作か。
もちっと頭使え。
0060nobodyさん2006/09/21(木) 13:50:34ID:???
>>58
メールマガジンで1万ってのは普通だろ


むしろ、スパムで「たった」1万通なわけないじゃん

スパムのアクション率なんて、0.00001% とかだぞ。
スパムするなら、最低500万通/日、業者なら1億通/日は送っているだろ。

0061nobodyさん2006/09/21(木) 13:50:39ID:???
>>58
また出た。
お前がツクリャ30人が関の山だろうが、俺の文章読みたさにがんがん登録があるってわけ。
貧相な想像力でねちねち言ってんじゃねーっつーの。
0062nobodyさん2006/09/21(木) 14:22:11ID:xRtMaydf
wwwwwww
0063nobodyさん2006/09/21(木) 14:22:18ID:???
でも個人のメールマガジンで1万の登録が有るってのもな。
0064nobodyさん2006/09/21(木) 16:30:17ID:???
てか、みんな一応質問に答えてやってんだから
それぐらいで着火するようなら自分で考えて自分でやれ
ちょっと調べればいくらでも出てくるぞ
0065nobodyさん2006/09/21(木) 19:39:32ID:???
↓そろそろ釣りでした宣言
0066nobodyさん2006/09/21(木) 20:13:30ID:???
本日の営業時間終ったから、レスは明日じゃないかな
0067nobodyさん2006/09/21(木) 21:46:53ID:???
スパマーも一応仕事だからな。
0068332006/09/22(金) 06:53:12ID:???
回答ありがとうございます。

>>56
仰るとおり長さの制限に引っ掛かりました。
ヘッダーが32kb超えてる、みたいな感じのエラーが出たので、10件ほどでのテストでは判明しない問題でした。
>>38が提案してくださったようなプロセスの小分けの方向で模索してみます。

>>57
シェルコマンドをエスケープですか。
難しそうですが、勉強してみます。
0069332006/09/22(金) 07:18:25ID:???
自分の頭の整理も含め、もう一度書き直しますね。

1: 自分はこういう事がしたい。
1万件のメールアドレス(@配列にいれてあります)にメールを送信したい。

2: それでこんな風にやってみたが・・・
a.foreach構文で1万回sendmailをやってみた
b.全部を$mailに入れてBccとして送らせてみた

3: こんなエラーが出て上手く行かなかった。
a.実行時間が長すぎて、途中で切られた
b.ヘッダーが長すぎると言われた

ヘッダーを短くするには繰り返し構文を使うしか思いつきません。
>>38の案を模索してみたんですが、バックグラウンド処理、リダイレクトというのがさっぱりわからなかったです。
一回の処理を短く行う方法は御座いませんでしょうか?

お教えくださいますようお願いします。
0070nobodyさん2006/09/22(金) 09:54:19ID:???
>>69
僕の使ってるサーバではやらないでね。
0071332006/09/22(金) 09:55:43ID:???
ない知恵を絞ってみました。
@maill[0..99]←([]の中身は変数で変更可能)
で100回だけループするようにして、
htmlのリフレシュを使って、@mail[100..200]を処理する(getメソッドで数値を渡しておく)ようにして、
それが@mailの行数を超えるまでリフレシュさせまくる、というのは不安定でしょうか?

それか、100件ごとに
sleep 5;
などを入れて休憩させるといけるのか、とかも考えましたが、
これだと「一回の処理の時間の長さが50秒追加されるだけで余計長くなってる」ってことになるでしょうか?
100件ごとに一回の処理として扱われるなら最後までいけると思うんですが。
0072332006/09/22(金) 09:57:18ID:???
>>70
昨日の結局何も答えてはいないだけのクズか。
しつけーぞ。しゃしゃり出るならなんか回答してみせろ無能め。
0073382006/09/22(金) 10:13:02ID:???
>>69
ふつう、1万件のメールをCGIプログラムでは送りません。タイムアウトするから。
ヘッダが長すぎるというのはあたりまえ。1行の長さが998文字以下と決まってるのです。
だから、やるなら、

Bcc: xxxxxx@xxxx.xx,
 xxxxx@xxxx.xx,
 yyyy@yyyy.yy,

のように、1つのヘッダ行が複数にまたぐ場合は、2行目以降は行頭に空白文字(スペースあるいはタブ)を置いて続けることができます。
このような仕様がいろいろあるので、メールクライアントを作りたかったら、RFCを読みましょう。
ttp://www.ietf.org/rfc/rfc2822.txt
ttp://www.puni.net/~mimori/rfc/rfc2822.txt(日本語訳)

プログラムで送ろうとせずに、eml形式のメールデータをローカルなperl環境で1万個作ってメーラーにインポートして一斉に送ってはいかが?
スパムを送られたら幇助しているようでいやなので詳しく書く気はないです。ごめんなさい。
0074nobodyさん2006/09/22(金) 10:18:03ID:???
> 1万件のメールアドレス(@配列にいれてあります)にメールを送信したい。
もうこの時点で目的は何であれスパムだよな。

そうじゃないんだったらメルマガやメーリングリストでも使えばいいじゃん。
0075nobodyさん2006/09/22(金) 10:20:42ID:???
>>72-73

>>35>>40
を書いた者だが、
もうおまえ去れ。
スパム業者でないという保証もないし。
これだけヒントもらってるんだから自分でやれよ。
0076nobodyさん2006/09/22(金) 10:39:14ID:???
>>74
そういうシステム使うと、その業者を儲けさせるだけ
やつらは、人様が苦労して作成したコンテンツに広告を載せて配信し、ぼろ儲けしている
0077332006/09/22(金) 10:50:43ID:???
>>73
> プログラムで送ろうとせずに、eml形式のメールデータをローカルなperl環境で1万個作ってメーラーにインポートして一斉に送ってはいかが?
ありがとうございます。
最終段階で送信プログラムを実行するんじゃなく、
<p><a href="mailto:foo\@bar.com?bcc=$mail&subject=$subject$body=$body">SUBMIT</a></p>
というHTMLを吐き出すことにしました。


>>74
>> 1万件のメールアドレス(@配列にいれてあります)にメールを送信したい。
> もうこの時点で目的は何であれスパムだよな。
配信希望者に送る場合もでもスパムというのでしょうか?

> そうじゃないんだったらメルマガやメーリングリストでも使えばいいじゃん。
そのメルマガのコーディングについての質問です。

>>75
いただいたヒントを参考に解決しました。

みなさま、本当に有難う御座いました。
0078nobodyさん2006/09/22(金) 11:04:03ID:d6rNV+wj
ID出して否定しないし33の名前は全部同一人物だろ
結局mailtoでBCCwwwww
Perl関係ないじゃんww
解決乙。もう来るなよ

>>75
>>73は33とは別の人ね。すげー親切で泣ける
0079752006/09/22(金) 11:10:34ID:???
ホントだ・・。>>73さんごめん。
0080332006/09/22(金) 11:12:12ID:???
>>78
> ID出して否定しないし33の名前は全部同一人物だろ
最初にIDを出していないので、否定しようと騒いでも余計に悪化すると思いまして。

お陰様で解決しました。
0081nobodyさん2006/09/22(金) 11:13:44ID:???
変ななりすましはスルーでOK
0082nobodyさん2006/09/22(金) 11:56:21ID:???
だが、否定ぐらいはしとけと。
0083nobodyさん2006/09/22(金) 12:14:06ID:???
>>57
最近のperl使ってシェルを経由させずに起動すれば良いだけ。

> Sendmail の引数で指定するのは、一般的にはやっちゃいけない方法と言われてるね
無知をさらけ出されても困る。
0084nobodyさん2006/09/22(金) 13:09:56ID:???
>>76
自分で鯖立てればいいだけじゃん。
0085nobodyさん2006/09/22(金) 16:20:39ID:URN28btq
post データが
a0=1&b0=1&a1=4&b1=2&a2=2&b2=2&・・・&an=8&bn=9
と"a".$i =数字と"b".$i=数字となっているものを
postgresql にperl でupdateしたいのですが、

for($i=0;$i < n; $i++){
$str ="update table set a=$html->param('\"a\".$i') where b=$html->param('\"b\".$i)";
$sth=$dbh->prepare($str);
$sth->execute();
}
こんな感じでupdateしたいのですが,試行錯誤の上に挫折中です。
うまい方法はないですか?
0086nobodyさん2006/09/22(金) 16:31:12ID:d6rNV+wj
$html->param('\"a\".$i')
をprintしてみたらどうでしょうかね
0087nobodyさん2006/09/22(金) 16:38:47ID:???
$html->paramはなんですか?文字列ですか?メソッドですか?
$strに何が代入されてるんですか?
0088nobodyさん2006/09/22(金) 16:50:49ID:???
>>87
どうみても $html は CGI のインスタンスだし、$str には SQL 文が代入されてるがな。(´・ω・)

文字列の中でメソッド呼び出しってできたっけ?
一旦 param の内容を変数に代入してから $str に埋め込んでみては?
0089nobodyさん2006/09/22(金) 16:50:53ID:URN28btq
>>87
>$html->param

$html=new CGI;
です。
>$str
にはpostgresqlに対するupdate のストリングが入って欲しいものです。

>>86
CGI=HASH(0x804c914)->param('"a".1')
となりました。
0090nobodyさん2006/09/22(金) 16:56:20ID:???
てか、パラメータを直接 SQL 文に埋め込むと SQL インジェクションできるんじゃね?
0091nobodyさん2006/09/22(金) 16:58:49ID:???
流石○○板だな
0092862006/09/22(金) 16:58:56ID:???
>>89
いや意味的には>>88と同じで変数を確認ってことです
っつーかbのシングルクォート
0093nobodyさん2006/09/22(金) 17:03:18ID:???
$html->paramはなんですか?クォートの中から呼び出せるんですか?
$strに何が代入されてるんですか?
確認しましたか?
0094nobodyさん2006/09/22(金) 17:04:10ID:???
アッー!
0095nobodyさん2006/09/22(金) 17:51:48ID:???
>>85
$htmlってのは
use CGI;
my $html = new CGI;
したもんだと仮定しますた。それから、
$dbh は、DBI/DBD::Pgで接続したときのインスタンスと仮定しますた。んで、

まず、$html->param('\"a\".$i') ってのがおかしい。全体をシングルクォートしてしまうと$iは展開されません。
まあ、$html->param("a$i") だとします。

そんで、ダブルクォーテーションの中に $html->param("a$i") を入れちゃうと、
$html と ->param("a$i") とに分かれて解釈されちゃうので、外に出してください。

だけれど、せっかくprepare使うんなら

my $sth = $dbh->prepare("update table set a=? where b=?");
for ( $i=0; $i < n; $i++) {
    $sth->execute($html->param("a$i"), $html->param("b$i"));
}

などとしてはいかがでしょうか?

※上記のソースで n が裸で出てくるのはおかしいです。use strictすれば教えてくれます。
※SQL-injectionのチェックはしてくださいね。
0096nobodyさん2006/09/23(土) 06:00:23ID:08cXFZbB
Perlで、サニタイズするときの定番の関数は何ですか?
PHPだとhtmlspecialchars()というのが標準で備わっているんですけど、Perlでそれに相当するものは何になるんでしょうか。
(自分で書くのは簡単なんですけど、できればPerl標準のものがあればそれを使ったほうがいいかなと考えています。)
0097nobodyさん2006/09/23(土) 06:57:54ID:???
PHPのそれに相当するビルトイン関数はないよ
0098nobodyさん2006/09/23(土) 07:46:28ID:???
>>97
ライブラリ関数で結構ですので、教えていただけませんか。
0099nobodyさん2006/09/23(土) 08:34:56ID:???
Perl標準もデファクタスタンダードと呼べるものもないと思うよ

HTMLを使用するモジュールには大概あるから(CGI、TT、HTML::Templateなど)
あとは自前で用意するんじゃないかな
0100nobodyさん2006/09/23(土) 08:39:51ID:???
>>98
http://perldoc.jp/docs/modules/CGI.pm-2.89/CGI.pod#item__escaped_string___escapeHTML__unescaped_string___
0101nobodyさん2006/09/23(土) 09:31:06ID:???
サニタイズゆうな。クズ。
0102162006/09/23(土) 16:17:05ID:???
今日、@IT に自分が質問していた内容に関する記事が追加されました。

http://www.atmarkit.co.jp/fsecurity/rensai/hoshino10/hoshino01.html

自分が書き込んでから数日以内のことなので、ひょっとしたらこのスレ見ててくれたのかな、と思ったりw
偶然かもしれないですけど・・・

もし、見ていてくれたのなら 杉山 さん、本当にありがとです。
0103nobodyさん2006/09/23(土) 17:05:32ID:???
ねーよw
0104nobodyさん2006/09/23(土) 17:24:16ID:???
>>16 より引用

> バイナリエディタで解析した " (ダブルクォート) の 16進表記は、"22" です。
> ここで、$hoge に バイナリレベルで "82" をいれてみるとどうなるかやってみました。(バイナリファイルを一般のテキストエディタで表示したときの、"・"(半角) と表示されるあれです。)
> それを出力して、IE と Firefox と Opera で表示したところ、 "82 22" で 1つの不正な文字 "・"(全角) として表示され、ダブルクォートが消えうせていました。


>>http://www.atmarkit.co.jp/fsecurity/rensai/hoshino10/hoshino02.html より引用

> 赤坂さんの入力には、「%82」という文字列が含まれている。


22 はダブルクォートだけど、82 はようするに22と組み合わされて1つの2バイト文字と扱われればいいわけで、82である必然性が無い。
参考リンクの、http://applesoup.googlepages.com/bypass_filter.txt にも 82 は出てこないからね


以上の理由により、杉山氏はこのスレを見ている可能性が高い
0105nobodyさん2006/09/23(土) 17:43:34ID:???
http://www.atmarkit.co.jp/fsecurity/rensai/hoshino10/hoshino03.html によれば、
php なら、mb_convert_encoding($_GET{'hoge'},'SJIS','SJIS')) で対策できるみたいだね。

Perl の jcode.pl で同じことやったが、無理だったわ。
不正な文字列を変換してもそのままになっちゃうみたい。

Perlで対策するにはどうすればいいんだろうか・・・。
0106nobodyさん2006/09/23(土) 17:59:04ID:???
>>29 じゃだめなんかい。
そんなに面倒だったら、受け取った文字列の後ろにスペース一個くっつけとけば?
01071052006/09/23(土) 18:02:03ID:???
>>106
なるほど
それでできるのか
ありがとうございます
01081052006/09/23(土) 18:15:29ID:???
$str = qr/^([\n\x20-\x7e\xa1-\xdf]|[\x81-\x9f\xe0-\xfc][\x40-\x7e\x80-\xfc])*$/

の qr ってなんだろう。と調べてみました。

http://psst.jp/syn/archives/000199.html

つまり、>>29 は、「^([\n\x20-\x7e\xa1-\xdf]|[\x81-\x9f\xe0-\xfc][\x40-\x7e\x80-\xfc])*$」を、正規表現としてコンパイルしているわけですね。


実際に $GET_hoge の無効な文字列を削除するには、

$GET_hoge =~ s/$str//g

とすればいいわけですね。

ありがとうございます。
0109nobodyさん2006/09/23(土) 18:23:40ID:???
この脆弱性、CGI配布サイトで配られている大部分の掲示板スクリプトとかにとかに影響していますね・・・
漏れの使っている Child Tree とかはもろ影響してるし

実はphpユーザなんでPerlのことよくわからないや(´・ω・`)
しかも自分で書いたスクリプトじゃないから修正が大変です><

本来出力時のエスケープがいいと思うのですが、、print 内の変数を全て書き換えるのは大変なので、
GET と POST として送られてきた全てのデータに >>29 の正規表現を適用させる方法は無いでしょうか

どうかお願いします
■ このスレッドは過去ログ倉庫に格納されています