質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Perl

Perlは多目的に使用される実用性が高い動的プログラミング言語のひとつです。

セキュリティー

このタグは、コンピューターシステムの安全性やデータの機密性に関連したトピックの為に使われます。

Webサイト

一つのドメイン上に存在するWebページの集合体をWebサイトと呼びます。

Q&A

解決済

6回答

2927閲覧

CGIプログラムのセキュリティリスク確認

c-ja

総合スコア15

Perl

Perlは多目的に使用される実用性が高い動的プログラミング言語のひとつです。

セキュリティー

このタグは、コンピューターシステムの安全性やデータの機密性に関連したトピックの為に使われます。

Webサイト

一つのドメイン上に存在するWebページの集合体をWebサイトと呼びます。

0グッド

5クリップ

投稿2017/08/03 00:15

編集2017/08/04 02:26

###前提・実現したいこと
現在、とある会社さんの依頼で自社開発したCGIプログラムのソースレビューを実施しています。
該当プログラムは「入力画面(静的html)⇒完了画面(CGI)」の形式になっているシンプルなお申込みフォームとなっています。(詳細は下部の補足情報参照)

当方はそのCGIに入力画面からのパラメータを一切チェックしていない事に、セキュリティリスクを感じた為、社長さんにお伝えしたのですが、どうもピンと来てない様子で修正する必要性を感じない、具体的に何が問題なのか調査して欲しいとの事でした。

補足情報のプログラム概要に記載していますが、該当のCGIに遷移する前の入力画面で、JavaScriptで入力チェックを行っている事。CGI処理後、後続のバッチで出力されたファイルの内容をチェックして不正なデータがあればエラー処理している為、問題は無いという認識でした。

当方で思いついた具体的なセキュリティリスクは以下のようなものですが、それ以外に何か有ればご教授頂きたいです。

なお、当方で色々実験しているのですが、インジェクション攻撃で何か起こせないかと思い、CGIに渡すデータに記号やら何や怪しいデータを含めてPOSTしても、出力されるファイルのデータ的には使えないものではあるのですが、後続のバッチで弾ける様子なので、取り立てて問題とも思えませんでした。
情報漏洩やら不正ログイン等のリスクにならないのであれば、このCGIでも問題は無いのかとも思えてきました。
みなさんのご意見を伺いたいです。

###セキュリティリスク
<DDOS攻撃によるサービス妨害>
リクエスト内容のチェックをしない為、DDOS攻撃による不特定大量リクエスト受信によるサービス妨害が可能。

<inode枯渇によるファイル作成不可事象発生⇒サービス停止の恐れ>
DDOSに関連だが完了画面へのリクエストを直接、大量に送信する事で、理論上ファイルを無制限に作成させる事が可能。
(一度に大量に送らずとも、特定のタイミングで継続して送り続ける事でNW機器による制限をすりぬける事も可能だと思われる。)
結果、CentOSのファイルシステムのinodeが枯渇して、これ以上ファイルを作れないといった状況が作り出せる。

###該当のソースコード

Perl

1#!/usr/bin/perl 2print "Content-type: text/html\n\n"; 3 4use Time::HiRes qw/ gettimeofday /; 5 6my ($epocsec, $microsec) = gettimeofday(); 7my ($sec,$min,$hour,$mday,$mon,$year,$wno) = localtime($epocsec); 8 9$nitizi = sprintf("%04d%02d%02d_%02d%02d%02d_%06d_",$year+1900,$mon+1,$mday,$hour,$min,$sec,$microsec).$$; 10$resString1 = "ERROR"; 11$resString2 = ""; 12$resString3 = ""; 13$resString4 = ""; 14$passcode = ""; 15 16use CGI; 17my $cgi = new CGI; 18my %input; 19 20for ($cgi->param) { 21$input{$_} = $cgi->param($_); 22} 23 24open (OUT,">> ./requests/archive/$nitizi.txt"); 25foreach my $key (keys %input) { 26 if( ($key eq "1.radio" ) && ($input{$key} eq "select-sign" ) ){ 27 $resString1 = "お申込受付完了"; 28 $resString2 = "2222222222"; 29 $resString3 = "3333333333"; 30 $resString4 = "4444444444"; 31 }elsif( ($key eq "1.radio" ) && ($input{$key} eq "select-deny" ) ){ 32 $resString1 = "お問合せ受付完了"; 33 $resString2 = "22222222222"; 34 $resString3 = "33333333333"; 35 $resString4 = "44444444444"; 36 } 37 if( $key eq "0.PassCode" ){ 38 $passcode = $input{$key}; 39 } 40 print OUT '"'.$key.'","'.$input{$key}.'"'."\n"; 41} 42if( $resString1 ne "ERROR" ){ 43 print OUT '"0.AccessIP","'.$ENV{'REMOTE_ADDR'}.'"'."\n"; 44} 45close (OUT); 46 47use File::Copy; 48 49if( $passcode ne "" ){ 50 my $deploy = "./apps/$passcode"; 51 my $past = "./apps/past/$passcode"; 52 move($deploy, $past); 53} 54my $old = "./requests/archive/$nitizi.txt"; 55my $new = "./requests/ftp/$nitizi.txt"; 56copy($old, $new); 57print <<"HTML"; 58<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd"> 59<html lang="ja"> 60<head> 61<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 62<title>受付完了</title> 63</head> 64<body> 65<p>$resString1</p> 66<p>$resString2</p> 67<p>$resString3</p> 68<p>$resString4</p> 69</body> 70</html> 71HTML 72exit;

