secure file writing (escaping characters from the file name)

Discussion in 'Ruby' started by Constantin Gavrilescu, Sep 12, 2007.

  1. I have a cgi script that writes files on the filesystem. The files are
    provided by the users. I need to save them with (almost) the same name
    as the user requests. What characters I need to escape?

    This is on linux. Right now the file: "Mick Jagger / Chris Jagger -
    Racketeer Blues" does not get saved because of the "/" character. I
    don't escape any characters now. I want to keep as many of the original
    characters in the file name as I can. For the characters that cannot be
    escaped, I suppose I need a translation table... to figure out what was
    the original filename.

    Any pointers? More importantly about escaping special characters, and
    avoiding directory traversal.
    --
    Posted via http://www.ruby-forum.com/.
    Constantin Gavrilescu, Sep 12, 2007
    #1
    1. Advertising

  2. On 9/12/07, Constantin Gavrilescu <> wrote:
    > I have a cgi script that writes files on the filesystem. The files are
    > provided by the users. I need to save them with (almost) the same name
    > as the user requests. What characters I need to escape?
    >
    > This is on linux. Right now the file: "Mick Jagger / Chris Jagger -
    > Racketeer Blues" does not get saved because of the "/" character. I
    > don't escape any characters now. I want to keep as many of the original
    > characters in the file name as I can. For the characters that cannot be
    > escaped, I suppose I need a translation table... to figure out what was
    > the original filename.
    >
    > Any pointers? More importantly about escaping special characters, and
    > avoiding directory traversal.


    Hi Constantin,

    Maybe instead of escaping/removing any character in the filename you
    can store the file with a unique name and have an index with the user
    supplied filename and the name of the file in the file system?


    --
    Luis Parravicini
    http://ktulu.com.ar/blog/
    Luis Parravicini, Sep 12, 2007
    #2
    1. Advertising

  3. Re: secure file writing (escaping characters from the file n

    Luis Parravicini wrote:
    > On 9/12/07, Constantin Gavrilescu <> wrote:
    >>
    >> Any pointers? More importantly about escaping special characters, and
    >> avoiding directory traversal.

    >
    > Hi Constantin,
    >
    > Maybe instead of escaping/removing any character in the filename you
    > can store the file with a unique name and have an index with the user
    > supplied filename and the name of the file in the file system?



    The files are also shared over the network with samba, so they need to
    have a meaningful name. That's why I need to escape just the "bad
    characters" and keep most of the other info in.

    --
    Posted via http://www.ruby-forum.com/.
    Constantin Gavrilescu, Sep 12, 2007
    #3
  4. Re: secure file writing (escaping characters from the file n

    Constantin Gavrilescu wrote:
    > Luis Parravicini wrote:
    >> On 9/12/07, Constantin Gavrilescu <> wrote:
    >>> Any pointers? More importantly about escaping special characters, and
    >>> avoiding directory traversal.

    >> Hi Constantin,
    >>
    >> Maybe instead of escaping/removing any character in the filename you
    >> can store the file with a unique name and have an index with the user
    >> supplied filename and the name of the file in the file system?

    >
    >
    > The files are also shared over the network with samba, so they need to
    > have a meaningful name. That's why I need to escape just the "bad
    > characters" and keep most of the other info in.
    >


    The unique caracter not acceptable for the filename in unix is /. So,
    why you not replace this caracter '/' to, for example, a blank caracter ''?

    --
    Jonas Roberto de Goes Filho (sysdebug)
    http://goes.eti.br
    Jonas Roberto de Goes Filho (sysdebug), Sep 12, 2007
    #4
  5. Re: secure file writing (escaping characters from the file n

    Felix Windt wrote:
    > If you only need this to work on POSIX compatible filesystems, all you
    > need
    > to remove are "/" (slash character, as it separates path components) and
    > \000 (nul, as it terminates strings in many languages) as POSIX file
    > names
    > can accept all other ASCII characters.


    <snip>

    That's interesting...

    irb(main):001:0> File.open("aa.php\000continue.jpg", "w")
    => #<File:aa.php>

    Creates the file aa.php. Welcome remote code execution vulnerabilities.

    irb(main):002:0> File.open("../aaa", "w")
    => #<File:../aaa>

    Directory traversal. Creates "aaa" in the parent directory.

    irb(main):002:0> File.open("bbb\\bbb.tst", "w")
    => #<File:bbb\bbb.tst>

    Linux accepts it. I guess it can be a directory traversal in windows.
    Samba exports it as BRRFFZ~N.TST
    --
    Posted via http://www.ruby-forum.com/.
    Constantin Gavrilescu, Sep 12, 2007
    #5
  6. Constantin Gavrilescu

    Carlos Guest

    [Constantin Gavrilescu <>, 2007-09-12 19.39 CEST]
    > I have a cgi script that writes files on the filesystem. The files are
    > provided by the users. I need to save them with (almost) the same name
    > as the user requests. What characters I need to escape?
    >
    > This is on linux. Right now the file: "Mick Jagger / Chris Jagger -
    > Racketeer Blues" does not get saved because of the "/" character. I
    > don't escape any characters now. I want to keep as many of the original
    > characters in the file name as I can. For the characters that cannot be
    > escaped, I suppose I need a translation table... to figure out what was
    > the original filename.
    >
    > Any pointers? More importantly about escaping special characters, and
    > avoiding directory traversal.


    You can "semi-URL-escape" the filenames. I mean, use the same method as
    CGI::escape, but with more characters allowed. Just adapt the original
    function, adding more characters to the regex to allow them, and taking out
    the last #tr (spaces to "+")). It is in cgi.rb:

    def CGI::escape(string)
    string.gsub(/([^ a-zA-Z0-9_.-]+)/n) do
    '%' + $1.unpack('H2' * $1.size).join('%').upcase
    end.tr(' ', '+')
    end

    Later, you can easily restore the original filename with CGI::unescape.

    For Unix/Linux you can let pass any character except "/" and "\000"; for
    Windows/Mac OS, here is a list of forbidden characters:
    http://www.xvsxp.com/files/forbidden.php

    Good luck.
    --
    Carlos, Sep 12, 2007
    #6
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Mike P

    escaping characters

    Mike P, Mar 29, 2006, in forum: ASP .Net
    Replies:
    1
    Views:
    361
    Karl Seguin [MVP]
    Mar 29, 2006
  2. Sean Berry

    Escaping characters in MySQLdb query

    Sean Berry, Apr 12, 2004, in forum: Python
    Replies:
    9
    Views:
    1,793
    Michael Walter
    Apr 13, 2004
  3. Jan Danielsson

    Escaping certain characters

    Jan Danielsson, Jul 31, 2005, in forum: Python
    Replies:
    9
    Views:
    357
    Kent Johnson
    Sep 11, 2005
  4. =?Utf-8?B?bWljaGFlbHJp?=

    SiteMap, SiteMapPath is Escaping Special Characters

    =?Utf-8?B?bWljaGFlbHJp?=, May 8, 2007, in forum: ASP .Net
    Replies:
    1
    Views:
    538
    =?Utf-8?B?bWljaGFlbHJp?=
    May 9, 2007
  5. Ken Fine
    Replies:
    2
    Views:
    184
    Ken Fine
    Feb 5, 2004
Loading...

Share This Page