Link to home
Start Free TrialLog in
Avatar of finnstone
finnstone

asked on

check file type and size of an attachment

how can i put a check in a cfform submit action to make sure a file is less than .25 MB and that it is a zip file?
Avatar of anandkp
anandkp
Flag of India image

There was some discussion a while back on a possible vulnerability in CFMX. I was worried that a denial of service attack would be possible by uploading a single very large file. My fear was that the ColdFusion server was buffering files in RAM before writing them out to the file system, however I was relieved when two people from the ColdFusion team confirmed that the files were written directly to disk and not buffered in RAM. In other words, the input stream from the request is written directly to a file output stream (without being buffered more than just a few K), which means you cannot cause the JVM to run out of memory by uploading a file. Very good implementation.

The next question, however, was whether or not it was possible to create a DOS attack by making the server run out of disk space. Could someone upload enough gigabytes of data to fill an entire partition? Shouldn't there be a way to guard against this type of issue?

Fortunately, there is. On the advice of Laurent Rouquette, I confirmed this morning that you can use the variable cgi.CONTENT_LENGTH to decide if you want to allow a file to be uploaded or not. The code below only allows files less than 25,000 bytes to be saved:

<cfif cgi.CONTENT_LENGTH lt 25000>
    <cffile action="upload"
            fileField="testFile"
            destination="/tmp"
            nameConflict="overwrite" />
</cfif>

Note that the file will still be uploaded and saved in a temporary location, but if the cffile tag does not get executed, the temp file will simply be deleted after the upload is complete.

I recommend that anyone who has an application that allows files to be uploaded use this technique as an extra level of security. Remember, though, that the content length of the request contains all the information in the request, so allow a little extra space for other data, as well.

U'll need to use the "ACCEPT" attribute for checking the file type

ACCEPT="mime_type/file_type"

hth

K'Rgds
Anand
so ur code shld look as :

<CFIF CGI.CONTENT_LENGTH LT 300000><!--- Bytes -- .25 MB shld be around 300KB ie around 300000 bytes --->
    <CFFILE ACTION="upload"
            FILEFIELD="testFile"
            DESTINATION="/tmp"
            NAMECONFLICT="overwrite"
            ACCEPT="application/zip"/>
</CFIF>

U shld be having chks for the filetype on client side itself ....

the above code will chk for file size & file type

let me know incase u need more help !
Avatar of finnstone
finnstone

ASKER

i need a few pointers..how do i upload it into a folder in my wwwroot.

Where do i put the code for the web site that allows them to upload a file into a field. Is FILEFIELD the name of the field>>?
ASKER CERTIFIED SOLUTION
Avatar of anandkp
anandkp
Flag of India image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
teh form uploading the file wld look as simple as this

<form NAME="frm" ACTION="file_thatcontains_abovegiven_code.cfm" ENCTYPE="multipart/form-data" METHOD="post">      
      <input TYPE="File" NAME="uploadimg">      
      <input TYPE="Submit" VALUE="subme">      
</FORM>
why are you deleting a file. i want  the users to be able to insert files with other records in a form. however this is an update form, i could have 2 forms, but i need to be able to save the filename in a row with the other information on the other form, so that i can display it later
and i would like the user never to be taken to a new page. i would like them to upload and then keep filling out the main form
also most importantly, i need to save the filename to a database field?
how can i send #file.serverfilename# back to the main form to be submitted when the user submits the main form?
if u see my comment dtd "Date: 12/12/2003 12:07PM IST" it has everything in it

hth
the problem is that the form tag is alreaedy this

<form method="post" name="form1" action="<cfoutput>#CurrentPage#</cfoutput>">

SO, I want the action to return the user to the page that they came from before they came to the page on the form.

you have suggested that i make action, upload.cfm, in this case, how can i return the user to the page they originally came from !
why am i getting this error

The start tag must have a matching end tag. This could be because CFCATCH is not the last tag nested in the CFTRY. CFCATCH must be the last tag inside a CFTRY.
The CFML compiler was processing:

a cfif tag beginning on line 16, column 3.
 
 
The Error Occurred in C:\CFusionMX\wwwroot\IERROR\Upload_Action.cfm: line 1
 
1 : <CFTRY>
2 : <CFFILE
3 : ACTION="upload"

 


