doc/en/security.sgml
1998-05-27 09:23:45 +00:00

226 lines
9.4 KiB
Text

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN" [
<!ENTITY date "$Date: 1998-05-27 09:23:45 $">
<!ENTITY title "FreeBSD Security Guide">
<!ENTITY % includes SYSTEM "includes.sgml"> %includes;
]>
<!-- $Id: security.sgml,v 1.8 1998-05-27 09:23:45 wosch Exp $ -->
<HTML>
&header;
<H1>FreeBSD Security Guide</H1>
<em>Last Updated: $Date: 1998-05-27 09:23:45 $ </em>
<P>This guide attempts to document some of the tips and tricks used by
many FreeBSD security experts for securing systems and writing secure
code. It is designed to help you learn about the various ways of protecting
a FreeBSD system against outside attack and how to recover from such attacks
if and when they should happen. It also lists the various ways in which
the systems programmer can become more security conscious and less likely
to introduce security holes in the first place.
<p>We welcome your comments on the contents and correctness of this page.
Please send email to <a href="mailto:security-officer@freebsd.org">the
FreeBSD Security Officers</a> if you have changes you'd like to see here.
<H2>How to secure a FreeBSD system:</H2>
<UL>
<LI>XXX This section needs to be written.
</UL>
<H2>How to recover from a security compromise </H2>
<UL>
<LI>XXX This section also needs to be written.
</UL>
<H2>Security Do's and Don'ts for Programmers:</H2>
<P><UL>
<LI><A NAME="#rule1"></A>Never trust any source of input, i.e. command line
arguments, environment variables, configuration files, incoming UDP packets,
hostname lookups, function arguments, etc. If the length or contents of
the data received is at all subject to outside control then the program
or function should watch for this when copying it around. Specific
security issues to watch for in this area are:
<P><UL>
<LI><A NAME="#rule1_1"></A>
<a href="http://www.freebsd.org/cgi/man.cgi?strcpy(3)">
strcpy(3)</a> and <a
href="http://www.freebsd.org/cgi/man.cgi?sprintf(3)">
sprintf(3)</a> calls from
unbounded data. Use
<a href="http://www.freebsd.org/cgi/man.cgi?strncpy(3)">
strncpy(3)</a> and
<a href="http://www.freebsd.org/cgi/man.cgi?snprintf(3)">
snprintf(3)</a> when the length is known
(or implement some other form of bounds-checking when it's not).
In fact, never use
<a href="http://www.freebsd.org/cgi/man.cgi?gets(3)">gets(3)</a>
or
<a href="http://www.freebsd.org/cgi/man.cgi?sprintf(3)">
sprintf(3)</a>, period.
<P><LI><A NAME="#rule1_2"></A>Watch for
<a href="http://www.freebsd.org/cgi/man.cgi?strvis(3)">strvis(3)</a>
and <a href="http://www.freebsd.org/cgi/man.cgi?getenv(3)">getenv(3)</a>
abuse.
<a href="http://www.freebsd.org/cgi/man.cgi?strvis(3)">strvis(3)</a>
is easy to get the destination string wrong for, and
<a href="http://www.freebsd.org/cgi/man.cgi?getenv(3)">getenv(3)</a>
can return strings much longer than the user might expect - they are
one of the key ways an attack is often made on a program, causing it
to overwrite stack or variables by setting its environment variables
to unexpected values. If your program reads environment variables,
be paranoid!
<P><LI>Every time you see an
<a href="http://www.freebsd.org/cgi/man.cgi?open(2)">open(2)</a>
or
<a href="http://www.freebsd.org/cgi/man.cgi?stat(2)">stat(2)</a>
call, ask yourself, "What
if it's a symbolic link?"
<P><LI><A NAME="#rule1_3"></A>All uses of
<a href="http://www.freebsd.org/cgi/man.cgi?mktemp(3)">
mktemp(3)</a>, <a
href="http://www.freebsd.org/cgi/man.cgi?tempnam(3)">
tempnam</a>, <a
href="http://www.freebsd.org/cgi/man.cgi?mkstemp(3)">
mkstemp(3)</a>,
etc.; make sure that they use
<a href="http://www.freebsd.org/cgi/man.cgi?mkstemp(3)">
mkstemp(3)</a> instead. Also look for races in
/tmp in general, being aware that there are very few things can be atomic
in /tmp:
<UL>
<LI>Creating a directory. This will either succeed or fail.
<LI>Opening a file O_CREAT | O_EXCL
</UL>
<a href="http://www.freebsd.org/cgi/man.cgi?mkstemp(3)">
mkstemp(3)</a> properly handles this for you, so all temp files should
use mkstemp to guarantee there's no race and that the permissions
are right.
<P><LI><A NAME="#rule1_4"></A>If an attacker can force packets to go/come
from another arbitrary system then that hacker has complete control
over the data that we get and *NONE* of it should be trusted.
<P><LI><A NAME="#rule1_5"></A>Understand the differences between uid,
euid and svuid in 2.1 and 2.2. We sure don't. [XXX but we should find out
and fill this in after talking to Bruce]
<P><LI><A NAME="#rule1_6"></A>Never trust that a config file is correctly
formatted or that it was generated by the appropriate utility. If there
is some chance for being sneaky, then some twisted cracker will try
to be sneaky: Don't trust user input like terminal names or language
strings to be free of '/' or ../../... embedded if there is any chance
that they can be used in a path name. Don't trust *ANY* paths supplied
by the user when you are running setuid root.
<P><LI><A NAME="#rule1_7"></A>Look for holes or weaknesses in how data
is stored. All temp files should be 600 permission.
<P><LI><A NAME="#rule1_8"></A>Don't just grep for the usual suspects
in programs which run at elevated privs. Look line by line for possible
overflows in these cases since there are a lot more ways than
<a href="http://www.freebsd.org/cgi/man.cgi?strcpy(3)">
strcpy(3)</a>
and friends to cause buffer overflows.
<P><LI><A NAME="#rule1_9"></A>Just because you drop privs somewhere doesn't
necessarily mean that no exploit is possible. The attacker may put the
necessary code on the stack to regain them before execing /bin/sh.
</UL>
<P><LI><A NAME="#rule2"></A>Do uid management. So drop privs as soon as possible,
and really drop them. Switching between euid and uid is not enough. Use
<a href="http://www.freebsd.org/cgi/man.cgi?setuid(2)">setuid(2)</a>
when you can.
<P><LI><A NAME="#rule3"></A>Never display configuration file contents on errors.
A line number and perhaps position count is enough. This is true for all
libs and for any SUID/SGID program.
<P><LI><A NAME="#rule4"></A>Tips for those reviewing existing code for security
problems:
<P><UL>
<LI><A NAME="#rule4_1"></A>If you're unsure of your security fixes, send them
to a reviewer with whom you've already made arrangements for a second glance
over. Don't commit code you're not sure of since breaking something in
the name of securing it is rather embarrassing. :)
<P><LI><A NAME="#rule4_2"></A>Those without CVS commit privileges should make
sure that at a reviewer with such privileges is among the last to review the
changes. That person will both review and incorporate the final version
you would like to have go into the tree.
<P><LI><A NAME="#rule4_3"></A>When sending changes around for review, always
use context or unidiff format diffs which may be easily fed to
<a href="http://www.freebsd.org/cgi/man.cgi?patch(1)">patch(1)</a>.
Do not simply send whole files! Diffs are much easier to read and apply to
local sources (especially those in which multiple, simultaneous changes
may be taking place). All changes should be relative to 3.0-current
just so we can all be working from a common base, unless there is strong
reason in a specific instance to do otherwise.
<P><LI><A NAME="#rule4_4"></A>Always directly test your changes (e.g. build and
run the affected module(s)) before sending them to a reviewer; no one likes
being sent obviously broken stuff for review, and it just makes it appear
as though the submitter didn't even really look at what he was
doing (which is hardly confidence-building). If you need accounts
on a 2.1, 2.2 or 3.0 machine in order to do proper testing, just
ask - the project has such resources available for just such
purposes.
<P><LI><A NAME="#rule4_5"></A>For committers: Be sure to retrofit -current
patches into the 2.2 and 2.1 branches as appropriate.
<P><LI><A NAME="#rule4_6"></A>Do not needlessly rewrite code to suit
your style/tastes - it only makes the reviewer's job needlessly more
difficult. Do so only if there are clear technical reasons for it.
</UL>
<P><LI><A NAME="#rule5"></A>Look out for programs doing complex things in
signal handlers. Many routines in the various libraries are not
sufficiently reentrant to make this safe.
<P><LI><A NAME="#rule6"></A>Pay special attention to
<a href="http://www.freebsd.org/cgi/man.cgi?realloc(3)">
realloc(3)</a> usage - more
often than not, it's not done correctly.
<P><LI>When using fixed-size buffers, use sizeof() to prevent lossage when
a buffer size is changed but the code which uses it isn't. For example:
<LISTING>
char buf[1024];
struct foo { ... };
...
BAD:
xxx(buf, 1024)
xxx(yyy, sizeof(struct foo))
GOOD:
xxx(buf, sizeof(buf))
xxx(yyy, sizeof(yyy))
</LISTING>
<P><LI>Every time you see "char foo[###]", check every usage of foo to
make sure it can't be overflowed. If you can't avoid overflow
(and cases of this have been seen) then at least malloc the buffer
so you can't walk on the stack.
<P><LI>Always close file descriptors as soon as you can -- this makes it
more likely that the stdio buffer contents will be discarded. In
library routines, always set any file descriptors that you open to
close-on-exec.
<P>
</UL>
&footer;
</BODY>
</HTML>