###補足情報(言語/FW/ツール等のバージョンなど)
<環境>レンタルサーバ(OS:CentOS)

<前提>
CGIプログラムは誰でもアクセス可能。制限なし。

<プログラム概要>
1.ユーザがメールを受信⇒メールに記載のユーザ一意のリンクにアクセスする事で入力画面を表示
2.ユーザが各項目を入力。項目を入力すると、JavaScriptで項目チェックをする。
また、項目は申込の種類を選択する事で動的に変わる。(サーバ側で受け取るパラメータが変わる。)
3.入力画面の申込ボタンを押下する事で上記CGIにPOSTされます。
4.CGI処理中にファイル出力を行っており、そのファイルを後続のバッチが解析。
不正なデータであれば、そのデータは弾くようにしている。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答6

0

プログラム全体としては、アクセス制御がまったくされていないところが問題で、偽のデータを送信される等の問題が現実的には大きいと思いますが、既にご認識のようですので、私からは別の問題を指摘したいと思います。
このプログラムはディレクトリトラバーサル脆弱性があります。以下の箇所です。

Perl

1my $deploy = "./apps/$passcode"; 2my $past = "./apps/past/$passcode"; 3move($deploy, $past);

ここで、$passcodeは外部から指定できる値であるので、ファイル名を操作される危険性があります。ただし、移動前と移動後に同じ $passcode というファイル名が含まれるので、攻撃のバリエーションはあまりありませんが、以下のようなケースは考えられます。

ここで、このプログラムが /home/hogehoge/public_html というディレクトリに設置されているとします。レンタルサーバーとしてはあり得る想定です。

ここで、攻撃者がURLに 0.PassCode=../../data というパラメータを追加したとします。$passcode は../../data という値が入ります。
この場合、move 関数は下記のパラメータが入ります。

Perl

1move('./apps/../../data', './apps/past/../../data');

上記の相対ディレクトリを絶対ディレクトリに変換すると下記の通り。

Perl

1move('/home/hogehoge/public_html/apps/../../data', '/home/hogehoge/public_html/apps/past/../../data');

../ は親ディレクトリを意味するので、それを正規化すると下記の通り。

Perl

1move('/home/hogehoge/data', '/home/hogehoge/public_html/data');

つまり、ホームディレクトリ上の /data ディレクトリが、/public_html/data に移動させられてしまいます。
/data は元々外部からは閲覧できませんが、/public_html/data は外部から閲覧できるので、情報漏えいの原因になります。
通常この種の攻撃は、ファイルパーミッションの関係で上手くいかない場合が多いのですが、レンタルサーバーの場合は全てのファイルのオーナーが同じ(上記の例だと hogehoge)ですし、CGIプログラムが動作するユーザも同じ(hogehoge)なので成功する可能性が高いです。

対策としては、標準的なディレクトリトラバーサル対策で問題ありません。

投稿2017/08/03 12:50

ockeghem

総合スコア11701

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

c-ja

2017/08/03 13:07

ご指摘ありがとうございます。 そこは何となく気になっていたのですが、同じ値が入るから何となく大丈夫かなと思っていましたが。。。 大変勉強になりました。 情報漏えいのリスクが有ると先方の社長さんにご報告致します。
guest

0

ベストアンサー

JavaScriptもHTMLも色んな形で変更することが可能です。
JavaScriptのチェック内容は見ようと思えば誰でも見れるわけですし、
何をしているかわかれば悪さをしようと思えば誰でもできるわけです。
そのチェックをすっ飛ばして悪意のあるコードを送信したり。
(悪意のあるコード・についてはパターンもたくさんあるので調べてもらった方が早いです)
「ユーザーからの入力は信用しない」というのがWebサイトを作る上での基本です。

色々調べた上で、クライアント側のみのチェックだと改変が可能で、
それによる攻撃例と事故例を提示できたらいいですね。

下記のような記事も参考にしてみてください。

