Skip to main content
Participant
September 4, 2006
Answered

Getting file extension from cfhttp transfer.

  • September 4, 2006
  • 3 replies
  • 753 views
Hi,
I run a file hosting website built in Coldfusion. The server runs Coldfusion MX 6.1 and IIS/6.0 on Windows Server 2003 Standard edition.

At the moment, i'm using just a standard upload form and the <cffile action="upload"> tag for users to upload files.

I'd like to implement a feature on my site where users have the option to get files directly from another website by entering the url and have it transferred to my site to be hosted, kind of like imageshack does.

To do this, I'm using the cfhttp tag to get the file from the url and have it saved to a location on my server. the code i'm using at the moment is like this:

<cfhttp url="#form.url#" getAsBinary="yes" path="C:\Inetpub\wwwroot\files\"></cfhttp>

This basically works fine in that the file is transferred from the site and stored on my server ok, but there are a few more things I need to be able to accomplish.

1. I need to be able to make the file name unique, like the <cffile nameconflict="makeunique"> option, so it doesn't have a problem with duplicate file names.

2. I need to be able to limit the file extensions and file size that the users can host, for example only jpg, bmp, png files and no bigger than 1.5mb

3. I need to be able to get the file name as a variable so I can output the path to the file for the user .

I'd be grateful if someone could help me with this.

Thanks in advance.
    This topic has been closed for replies.
    Correct answer LeftCorner
    I understand the purpose of your site and just wanted to ensure you understood the risks.

    You would indeed need to use cfhttp and not cffile to get a file from another server in this case.

    So the design may resemble

    - Use <chttp> to get your file and put it in a temp directory
    - Use <chttp> to verify the mime type (CFHTTP.MimeType)
    - Use <cfhttp> to verify the file does not exceed your size requirements (CFHTTP.ResponseHeader["Content-Length"])
    - Move the file if it is ok, otherwise delete it

    You can verify the mime type of the file and reject it if need be:

    <cfoutput>#CFHTTP.MimeType#</cfoutput>

    And see its size:

    <cfoutput>#CFHTTP.ResponseHeader["Content-Length"]#</cfoutput>

    You can get the file extension like so:

    #ListLast(" http://www.domain.com/image.gif", ".")#

    And you can you can create a unique file name like so:

    #CreateUUID()# & "." & #ListLast(" http://www.domain.com/image.gif", ".")#

    Coding up a whole example tying it all together would take a while, I hope this is enough to point you in the correct direction.

    3 replies

    ms5422Author
    Participant
    September 4, 2006
    leftcorner, thanks for that, it worked great.

    Also, Thanks Mr Black for the helpful suggestions.

    Thanks guys.
    LeftCornerCorrect answer
    Participating Frequently
    September 4, 2006
    I understand the purpose of your site and just wanted to ensure you understood the risks.

    You would indeed need to use cfhttp and not cffile to get a file from another server in this case.

    So the design may resemble

    - Use <chttp> to get your file and put it in a temp directory
    - Use <chttp> to verify the mime type (CFHTTP.MimeType)
    - Use <cfhttp> to verify the file does not exceed your size requirements (CFHTTP.ResponseHeader["Content-Length"])
    - Move the file if it is ok, otherwise delete it

    You can verify the mime type of the file and reject it if need be:

    <cfoutput>#CFHTTP.MimeType#</cfoutput>

    And see its size:

    <cfoutput>#CFHTTP.ResponseHeader["Content-Length"]#</cfoutput>

    You can get the file extension like so:

    #ListLast(" http://www.domain.com/image.gif", ".")#

    And you can you can create a unique file name like so:

    #CreateUUID()# & "." & #ListLast(" http://www.domain.com/image.gif", ".")#

    Coding up a whole example tying it all together would take a while, I hope this is enough to point you in the correct direction.
    Participating Frequently
    September 4, 2006
    Just a few comments/suggestions:

    1. Checking for Content-Length and Content-Type header might be totally useless, because:
    a) File already arrvied and it can be wrong size (like 4GB) or type.
    b) Content-Length is not a required header for HTTP response. Therefore, it simply might not be there.

    2. I would recommend to use HEAD request first to obtain resource properties: length (if possible) and type. So, you could make a decision BEFORE downloading a file. This can save a lot of time and resources, if it works. Unfortunately, it does not work for all servers/resources.
    Participating Frequently
    September 4, 2006
    I seriously suggest you rethink this.

    <cfhttp url="#form.url#" getAsBinary="yes" path="C:\Inetpub\wwwroot\files\"></cfhttp>

    This code allows a user to grab any file on the Internet and put it on your server, in a web accessible (I assume) directory. The security risks to your server with this design are enormous. One malicious user could compromise your server, and perhaps network, with the design.

    Allowing users to upload files to your server is one the most dangerous actions an application can allow. It is one of the areas that CF makes it incredibly easy for developers to do, and do incorrectly.

    You can minimize the risks by:

    1) Using <cffile> to check the mime type of the file and rejecting others.
    2) Using <cffile> to upload files to a web inaccessible directory
    3) Using <cffile> to delete files which are larger than your desired size
    4) Virus scanning the files after upload (CF does not do this)

    1, 2 and 3 you can do with <cffile>. Doing it with <cfhttp> is not possible to my knowledge, or requires quite a bit of convulted code. Implementing your feature correctly is out of the scope of this post. I would seriously reconsider the value of this feature verse the risks.

    In the meantime I recommend reading these articles:

    http://www.adobe.com/cfusion/knowledgebase/index.cfm?id=tn_17618
    http://www.adobe.com/devnet/server_archive/articles/top5_cf_security_issues.html#5
    enormous
    ms5422Author
    Participant
    September 4, 2006
    Thanks for the reply.

    I understand the obvious security risks with allowing users to do this, but it's essential to allow this as, by very design, my site is a website that allows users to upload files to be hosted on the internet. I've implemented a number of security measures to prevent problems, including setting directory permissions on the directory where files are uploaded to in IIS to not allow scripts or applications to be executed from this folder.

    Is it possible to use the <cffile> tag to get files from another webserver? If so this would be an easy solution, but I was under the impression that you had to use the <cfhttp> tag to do this.