user2127860
user2127860

Reputation: 69

ColdFusion CFFILE to limit text file upload

I'm want to use CFFILE upload to detect only .txt file. I've tried to use file.clientfileext to detect the extension. When TXT is detected, I'm showing a pop up error message to users and delete the file. But I was told I should not even allow user's file to reach our server.

Then I use CFFILE accept attribute to only accept text/plain. This should do it but unfortunately on my test when I tried uploading non text file I got ColdFusion error:

The MIME type of the uploaded file application/pdf was not accepted by the server. Only files of type text/plain can be uploaded. Verify that you are uploading a file of the appropriate type.

I tried to use cftry and cfcatch but I still get the same error, this mainly due to the MIME Type that I don't know when the file is being uploaded by the browser. I also found the same question in this forum and tried the suggested answer, it did not work, still got the same error message (see below)

I also found another posting in this forum that do not suggest the use of CF "accept" attribute. This link is provided for a further detail explanation: http://www.petefreitag.com/item/701.cfm

So my question is, since I'm still using CF8, I actually don't have many options to prevent my users from uploading other than .txt file securely? If I can't use the accept attribute of the CFFILE, can I at least secure my file upload functionality by doing the following? but is doing it this way safe enough?

  1. Upload the file to a temp folder that is not under the root dir
  2. verify the file extension
  3. change the file name even if the extension is detected to be a .txt
  4. move the file to the destination file under the root dir

Even if I do these steps, I have to allowed the file to reach our server, the order is to NOT allow the file to reach our server.

Below is the answer/suggestion from previous question. But it doesn't work when I tested it:

    <CFTRY>                     
    <cflock name="write_lock" type="Exclusive" timeout="120">
     <cffile action="upload" filefield="filepath" destination="#DestDir#"    
           nameconflict="Overwrite" attributes="Archive">        
    </cflock>

    <CFCATCH>
          <cfif FindNoCase("not accepted", cfcatch.Message)>
            <script>
               $(function(){
                alert("Only the following file types are allowed: .jpg, .gif, .bmp, 
                .png.");
            });
        </script>
        <cfabort />
     <cfelse>
        <!--- looks like non-MIME error, handle separately --->
        <cfdump var="#cfcatch#" abort />
     </cfif>
    </CFCATCH>

    </CFTRY>

Upvotes: 3

Views: 2220

Answers (4)

Anit Kumar
Anit Kumar

Reputation: 1228

You can use the below code:

<cffile action="upload" filefield="BidDoc" 
     destination="C:\upload\" 
     nameconflict="makeunique" 
     accept="text/plain">

The other mime types which you may use are:

  • application/pdf
  • application/msword
  • application/vnd.ms-excel
  • application/vnd.openxmlformats-officedocument.wordprocessingml.document
  • application/vnd.openxmlformats-officedocument.spreadsheetml.sheet

Upvotes: 1

Nebu
Nebu

Reputation: 1793

Coldfusion will not prevent a file from being uploaded to a server. You can set a maximum file size but this is processed during the upload. The cffile tag kicks in after the file is uploaded. Furthermore it is rather difficult to really determine if a file is a text file or a jpg, exe, rar etc file. The following q & a may help:

Determining binary/text file type in Java?

In my opinion it is best to follow the tips given by pete freitag and use a java class to determine the file type. Then you can delete all non text files.

Upvotes: 0

Joe C
Joe C

Reputation: 3546

As discussed in this answer, there really is no 100% fool-proof way.

If you don't want to trust the "accept" attribute, I would suggest allowing the user to upload the file and then checking the mime type of the uploaded file using the cffile.contentType property. Check against whatever mime types you wish to allow/restrict and reject with the appropriate message. You may also choose to employ a check of the file extension as an added layer of error checking.

It must be noted that like file extensions, mime types can not be 100% trusted to be accurate as they can be edited by the user. But using a combination of checks you can be reasonably that most files uploaded are of the correct type.

Upvotes: 0

Henry
Henry

Reputation: 32885

I think your steps are reasonable if you don't like using the Accept attribute for validation. FYI you can set accept to .txt instead of the MIME types. The MIME type was determined by the client so it's safer to check the extension anyway.

The exception thrown by cffile failing attribute validation may not have a type, so the code you posted tried to detect it with FindNoCase() by looking at the exception's message. You can dump the exception out and find out why the FindNoCase() failed to catch the exception.

Make sure you treat whatever uploaded as something potentially malicious and do not process them (e.g. cfinclude them). Forcing the file extension to be .txt should be safe enough, but I'll let other security experts charm in.

Upvotes: 1

Related Questions