投稿2017/08/03 00:35

編集2017/08/03 00:37
m.ts10806

総合スコア80850

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

c-ja

2017/08/03 00:38

ごもっともです。 そうなのですが、このCGIを公開する事で実際どのようなリスクが考えられるのか? そういった具体性の有る、お話しを社長さんにしたいので、今回質問させて頂いています。 どういった事が考えられるでしょうか?
m.ts10806

2017/08/03 00:41

具体的な説明にはプログラム概要ではなく本システム全体の具体的な用途や仕様の説明が必要です。 社内に限るのか、誰でも見れるのか、データの流れ、使用者、などなど。 それがないと回答者も一般的な内容の提示と「あとは参考に調べてみてください」くらいしか案を提示できません。
m.ts10806

2017/08/03 00:42 編集

プログラムも受けた内容をそのまま流すだけなのでありとあらゆるリスクが考えられます。 そうなると単なる回答におさまらないので「調べた方が早い」と注記させてもらってます。
c-ja

2017/08/03 00:46

申し訳ございません。 現状公開できるのは、既に提示済みの情報位なので、そこから分かる範囲のもので大丈夫です。 ご指摘ありがとうございました。
c-ja

2017/08/03 00:47

申し訳ございません。 1点追加情報で、誰でもアクセス可能な事を追記しておきます。 一番大事な事だった気がします。。。
m.ts10806

2017/08/03 01:19

んーせめて送信側のhtmlでもあればいいんですが。。
m.ts10806

2017/08/03 01:47 編集

perlってpostとgetの区別がなかったという記憶があります。 つまり、tacsheavenさんの指摘のように直接perlをパラメータをつないで実行することで、javascriptのチェックを通さずperl実行が可能となり、 javascriptのチェックが意味がない、、、ということですね。 pl?name=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa とか。10文字しか入れられないところに何百何千自と入れたり不正なメールアドレスを入れたり、 テキストファイル出力をしているようなのでその後続のバッチとやらが動き出す前にテキストファイル自体を無効なファイルにしたりとか、できないことも内容に思います(私は攻撃者じゃないのでそこまで詳しくないのですが、可能性のひとつとして) URL文字数にも制限があるのですが、その文字数の範囲で可能なことが何でもできるってことですね。
c-ja

2017/08/03 02:14

ご認識の通り、お手軽クエリストリングで自由にデータ作って送信できてしまう状態です。 ご指摘された無効なファイルという点が気になる所ではあるのですが、データ的にシステム側で使えないデータであるだけなら、後続バッチは基本的に不正データとして使わないだけなので、先方の社長さんは問題無いという考えのようです。
m.ts10806

2017/08/03 02:21 編集

そうですね。先方がそこまで必要ないと考えるのは「開発コストに見合わない」と考えているようなフシがありますね(ちょっと知識をもったお客さんにありがちな状況です) セキュリティリスクの洗い出し、対応の検討、実装、試験まで考えると、ちょっとやってみようというにはあまりに膨大な時間がかかるように思います。「どこまでやるか」の落としどころはお客さんと相談して決めるべきとも思います。その結果「最低限(サーバー側での入力チェックのみ)しかしない」とか「サーバー側では何もしない」となることもあります。 あとは、ご自身が提示して懸念されているセキュリティリスクをテスト環境などで再現してみて、どれだけの損害が出るかというのを見ていただくことで理解を得るしかないように思います。
tacsheaven

2017/08/03 02:22

不正なデータであれば弾く、のはまあいいんですが、不正でない偽造データを潜り込ませることができる、ってのが問題になるかと思います。この場合突っ込まれたデータが正常ルートから来たのか、別ルートからのものなのかを判断する材料すらないわけですし。
m.ts10806

2017/08/03 02:26

そうですね。相手は社長さんですから損害の大きさを理解してもらう必要がありますね。経営的な観点も必要そうです。
takito

2017/08/03 02:51

たしかに、システム面の問題からアプローチするよりも、経営面からアプローチする方が社長さんにとって分かりやすそうですね。tacsheavenさんの指摘されるように、「正しい偽造データ」を受け付けられる仕組みによって「偽造データへの対応によって業務が滞ったり、本来対応すべき正当なお客様を誤って除外してしまったりなどの影響が出ます」となれば、社長さんも「それは困るので対応できないか」となりそう。
c-ja

2017/08/03 03:15

>不正でない偽造データを潜り込ませることができる 仰る通りです。 あまりにも無防備なCGIで派手なセキュリティリスクの方ばかり気になってしまっていました。 これは大事なポイントかと思います。社長さんにご報告させて頂きます。 みなさんもコメントありがとうございます。
m.ts10806

2017/08/03 04:05

