[Tutor] Re: I need help slicing.

Derrick 'dman' Hudson dman@dman.ddts.net
Sat, 13 Jul 2002 01:34:12 -0500


--fd5uyaI9j6xoeUBo
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable

On Fri, Jul 12, 2002 at 02:26:54PM -0500, SA wrote:
=20
| Yes. I thought about the os module. But all of the paths in the
| querystrings will be relative.

The os.path module works on relative paths as well.

| For example:
|=20
| http://localhost/cgi-bin/somepython.py?filename=3Ddocs/test.txt  or
| http://localhost/cgi-bin/somepython.py?filename=3Ddocs/test.html
|=20
| So what I want to prevent is someone doing the following:
|=20
| http://localhost/cgi-bin/somepython.py?filename=3D/etc/passwd

Good thinking.

| So my thought was either write the script to limit all filenames to
| files in this relative directory or to use splicing to verify the
| file extension.  Does this sound like a secure enough method?

You can do checks like the following :

1)  ensure every path begins with 'docs/'
2)  ensure that no path has '..' in it anywhere
3)  ensure that no path has any control characters -- eg
        .^H.
    (a dot followed by a backspace followed by a dot)
    (I think that BS will be included in the filename literally, but
     why mess with that stuff anyways)

There may be other potential exploits that I haven't thought of.


Some other possible solutions :

1)  Make a static list of allowed filenames.  Check the parameter that
    is passed against that list and reject it if it isn't in there.
    This means you need to update the list if you ever
    add/remove/rename any files.

2)  Get the directory listing.  Look to see if the filename you were
    passed is in that listing.  Use absolute, normalized, paths for
    everything.  Eg if someone passes ./././/.//////docs/test.txt it
    would be qualified and normalized to
    /home/me/public/html/docs/test.txt and match the entry in the
    list.

3)  Don't use a cgi script like that.  It is precisely for reasons
    like this that SSI (server-side includes) can be a security hole.
    If you let the users of your site use SSI, they can
    "#include /etc/passwd", and you really don't want that :-).

    Alternatives include
        Static directory listings.  This may not provide the fancy
            look you were striving for.
        A Content Management Framework, such as Zope where you would
            store all the accessible content in the framework, and
            also have templates and scripts to make the content look
            nice.  The content could be stored directly in the ZODB,
            or it could be in a SQL backend (eg postgresql), or you
            could use a Product like LocalFile to create pointers from
            inside the ZODB to files on disk.

            One of the main benefits here is that it is impossible for
            a user to access data not available in the framework, such
            as /etc/passwd.  The effect is rather similar to
            alternative #1, but it leverages other software rather
            than being a roll-your-own.  While something like zope
            might be overkill now, once you know how to work with the
            framework you might get ideas on how to provide better
            dynamic content in other areas as well.


HTH,
-D

--=20
=20
Do not be afraid of those who kill the body but cannot kill the soul.
Rather be afraid of the One who can destroy both soul and body in hell.
        Matthew 10:28
=20
http://dman.ddts.net/~dman/


--fd5uyaI9j6xoeUBo
Content-Type: application/pgp-signature
Content-Disposition: inline

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.0.6 (GNU/Linux)
Comment: For info see http://www.gnupg.org

iEYEARECAAYFAj0vyeQACgkQO8l8XBKTpRRteACgwqjad9JaCfxw9eg3UcNjUwOX
Oz8AoKchuKjrk8yIp7Y3yCpdBvjImb8u
=GY0Q
-----END PGP SIGNATURE-----

--fd5uyaI9j6xoeUBo--