Setting Limits on an Applications Permissions

Setting Limits on an Application s Permissions

Most operating systems reserve ports below 1024 for system-wide servers. To enforce this reservation, only users with root permissions are allowed to run programs that bind to these ports. But running a server with root permissions tends to greatly magnify security issues. Security breaches happen when a malicious user tricks your application into doing something you didn't intend. This problem is never desirable, but the possibility for damage is especially high if your application has access to every file on the computer.

To limit the potential for damage, a well-behaved Unix server will run under a privileged account for just long enough to listen on the necessary ports, and then switch its identity to that of another user with minimal permissions. twistd makes it easy to use this technique for running your application.

This example is specific to Unix-like operating systems, such as Linux and Mac OS X. Twisted doesn't provide a way to switch user IDs on Windows.


11.2.1. How Do I Do That?

Pass uid and gid keyword arguments when you call twisted.application.service.Application. Once your application has started listening on the ports it needs, twistd will change your application's user and group to those you specified. Example 11-3 creates a server that runs on the reserved Telnet port, 23, and reads the contents of files from disk. By running it with a set user ID and group ID, it's limited to reading files that are available to its user and group.

Example 11-3. catserver.py

from twisted.application import service, internet

from twisted.internet import protocol, reactor

from twisted.protocols import basic

import os

class FileDumpProtocol(basic.LineReceiver):

 def lineReceived(self, line):

 if hasattr(self, 'handle_' + line):

 getattr(self, 'handle_' + line)( )



 def listDir(self, filename):


 f = open(filename)

 for line in f:


 except Exception, e:

 self.sendLine("ERROR: %s" % e)

 def handle_quit(self):

 self.transport.loseConnection( )

class FileDumpFactory(protocol.ServerFactory):

 protocol = FileDumpProtocol

UID = 1000

GID = 1000

fileDumpService = internet.TCPServer(23, FileDumpFactory( ))

application = service.Application('Cat Server', uid=UID, gid=GID)


Modify the UID and GID values in Example 11-3 to match a valid user and group on your system. Start catserver.py as root using twistd with the -n option to keep it in the foreground. It will start a server on port 23. (If you're already running a Telnet server on port 23, modify Example 11-3 to use a different port.) You'll see a log message informing you that twistd has switched to your user and group:

 $ twistd -noy catserver.py

 2005/06/25 17:32 EDT [-] Log opened.

 2005/06/25 17:32 EDT [-] twistd 2.0.0 (/usr/bin/python2.3 2.3.5) starting up

 2005/06/25 17:32 EDT [-] reactor class: twisted.internet.selectreactor.SelectReactor

 2005/06/25 17:32 EDT [-] Loading catserver.py...

 2005/06/25 17:32 EDT [-] Loaded.

 2005/06/25 17:32 EDT [-] _ _builtin_ _.FileDumpFactory starting on 2323

 2005/06/25 17:32 EDT [-] Starting factory <_ _builtin_ _.FileDumpFactory instance at


 2005/06/25 17:32 EDT [-] set uid/gid 1000/1000

Telnet to localhost and enter some filenames. You will be able to access only files that your application's user has the right to read:

 $ telnet localhost


 Connected to sparky.

 Escape character is '^]'.










 ERROR: [Errno 13] Permission denied: '/etc/shadow'


 Connection closed by foreign host.


11.2.2. How Does That Work?

Example 11-3 calls twisted.application.service.Application with uid and gid keyword arguments. twistd uses these values to set the process owner of the application after it has opened the ports. Behind the scenes, this process works by using the privilegedStartService method of IService. If a service provides the method privilegedStartService, it will be called at startup before the application switches users. After it switches to the unprivileged user, the application calls the Service's regular startService method. In the twisted.application.internet.TCPServer class, the code for listening on a port is in the privilegedStartService method, so it's able to bind to the port as root before the process switches to an unprivileged user.

Typically, you wouldn't design a protocol like FileDumpProtocol in Example 11-3, which lets any anonymous user dump the contents of any file on your system. But it's possible that you'd accidentally create a security hole in your application that would let a malicious user trick it into reading arbitrary files. By running it as an unprivileged user, you prevent such a security hole from revealing sensitive files on your system, such as /etc/shadow, which contains user/password hashes.

Example 11-3 defines the application classes and builds the application object in the same file. This is OK for short examples like this one, but the best practice is to set up your application object in a separate, minimal file.


11.2.3. What About...

...running the application in a chroot environment? An alternative way to limit the potential damage of a security flaw in your application is to run it in a chroot "jail," where the operating system makes it impossible for the process to see or access any files outside of one specific directory. twistd has built-in support for this: just run it with the flag chroot directory.

Getting Started

Building Simple Clients and Servers

Web Clients

Web Servers

Web Services and RPC


Mail Clients

Mail Servers

NNTP Clients and Servers


Services, Processes, and Logging

Twisted Network Programming Essentials
Twisted Network Programming Essentials
ISBN: 0596100329
EAN: 2147483647
Year: 2004
Pages: 107
Authors: Abe Fettig

Similar book on Amazon

Flylib.com © 2008-2020.
If you may any questions please contact us: flylib@qtcs.net