HERE IS MY UPLOADACTION CFM CODE

<CFTRY>
<CFFILE
ACTION="upload"
FILEFIELD="UploadFile"
DESTINATION="C:\TEMP"
NAMECONFILCT="MakeUnique">

<cfif CFFILE.FileSize GT 200000>
<CFTHROW TYPE="SizeError"
MESSAGE="File too Large. Cannot be greater than 200l.">
</cfif>

<cfif CFFILE.ClientFileExt NEQ "gif"></cfif>
<CFTHROW TYPE="ExtError"
MESSAGE="File is wrong type. Please only upload zip file">
</cfif>

<cfcatch type="SizeError">
<cfabort showerror="#cfcatch.message#">
</cfcatch>

<cfcatch type="ExtError">
<cfabort showerror="#cfcatch.message#">
</cfcatch>
</CFTRY>

<cffile
ACTION="move"
SOURCE="C:\TEMP\#CFFILE.ServerFile#"
DESTINATION="C:\CFusionMX\wwwroot\DRWEB\Attachments\#CFFILE.ServerFile#">

<cfoutput>#session.page#</cfoutput>
im no longer having that error above
hi finnstone

when u chnage the action to Upload.cfm - it wld upload the file & do the necessary updates in the DB

once done - u can write a CFLOCATION down below ... it will redirect the user back to the page where u wanted to ...

also ur missing out teh "enctype" in ur form tag ... this is required if ur uploading files & using Input type="file" in ur form
ur form tag shld look like this

<form NAME="frm" ACTION="file_thatcontains_abovegiven_code.cfm" ENCTYPE="multipart/form-data" METHOD="post">    
anand, where can i put the cflocation, can i put that in my Upload.cfm? i will test this monday back at work, but think all i have to do is move my INSERT SQL statement from my form page to the Upload.cfm page, and also move my cflocation code from the form page to the Upload.cfm page.

Does this sound correct? I hope to close out these 2 questions for you monday AM!
yes ur going perfect !

ur CFLOCATION wld come at the end of ur upload.cfm file
& the insert statement of urs will move to upload.cfm.

hope u get everything sorted out....

buzz me incase u need more help !

K'Rgds
Anand
my problem is that my update statement depends on the contents of the form, how do i move the below code to my upload page, because the form is on the other page the below code does not work

<cfif IsDefined("FORM.MM_UpdateRecord") AND FORM.MM_UpdateRecord EQ "form1">
  <cfquery datasource="IDR">
  UPDATE output_login SET  
    Researcher=
  <cfif IsDefined("FORM.Researcher") AND #FORM.Researcher# NEQ "">
    '#FORM.Researcher#'
      <cfelse>
      NULL
  </cfif>
  , ResponseDate=
  <cfif IsDefined("FORM.ResponseDate") AND #FORM.ResponseDate# NEQ "">
    '#FORM.ResponseDate#'
      <cfelse>
      NULL
  </cfif>
  , Whathappened=
  <cfif IsDefined("FORM.Whathappened") AND #FORM.Whathappened# NEQ "">
    '#FORM.Whathappened#'
      <cfelse>
      NULL
  </cfif>
  , Howwhydidithappen=
  <cfif IsDefined("FORM.Howwhydidithappen") AND #FORM.Howwhydidithappen# NEQ "">
    '#FORM.Howwhydidithappen#'
      <cfelse>
      NULL
  </cfif>
  , WhatistheSymptom=
  <cfif IsDefined("FORM.WhatistheSymptom") AND #FORM.WhatistheSymptom# NEQ "">
    '#FORM.WhatistheSymptom#'
      <cfelse>
      NULL
  </cfif>
  , DidyourgroupsourcecausethisDR=
  <cfif IsDefined("FORM.DidyourgroupsourcecausethisDR") AND #FORM.DidyourgroupsourcecausethisDR# NEQ "">
    '#FORM.DidyourgroupsourcecausethisDR#'
      <cfelse>
      NULL
  </cfif>
  , yes=
  <cfif IsDefined("FORM.yes") AND #FORM.yes# NEQ "">
    '#FORM.yes#'
      <cfelse>
      NULL
  </cfif>
  ,no=
  <cfif IsDefined("FORM.no") AND #FORM.no# NEQ "">
    '#FORM.no#'
      <cfelse>
      NULL
  </cfif>
  , evidence=
  <cfif IsDefined("FORM.evidence") AND #FORM.evidence# NEQ "">
    '#FORM.evidence#'
      <cfelse>
      NULL
  </cfif>
  , Whatchangecouldpreventthisinthefuture=
  <cfif IsDefined("FORM.Whatchangecouldpreventthisinthefuture") AND #FORM.Whatchangecouldpreventthisinthefuture# NEQ "">
    '#FORM.Whatchangecouldpreventthisinthefuture#'
      <cfelse>
      NULL
  </cfif>
   WHERE SRnum='#FORM.SRnum#'
  </cfquery>
  <cflocation url="internal.cfm">
