You are not logged in.

#1 2010-03-16 11:18:50

y27
Member
Registered: 2009-05-27
Posts: 147
Website

[SOLVED] C : How to block opening files "above" a specified directory?

SOLVED: Used

man 3 realpath

Hello Archers,

I have this one problem I've been struggling with. I kind of solved it but the solution's hackish.

My question is how do you prevent the opening of files "above" a specified directory? The reason behind this is that I'm writing a simple sharing server, something like Xyne's quickserve, but in C and with a GTK GUI. I'm using the libmicrohttpd library.

The program works this way: the user selects a port and a directory to be "served", and then he can access the files under the directory he chose. However, there obviously needs to be a way to prevent the user from opening files above the directory by using ".."'s for example.

For now, I simply plan on rejecting all queries containing ".." (http://github.com/houbysoft/quickshare/ … hare.c#L59), but that's obviously very imperfect -- and you could get around it if there is a symlink in the directory for example.


Any pointers will be very appreciated, thanks.

Last edited by y27 (2010-03-17 02:59:14)

Offline

#2 2010-03-16 11:19:59

Peasantoid
Member
Registered: 2009-04-26
Posts: 928
Website

Re: [SOLVED] C : How to block opening files "above" a specified directory?

chroot()? Though you need root privileges for that to work.

** edit: s/priveleges/privileges/

Last edited by Peasantoid (2010-03-16 20:57:58)

Offline

#3 2010-03-16 11:39:42

y27
Member
Registered: 2009-05-27
Posts: 147
Website

Re: [SOLVED] C : How to block opening files "above" a specified directory?

Thanks, didn't think of that, but I can't use that anyway since the program needs to run under normal users.

Offline

#4 2010-03-16 20:14:23

SiC
Member
From: Liverpool, England
Registered: 2008-01-10
Posts: 430

Re: [SOLVED] C : How to block opening files "above" a specified directory?

Why not just parse the query they pass to your server before processing to ensure that the request falls within your new "root" structure?

Offline

#5 2010-03-16 20:57:27

y27
Member
Registered: 2009-05-27
Posts: 147
Website

Re: [SOLVED] C : How to block opening files "above" a specified directory?

Well that's kind of what I'm doing, by checking for "..". I also guess I could check symlinks, etc., and always try to resolve the path into its full form and then check, but isn't there a simpler way?

Offline

#6 2010-03-17 01:15:51

tavianator
Member
From: Waterloo, ON, Canada
Registered: 2007-08-21
Posts: 859
Website

Re: [SOLVED] C : How to block opening files "above" a specified directory?

I don't think there's any easy way other than chroot().  My two ideas are:
- Make your program setuid, use chroot(), then drop root privileges
- Using whatever logic readlink -f uses, resolve the pathname, then check if it begins with the allowed directory

Offline

#7 2010-03-17 02:58:10

y27
Member
Registered: 2009-05-27
Posts: 147
Website

Re: [SOLVED] C : How to block opening files "above" a specified directory?

@tavianator:
Thanks mainly for the second suggestion which made me get the coreutils source code; and I learned what this "path resolving" is called (canonicalizing), so I knew what to google for.

I found a function very suitable to my needs :

man 3 realpath

I now check if it begins with the allowed directory (and if that's where the directory name ends, so that somebody can't access for example with the path /test/blah/something123 when the base directory is set /test/blah/something12).


I marked this as SOLVED, thanks everybody for assistance.

Offline

#8 2010-03-17 03:33:35

tavianator
Member
From: Waterloo, ON, Canada
Registered: 2007-08-21
Posts: 859
Website

Re: [SOLVED] C : How to block opening files "above" a specified directory?

man realpath wrote:

BUGS
       The  POSIX.1-2001  standard  version of this function is broken by design, since it is impossible to
       determine a suitable size for the output buffer, resolved_path.  According to POSIX.1-2001 a  buffer
       of  size PATH_MAX suffices, but PATH_MAX need not be a defined constant, and may have to be obtained
       using pathconf(3).  And asking pathconf(3) does not really help, since, on the one hand POSIX  warns
       that  the  result  of  pathconf(3) may be huge and unsuitable for mallocing memory, and on the other
       hand pathconf(3) may return -1 to signify that PATH_MAX is not bounded.   The  resolved_path == NULL
       feature,  not  standardized  in  POSIX.1-2001,  but standardized in POSIX.1-2008, allows this design
       problem to be avoided.

So be careful to either pass resolved_path as NULL and bite the potential unportablilty bullet, or copy canonicalize_file_name or canonicalize_filename_mode from gnulib.

Last edited by tavianator (2010-03-17 03:36:21)

Offline

#9 2010-03-17 10:30:57

SiC
Member
From: Liverpool, England
Registered: 2008-01-10
Posts: 430

Re: [SOLVED] C : How to block opening files "above" a specified directory?

y27 wrote:

@tavianator:
Thanks mainly for the second suggestion which made me get the coreutils source code; and I learned what this "path resolving" is called (canonicalizing), so I knew what to google for.

I found a function very suitable to my needs :

man 3 realpath

I now check if it begins with the allowed directory (and if that's where the directory name ends, so that somebody can't access for example with the path /test/blah/something123 when the base directory is set /test/blah/something12).


I marked this as SOLVED, thanks everybody for assistance.

Didn't know about that function, but it seems the most elegant way of doing it smile

Offline

#10 2010-03-17 11:09:04

y27
Member
Registered: 2009-05-27
Posts: 147
Website

Re: [SOLVED] C : How to block opening files "above" a specified directory?

tavianator wrote:
man realpath wrote:

BUGS
       The  POSIX.1-2001  standard  version of this function is broken by design, since it is impossible to
       determine a suitable size for the output buffer, resolved_path.  According to POSIX.1-2001 a  buffer
       of  size PATH_MAX suffices, but PATH_MAX need not be a defined constant, and may have to be obtained
       using pathconf(3).  And asking pathconf(3) does not really help, since, on the one hand POSIX  warns
       that  the  result  of  pathconf(3) may be huge and unsuitable for mallocing memory, and on the other
       hand pathconf(3) may return -1 to signify that PATH_MAX is not bounded.   The  resolved_path == NULL
       feature,  not  standardized  in  POSIX.1-2001,  but standardized in POSIX.1-2008, allows this design
       problem to be avoided.

So be careful to either pass resolved_path as NULL and bite the potential unportablilty bullet, or copy canonicalize_file_name or canonicalize_filename_mode from gnulib.

Yeah, I am passing NULL.

Offline

Board footer

Powered by FluxBB