###前提・実現したいこと
現在、とある会社さんの依頼で自社開発した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処理中にファイル出力を行っており、そのファイルを後続のバッチが解析。
不正なデータであれば、そのデータは弾くようにしている。
回答6件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2017/08/03 13:07