</cfif>
ok the above actually works!! my problem now is that if the zip file is named the same, it does not work. i look in the temp file and it is not there either!

<CFTRY>
<CFFILE
ACTION="upload"
FILEFIELD="UploadFile"
DESTINATION="C:\TEMP"
NAMECONFLICT="MakeUnique">

<cfif CFFILE.FileSize GT 200000>
<CFTHROW TYPE="SizeError"
MESSAGE="File too Large. Cannot be greater than 200k.">
</cfif>

<cfif CFFILE.ClientFileExt NEQ "zip">
<CFTHROW TYPE="ExtError"
MESSAGE="File is wrong type. Please only upload zip file">
</cfif>

<cfcatch type="SizeError">
<cfabort showerror="#cfcatch.message#">
</cfcatch>

<cfcatch type="ExtError">
<cfabort showerror="#cfcatch.message#">
</cfcatch>
</CFTRY>

<cffile
ACTION="move"
SOURCE="C:\TEMP\#CFFILE.ServerFile#"
DESTINATION="C:\CFusionMX\wwwroot\DRWEB\Attachments\#CFFILE.ServerFile#">
also, how do i let future web visitors download the file that is saved on my computer?
anand, why is MAKEUNIQUE not working. i am just curious now because i established a work around. For some reason make unique code above was not creating an entry in the temp file, so there CF was unable to move the new name, however , CF did know the new name for example Filename1

I STILL NEED HELP SHOWING THE FILE IN ANOTHER PAGE, HOW DO I DO THIS ONCE THE FILENAME IS STORED IN THE DATABASE??

below is my workaround to makeunique

<CFIF #File.FileExisted# is "YES">
<!--- if the file already exists --->
   
<cffile action="UPLOAD" filefield="UploadFile" destination="c:\Temp" nameconflict="MAKEUNIQUE">
<!--- upload the file but let CF rename it --->

     <CFDIRECTORY action="LIST" directory="c:\Temp" Name="ListFiles" filter="#File.ClientFileName#*.#File.ClientFileExt#">
     <!--- find all files already uploaded with the same name
           and define the version of the new file--->
     
<CFSET NbVersion = 0>

<cfoutput query="ListFiles">

     <CFSET Version = Replace(ListFiles.Name, File.ClientFileName, "")>
     <CFSET Version = Replace(Version, "."&File.ClientFileExt, "")>

     <CFIF Version IS NOT "">
             <cfset NbVersion = NbVersion + 1>
     </cfif>

     <CFSET NewFileName = File.ClientFileName & NbVersion & "." & File.ClientFileExt>
     <!--- create the new filename --->

</cfoutput>

<cffile action="RENAME" source="C:\Temp\#File.serverfile#" destination="C:\Temp\#NewFileName#">
<!--- rename the file uploaded previously by CF with the one generated --->

<cffile
ACTION="COPY"
SOURCE="C:\TEMP\#NewFileName#"
DESTINATION="C:\CFusionMX\wwwroot\DRWEB\Attachments\#NewFileName#">

<CFELSE>
<cffile
ACTION="copy"
SOURCE="C:\TEMP\#CFFILE.ServerFile#"
DESTINATION="C:\CFusionMX\wwwroot\DRWEB\Attachments\#CFFILE.ServerFile#">
</cfif>
i found answers i needed
glad u figured it out ... i was asleep while u were asking the above questions .. i hope u didnt mind me not being able to answere them at that hr.

incase u need - just ask :)

Cheers
Anand