
perlでメールフォームを作成しています。
メールの送信にはsendmail をopen関数で使用していたのですが
openはセキュリティ上の問題があることを知り、対策を調べているうちに
sysopenを使用することが有効だという情報にたどり着きました。
しかし、単純にopenをsysopenに書き換え、オープンモードも設定したのですが
sysopenに失敗してしまいます。
sendmail以外のテキストファイルのオープンには成功しているので
sysopenの使用方法が間違っている
sysopenを使用したsendmailの実行方法を教えていただけませんでしょうか?
[ソース]
use Fcntl;
…
$sendmail = '/usr/xxx/sendmail -t -io';
…
sysopen(MAIL,"$sendmail ", O_WRONLY ) or die "error!!"
my $mailstr = &MAILHEADER($to,$subject);
my $mailbody = &MAILBODY($fileId);
$mailstr .= $mailbody;
print MAIL $mailstr;
close MAIL;
&MAILHEADER()
→To,From,Subjectの設定
&MAILBODY()
→メール本文の設定
・sysopen部分は今まで以下の記述で、メールの送信をしていました。
open(MAIL,"| $sendmail") or die "error!!"
・念のため、-fで「/usr/xxx/sendmail」の存在チェックをおこない、
存在していることを確認しました。
・sysopenの使用方法が間違っているのかと思い、以下のサンプルを作成してみましたが
問題なく動きました。
my $file = 'test1.txt';
sysopen(MSG,$file, O_WRONLY|O_CREAT|O_APPEND ) or die "sysopen error!!"
print MSG "sysopen OK";
close MSG;
サンプルが動いたことで、ますますsendmailをオープンできないことに
行き詰ってしまいました。
どうぞよろしくお願いいたします。
質問内容でわかららない部分があればご指摘ください。
可能な限りソースも載せます。
No.6ベストアンサー
- 回答日時:
>少なくとも、$subject は定数なので、ユーザからの入力は反映されません。
$subject は例としてあげただけで $to や、その他に参照される変数なども同じですが大丈夫でしょうか。
実際にできるかどうかは別として他の思い当たるのは、例えばそのメール送信処理のcgiに
$ telnet そのサーバのホスト名 80
GET パス?SUBJECT=...
ように直接urlでアクセスできてしまうとか、
それを処理しているサーバのsendmailが外部から直接アクセス可能で自由に利用できる状態になってるとか。
今のところ思いつくのはこれくらいです。
休日にも関わらず、何度もありがとうございます。
>$ telnet そのサーバのホスト名 80
>GET パス?SUBJECT=...
>ように直接urlでアクセスできてしまうとか、
>それを処理しているサーバのsendmailが外部から
>直接アクセス可能で自由に利用できる状態になってるとか。
sshでの直接アクセスはIPアドレス指定で制限しているので基本的にはできないはずです。
サーバのsendmail等へのアクセスは、上記設定が有効である以上、できないと思います。
PCがハッキングされたりすれば別ですが、
そこまで考えているとキリがないので、
プログラム上のことしか今は考えないことにします。
サーバまわりは、そちらの管理者の管轄ですから
質問や「大丈夫ですよね?」って念を押すことはできても
実対応は口出しはできません。
結論として、kmeeさまよりご提案いただいた
Mail::Sendmail案を採用することになりました。
wormholeさまにはたくさんのご意見をいただき
ありがとうございました。
いろいろと私が考えていなかったことなどもありましたので
ベストアンサーとさせていただきます。
perlまわりで質問することもあると思いますので
今後ともよろしくお願いいたします。
ありがとうございました。
No.5
- 回答日時:
>$sendmail にユーザの入力値が反映されるつくりではありませんが
>お恥ずかしながら、ログを解析すると当方のメールフォームを踏み台とし、
>spamメールの送信を行われた可能性が大きいことがわかりました。
それはopenの問題ではなくて
>my $mailstr = &MAILHEADER($to,$subject);
>my $mailbody = &MAILBODY($fileId);
>$mailstr .= $mailbody;
>print MAIL $mailstr;
の方じゃないかなと。
例えば $subject が "サブジェクト\nBCC: どっかのメールアドレス" だったりメール本文の先頭に "CC: どっかのメールアドレス" あったりしたら、$mailstr でのメールヘッダとして解釈される部分に含まれたりしませんか?
ご回答ありがとうございます。
少なくとも、$subject は定数なので、ユーザからの入力は反映されません。
>メール本文の先頭に "CC: どっかのメールアドレス" あったりしたら、
>$mailstr でのメールヘッダとして解釈される部分に含まれたりしませんか?
この可能性は考えていませんでした。
テストしてみたら、メールは送信されませんでした。
ありがとうございます。
参考までに、&MAILBODY のソースを載せます。
改修後のソースなので、引数はなくなっています。
## メールフォーム入力内容から本文作成
sub MAILBODY {
my $name = $FORM{'name'};
my $mail = $FORM{'mail1'};
my $comment = $FORM{'comment'};
$strbody = "[お名前]: $name\n";
$strbody .= "[メールアドレス]: $mail\n";
$strbody .= "[コメント]:\n $comment\n\n";
$strbody = encode_base64($strbody);
}
※$mail(メールアドレス)にカンマ、セミコロンでの区切りで複数のアドレスが入力されていないことはチェック済みです。
メール本文のログを見る限り、本文に入力文字はありませんでした。
そのため、
open(MAIL,"| $sendmail") に対し、
パイプで何かのコマンドなりなんなりをつなげられたのかなと推測し、
open関数の使用に慎重になっている次第です。
(どうやってやったのかは、不明です。
悪用手口がわかれば、適切な対処もできるのですが、
残念ながら、そこまで至っておりません)
汚染チェック等の強化でopen関数&sendmailコマンドで実施してもよいか、Mail::sendmailに移行するか検討していますが、
その結果次第ではopen関数&sendmailコマンドということもあり得ます。
もともとも質問である”sysopenでのsendmailの方法”は
見当違い、勘違いでしたが、
perlの知識がある人・社外の人からのご意見は非常にありがたいです。
本当に、何度も回答させてしまい申し訳ありません。
ありがとうございます。
No.4
- 回答日時:
>「脆弱性」とは、OSコマンドイジェクションのことを指しています。
注意されることはとてもよいことだとは思いますが単純に「openを使うのは危険」という認識のされかたしていませんか?
https://www.ipa.go.jp/security/awareness/vendor/ …
http://www.atmarkit.co.jp/icd/root/87/24084287.h …
に書かれているのは不適切な使い方をした場合の話ですけど。
質問に書かれているソースも $sendmail がユーザーからの入力を反映したりするなら問題はありますけど定数的に'/usr/xxx/sendmail -t -io'から変わることないということなら特に書き直す必要ないと私は思いますが。
何度もありがとうございます。
perl開発の経験の浅さ(知識の少なさ)故かもしれませんが
単純に「openを使うのは危険」という認識をしています。
というのも、
$sendmail にユーザの入力値が反映されるつくりではありませんが
お恥ずかしながら、ログを解析すると当方のメールフォームを踏み台とし、
spamメールの送信を行われた可能性が大きいことがわかりました。
(悪用した人が、何をどうやったかまではわかりません。
実際にspamメールの送信だったかもわかりませんが、
ログ等の情報から可能性として一番濃厚という程度です。)
実際に「事故が起きた」後であるため過剰反応気味かもしれませんが、対応に慎重になっております。
No.3
- 回答日時:
http://perldoc.jp/func/open
openにはちゃんと「ファイル名は出力がパイプされるコマンドとして 解釈され」等とコマンドとして実行する場合があることが書いてあります。
sysopenにはありません。sysopenはファイル(状のもの)が対象です。
その「脆弱性」って、具体的に何のことですか?
事前チェックや、MODEを別引数にしたopenを使う等で避けられませんか?
あるいは、 Sendmail.pm等を使うことはできませんか?
http://search.cpan.org/~mivkovic/Mail-Sendmail-0 …
この回答への補足
ご回答ありがとうございます。
「脆弱性」とは、OSコマンドイジェクションのことを指しています。
恥ずかしながら、この言葉も知らず、
"perl OSコマンドイジェクション 対策"等で検索し、
https://www.ipa.go.jp/security/awareness/vendor/ …
や
http://www.atmarkit.co.jp/icd/root/87/24084287.h …
等で、openではなく、sysopenを使用するほうが安全だと知りました。
sendmailがファイルというより、コマンドである認識ではいますが、openではなくsysopenを使用するほうが安全だというサイトを多くみて、質問に書いたようなソースを作成しました。
汚染チェックでopen関数でも安全であれば
open関数でもいいと思います。
Sendmail.pmの使用もテストしてみます。
本日、ご提案いただいた
Mail::Sendmail案を採用することが決定し、
メール送信に至りました。
open関数を否定する気はありませんが、
こちらの記事を見つけ、Mail::Sendmail案の採用のほうが
好ましいとの上の判断でした。
(私も、自分の知識不足故に悪用されたであろう
open関数ですので、気持ちはMail::Sendmail案寄りでした)
http://firegoby.jp/archives/968
ありがとうございました。
No.2
- 回答日時:
もう一点、
sysopenは">ファイル名","|プログラム名"のようなモード指定はサポートしていなかったような。
この回答への補足
確かに、open関数のように、"<"や"|"は見当りませんね。
http://itpro.nikkeibp.co.jp/article/Reference/20 …
を参照しました。
サンプルは、sysopen関数そのものの実行が間違えているのかと思い、シンプルなものを作成しました。
おっしゃる通り、sendmailのオプションである、"-t"等も含んだ
「/usr/xxxにある"sendmail -t -ioというファイル」をオープンしようとしているという実行文ですよね。
open関数または、kmee様が提示してくださったSendmail.pmでのメール送信を検討します。
(当然、汚染チェックを前提です)
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Visual Basic(VBA) VBAにてメール作成した際、一部指定箇所のみ赤文字にしたいです。 下記の内容ですと作成されたメール本 1 2022/04/27 13:31
- CGI -T(汚染モード)でメールが送れません 1 2022/06/12 14:11
- UNIX・Linux Ubuntuサーバーでメールを受信できない 7 2022/08/23 20:55
- CGI htmlからパラメータで、cgiに渡したい。 1 2023/02/06 16:15
- Gmail 【お助け!】サーバーからのメール送信でGmailに送信されない問題について 1 2023/06/20 22:03
- UNIX・Linux iptablesを設定するとメール送信処理が遅くなる!? 6 2022/06/07 01:11
- サーバー 接続・ログインはできているのにメールが送信できない 2 2022/06/27 15:03
- Yahoo!メール yahooメール使用できなくなった。 1 2022/07/05 11:45
- Visual Basic(VBA) エクセルのマクロを使ってメールを送る方法について教えてください 2 2022/03/29 01:36
- Outlook(アウトルック) Outlookのメール送信を取り消す方法 1 2022/11/17 13:10
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・「それ、メッセージ花火でわざわざ伝えること?」
- ・ゆるやかでぃべーと すべての高校生はアルバイトをするべきだ。
- ・【お題】甲子園での思い出の残し方
- ・【お題】動物のキャッチフレーズ
- ・人生で一番思い出に残ってる靴
- ・これ何て呼びますか Part2
- ・スタッフと宿泊客が全員斜め上を行くホテルのレビュー
- ・あなたが好きな本屋さんを教えてください
- ・かっこよく答えてください!!
- ・一回も披露したことのない豆知識
- ・ショボ短歌会
- ・いちばん失敗した人決定戦
- ・性格悪い人が優勝
- ・最速怪談選手権
- ・限定しりとり
- ・性格いい人が優勝
- ・これ何て呼びますか
- ・チョコミントアイス
- ・単二電池
- ・初めて自分の家と他人の家が違う、と意識した時
- ・「これはヤバかったな」という遅刻エピソード
- ・ゴリラ向け動画サイト「ウホウホ動画」にありがちなこと
- ・泣きながら食べたご飯の思い出
- ・一番好きなみそ汁の具材は?
- ・人生で一番お金がなかったとき
- ・カラオケの鉄板ソング
- ・自分用のお土産
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
sendmailでFROMに勝手に@~が追...
-
ホームページビルダー20SPで...
-
ビジネスメールの敬称
-
初歩的な事だと思います。 Sub...
-
エクセルVBA テキストボックス...
-
テキストボックスの番号を使っ...
-
VBAでInputBoxの再入力をさせる...
-
エディットボックスの入力制限...
-
フォームを再送信しますか?
-
「イ分」・・・フンという文字...
-
DataGridView 列ごとの入力制限
-
DataGridViewの桁数制限に関して
-
Googleフォームを回答したか確...
-
お問い合わせフォームから送信...
-
DATE型変数を初期化する方法
-
TextBoxから数字が文字...
-
PHPによるフォーム入力プログラ...
-
入力フォームの値をQRコードで...
-
VBAのユーザーフォーム上で名簿...
-
excel vba でユーザーフォーム...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
ホームページビルダー20SPで...
-
C言語でのメール送信
-
sendmailで存在しないアドレス...
-
ReturnPathが指定できない?
-
sendmailでメールが送信されない。
-
sysopenを使用したメール送信の...
-
他のサーバのSendmailへのパスは?
-
Movable Typeのシステムのメー...
-
sendmailが踏み台にされている...
-
sendmailのエラーを知りたい
-
(海外特定サーバ)メールが届...
-
hypermartのsendmailのパス?
-
ビジネスメールの敬称
-
エクセルVBA テキストボックス...
-
Googleフォームを回答したか確...
-
初歩的な事だと思います。 Sub...
-
テキストボックスの番号を使っ...
-
フォームを再送信しますか?
-
EXCEL VBA で指定した範囲に入...
-
VBAでInputBoxの再入力をさせる...
おすすめ情報