From: jfs Date: Sat, 22 Oct 2005 21:21:45 +0000 (+0000) Subject: First version of a section related to Best practices on security, as the current... X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=developers-reference.git;a=commitdiff_plain;h=e5930eb024a8b8977986a44e492fa90264c5b97c First version of a section related to Best practices on security, as the current manual does not have any git-svn-id: svn://anonscm.debian.org/ddp/manuals/trunk/developers-reference@3570 313b444b-1b9f-4f58-a734-7bb04f332e8d --- diff --git a/developers-reference.sgml b/developers-reference.sgml index 2af349a..2643680 100644 --- a/developers-reference.sgml +++ b/developers-reference.sgml @@ -7,7 +7,7 @@ %dynamicdata; - + @@ -4060,6 +4060,286 @@ before the /usr partition is mounted. Most scripts won't have this problem, though. + + Best practices for security review and design + +

When you are packaging software for other users you should make a +best effort to ensure that the installation of the software, or its +use, does not introduce security risks to either the system it is +installed on or its users.

+ +

You should make your best to review the source code of the package and +detect issues that might introduce security bugs. The programming bugs +which lead to security bugs typically include: , , and (in C/C++ programs), temporary (in scripts), and command injection (in servers) and , and (in the case of web-oriented applications).

+ +

Some of these issues might not be easy to spot unless you are an +expert in the programming language the program uses, but some security +problems are easy to detect and fix. For example, finding temporary +race conditions in the source code can easily be done by running +grep -r "/tmp/" . in the source code replace +hardcoded filenames using temporary directories to calls to either +mktemp or tempfile in shell +scripts, in Perl scripts, +and in C/C++. You can also use + to assist to the security code review phase.

+ +

When packaging software make sure that: + + + +The software runs with the minimum privileges it needs: + + +The package does install binaries setuid or setgid. +Lintian will warn of , + and binaries. + +The daemons the package provide run with a +low privilege user (see ) + + + +Programmed (i.e., cron) tasks running in the +system do NOT run as root or, if they do, do not implement complex +tasks. + + + +

If you have to do any of the above make sure the programs that +might run with higher privileges have been audited for security +bugs. If you are unsure, or need help, contact the . In the case of setuid/setgid binaries, follow the Debian +policy section regarding + +

+ +

For more information, specific to secure programming, make sure you +read (or point your upstream to) and the portal. For more information specific to Debian security you can +read the +

+ + + + + Creating users and groups for software daemons + +

If your software runs a daemon that does not need root privileges, +you need to create a user for it. There are two kind of Debian users +that can be used by packages: static uids (assigned by +base-passwd) and dynamic uids in the range assigned +to system users. + +

In the first case, you need to ask for a user or group id to the +base-passwd, and a proper versioned depends to the +base-passwd package that provides the user. + +

In the second case, you need to create the system user either in +the preinst or in the postinst and make the package +depend on adduser (>= 3.11). + +

The following example code creates the user and group the daemon +will run as when the package is installed or upgraded: + + +[...] +case "$1" in + install|upgrade) + + # If the package has default file it could be sourced, so that + # the local admin can overwrite the defaults + + [ -f "/etc/default/packagename" ] && . /etc/default/packagename + + + # Sane defaults: + + [ -z "$SERVER_HOME" ] && SERVER_HOME=server_dir + [ -z "$SERVER_USER" ] && SERVER_USER=server_user + [ -z "$SERVER_NAME" ] && SERVER_NAME="Server description" + [ -z "$SERVER_GROUP" ] && SERVER_GROUP=server_group + + # Groups that the user will be added to, if undefined, then none. + ADDGROUP="" + + + # create user to avoid running server as root + # 1. create group if not existing + if ! getent group | grep -q "^$SERVER_GROUP:" ; then + echo -n "Adding group $SERVER_GROUP.." + addgroup --quiet --system $SERVER_GROUP 2>/dev/null ||true + echo "..done" + fi + # 2. create homedir if not existing + test -d $SERVER_HOME || mkdir $SERVER_HOME + # 3. create user if not existing + if ! getent passwd | grep -q "^$SERVER_USER:"; then + echo -n "Adding system user $SERVER_USER.." + adduser --quiet \ + --system \ + --ingroup $SERVER_GROUP \ + --no-create-home \ + --disabled-password \ + $SERVER_USER 2>/dev/null || true + echo "..done" + fi + # 4. adjust passwd entry + usermod -c "$SERVER_NAME" \ + -d $SERVER_HOME \ + -g $SERVER_GROUP \ + $SERVER_USER + # 5. adjust file and directory permissions + if ! dpkg-statoverride --list $SERVER_HOME >/dev/null + then + chown -R $SERVER_USER:adm $SERVER_HOME + chmod u=rwx,g=rxs,o= $SERVER_HOME + fi + # 6. Add the user to the ADDGROUP group + if test -n $ADDGROUP + then + if ! groups $SERVER_USER | grep -q $ADDGROUP; then + adduser $SERVER_USER $ADDGROUP + fi + fi + ;; + configure) + +[...] + + +

