130 likes | 214 Views
Roxen Security++. A Z U N D R I S. NetUSE AG Working around the chroot()-issue - Concepts & Implementation -. W o r k i n g a r o u n d t h e c h r o o t ( ) - i s s u e. /. dev. home. etc. bunbun. azundris. www. client1. client2. Security Model. E. S cu ity odel. M.
E N D
Roxen Security++ A Z U N D R I S NetUSE AG Working around the chroot()-issue - Concepts & Implementation - Working aroundthe chroot()-issue
/ dev home etc bunbun azundris www client1 client2 Security Model E S cu ity odel M E R Security Model Like in an apartment complex, we want each party to have access to their own apartment only, with only the house- keeper (admin, root) having access to everything so she can maintain the building etc.* * standard security model. 1701. No bloody A, B, C, ACL, or RBA.
/ dev home etc bunbun azundris www client1 client2 chroot(2) A program running as root (»housekeeper«) can read and modify all data, all directories starting at the root of the directory tree. If we »fool« a program into thinking another directory (such as »client1«) is the topmost directory (or root directory), we can have the program run as user root without it being able to read/modify/delete all data -- namely that data which is not in our below or new root directory. To set a »fake« root-directory, the chroot-command is used -- chroot(1M) on CLI-level, or the chroot(2) at C-level.
/ dev home etc bunbun azundris www client1 client2 When to chroot()... When to chroot()... A webserver that is to serve pages from several users' directories needs to run as root unless you can afford to make user data readable and writable to all - which quite simply, you can not. Once you know who a request is for, you could chroot() the server to their directory though. Only you'll be stuck with that root, which is okay in a forking environment with throwaway server tasks.
Process vs Thread X X P R C A H X N A E E O Process / Forking model * a copy of the entire process is created for each request * each process operates in its own context* * PRO - secure: chroot() works CON - requires much RAM - takes long to create** * for limitations, see fork(2) ** this is usually worked around by pre-forking Thread-based model * bits of the same program (process) run concurrently sharing the same context* * PRO - thread creation is »cheap« in terms of CPU cycles and RAM (no duplication of the entire process) CON - security does not come easily (no chroot() etc., each thread can modify global resources)
Roxen * several pike-threads sharing a common »root«, each with access to all server variables Server Module *.pike <pike> P ¡ |< (e Danger ZonEs g CGI * independent process * chroot() possible * no access to server variables
* create a copy of the current process (that'd be the pike interpiler) * chroot() that copy to the right user's directory * run that ol' CGI Securing CGI * prerequisite: make sure there is a copy of what the CGI depends on (/dev, /etc, whatever) in the user's www directory
Roxen * several pike-threads sharing a common »root«, each with access to all server variables Server Module *.pike <pike> P ¡ |< (e Securing the Server * user-supplied server modules * user-supplied .pike pages (index.pike etc.) * user-supplied pages containing the <pike> tag * user-supplied pages containing RXML (<insert>...) may all read and/or write data with the server's privileges (root!). Therefore, we need to lock the users into their respective directories, emulating chroot(2).
Emulating chroot() Emulating chroot() * chroot() only grants access to a specified subtree * all Roxen-access is done via Pike-functions (open(), mkdir()...) * determine allowed path for current request * add allowed path (path prefix) to all file-functions 4 this request. * deny all absolute access outside allowed directory.
Deter ining the path- prefix fo a request m g a r f * HTTP/1.1 requests contain the host-line stating which (virtual) server to get a document from. * protocols/http.pike will see this header. * It is passed on as RequestID, identifying the request * we will save the host in the RequestID in a way that allows noone to change or overload the variable. * there will be one or many http.pike-objects on the call-stack for each request. By accessing the top-most one (which is created before any user-code may temper), we are safe against fraud RequestIDs.
Changing P .|< (e Changing P i|< (e * If we implemented security directly in Roxen (pike-code), user-modules may choose to bypass that new functionality. * An implementation in C (building security directly into the pike-interpiler) must count as safe, since it cannot be compromised by user-level pike-code. * All relevant Pike functions that accept file- or directory names can now read the path-prefix out of the highest http.pike-module on the callstack, »from the inside«.
So far... * The above functionality has been implemented, extending a copy of Pike 7.1.5. CGI-security and file-level secu- rity are fully operational. * ToDo: Add object-level security so that one user may not change another's configuration data etc. This has been put on hold since there is experimental o/l-sec in Pike 7.1.5 which may solve the issue, but the API of which has not been cemented.
Further Info http://www.netuse.de/ http://www.roxen.de/ http://www.azundris.com/ NetUSE AG NetUSE AG NetUSE AG NetUSE AG NetUSE AG NetUSE AG NetUSE AG