「後続のバッチ」に絶対的な自信をもっていそうなところが気にはなります。 でも、バッチが来る前にやられることが絶対にないとは言えない(むしろそこが狙いどころ)というところを理解いただく必要がありますね。
c-ja

2017/08/03 05:24

>バッチが来る前にやられることが絶対にないとは言えない(むしろそこが狙いどころ) 私もそう思います。 危険性を示すために、インジェクション攻撃でリモートでコマンド実行可能とか、不正ログイン可能とか、情報漏洩の可能性等が 示せれば手っ取り早かったのですが。 例えばOpen関数の引数に入力値を使用するCGIはコマンドインジェクション等を引き起こす恐れがあると思います。 しかし、本CGIではそういった事はしていませんので、プログラム実行中にコマンドインジェクションのような想定外の処理は引き起こせないと思います。 バッチが来る前に自由に出来てしまう事の危険性は、それが具体的に何なのかを示す必要が有ります。 しかし、その説明がなかなか難しいと思うのです。
guest

0

もうベストアンサー出てしまっていますが、ちょろっと見た感じで回答。

どうやら CSV を出力している様ですが、外部からの入力をそのまま出してしまいっているので例えばリクエストに

0.PassCode=やっほー"%0A"0.AccessIP","徳丸だよ

という文字列を送ると以下のCSVが出力されます。

"0.PassCode","やっほー" "0.AccessIP","徳丸だよ"

投稿2017/08/03 15:41

mattn

総合スコア5030

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

コードレビューには

  • 気付いた範囲で問題を指摘する
  • 確認可能な範囲で網羅的に問題を指摘する(=確認可能な範囲では他に問題がないことを担保する)

の2種類あります。一般的にセキュリティ目的でのコード監査は後者であることが明示的または暗黙的に期待されます。しかし、この分量であっても、後者のレビューをするにはそれなりの知識と経験と労力が必要になるので、回答者は当然の前提として気付いた点の指摘をするに過ぎないことになります。そこで認識のずれはありませんか?また、依頼者とあなたの間でも同様に認識のずれはありませんか?

このコードについて言えば、すでに指摘されている具体的な脆弱性の他にも、一般的な範囲での入力値チェックがない、エラーチェックがない、出力がおかしいなどまずい点がいくらでもあり、とてもではないですがプロダクションレベルの品質を満たしているとは言いがたい物です。このレベルでは前後処理で適切に処理されているというのも眉唾です。

そこでコードレビューに対する認識のずれがあり「指摘された点だけ直せばいい」と思われると大変です。

少なくとも外部公開の範囲については、中途半端な指摘ではなく、きちんとした業者による監査が必要だと思います。

投稿2017/08/03 23:40

suzukis

総合スコア1449

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

c-ja

2017/08/03 23:56

>プロダクションレベルの品質を満たしているとは言いがたい物です。 >このレベルでは前後処理で適切に処理されているというのも眉唾です。 同感です。私のような専門家ではない人間が見ても、製品レベルに至っていないと感じました。 先方もセキュリティ周りに漠然とした不安を抱えていた為、今回私の方にコードレビューの依頼を持ちかけてきたようですが、専門家に依頼するとコストが掛かる為、私の方に話を持ってきたのかもしれませんね。 >少なくとも外部公開の範囲については、中途半端な指摘ではなく、 >きちんとした業者による監査が必要だと思います。 そうかもしれません。合わせて先方にご報告致します。 ご指摘ありがとうございました。
guest

0

入力を画面側でチェックしているから、というのは、入り口が本来の画面からしかありえない、という前提があって初めて成り立ちます。
REFERER をチェックしているわけではないので、http://{CGIのURL}?{パラメータ群} とやれば、任意のパラメータをチェックなしで突っ込むことが可能ですね、これ。

投稿2017/08/03 00:25

tacsheaven

総合スコア13703

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

c-ja

2017/08/03 00:29

ご認識の通りです。 CGIは入力画面から遷移しなくても、直接アクセス可能である為、その辺のリスクを説明したいです。
c-ja

2017/08/03 12:36

すみません。mts10806さんの回答に対するコメントをベストアンサーにしたかったのですが、そういうのは出来ないんですね。。。
guest

0

考えられるリスクは

F5アタックとかで大量にデータが投入されてしまう。
検索エンジンにクロールされる可能性がある。(googleさんからアクセスあるかもね)
クロールされた結果、goolgeの検索結果に表示されてしまう。

そもそも入力チェックについてはフロントのチェックと同じことをサーバーでもやらないと駄目です。
Javascriptを無効にしたら何でもフォームから送信できてしまいます。

投稿2017/08/03 02:36

Tak1016

総合スコア1408

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

c-ja

2017/08/03 03:16

ご指摘の通りかと思います。コメントありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問