You have to make sure that the init.d script file: + + +Starts the daemon dropping privileges, if the software does not +do the or call itself, you can use the --chuid +call of start-stop-daemon. + +Stops the daemon only if the user id matches, you can use the +start-stop-daemon --user option +for this. + +Does not run if either the user or the group do not exist: + + if getent passwd | grep -q "^server_user:"; then + echo "Server user does not exist. Aborting" >&2 + exit 1 + fi + if getent group | grep -q "^server_group:" ; then + echo "Server group does not exist. Aborting" >&2 + exit 1 + fi + + + + +

If the package creates the system user it can remove it when it is +purged in its postrm, this has some drawbacks +For example, files created by it will be orphaned +and might be taken over by a new system user in the future if it is +assigned the same uid. Some relevant threads discussing these +drawbacks include + +and + + +so this is not mandatory and depends on the +package needs. If unsure, it could be handled by asking the +administrator for the prefered action when the package is installed +(see ). The following example code removes the user +and groups created before only, and only if, the uid is in the range of +dynamic assigned system uids and the gid is belongs to a system group: + + +case "$1" in + purge) +[...] + # find first and last SYSTEM_UID numbers + for LINE in `grep SYSTEM_UID /etc/adduser.conf | grep -v "^#"`; do + case $LINE in + FIRST_SYSTEM_UID*) + FIST_SYSTEM_UID=`echo $LINE | cut -f2 -d '='` + ;; + LAST_SYSTEM_UID*) + LAST_SYSTEM_UID=`echo $LINE | cut -f2 -d '='` + ;; + *) + ;; + esac + done + # Remove system account if necessary + CREATEDUSER="server_user" + if [ -n "$FIST_SYSTEM_UID" ] && [ -n "$LAST_SYSTEM_UID" ]; then + if USERID=`getent passwd $CREATEDUSER | cut -f 3 -d ':'`; then + if [ -n "$USERID" ]; then + if [ "$FIST_SYSTEM_UID" -le "$USERID" ] && \ + [ "$USERID" -le "$LAST_SYSTEM_UID" ]; then + echo -n "Removing $CREATEDUSER system user.." + deluser --quiet $CREATEDUSER || true + echo "..done" + fi + fi + fi + fi + # Remove system group if necessary + CREATEDGROUP=server_group + FIRST_USER_GID=`grep ^USERS_GID /etc/adduser.conf | cut -f2 -d '='` + if [ -n "$FIST_USER_GID" ] then + if GROUPGID=`getent group $CREATEDGROUP | cut -f 3 -d ':'`; then + if [ -n "$GROUPGID" ]; then + if [ "$FIST_USER_GID" -gt "$GROUPGID" ]; then + echo -n "Removing $CREATEDGROUP group.." + delgroup --only-if-empty $CREATEDGROUP || true + echo "..done" + fi + fi + fi + fi +[...] + + +

Running programs with a user with limited privileges makes sure +that any security issue with the program makes limited damaged to the +system and follows the principle of least privilege you can +limit privileges in programs through other mechanisms besides running +as non-root. Fore more information, read the chapter of the Secure Programming for +Linux and Unix HOWTO book. + + + + Configuration management with debconf