2

プログラミングのインストラクターから頼まれたので、セキュリティ付きのファイルアップロード機能を開発しようとしています。サイズ、ファイル形式、ファイルの有無を確認できるように実装しました。ファイルの存在をチェックすることを除いて、ロジックはうまく機能していました。たとえば、すでに存在するファイルをアップロードしようとしても、ファイルがすでに存在していることを通知するメッセージが表示されず、なぜ機能しないのかわかりません。

protected void UploadFile(object sender, EventArgs e)
    {
        if(FileUpload1.HasFile)
            try 
            {
                string[] validTypes = { "bmp", "gif"};
                string ext = System.IO.Path.GetExtension(FileUpload1.PostedFile.FileName);

                if (size < limit) 
                {
                    for (int i = 0; i < validTypes.Length; i++)
                    {
                        if (ext == "." + validTypes[i])
                        {
                            string path = @"~\Images\"; 
                            string comPath = Server.MapPath(path + "\\" + FileUpload1.FileName);
                            if (!File.Exists(comPath))
                            {
                                FileUpload1.PostedFile.SaveAs(comPath);
                                Label1.Text = "File uploaded";
                            }
                            else
                            {
                                Label1.Text = "Existed";
                            }
                        }
                        else 
                        {
                            Label1.Text = "Invalid File." + string.Join(",", validTypes);
                        }
                    }                         
                }

                else 
                {
                    Label2.ForeColor = System.Drawing.Color.Red;
                    Label2.Text = "file is heavy";
                }
            }

            catch (Exception ex)
            {
                Label2.Text = "The file could not be uploaded. The following error occured: " + ex.Message;
            }
}

コードをデバッグしたところ、elseステートメントが実行されることがわかりましたが、ユーザーに表示する代わりに、外側のelseステートメントに「無効なファイル」というメッセージが表示されます。なんで?

if (ext == "." + validTypes[i])
                            {
                                string path = @"~\Images\"; 
                                string comPath = Server.MapPath(path + "\\" + FileUpload1.FileName);
                                if (!File.Exists(comPath))
                                {
                                    FileUpload1.PostedFile.SaveAs(comPath);
                                    Label1.Text = "File uploaded";
                                }
                                else
                                {
                                    Label1.Text = "Existed";
                                }
                            }
                            else 
                            {
                                Label1.Text = "Invalid File." + string.Join(",", validTypes);
                            }

また、私のインストラクターは、次の行がパストラバーサルと呼ばれる脆弱性を引き起こすと私に言いました。

string path = @"~\Images\"; 

では、このセキュリティホールを防ぐ方法は??何か案は?

4

1 に答える 1

2

コードに論理的な問題があります。
ブロックで

for (int i = 0; i < validTypes.Length; i++)

ファイルごとに常に2回実行されます。

何ができるかは、ブール変数をfalseに設定するときに取得します。
ループ内に入り、ファイルが見つかった場合はブール値をtrueに設定し、breakステートメントを使用します。
ループの最後にブール値をチェックし、それに応じてコードを記述します。

編集-1

配列をループするのではなく、次のように使用できます

string[] stringArray = { "text1", "text2", "text3", "text4" };
string value = "text3";
int pos = Array.IndexOf(stringArray, value);
if (pos >- 1)
{
    // the array contains the string and the pos variable
    // will have its position in the array
}

あなたの場合

 string[] validTypes = { "bmp", "gif"};
 string ext = System.IO.Path.GetExtension(FileUpload1.PostedFile.FileName);
 int pos = Array.IndexOf(validTypes , ext );
 if(pos>=0)
 {
     string path = @"~\Images\"; 
     string comPath = Server.MapPath(path + "\\" + FileUpload1.FileName);
     if (!File.Exists(comPath))
     {
         FileUpload1.PostedFile.SaveAs(comPath);
         Label1.Text = "File uploaded";
     }
     else
     {
         Label1.Text = "Existed";
     }
 }
 else
 {
    Label1.Text = "Invalid File." + string.Join(",", validTypes);
 }
于 2013-03-20T09:32:51.473 に答える