mirror of https://github.com/tLDP/LDP
8367 lines
311 KiB
Plaintext
8367 lines
311 KiB
Plaintext
<!DOCTYPE Book PUBLIC "-//Davenport//DTD DocBook V3.0//EN">
|
||
|
||
<!-- "Secure Programming for Linux and Unix HOWTO",
|
||
Copyright (C) 2000 David A. Wheeler
|
||
http://www.dwheeler.com/secure-programs -->
|
||
|
||
|
||
<!-- This is a sample comment.
|
||
This document has more titles than I'd like to think about. It was
|
||
originally titled "How to Write Secure Programs for Linux", then
|
||
"Design and Implementation Guidelines for Secure Linux Applications".
|
||
I first released it widely as the
|
||
"Secure Programming for Linux HOWTO", and then it morphed into the
|
||
"Secure Programming for Linux and Unix HOWTO".
|
||
|
||
You can get the latest version of this document from:
|
||
http://www.dwheeler.com/secure-programs/
|
||
|
||
Note that this is the DocBook DTD version!
|
||
To process it, get DocBook tools. If you are using Cygnus's tools, do this:
|
||
db2html Secure*.sgml
|
||
db2ps Secure*.sgml
|
||
|
||
Earlier versions through version 1.60 used the Linuxdoc DTD;
|
||
Version 2.00 has the same content as 1.60, but in DocBook foramat.
|
||
While the document is now legal DocBook content, it's not "fully"
|
||
marked-up; suggestions on missing markings welcome.
|
||
|
||
|
||
-->
|
||
|
||
|
||
<book>
|
||
|
||
<bookinfo>
|
||
|
||
<!-- bookbiblio -->
|
||
|
||
<title>Secure Programming for Linux and Unix HOWTO</title>
|
||
<author>
|
||
<firstname>David</firstname> <othername role="mi">A.</othername><surname>Wheeler</surname>
|
||
</author>
|
||
<address><email>dwheeler@dwheeler.com</email></address>
|
||
<pubdate>31 July 2000</pubdate>
|
||
<edition>Version 2.31</edition>
|
||
<copyright>
|
||
<year>1999</year>
|
||
<year>2000</year>
|
||
<holder>David A. Wheeler</holder>
|
||
</copyright>
|
||
|
||
<legalnotice>
|
||
<para>
|
||
This document is Copyright (C) 1999-2000 David A. Wheeler.
|
||
Permission is granted to copy, distribute and/or modify
|
||
this document under the terms of the GNU Free Documentation License (GFDL),
|
||
Version 1.1 or any later version published by the Free Software Foundation;
|
||
with the invariant sections being ``About the Author'',
|
||
with no Front-Cover Texts, and no Back-Cover texts.
|
||
A copy of the license is included in the section entitled
|
||
"GNU Free Documentation License".
|
||
This document is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||
</para>
|
||
</legalnotice>
|
||
|
||
<abstract>
|
||
<para>
|
||
This paper provides a set of design and implementation
|
||
guidelines for writing secure programs for Linux and Unix systems.
|
||
Such programs include application programs used as viewers of remote data,
|
||
web applications (including CGI scripts),
|
||
network servers, and setuid/setgid programs.
|
||
Specific guidelines for C, C++, Java, Perl, Python, TCL,
|
||
and Ada95 are included.
|
||
</para>
|
||
</abstract>
|
||
|
||
<!-- /bookbiblio -->
|
||
<keywordset>
|
||
<keyword>secure</keyword>
|
||
<keyword>programming</keyword>
|
||
<keyword>secure programs</keyword>
|
||
<keyword>secure applications</keyword>
|
||
<keyword>security</keyword>
|
||
<keyword>Linux</keyword>
|
||
<keyword>Unix</keyword>
|
||
<keyword>hack</keyword>
|
||
<keyword>crack</keyword>
|
||
<keyword>vulnerability</keyword>
|
||
<keyword>buffer overflow</keyword>
|
||
<keyword>design</keyword>
|
||
<keyword>implementation</keyword>
|
||
<keyword>web application</keyword>
|
||
<keyword>web applications</keyword>
|
||
<keyword>CGI</keyword>
|
||
<keyword>setuid</keyword>
|
||
<keyword>setgid</keyword>
|
||
<keyword>C</keyword>
|
||
<keyword>C++</keyword>
|
||
<keyword>Java</keyword>
|
||
<keyword>Perl</keyword>
|
||
<keyword>Python</keyword>
|
||
<keyword>TCL</keyword>
|
||
<keyword>Ada</keyword>
|
||
<keyword>Ada95</keyword>
|
||
</keywordset>
|
||
|
||
</bookinfo>
|
||
|
||
<!-- Begin the document -->
|
||
|
||
|
||
<chapter>
|
||
<title>Introduction</title>
|
||
|
||
<epigraph>
|
||
<attribution>Proverbs 21:22 (NIV)</attribution>
|
||
<para>
|
||
A wise man attacks the city of the mighty
|
||
and pulls down the stronghold in which they trust.
|
||
</para>
|
||
</epigraph>
|
||
|
||
<para>
|
||
This paper describes a set of design and implementation guidelines for
|
||
writing secure programs on Linux and Unix systems.
|
||
For purposes of this paper, a ``secure program'' is a program
|
||
that sits on a security boundary, taking input from a source that does
|
||
not have the same access rights as the program.
|
||
Such programs include application programs used as viewers of remote data,
|
||
web applications (including CGI scripts),
|
||
network servers, and setuid/setgid programs.
|
||
This paper does not address modifying the operating system kernel itself,
|
||
although many of the principles discussed here do apply.
|
||
These guidelines were developed as a survey of
|
||
``lessons learned'' from various sources on how to create such programs
|
||
(along with additional observations by the author),
|
||
reorganized into a set of larger principles.
|
||
This paper includes specific guidance for a number of languages,
|
||
including C, C++, Java, Perl, Python, TCL, and Ada95.
|
||
</para>
|
||
|
||
<para>
|
||
This paper does not cover assurance measures, software engineering
|
||
processes, and quality assurance approaches,
|
||
which are important but widely discussed elsewhere.
|
||
Such measures include testing, peer review,
|
||
configuration management, and formal methods.
|
||
Documents specifically identifying sets of development
|
||
assurance measures for security issues include
|
||
the Common Criteria [CC 1999]
|
||
and the
|
||
System Security Engineering Capability Maturity Model [SSE-CMM 1999].
|
||
More general sets of software engineering methods or processes
|
||
are defined in documents such as the
|
||
Software Engineering Institute's Capability Maturity Model for Software
|
||
(SE-CMM), ISO 9000 (along with ISO 9001 and ISO 9001-3), and ISO 12207.
|
||
<!-- ??? Ideally have references for these. -->
|
||
</para>
|
||
|
||
<para>
|
||
This paper does not discuss how to configure a system (or network)
|
||
to be secure in a given environment. This is clearly necessary for
|
||
secure use of a given program,
|
||
but a great many other documents discuss secure configurations.
|
||
An excellent general book on configuring Unix-like systems to be
|
||
secure is Garfinkel [1996].
|
||
Other books for securing Unix-like systems include Anonymous [1998].
|
||
You can also find information on configuring Unix-like systems at web sites
|
||
such as
|
||
<ulink url="http://www.unixtools.com/security.html">http://www.unixtools.com/security.html</ulink>.
|
||
Information on configuring a Linux system to be secure is available in a
|
||
wide variety of documents including
|
||
Fenzi [1999], Seifried [1999], Wreski [1998], and Anonymous [1999].
|
||
For Linux systems (and eventually other Unix-like systems),
|
||
you may want to examine the Bastille Hardening System, which
|
||
attempts to ``harden'' or ``tighten'' the Linux operating system.
|
||
You can learn more about Bastille at
|
||
<ulink url="http://www.bastille-linux.org">http://www.bastille-linux.org</ulink>;
|
||
it is available for free under the General Public License (GPL).
|
||
</para>
|
||
|
||
<para>
|
||
This paper assumes that the reader understands computer
|
||
security issues in general, the general security model of Unix-like systems,
|
||
and the C programming language.
|
||
This paper does include some information about the Linux and Unix
|
||
programming model for security.
|
||
</para>
|
||
|
||
<para>
|
||
This paper covers all Unix-like systems, including Linux and the
|
||
various strains of Unix, and it particularly stresses Linux and provides
|
||
details about Linux specifically.
|
||
There are several reasons for this, but a simple reason is popularity.
|
||
According to a 1999 survey by IDC,
|
||
significantly more servers (counting both Internet and intranet servers)
|
||
were installed in 1999 with Linux than with all
|
||
Unix operating system types combined (25% for Linux versus
|
||
15% for all Unix system types combined; note that
|
||
Windows NT came in with 38% compared to the 40% of all Unix-like servers)
|
||
[Shankland 2000].
|
||
<!-- http://news.cnet.com/news/0-1003-200-1549312.html -->
|
||
A survey by Zoebelein in April 1999 found that, of the total number of
|
||
servers deployed on the Internet in 1999
|
||
(running at least ftp, news, or http (WWW)), the majority were running
|
||
Linux (28.5%), with others trailing (24.4% for all Windows 95/98/NT
|
||
combined, 17.7% for Solaris or SunOS,
|
||
15% for the BSD family, and 5.3% for IRIX).
|
||
Advocates will notice that the majority of servers on the Internet
|
||
(around 66%) were running Unix-like
|
||
systems, while only around 24% ran a Microsoft Windows variant.
|
||
<!-- http://www.leb.net/hzo/ioscount -->
|
||
<!-- Other surveys of the Internet are interesting but don't shed light
|
||
on this issue. E.G. The Internet Domain Survey at http://www.isc.org/ds
|
||
tries to find every host, but doesn't id who runs what -->
|
||
Finally, the original version of this document only discussed Linux, so
|
||
although its scope has expanded, the Linux information is still
|
||
noticeably dominant.
|
||
If you know relevant information not already included here, please let
|
||
me know.
|
||
</para>
|
||
|
||
<para>
|
||
You can find the master copy of this document at
|
||
<ulink url="http://www.dwheeler.com/secure-programs">http://www.dwheeler.com/secure-programs</ulink>.
|
||
This document is also part of the Linux Documentation Project (LDP) at
|
||
<ulink
|
||
url="http://www.linuxdoc.org">http://www.linuxdoc.org</ulink>
|
||
It's also mirrored in several other places.
|
||
Please note that these mirrors, including the LDP copy and/or the
|
||
copy in your distribution, may be older than the master copy.
|
||
I'd like to hear comments on this document, but please do not send comments
|
||
until you've checked to make sure that your comment is valid for the
|
||
latest version.
|
||
</para>
|
||
|
||
<para>
|
||
This document is (C) 1999-2000 David A. Wheeler and is covered by the
|
||
GNU Free Documentation License (GFDL);
|
||
see the last section for more information.
|
||
</para>
|
||
|
||
<para>
|
||
This paper first discusses the background of Unix, Linux, and security.
|
||
The next section describes the general Unix and Linux security model,
|
||
giving an overview of the security attributes and operations of
|
||
processes, filesystem objects, and so on.
|
||
This is followed by the meat of this paper, a set of design and implementation
|
||
guidelines for developing applications on Linux and Unix systems.
|
||
The paper ends with conclusions, a lengthy bibliography, and appendices.
|
||
</para>
|
||
|
||
<!-- ???: Put a picture here -->
|
||
<!-- ???: Reference other taxonomies, such as Bisbey's at
|
||
http://seclab.cs.ucdavis.edu/projects/history/papers/bisb78.pdf
|
||
and see if I should (partially) switch to one of them.
|
||
-->
|
||
<para>
|
||
The design and implementation guidelines are divided into
|
||
categories which I believe emphasize the programmer's viewpoint.
|
||
Programs accept inputs, process data, call out to other resources,
|
||
and produce output; notionally all security guidelines
|
||
fit into one of these categories.
|
||
I've divided processing data into further categories:
|
||
avoiding buffer overflows (which in some cases can also be considered
|
||
an input issue),
|
||
structuring program internals and approach,
|
||
language-specific information, and special topics.
|
||
The actual chapter layout was reordered slightly to be easier to follow.
|
||
Thus, the document chapters on guidelines discuss
|
||
validating all input, avoiding buffer overflows,
|
||
structuring program internals and approach,
|
||
carefully calling out to other resources,
|
||
judiciously sending information back, language-specific
|
||
information, and finally information on
|
||
special topics (such as how to acquire random numbers).
|
||
</para>
|
||
|
||
</chapter>
|
||
|
||
<chapter>
|
||
<title>Background</title>
|
||
|
||
<epigraph>
|
||
<attribution>Ezra 4:19 (NIV)</attribution>
|
||
<para>
|
||
I issued an order and a search was made, and it was found that this
|
||
city has a long history of revolt against kings and has been
|
||
a place of rebellion and sedition.
|
||
</para>
|
||
</epigraph>
|
||
|
||
<sect1>
|
||
<title>History of Unix, Linux, and Open Source Software</title>
|
||
|
||
<sect2>
|
||
<title>Unix</title>
|
||
|
||
<para>
|
||
In 1969-1970, Kenneth Thompson, Dennis Ritchie, and others at
|
||
AT&T Bell Labs began developing
|
||
a small operating system on a little-used PDP-7.
|
||
The operating system was soon christened Unix, a pun on an earlier operating
|
||
system project called MULTICS.
|
||
In 1972-1973 the system was rewritten in the programming language C,
|
||
an unusual step that was visionary: due to this decision, Unix was
|
||
the first widely-used operating system that
|
||
could switch from and outlive its original hardware.
|
||
Other innovations were added to Unix as well, in part due to synergies
|
||
between Bell Labs and the academic community.
|
||
In 1979, the ``seventh edition'' (V7) version
|
||
of Unix was released, the grandfather of all extant Unix systems.
|
||
</para>
|
||
|
||
<para>
|
||
After this point, the history of Unix becomes somewhat convoluted.
|
||
The academic community, led by Berkeley, developed a variant called the
|
||
Berkeley Software Distribution (BSD), while AT&T continued developing
|
||
Unix under the names ``System III'' and later ``System V''.
|
||
In the late 1980's through early 1990's
|
||
the ``wars'' between these two major strains raged.
|
||
After many years each variant adopted many of the key features of the other.
|
||
Commercially, System V won the ``standards wars'' (getting most of its
|
||
interfaces into the formal standards), and
|
||
most hardware vendors switched to AT&T's System V.
|
||
However, System V ended up incorporating many BSD innovations, so the
|
||
resulting system was more a merger of the two branches.
|
||
The BSD branch did not die, but instead became widely used
|
||
for research, for PC hardware, and for
|
||
single-purpose servers (e.g., many web sites use a BSD derivative).
|
||
</para>
|
||
|
||
<para>
|
||
The result was many different versions of Unix,
|
||
all based on the original seventh edition.
|
||
Most versions of Unix were proprietary and maintained by their respective
|
||
hardware vendor, for example, Sun Solaris is a variant of System V.
|
||
Three versions of the BSD branch of Unix ended up as open source:
|
||
FreeBSD (concentating on ease-of-installation for PC-type hardware),
|
||
NetBSD (concentrating on many different CPU architectures), and
|
||
a variant of NetBSD, OpenBSD (concentrating on security).
|
||
More general information can be found at
|
||
<ulink
|
||
url="http://www.datametrics.com/tech/unix/uxhistry/brf-hist.htm">http://www.datametrics.com/tech/unix/uxhistry/brf-hist.htm</ulink>.
|
||
Much more information about the BSD history can be found in
|
||
[McKusick 1999] and
|
||
<ulink
|
||
url="ftp://ftp.freebsd.org/pub/FreeBSD/FreeBSD-current/src/share/misc/bsd-family-tree">ftp://ftp.freebsd.org/pub/FreeBSD/FreeBSD-current/src/share/misc/bsd-family-tree</ulink>.
|
||
</para>
|
||
|
||
<para>
|
||
Those interested in reading an advocacy piece that presents arguments
|
||
for using Unix-like systems should see
|
||
<ulink
|
||
url="http://www.unix-vs-nt.org">http://www.unix-vs-nt.org</ulink>.
|
||
</para>
|
||
|
||
</sect2>
|
||
|
||
<sect2>
|
||
<title>Free Software Foundation</title>
|
||
|
||
<para>
|
||
In 1984 Richard Stallman's Free Software Foundation (FSF) began the GNU
|
||
project, a project to create a free version of the Unix operating system.
|
||
By free, Stallman meant software that could be freely
|
||
used, read, modified, and redistributed.
|
||
The FSF successfully built a vast number of
|
||
useful components, including a C compiler (gcc), an
|
||
impressive text editor (emacs), and a host of fundamental tools.
|
||
However, in the 1990's the FSF
|
||
was having trouble developing the operating system kernel [FSF 1998];
|
||
without a kernel the rest of their software would not work.
|
||
</para>
|
||
|
||
</sect2>
|
||
|
||
<sect2>
|
||
<title>Linux</title>
|
||
|
||
<para>
|
||
In 1991 Linus Torvalds began developing an operating system kernel, which
|
||
he named ``Linux'' [Torvalds 1999].
|
||
This kernel could be combined with the FSF material and other components
|
||
(in particular some of the BSD components and MIT's X-windows software) to
|
||
produce a freely-modifiable and very useful operating system.
|
||
This paper will term the kernel itself the ``Linux kernel'' and
|
||
an entire combination as ``Linux''.
|
||
Note that many use the term ``GNU/Linux'' instead for this combination.
|
||
</para>
|
||
|
||
<para>
|
||
In the Linux community,
|
||
different organizations have combined the available components differently.
|
||
Each combination is called a ``distribution'', and the organizations that
|
||
develop distributions are called ``distributors''.
|
||
Common distributions include Red Hat, Mandrake, SuSE, Caldera, Corel,
|
||
and Debian.
|
||
There are differences between the various distributions,
|
||
but all distributions are based on the same foundation: the
|
||
Linux kernel and the GNU glibc libraries.
|
||
Since both are covered by ``copyleft'' style licenses, changes to
|
||
these foundations generally must be made available to all, a
|
||
unifying force between the Linux distributions at their foundation
|
||
that does not exist between the BSD and AT&T-derived Unix systems.
|
||
This paper is not specific to any Linux distribution; when it
|
||
discusses Linux it presumes Linux
|
||
kernel version 2.2 or greater and the C library glibc 2.1 or greater,
|
||
valid assumptions for essentially all current major
|
||
Linux distributions.
|
||
</para>
|
||
|
||
</sect2>
|
||
|
||
<sect2>
|
||
<title>Open Source Software</title>
|
||
|
||
<para>
|
||
Increased interest in software that is freely shared
|
||
has made it increasingly necessary to define and explain it.
|
||
A widely used term is ``open source software'', which is further defined in
|
||
[OSI 1999].
|
||
Eric Raymond [1997, 1998] wrote several seminal articles examining
|
||
its various development processes.
|
||
Another widely-used term is ``free software'', where the ``free''
|
||
is short for ``freedom'': the usual explanation is ``free speech, not
|
||
free beer.''
|
||
Neither phrase is perfect.
|
||
The term
|
||
``free software'' is often confused with programs whose executables are
|
||
given away at no charge, but whose source code cannot be viewed, modified,
|
||
or redistributed.
|
||
Conversely, the term ``open source'' is sometime (ab)used
|
||
to mean software whose
|
||
source code is visible, but for which there are limitations on
|
||
use, modification, or redistribution.
|
||
This paper uses the term ``open source'' for its usual meaning, that
|
||
is, software which has its source code freely available for
|
||
use, viewing, modification, and redistribution; a more detailed
|
||
definnition is contained in the
|
||
<ulink
|
||
url="http://www.opensource.org/osd.html">Open Source Definition</ulink>.
|
||
In some cases, a difference in motive is suggested;
|
||
those preferring the term ``free software'' wish to strongly
|
||
emphasize the need for freedom, while those using the term may have
|
||
other motives (e.g., higher reliability) or simply wish to appear less
|
||
strident.
|
||
</para>
|
||
|
||
<para>
|
||
Those interested in reading advocacy pieces for open source software
|
||
and free software should see
|
||
<ulink
|
||
url="http://www.opensource.org">http://www.opensource.org</ulink> and
|
||
<ulink
|
||
url="http://www.fsf.org">http://www.fsf.org</ulink>.
|
||
There are other papers which examine such software, for example,
|
||
Miller [1995]
|
||
found that the open source software were noticeably
|
||
more reliable than proprietary software
|
||
(using their measurement technique, which measured
|
||
resistance to crashing due to random input).
|
||
</para>
|
||
|
||
</sect2>
|
||
|
||
<sect2>
|
||
<title>Comparing Linux and Unix</title>
|
||
|
||
<para>
|
||
This paper uses the term ``Unix-like'' to describe
|
||
systems intentionally like Unix.
|
||
In particular, the term ``Unix-like'' includes
|
||
all major Unix variants and Linux distributions.
|
||
</para>
|
||
|
||
<para>
|
||
Linux is not derived from Unix source code, but its interfaces are
|
||
intentionally like Unix.
|
||
Therefore, Unix lessons learned generally apply to both, including information
|
||
on security.
|
||
Most of the information in this paper applies to any Unix-like system.
|
||
Linux-specific information has been intentionally added to
|
||
enable those using Linux to take advantage of Linux's capabilities.
|
||
</para>
|
||
|
||
<para>
|
||
Unix-like systems share a number of security mechanisms, though there
|
||
are subtle differences and not all systems have all mechanisms available.
|
||
All include user and group ids (uids and gids) for each process and
|
||
a filesystem with read, write, and execute permissions (for user, group, and
|
||
other).
|
||
<!-- ???: Most include System V single-machine
|
||
inter-process communication (IPC) mechanisms
|
||
and BSD's socket-based IPC (which support networks). -->
|
||
See Thompson [1974] and Bach [1986]
|
||
for general information on Unix systems, including their basic
|
||
security mechanisms.
|
||
Section 3 summarizes key Unix and Linux security mechanisms.
|
||
<!-- ???: This is cheating; switch eventually to a real cross-reference -->
|
||
</para>
|
||
|
||
</sect2>
|
||
|
||
</sect1>
|
||
|
||
<sect1>
|
||
<title>Security Principles</title>
|
||
|
||
<para>
|
||
There are many general security principles which you should be
|
||
familiar with; consult a general text on computer security such as
|
||
[Pfleeger 1997].
|
||
Often computer security goals are described in terms of three
|
||
overall goals:
|
||
|
||
<itemizedlist>
|
||
<listitem>
|
||
|
||
<para>
|
||
<emphasis remap="it">Confidentiality</emphasis> (also known as secrecy), meaning that the
|
||
computing system's assets are accessible only by authorized parties.
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
|
||
<para>
|
||
<emphasis remap="it">Integrity</emphasis>, meaning that the assets can only be modified by
|
||
authorized parties in authorized ways.
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
|
||
<para>
|
||
<emphasis remap="it">Availability</emphasis>, meaning that the assets are accessible to the
|
||
authorized parties.
|
||
This goal is often referred to by its antonym, denial of service.
|
||
</para>
|
||
</listitem>
|
||
|
||
</itemizedlist>
|
||
|
||
|
||
Some people define additional security goals, while others lump those
|
||
additional goals as special cases of these three goals.
|
||
For example, some separately
|
||
identify non-repudiation as a goal; this is
|
||
the ability to ``prove'' that a sender sent or receiver received a message,
|
||
even if the sender or receiver wishes to deny it later.
|
||
Privacy is sometimes addressed separately from confidentiality;
|
||
some define this as protecting the confidentiality of a
|
||
<emphasis>user</emphasis> (e.g., their identity) instead of the data.
|
||
Most goals require identification and authentication, which is
|
||
sometimes listed as a separate goal.
|
||
Often auditing (also called accountability) is identified
|
||
as a desirable security goal.
|
||
Sometimes ``access control'' and ``authenticity'' are listed separately
|
||
as well.
|
||
In any case, it is important to identify your program's overall
|
||
security goals, no matter how you group those goals together,
|
||
so that you'll know when you've met them.
|
||
</para>
|
||
|
||
<!-- ???: Reference other classics? Orange Book? CC? See
|
||
http://seclab.cs.ucdavis.edu/projects/history/seminal.html
|
||
|
||
Reference other Computer security websites and issues, including:
|
||
http://www.centralwebs.co.uk/Links/secure.html
|
||
Maximum Security's appendix:
|
||
http://www.uzsci.net/documentation/Books/Max_Security/apa/apa.htm
|
||
-->
|
||
|
||
<para>
|
||
Saltzer [1974] and later Saltzer and Schroeder [1975]
|
||
list the following principles of the design of secure
|
||
protection systems, which are still valid:
|
||
|
||
<itemizedlist>
|
||
<listitem>
|
||
|
||
<para>
|
||
<emphasis remap="it">Least privilege</emphasis>.
|
||
Each user and program should operate using the fewest privileges possible.
|
||
This principle limits the damage from an accident, error, or attack.
|
||
It also reduces the number of potential interactions among privileged programs,
|
||
so unintentional,
|
||
unwanted, or improper uses of privilege are less likely to occur.
|
||
This idea can be extended to the internals of a program: only the smallest
|
||
portion of the program which needs those privileges should have them.
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
|
||
<para>
|
||
<emphasis remap="it">Economy of mechanism</emphasis>.
|
||
The protection system's design should be simple and
|
||
small as possible.
|
||
In their words,
|
||
``techniques such as line-by-line inspection of software and physical
|
||
examination of hardware that implements protection mechanisms are necessary.
|
||
For such techniques to be successful, a small and simple design is essential.''
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
|
||
<para>
|
||
<emphasis remap="it">Open design</emphasis>.
|
||
The protection mechanism must not depend on attacker ignorance.
|
||
Instead, the mechanism should be public, depending on the secrecy of
|
||
relatively few (and easily changeable) items like passwords or private keys.
|
||
An open design makes extensive public scrutiny possible, and it also
|
||
makes it possible for users to convince themselves that the system about
|
||
to be used is adequate.
|
||
Frankly, it isn't realistic to try to maintain secrecy for a system that
|
||
is widely distributed;
|
||
decompilers and subverted hardware can quickly expose any ``secrets''
|
||
in an implementation.
|
||
Bruce Schneier argues that smart engineers should ``demand
|
||
open source code for anything related to security'',
|
||
as well as ensuring that it receives widespread review and that
|
||
any identified problems are fixed [Schneier 1999].
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
|
||
<para>
|
||
<emphasis remap="it">Complete mediation</emphasis>.
|
||
Every access attempt must be checked; position the mechanism
|
||
so it cannot be subverted.
|
||
For example, in a client-server model, generally the server must do all
|
||
access checking because users can build or modify their own clients.
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
|
||
<para>
|
||
<emphasis remap="it">Fail-safe defaults (e.g., permission-based approach)</emphasis>.
|
||
The default should be denial of service, and the
|
||
protection scheme should then identify conditions under which
|
||
access is permitted.
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
|
||
<para>
|
||
<emphasis remap="it">Separation of privilege</emphasis>.
|
||
Ideally, access to objects should depend on more than one condition, so
|
||
that defeating one protection system won't enable complete access.
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
|
||
<para>
|
||
<emphasis remap="it">Least common mechanism</emphasis>.
|
||
Minimize the amount and
|
||
use of shared mechanisms (e.g. use of the /tmp or /var/tmp directories).
|
||
Shared objects provide potentially dangerous channels for information
|
||
flow and unintended interactions.
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
|
||
<para>
|
||
<emphasis remap="it">Psychological acceptability / Easy to use</emphasis>.
|
||
The human interface must be designed for ease of use so users will routinely
|
||
and automatically use the protection mechanisms correctly.
|
||
Mistakes will be reduced if
|
||
the security mechanisms closely match the user's mental image of
|
||
his or her protection goals.
|
||
</para>
|
||
</listitem>
|
||
|
||
</itemizedlist>
|
||
|
||
</para>
|
||
|
||
</sect1>
|
||
|
||
<sect1>
|
||
<title>Types of Secure Programs</title>
|
||
|
||
<para>
|
||
Many different types of programs may need to be secure programs
|
||
(as the term is defined in this paper).
|
||
Some common types are:
|
||
|
||
<itemizedlist>
|
||
<listitem>
|
||
<para>
|
||
Application programs used as viewers of remote data.
|
||
Programs used as viewers (such as word processors or file format viewers)
|
||
are often asked to view data sent remotely by an untrusted user
|
||
(this request may be automatically invoked by a web browser).
|
||
Clearly, the untrusted
|
||
user's input should not be allowed to cause the application
|
||
to run arbitrary programs.
|
||
It's usually unwise to support initialization macros (run when the data
|
||
is displayed); if you must, then you must create a secure sandbox
|
||
(a complex and error-prone task).
|
||
Be careful of issues such as buffer overflow, discussed later, which might
|
||
allow an untrusted user to force the viewer to run an arbitrary program.
|
||
</para>
|
||
</listitem>
|
||
|
||
<listitem>
|
||
<para>
|
||
Application programs used by the administrator (root).
|
||
Such programs shouldn't trust information that can be controlled
|
||
by non-administrators.
|
||
</para>
|
||
</listitem>
|
||
|
||
<listitem>
|
||
<para>
|
||
Local servers (also called daemons).
|
||
</para>
|
||
</listitem>
|
||
|
||
<listitem>
|
||
<para>
|
||
Network-accessible servers (sometimes called network daemons).
|
||
</para>
|
||
</listitem>
|
||
|
||
<listitem>
|
||
<para>
|
||
Web-based applications (including CGI scripts).
|
||
These are a special case of network-accessible servers, but they're
|
||
so common they deserve their own category.
|
||
Such programs are invoked indirectly via a web server, which filters out
|
||
some attacks but nevertheless leaves many attacks that must be withstood.
|
||
</para>
|
||
</listitem>
|
||
|
||
<listitem>
|
||
<para>
|
||
Applets (i.e., programs downloaded to the client for automatic execution).
|
||
This is something Java is especially famous for, though other languages
|
||
(such as Python) support mobile code as well.
|
||
There are several security viewpoints here; the implementor of the
|
||
applet infrastructure on the client side has to make sure that the
|
||
only operations allowed are ``safe'' ones, and the writer of an applet has
|
||
to deal with the problem of hostile hosts (in other words, you can't
|
||
normally trust the client).
|
||
There is some research attempting to deal with running applets on
|
||
hostile hosts, but frankly
|
||
I'm sceptical of the value of these approaches
|
||
and this subject is exotic enough that I don't cover it further here.
|
||
</para>
|
||
</listitem>
|
||
|
||
<listitem>
|
||
<para>
|
||
setuid/setgid programs.
|
||
These programs are invoked by a local user and, when executed, are
|
||
immediately granted the privileges of the program's owner and/or
|
||
owner's group.
|
||
In many ways these are the hardest programs to secure, because so many
|
||
of their inputs are under the control of the untrusted user and some
|
||
of those inputs are not obvious.
|
||
</para>
|
||
</listitem>
|
||
|
||
</itemizedlist>
|
||
|
||
</para>
|
||
|
||
<para>
|
||
This paper merges the issues of these different types of program into
|
||
a single set.
|
||
The disadvantage of this approach is that some of the issues identified
|
||
here don't apply to all types of programs.
|
||
In particular, setuid/setgid programs have many surprising inputs and several
|
||
of the guidelines here only apply to them.
|
||
However, things are not so clear-cut, because
|
||
a particular program may cut across these boundaries (e.g., a CGI script
|
||
may be setuid or setgid, or be configured in a way that has the same effect),
|
||
and some programs are divided into several executables each of which
|
||
can be considered a different ``type'' of program.
|
||
The advantage of considering all of these program types together is that we can
|
||
consider all issues without trying to apply an inappropriate category
|
||
to a program.
|
||
As will be seen, many of the principles apply to all programs that
|
||
need to be secured.
|
||
</para>
|
||
|
||
<para>
|
||
There is a slight bias in this paper towards programs written in
|
||
C, with some notes on other languages such as C++, Perl, Python, Ada95, and
|
||
Java.
|
||
This is because C is the most common language for
|
||
implementing secure programs on Unix-like systems
|
||
(other than CGI scripts, which tend to use Perl),
|
||
and most other languages' implementations call the C library.
|
||
This is not to imply that C is somehow the ``best'' language for this purpose,
|
||
and most of the principles described here apply regardless of the
|
||
programming language used.
|
||
</para>
|
||
|
||
</sect1>
|
||
|
||
<sect1>
|
||
<title>Paranoia is a Virtue</title>
|
||
|
||
<para>
|
||
The primary difficulty in writing secure programs is that
|
||
writing them requires a different mindset, in short, a paranoid mindset.
|
||
The reason is that the impact of errors (also called defects or bugs)
|
||
can be profoundly different.
|
||
</para>
|
||
|
||
<para>
|
||
Normal non-secure programs have many errors.
|
||
While these errors are undesirable, these errors usually
|
||
involve rare or unlikely situations, and if a user should stumble upon
|
||
one they will try to avoid using the tool that way in the future.
|
||
</para>
|
||
|
||
<para>
|
||
In secure programs, the situation is reversed.
|
||
Certain users will intentionally search out and cause rare or unlikely
|
||
situations, in the hope that such attacks will give them unwarranted privileges.
|
||
As a result, when writing secure programs, paranoia is a virtue.
|
||
</para>
|
||
|
||
</sect1>
|
||
|
||
<sect1>
|
||
<title>Why Did I Write This Document?</title>
|
||
<!-- ???: Okay, this doesn't really belong here, but I can't figure out
|
||
where else to put it. I don't want the introduction to get longer. -->
|
||
<!-- ???: http://www.wired.com/news/politics/0,1283,34865,00.html
|
||
"Developers Blasted on Security", Reuters, 8:45 a.m. Mar. 9, 2000 PST
|
||
Rich Pethia stated to the U.S. Congress that
|
||
"There is little evidence of improvement in the security features of most
|
||
products,"
|
||
"Developers are not devoting sufficient effort to apply lessons
|
||
learned about the sources of vulnerabilities."
|
||
Richard D. Pethia is manager of the SEI Survivable Systems
|
||
Initiative and first manager of the CERT<52> Coordination Center (CERT<52>/CC).
|
||
(see Spotlight . Volume 1 . Issue 3 . December 1998,
|
||
"Interview with Richard D. Pethia" by Bill Pollak at
|
||
http://interactive.sei.cmu.edu/Features/1998/December/Spotlight/spotlight_dec98.htm
|
||
This interview states "The problem that I see is at the implementation
|
||
level - the code that's going out today is just as buggy as the code
|
||
that went out 10 years ago."
|
||
|
||
|
||
??? : Somehow add:
|
||
"A secure and Open society"
|
||
August 27, 1999
|
||
by Michael MacMillan
|
||
http://www.itworldcanada.com/cw/archive/cw15-17/cw_wtemplate.cfm?filename=c1517n8.htm
|
||
ITworldcanada.com
|
||
(interview with Theo de Raadt,
|
||
head of the OpenBSD project, which is focused on security.
|
||
The problem with professional programmers is not a lack of ability,
|
||
but lack of attention to detail, he said.
|
||
...
|
||
The secret is straightforward - de Raadt and his peers assume that
|
||
every single bug found in the code occurs elsewhere.
|
||
de Raadt admits it sounds simple, but just rooting security bugs
|
||
out of the entire source tree took 10 full-time developers
|
||
one and a half years to complete.
|
||
"It?s a hell of a lot of work and I think that explains why it hasn't
|
||
been done by many people," he said. www.openbsd.org.
|
||
|
||
-->
|
||
|
||
|
||
<para>
|
||
One question I've been asked is ``why did you write this document''?
|
||
Here's my answer:
|
||
Over the last several years I've noticed that many developers for
|
||
Linux and Unix
|
||
seem to keep falling into the same security pitfalls, again and again.
|
||
Auditors were slowly catching problems, but it would have been better
|
||
if the problems weren't put into the code in the first place.
|
||
I believe that part of the problem was that there wasn't a single, obvious
|
||
place where developers could go and get information on how to avoid
|
||
known pitfalls.
|
||
The information was publicly available, but it was often hard to find,
|
||
out-of-date, incomplete, or had other problems.
|
||
Most such information didn't particularly discuss Linux at all, even
|
||
though it was becoming widely used!
|
||
That leads up to the answer: I developed this document
|
||
in the hope that future software developers for Linux won't repeat
|
||
past mistakes, resulting in an even more secure form of Linux.
|
||
I added Unix, since it's often wise to make sure that programs can
|
||
port between these systems.
|
||
You can see a larger discussion of this at
|
||
<ulink
|
||
url="http://www.linuxsecurity.com/feature_stories/feature_story-6.html">http://www.linuxsecurity.com/feature_stories/feature_story-6.html</ulink>.
|
||
</para>
|
||
|
||
<para>
|
||
A related question that could be asked is ``why did you write your own document
|
||
instead of just referring to other documents''?
|
||
There are several answers:
|
||
|
||
<itemizedlist>
|
||
<listitem>
|
||
|
||
<para>
|
||
Much of this information was scattered about; placing
|
||
the critical information in one organized document
|
||
makes it easier to use.
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
|
||
<para>
|
||
Some of this information is not written for the programmer, but
|
||
is written for an administrator or user.
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
|
||
<para>
|
||
Much of the available information emphasizes portable constructs
|
||
(constructs that work on all Unix-like systems), and
|
||
failed to discuss Linux at all.
|
||
It's often best to avoid Linux-unique abilities for portability's sake,
|
||
but sometimes the Linux-unique abilities can really aid security.
|
||
Even if non-Linux portability is desired, you may want to support
|
||
the Linux-unique abilities when running on Linux.
|
||
And, by emphasizing Linux, I can include references to information that
|
||
is helpful to someone targeting Linux that is not necessarily true for
|
||
others.
|
||
</para>
|
||
</listitem>
|
||
|
||
</itemizedlist>
|
||
|
||
</para>
|
||
|
||
</sect1>
|
||
|
||
<sect1>
|
||
<title>Sources of Design and Implementation Guidelines</title>
|
||
|
||
<para>
|
||
Several documents help describe how to write
|
||
secure programs (or, alternatively, how to find security problems in
|
||
existing programs), and were the basis for the guidelines highlighted
|
||
in the rest of this paper.
|
||
<!-- ???: Add http://securityparadigm.com's "Computer Vulnerabilities" notes -->
|
||
<!-- ???: Add http://www.linuxhelp.org/lsap.shtml alternatively
|
||
http://ferret.lmh.ox.ac.uk/~security
|
||
Security-Audit's Frequently Asked Questions
|
||
v 1.9 2000/03/21 01:01:08, Jeff Graham <lsap@demit.net> -->
|
||
<!-- I added fish (Dan Farmer's) refs at http://www.fish.com/security -->
|
||
<!-- ??? Really need to emphasize the risks of symbolic/hard links, esp.
|
||
shared directories, such as /tmp. Symbolic links to /dev/zero can
|
||
really do bad things, symbolic links to /etc/passwd is of course
|
||
an ancient attack. -->
|
||
<!-- ??? Mention "terminal" and the possibility of retransmission back -->
|
||
<!-- ???: Traverse the Bugtraq archives, CERT advisories,
|
||
MITRE's CVE at http://cve.mitre.org etc.
|
||
to make sure I've covered the important stuff and pull out good
|
||
examples/stories. -->
|
||
<!-- ???: Add info and reference to
|
||
Landwehr 1994. Landwehr, Carl E., Alan R. Bull, John P. McDermott,
|
||
and William S. Choi. September 1994.
|
||
A Taxonomy of Computer Program Security Flaws.
|
||
ACM Computing Surveys. Vol. 26, No. 3.
|
||
-->
|
||
|
||
</para>
|
||
|
||
<para>
|
||
For general-purpose servers and setuid/setgid programs, there are a number
|
||
of valuable documents (though some are difficult to find without
|
||
having a reference to them).
|
||
</para>
|
||
|
||
|
||
<para>
|
||
Matt Bishop [1996, 1997]
|
||
has developed several extremely valuable papers and presentations
|
||
on the topic, and in fact he has a web page dedicated to the topic at
|
||
<ulink
|
||
url="http://olympus.cs.ucdavis.edu/~bishop/secprog.html">http://olympus.cs.ucdavis.edu/~bishop/secprog.html</ulink>.
|
||
AUSCERT has released a programming checklist
|
||
<ulink
|
||
url="ftp://ftp.auscert.org.au/pub/auscert/papers/secure_programming_checklist">[AUSCERT 1996]</ulink>,
|
||
based in part on chapter 23 of Garfinkel and Spafford's book discussing how
|
||
to write secure SUID and network programs
|
||
<ulink
|
||
url="http://www.oreilly.com/catalog/puis">[Garfinkel 1996]</ulink>.
|
||
<ulink
|
||
url="http://www.sunworld.com/swol-04-1998/swol-04-security.html">Galvin [1998a]</ulink> described a simple process and checklist
|
||
for developing secure programs; he later updated the checklist in
|
||
<ulink
|
||
url="http://www.sunworld.com/sunworldonline/swol-08-1998/swol-08-security.html">Galvin [1998b]</ulink>.
|
||
<ulink
|
||
url="http://www.pobox.com/~kragen/security-holes.html">Sitaker [1999]</ulink>
|
||
presents a list of issues for the ``Linux security audit'' team to search for.
|
||
<ulink
|
||
url="http://www.homeport.org/~adam/review.html">Shostack [1999]</ulink>
|
||
defines another checklist for reviewing security-sensitive code.
|
||
The NCSA
|
||
<ulink url="http://www.ncsa.uiuc.edu/General/Grid/ACES/security/programming">[NCSA]</ulink>
|
||
provides a set of terse but useful secure programming guidelines.
|
||
Other useful information sources include the
|
||
<emphasis remap="it">Secure Unix Programming FAQ</emphasis>
|
||
<ulink
|
||
url="http://www.whitefang.com/sup/">[Al-Herbish 1999]</ulink>,
|
||
the
|
||
<emphasis remap="it">Security-Audit's Frequently Asked Questions</emphasis>
|
||
<ulink
|
||
url="http://lsap.org/faq.txt">[Graham 1999]</ulink>,
|
||
and
|
||
<ulink
|
||
url="http://www.clark.net/pub/mjr/pubs/pdf/">Ranum [1998]</ulink>.
|
||
Some recommendations must be taken with caution, for example,
|
||
the BSD setuid(7) man page
|
||
<ulink
|
||
url="http://www.homeport.org/~adam/setuid.7.html">[Unknown]</ulink>
|
||
recommends the use of access(3) without noting the dangerous race conditions
|
||
that usually accompany it.
|
||
Wood [1985] has some useful but dated advice
|
||
in its ``Security for Programmers'' chapter.
|
||
<ulink
|
||
url="http://www.research.att.com/~smb/talks">Bellovin [1994]</ulink>
|
||
includes useful guidelines and some specific examples, such as how to
|
||
restructure an ftpd implementation to be simpler and more secure.
|
||
<ulink
|
||
url="http://www.freebsd.org/security/security.html">FreeBSD [1999]</ulink>
|
||
<ulink url="http://developer.gnome.org/doc/guides/programming-guidelines/book1.html">[Quintero 1999]</ulink>
|
||
is primarily concerned with GNOME programming guidelines, but it
|
||
includes a section on security considerations.
|
||
<ulink url="http://www.fish.com/security/murphy.html">[Venema 1996]</ulink>
|
||
provides a detailed discussion (with examples) of some common errors
|
||
when programming secure prorams (widely-known or predictable passwords,
|
||
burning yourself with malicious data, secrets in user-accessible data,
|
||
and depending on other programs).
|
||
<ulink url="http://www.fish.com/security/maldata.html">[Sibert 1996]</ulink>
|
||
describes threats arising from malicious data.
|
||
</para>
|
||
|
||
<para>
|
||
There are many documents giving security guidelines for
|
||
programs using
|
||
the Common Gateway Interface (CGI) to interface with the web.
|
||
These include
|
||
<!-- ???: Re-examine this one: anything new here? -->
|
||
<ulink url="http://www.csclub.uwaterloo.ca/u/mlvanbie/cgisec">Van Biesbrouck [1996]</ulink>,
|
||
<ulink
|
||
url="http://language.perl.com/CPAN/doc/FAQs/cgi/perl-cgi-faq.html">Gundavaram [unknown]</ulink>,
|
||
<ulink url="http://webreview.com/wr/pub/97/08/08/bookshelf">
|
||
[Garfinkle 1997]</ulink>
|
||
<ulink
|
||
url="http://www.eekim.com/pubs/cgibook">Kim [1996]</ulink>,
|
||
<ulink
|
||
url="http://www.go2net.com/people/paulp/cgi-security/safe-cgi.txt">Phillips [1995]</ulink>,
|
||
<ulink
|
||
url="http://www.w3.org/Security/Faq/www-security-faq.html">Stein [1999]</ulink>,
|
||
<ulink url="http://members.home.net/razvan.peteanu">[Peteanu 2000]</ulink>,
|
||
and
|
||
<ulink
|
||
url="http://advosys.ca/tips/web-security.html">[Advosys 2000]</ulink>.
|
||
</para>
|
||
|
||
<para>
|
||
There are many documents specific to a language, which are further
|
||
discussed in the language-specific sections of this document.
|
||
For example, the Perl distribution includes
|
||
<ulink url="http://www.perl.com/pub/doc/manual/html/pod/perlsec.html">
|
||
perlsec(1)</ulink>, which describes how to use Perl more securely.
|
||
The Secure Internet Programming site at
|
||
<ulink url="http://www.cs.princeton.edu/sip">http://www.cs.princeton.edu/sip</ulink>
|
||
is interested in computer security issues in general, but focuses on
|
||
mobile code systems such as Java, ActiveX, and JavaScript; Ed Felten
|
||
(one of its principles) co-wrote a book on securing Java
|
||
(<ulink url="www.securingjava.com">[McGraw 1999]</ulink>)
|
||
which is discussed in the section on Java.
|
||
Sun's security code guidelines provide some guidelines primarily
|
||
for Java and C; it is available at
|
||
<ulink url="http://java.sun.com/security/seccodeguide.html">
|
||
http://java.sun.com/security/seccodeguide.html</ulink>.
|
||
</para>
|
||
|
||
<para>
|
||
Yoder [1998] contains a collection of patterns to be used
|
||
when dealing with application security.
|
||
It's not really a specific set of guidelines, but a set of commonly-used
|
||
patterns for programming that you may find useful.
|
||
The Schmoo group maintains a web page linking to information on
|
||
how to write secure code at
|
||
<ulink url="http://www.shmoo.com/securecode">http://www.shmoo.com/securecode</ulink>
|
||
</para>
|
||
|
||
<para>
|
||
There are many documents describing the issue from
|
||
the other direction (i.e., ``how to crack a system'').
|
||
One example is McClure [1999], and there's countless amounts of material
|
||
from that vantage point on the Internet.
|
||
</para>
|
||
|
||
<para>
|
||
There's also a large body of information on vulnerabilities
|
||
already identified in existing programs.
|
||
This can be a useful set of
|
||
examples of ``what not to do,'' though it takes effort to extract more
|
||
general guidelines from the large body of specific examples.
|
||
There are mailing lists that discuss security issues; one of the most
|
||
well-known is
|
||
<ulink url="http://SecurityFocus.com/forums/bugtraq/faq.html">
|
||
Bugtraq</ulink>, which among other things develops a list of vulnerabilities.
|
||
The CERT Coordination Center (CERT/CC)
|
||
is a major reporting center for Internet security problems which
|
||
reports on vulnerabilities.
|
||
The CERT/CC occasionally produces advisories that
|
||
provide a description of a serious security problem
|
||
and its impact, along with
|
||
instructions on how to obtain a patch or details of a workaround; for
|
||
more information see
|
||
<ulink url="http://www.cert.org">http://www.cert.org</ulink>.
|
||
Note that originally the CERT was
|
||
a small computer emergency response team, but officially
|
||
``CERT'' doesn't stand for anything now.
|
||
The Department of Energy's
|
||
<ulink url="http://ciac.llnl.gov/ciac">Computer
|
||
Incident Advisory Capability (CIAC)</ulink> also reports on vulnerabilities.
|
||
<!-- Could reference ntbugtraq and the ones listed in
|
||
http://www.cert.org/other_sources/other_teams.html and the
|
||
various backers of CVE -->
|
||
These different groups may identify the same vulnerabilities but use different
|
||
names.
|
||
To resolve this problem,
|
||
MITRE supports the Common Vulnerabilities and Exposures (CVE) list
|
||
which creates a single unique identifier (``name'')
|
||
for all publicly known vulnerabilities and security exposures
|
||
identified by others; see
|
||
<ulink url="http://www.cve.mitre.org">http://www.cve.mitre.org</ulink>.
|
||
NIST's ICAT
|
||
is a searchable catalogue of computer vulnerabilities, taking the
|
||
each CVE vulnerability and categorizing them so they can be searched
|
||
and compared later; see
|
||
<ulink url="http://csrc.nist.gov/icat">http://csrc.nist.gov/icat</ulink>.
|
||
</para>
|
||
|
||
|
||
<para>
|
||
This paper is a summary of what I believe are the most
|
||
useful and important guidelines; my goal is a document that
|
||
a good programmer can just read and then be fairly well prepared
|
||
to implement a secure program.
|
||
No single document can really meet this goal, but
|
||
I believe the attempt is worthwhile.
|
||
My goal is to strike a balance somewhere between a
|
||
``complete list of all possible guidelines''
|
||
(that would be unending and unreadable)
|
||
and the various ``short'' lists available on-line that are nice and short
|
||
but omit a large number of critical issues.
|
||
When in doubt, I include the guidance; I believe in that case it's better
|
||
to make the information
|
||
available to everyone in this ``one stop shop'' document.
|
||
The organization presented here is my own (every list has its own, different
|
||
structure), and some of the guidelines (especially the Linux-unique
|
||
ones, such as those on capabilities and the fsuid value) are also my own.
|
||
Reading all of the referenced documents listed above as well
|
||
is highly recommended.
|
||
</para>
|
||
|
||
</sect1>
|
||
|
||
<sect1>
|
||
<title>Document Conventions</title>
|
||
|
||
<para>
|
||
System manual pages are referenced in the format <emphasis remap="it">name(number)</emphasis>,
|
||
where <emphasis remap="it">number</emphasis> is the section number of the manual.
|
||
The pointer value that means ``does not point anywhere'' is called NULL;
|
||
C compilers will convert the integer 0 to the value NULL in most circumstances
|
||
where a pointer is needed,
|
||
but note that nothing in the C standard requires that NULL actually
|
||
be implemented by a series of all-zero bits.
|
||
C and C++ treat the character '\0' (ASCII 0) specially, and this value
|
||
is referred to as NIL in this paper (this is usually called ``NUL'',
|
||
but ``NUL'' and ``NULL'' sound identical).
|
||
Function and method names always use the correct case, even if that means
|
||
that some sentences must begin with a lower case letter.
|
||
I use the term ``Unix-like'' to mean Unix, Linux, or other systems whose
|
||
underlying models are very similar to Unix;
|
||
I can't say POSIX, because there are systems such as Windows 2000 that
|
||
implement portions of POSIX yet have vastly different security models.
|
||
</para>
|
||
|
||
<para>
|
||
An attacker is called an ``attacker'', ``cracker'', or ``adversary''.
|
||
Some journalists use the word ``hacker'' instead of ``attacker'';
|
||
this paper avoids this (mis)use, because many
|
||
Linux and Unix developers refer to themselves as ``hackers''
|
||
in the traditional non-evil sense of the term.
|
||
That is, to many Linux and Unix developers, the term ``hacker'' continues
|
||
to mean simply an expert or enthusiast, particularly regarding computers.
|
||
</para>
|
||
|
||
<!-- TRANSLATORS: FEEL FREE TO OMIT THE FOLLOWING PARAGRAPH
|
||
(OR PORTIONS OF IT) IF IT DOES NOT APPLY TO YOUR LANGUAGE. -->
|
||
<para>
|
||
This document uses the ``new'' or ``logical'' quoting system, instead
|
||
of the traditional American quoting system: quoted information
|
||
does not include any trailing punctuation if the punctuation
|
||
is not part of the material being quoted.
|
||
While this may cause a minor loss of typographical beauty, the traditional
|
||
American system causes extraneous characters to be placed inside the quotes.
|
||
These extraneous characters have
|
||
no effect on prose but can be disastrous in code or computer commands.
|
||
<!-- See http://www.tuxedo.org/~esr/jargon/html/Hacker-Writing-Style.html -->
|
||
<!-- I distinguish between the terms privilege and permission in this paper;
|
||
a process (subject) may acquire privileges, while an object has permissions. -->
|
||
I use standard American (not British) spelling; I've yet to meet an
|
||
English speaker on any continent who has trouble with this.
|
||
</para>
|
||
|
||
</sect1>
|
||
|
||
</chapter>
|
||
|
||
<chapter>
|
||
<title>Summary of Linux and Unix Security Features</title>
|
||
|
||
<epigraph>
|
||
<attribution>Proverbs 2:11 (NIV)</attribution>
|
||
<para>
|
||
Discretion will protect you, and understanding will guard you.
|
||
</para>
|
||
</epigraph>
|
||
|
||
<para>
|
||
Before discussing guidelines on how to use Linux or Unix security features,
|
||
it's useful to know what those features are from a programmer's viewpoint.
|
||
This section briefly describes those features that are widely available
|
||
on nearly all Unix-like systems.
|
||
However, note that there is considerable variation between
|
||
different versions of Unix-like systems, and
|
||
not all systems have the abilities described here.
|
||
This chapter also notes some extensions or features specific to Linux;
|
||
Linux distributions tend to be fairly similar to each other from the
|
||
point-of-view of programming for security, because they all use essentially
|
||
the same kernel and C library (and the GPL-based licenses encourage rapid
|
||
dissemination of any innovations).
|
||
This chapter doesn't discuss issues such as implementations of
|
||
mandatory access control (MAC) which many Unix-like systems do not implement.
|
||
If you already know what
|
||
those features are, please feel free to skip this section.
|
||
</para>
|
||
|
||
<para>
|
||
Many programming guides skim briefly over the security-relevant portions
|
||
of Linux or Unix and skip important information.
|
||
In particular, they often discuss ``how to use'' something in general terms
|
||
but gloss over the security attributes that affect their use.
|
||
Conversely, there's a great deal of detailed information in
|
||
the manual pages about individual functions, but the manual pages
|
||
sometimes obscure key security issues with detailed discussions on how
|
||
to use each individual function.
|
||
This section tries to bridge that gap; it gives an overview of
|
||
the security mechanisms in Linux that are likely to be used
|
||
by a programmer, but concentrating specifically on the security
|
||
ramifications.
|
||
This section has more depth than the typical programming guides, focusing
|
||
specifically on security-related matters, and points to references
|
||
where you can get more details.
|
||
</para>
|
||
|
||
<para>
|
||
First, the basics.
|
||
Linux and Unix are
|
||
fundamentally divided into two parts: the kernel and ``user space''.
|
||
Most programs execute in user space (on top of the kernel).
|
||
Linux supports the concept of ``kernel modules'', which is simply the
|
||
ability to dynamically load code into the kernel, but note that it
|
||
still has this fundamental division.
|
||
Some other systems (such as the HURD) are ``microkernel'' based systems; they
|
||
have a small kernel with more limited functionality, and a set of ``user''
|
||
programs that implement the lower-level functions traditionally implemented
|
||
by the kernel.
|
||
</para>
|
||
|
||
<para>
|
||
Some Unix-like systems have been extensively modified to support
|
||
strong security, in particular to support U.S. Department of Defense
|
||
requirements for Mandatory Access Control (level B1 or higher).
|
||
This version of this paper doesn't cover these systems or issues;
|
||
I hope to expand to that in a future version.
|
||
<!-- ???: Mention trusted Unix-like systems, MAC, ACLs, Trusted Solaris -->
|
||
</para>
|
||
|
||
<para>
|
||
When users log in, their usernames are mapped to integers marking their
|
||
``UID'' (for ``user id'') and the ``GID''s (for ``group id'') that they
|
||
are a member of.
|
||
UID 0 is a special privileged user (role) traditionally called ``root'';
|
||
on most Unix-like systems (including Unix) root
|
||
can overrule most security checks and is used to administrate the system.
|
||
Processes are the only ``subjects'' in terms of security (that is, only
|
||
processes are active objects).
|
||
Processes can access various data objects, in particular filesystem
|
||
objects (FSOs), System V Interprocess Communication (IPC) objects, and
|
||
network ports.
|
||
Processes can also set signals.
|
||
Other security-relevant topics include quotas and limits, libraries,
|
||
auditing, and PAM.
|
||
The next few subsections detail this.
|
||
</para>
|
||
|
||
<sect1>
|
||
<title>Processes</title>
|
||
|
||
<para>
|
||
In Unix-like systems,
|
||
user-level activities are implemented by running processes.
|
||
Most Unix systems support a ``thread'' as a separate concept;
|
||
threads share memory inside a process, and the system scheduler actually
|
||
schedules threads.
|
||
Linux does this differently (and in my opinion uses a better approach):
|
||
there is no essential difference between a thread and a process.
|
||
Instead, in Linux, when a process creates another process it can choose
|
||
what resources are shared (e.g., memory can be shared).
|
||
The Linux kernel then performs optimizations to get thread-level speeds;
|
||
see clone(2) for more information.
|
||
It's worth noting that the Linux kernel developers tend to use the
|
||
word ``task'', not ``thread'' or ``process'', but the external
|
||
documentation tends to use the word process
|
||
(so I'll use that terminology here).
|
||
When programming a multi-threaded application,
|
||
it's usually better to use one of the standard
|
||
thread libraries that hide these differences.
|
||
Not only does this make threading more portable, but some libraries
|
||
provide an additional level of indirection, by implementing more than
|
||
one application-level thread as a single operating system thread;
|
||
this can provide some improved performance on some systems for
|
||
some applications.
|
||
</para>
|
||
|
||
<sect2>
|
||
<title>Process Attributes</title>
|
||
|
||
<para>
|
||
Here are typical attributes associated with each process in a
|
||
Unix-like system:
|
||
|
||
<itemizedlist>
|
||
<listitem>
|
||
|
||
<para>
|
||
RUID, RGID - real UID and GID
|
||
of the user on whose behalf the process is running
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
|
||
<para>
|
||
EUID, EGID - effective UID and GID
|
||
used for privilege checks (except for the filesystem)
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
|
||
<para>
|
||
SUID, SGID - Saved UID and GID;
|
||
used to support switching permissions ``on and off'' as discussed below.
|
||
Not all Unix-like systems support this.
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
|
||
<para>
|
||
supplemental groups - a list of groups (GIDs) in which this
|
||
user has membership.
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
|
||
<para>
|
||
umask - a set of bits determining the default access control settings
|
||
when a new filesystem object is created; see umask(2).
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
|
||
<para>
|
||
scheduling parameters - each process has a scheduling policy, and those
|
||
with the default policy SCHED_OTHER have the additional parameters
|
||
nice, priority, and counter. See sched_setscheduler(2) for more information.
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
|
||
<para>
|
||
limits - per-process resource limits (see below).
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
|
||
<para>
|
||
filesystem root - the process' idea of where the root filesystem
|
||
begins; see chroot(2).
|
||
</para>
|
||
</listitem>
|
||
|
||
</itemizedlist>
|
||
|
||
</para>
|
||
|
||
<para>
|
||
Here are less-common attributes associated with processes:
|
||
|
||
<itemizedlist>
|
||
<listitem>
|
||
|
||
<para>
|
||
FSUID, FSGID - UID and GID used for filesystem access checks;
|
||
this is usually equal to the EUID and EGID respectively.
|
||
This is a Linux-unique attribute.
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
|
||
<para>
|
||
capabilities - POSIX capability information; there are actually three
|
||
sets of capabilities on a process: the effective, inheritable, and permitted
|
||
capabilities. See below for more information on POSIX capabilities.
|
||
Linux kernel version 2.2 and greater support this; some other Unix-like
|
||
systems do too, but it's not as widespread.
|
||
</para>
|
||
</listitem>
|
||
|
||
</itemizedlist>
|
||
|
||
</para>
|
||
|
||
<para>
|
||
In Linux,
|
||
if you really need to know exactly what attributes are associated
|
||
with each process, the most definitive source is the
|
||
Linux source code, in particular
|
||
<filename>/usr/include/linux/sched.h</filename>'s definition of task_struct.
|
||
</para>
|
||
|
||
<para>
|
||
The portable way to create new processes it use the fork(2) call.
|
||
BSD introduced a variant called vfork(2) as an optimization technique.
|
||
The bottom line with vfork(2) is simple: <emphasis remap="it">don't</emphasis> use it if you
|
||
can avoid it.
|
||
In vfork(2), unlike fork(2), the child borrows the parent's memory
|
||
and thread of control until a call to execve(2V) or an exit occurs;
|
||
the parent process is suspended while the child is using its resources.
|
||
The rationale is that in old BSD systems, fork(2) would actually cause
|
||
memory to be copied while vfork(2) would not.
|
||
Linux never had this problem; because Linux used copy-on-write
|
||
semantics internally, Linux only copies pages when they changed
|
||
(actually, there are still some tables that have to be copied; in most
|
||
circumstances their overhead is not significant).
|
||
Nevertheless, since some programs depend on vfork(2),
|
||
recently Linux implemented the BSD vfork(2) semantics
|
||
(previously it had been an alias for fork(2)).
|
||
The problem with vfork(2) is that it's actually fairly tricky for a
|
||
process to not interfere with its parent, especially in high-level languages.
|
||
The result: programs using vfork(2) can easily fail when code changes
|
||
or even when compiler versions change.
|
||
Avoid vfork(2) in most cases; its primary use is to support old
|
||
programs that needed vfork's semantics.
|
||
</para>
|
||
|
||
<para>
|
||
Linux supports the Linux-unique clone(2) call.
|
||
This call works like fork(2), but allows specification of which resources
|
||
should be shared (e.g., memory, file descriptors, etc.).
|
||
Portable programs shouldn't use this call directly; as noted earlier,
|
||
they should instead rely on threading libraries that use the call to implement
|
||
threads.
|
||
</para>
|
||
|
||
<para>
|
||
This document is not a full tutorial on writing programs, so
|
||
I will skip widely-available information handling processes.
|
||
You can see the documentation for wait(2), exit(2), and so on for more
|
||
information.
|
||
</para>
|
||
|
||
</sect2>
|
||
|
||
<sect2>
|
||
<title>POSIX Capabilities</title>
|
||
|
||
<para>
|
||
POSIX capabilities are sets of bits that permit splitting of the privileges
|
||
typically held by root into a larger set of more specific privileges.
|
||
POSIX capabilities are defined
|
||
by a draft IEEE standard; they're not unique to Linux but they're not
|
||
universally supported by other Unix-like systems either.
|
||
Linux kernel 2.0 did not support POSIX capabilities, while version 2.2
|
||
added support for POSIX capabilities to processes.
|
||
When Linux documentation (including this one)
|
||
says ``requires root privilege'', in nearly all cases it
|
||
really means ``requires a capability'' as documented in the capability
|
||
documentation.
|
||
If you need to know the specific capability required, look it up in the
|
||
capability documentation.
|
||
</para>
|
||
|
||
<para>
|
||
In Linux,
|
||
the eventual intent is to permit capabilities to be attached to files
|
||
in the filesystem; as of this writing, however, this is not yet supported.
|
||
There is support for transferring capabilities, but this is disabled
|
||
by default.
|
||
Linux version 2.2.11 added a feature that makes capabilities
|
||
more directly useful, called the ``capability bounding set''.
|
||
The capability bounding set is a list of capabilities
|
||
that are allowed to be held by any process on the system (otherwise,
|
||
only the special init process can hold it).
|
||
If a capability does not appear in the bounding set, it may not be
|
||
exercised by any process, no matter how privileged.
|
||
This feature can be used to, for example, disable kernel module loading.
|
||
A sample tool that takes advantage of this is LCAP at
|
||
<ulink
|
||
url="http://pweb.netcom.com/~spoon/lcap/">http://pweb.netcom.com/~spoon/lcap/</ulink>.
|
||
</para>
|
||
|
||
<para>
|
||
More information about POSIX capabilities is available at
|
||
<ulink
|
||
url="ftp://linux.kernel.org/pub/linux/libs/security/linux-privs">ftp://linux.kernel.org/pub/linux/libs/security/linux-privs</ulink>.
|
||
</para>
|
||
|
||
</sect2>
|
||
|
||
<sect2>
|
||
<title>Process Creation and Manipulation</title>
|
||
|
||
<para>
|
||
Processes may be created using fork(2), the non-recommended vfork(2),
|
||
or the Linux-unique clone(2); all of these system calls duplicate the existing
|
||
process, creating two processes out of it.
|
||
A process can execute a different program by calling execve(2),
|
||
or various front-ends to it (for example, see exec(3), system(3), and popen(3)).
|
||
</para>
|
||
|
||
<para>
|
||
<!-- I've known about the scripting race condition since forever, but the
|
||
description here is vaguely derived from perlsec(1) -->
|
||
When a program is executed, and its file has its setuid or setgid bit set,
|
||
the process' EUID or EGID (respectively) is usually set to the file's value.
|
||
This functionality was the source of an old Unix security weakness
|
||
when used to support setuid or setgid scripts, due to a race condition.
|
||
Between the time the kernel opens the file to see which interpreter to run,
|
||
and when the (now-set-id) interpreter turns around and reopens
|
||
the file to interpret it, an attacker might change the file
|
||
(directly or via symbolic links).
|
||
</para>
|
||
|
||
<para>
|
||
Different Unix-like systems handle the security issue for setuid scripts
|
||
in different ways.
|
||
Some systems, such as Linux, completely ignore the setuid and setgid
|
||
bits when executing scripts, which is clearly a safe approach.
|
||
Most modern releases of SysVr4 and BSD 4.4 use a different approach to
|
||
avoid the kernel race condition.
|
||
On these systems, when the kernel passes
|
||
the name of the set-id script to open to the interpreter,
|
||
rather than using a pathname (which would permit the race condition)
|
||
it instead passes the filename /dev/fd/3. This is a special
|
||
file already opened on the script, so that there can be no
|
||
race condition for attackers to exploit.
|
||
Even on these systems I recommend against using the setuid/setgid
|
||
shell scripts language for secure programs, as discussed below.
|
||
</para>
|
||
|
||
|
||
<para>
|
||
In some cases a process can affect the various UID and GID values; see
|
||
setuid(2), seteuid(2), setreuid(2), and the Linux-unique setfsuid(2).
|
||
In particular the saved user id (SUID) attribute
|
||
is there to permit trusted programs to temporarily switch UIDs.
|
||
Unix-like systems supporting the SUID use the following rules:
|
||
If the RUID is changed, or the EUID is set to a value not equal to the RUID,
|
||
the SUID is set to the new EUID.
|
||
Unprivileged users can set their EUID from their SUID,
|
||
the RUID to the EUID, and the EUID to the RUID.
|
||
</para>
|
||
|
||
<para>
|
||
The Linux-unique
|
||
FSUID process attribute is intended to permit programs like the NFS server
|
||
to limit themselves to only the filesystem rights of some given UID
|
||
without giving that UID permission to send signals to the process.
|
||
Whenever the EUID is changed, the FSUID is changed to the new
|
||
EUID value; the FSUID value can be set separately using setfsuid(2), a
|
||
Linux-unique call.
|
||
Note that non-root callers can only set FSUID to the current
|
||
RUID, EUID, SEUID, or current FSUID values.
|
||
</para>
|
||
|
||
</sect2>
|
||
|
||
</sect1>
|
||
|
||
<sect1>
|
||
<title>Files</title>
|
||
|
||
<para>
|
||
On all Unix-like systems, the primary repository of information is
|
||
the file tree, rooted at ``/''.
|
||
The file tree is a hierarchical set of directories, each of which
|
||
may contain filesystem objects (FSOs).
|
||
</para>
|
||
|
||
<para>
|
||
In Linux,
|
||
filesystem objects (FSOs) may be ordinary files, directories,
|
||
symbolic links, named pipes (also called first-in first-outs or FIFOs),
|
||
sockets (see below),
|
||
character special (device) files, or block special (device) files
|
||
(in Linux, this list is given in the find(1) command).
|
||
Other Unix-like systems have an identical or similar list of FSO types.
|
||
</para>
|
||
|
||
<para>
|
||
Filesystem objects are collected on filesystems, which can be
|
||
mounted and unmounted on directories in the file tree.
|
||
A filesystem type (e.g., ext2 and FAT) is a specific set of conventions
|
||
for arranging data on the disk to optimize speed, reliability, and so on;
|
||
many people use the term ``filesystem'' as a synonym for the filesystem type.
|
||
</para>
|
||
|
||
<sect2>
|
||
<title>Filesystem Object Attributes</title>
|
||
|
||
<para>
|
||
Different Unix-like systems support different filesystem types.
|
||
Filesystems may have slightly different sets of access control attributes
|
||
and access controls can be affected by options selected at mount time.
|
||
On Linux, the ext2 filesystems is currently the most popular filesystem,
|
||
but Linux supports a vast number of filesystems.
|
||
Most Unix-like systems tend to support multiple filesystems too.
|
||
</para>
|
||
|
||
<para>
|
||
Most filesystems on Unix-like systems store at least the following:
|
||
|
||
<itemizedlist>
|
||
<listitem>
|
||
|
||
<para>
|
||
owning UID and GID - identifies the ``owner'' of the filesystem
|
||
object. Only the owner or root can change the access control attributes
|
||
unless otherwise noted.
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
|
||
<para>
|
||
permission bits -
|
||
read, write, execute bits for each of user (owner), group, and other.
|
||
For ordinary files, read, write, and execute have their typical meanings.
|
||
In directories, the ``read'' permission is necessary to display a directory's
|
||
contents, while the ``execute'' permission is sometimes called ``search''
|
||
permission and is necessary to actually enter the directory to use its contents.
|
||
In a directory ``write'' permission on a directory permits
|
||
adding, removing, and renaming files in that directory; if you only want
|
||
to permit adding, set the sticky bit noted below.
|
||
Note that the permission values of symbolic links are never used; it's only
|
||
the values of their containing directories and the linked-to file that matter.
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
|
||
<para>
|
||
``sticky'' bit - when set on a directory, unlinks (removes) and
|
||
renames of files in that directory are limited to
|
||
the file owner, the directory owner, or root privileges.
|
||
This is a very common Unix extension
|
||
and is specified in the
|
||
Open Group's Single Unix Specification version 2.
|
||
<!-- http://www.opengroup.org/onlinepubs/007908799/xsh/chmod.html -->
|
||
Old versions of Unix called this the ``save program text'' bit and used this
|
||
to indicate executable files that should stay in memory.
|
||
Systems that did this ensured that only root could set this bit
|
||
(otherwise users could have crashed systems by forcing ``everything''
|
||
into memory).
|
||
In Linux, this bit has no affect on ordinary files and ordinary users
|
||
can modify this bit on the files they own:
|
||
Linux's virtual memory management makes this old use irrelevant.
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
|
||
<para>
|
||
setuid, setgid - when set on an executable file,
|
||
executing the file will set the process' effective UID or effective GID
|
||
to the value of the file's owning UID or GID (respectively).
|
||
All Unix-like systems support this.
|
||
In Linux and System V systems,
|
||
when setgid is set on a file that does not have any execute privileges,
|
||
this indicates a file that is subject to mandatory locking
|
||
during access (if the filesystem is mounted to support mandatory locking);
|
||
this overload of meaning surprises many and is not universal across Unix-like
|
||
systems.
|
||
In fact, the Open Group's Single Unix Specification version 2 for chmod(3)
|
||
permits systems to ignore
|
||
requests to turn on setgid for files that aren't executable if such
|
||
a setting has no meaning.
|
||
In Linux and Solaris,
|
||
when setgid is set on a directory, files created in the directory will
|
||
have their GID automatically reset to that of the directory's GID.
|
||
The purpose of this approach is to support ``project directories'':
|
||
users can save files into such specially-set directories and the group
|
||
owner automatically changes.
|
||
However, setting the setgid bit on directories is not specified by
|
||
standards such as the Single Unix Specification
|
||
[Open Group 1997].
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
|
||
<para>
|
||
timestamps - access and modification times are stored for each
|
||
filesystem object. However, the owner is allowed to set these values
|
||
arbitrarily (see touch(1)), so be careful about trusting this information.
|
||
All Unix-like systems support this.
|
||
</para>
|
||
</listitem>
|
||
|
||
</itemizedlist>
|
||
|
||
</para>
|
||
|
||
<para>
|
||
The following are attributes are Linux-unique extensions on the ext2
|
||
filesystem, though many other filesystems have similar functionality:
|
||
|
||
<itemizedlist>
|
||
<listitem>
|
||
|
||
<para>
|
||
immutable bit - no changes to the filesystem object are allowed;
|
||
only root can set or clear this bit.
|
||
This is only supported by ext2 and is not portable across all Unix
|
||
systems (or even all Linux filesystems).
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
|
||
<para>
|
||
append-only bit - only appending to the filesystem object are allowed;
|
||
only root can set or clear this bit.
|
||
This is only supported by ext2 and is not portable across all Unix
|
||
systems (or even all Linux filesystems).
|
||
</para>
|
||
</listitem>
|
||
|
||
</itemizedlist>
|
||
|
||
</para>
|
||
|
||
<para>
|
||
Other common extensions include some sort of bit indicating ``cannot
|
||
delete this file''.
|
||
</para>
|
||
|
||
<para>
|
||
Many of these values can be influenced at mount time, so that, for example,
|
||
certain bits can be treated as though they had a certain value (regardless
|
||
of their values on the media).
|
||
See mount(1) for more information about this.
|
||
Some filesystems don't support some of these access control values; again,
|
||
see mount(1) for how these filesystems are handled.
|
||
In particular, many Unix-like systems support MS-DOS disks, which by
|
||
default support very few of these attributes (and there's not standard
|
||
way to define these attributes).
|
||
In that case, Unix-like systems emulate the standard attributes
|
||
(possibly implementing them through special on-disk files), and these
|
||
attributes are generally influenced by the mount(1) command.
|
||
</para>
|
||
|
||
<para>
|
||
It's important to note that, for adding and removing files, only the
|
||
permission bits and owner of the file's <emphasis>directory</emphasis>
|
||
really matter unless the Unix-like system supports
|
||
more complex schemes (such as POSIX ACLs).
|
||
Unless the system has other extensions, and stock Linux 2.2 doesn't,
|
||
a file that has no permissions in its permission bits
|
||
can still be removed if its containing directory permits it.
|
||
Also, if an ancestor directory permits its children to be changed by some
|
||
user or group, then any of that directory's descendents can be replaced by
|
||
that user or group.
|
||
</para>
|
||
|
||
<para>
|
||
The draft IEEE POSIX standard on security defines a technique for
|
||
true ACLs that support a list of users and groups with their permissions.
|
||
Unfortunately, this is not widely supported nor supported exactly the
|
||
same way across Unix-like systems.
|
||
Stock Linux 2.2, for example, has neither ACLs nor POSIX capability
|
||
values in the filesystem.
|
||
</para>
|
||
|
||
<para>
|
||
It's worth noting that in Linux, the Linux ext2
|
||
filesystem by default reserves a small amount of space for the root user.
|
||
This is a partial defense against denial-of-service attacks; even if a user
|
||
fills a disk that is shared with the root user, the root user has a little
|
||
space left over (e.g., for critical functions).
|
||
The default is 5% of the filesystem space; see mke2fs(8),
|
||
in particular its ``-m'' option.
|
||
</para>
|
||
|
||
</sect2>
|
||
|
||
<sect2>
|
||
<title>Creation Time Initial Values</title>
|
||
|
||
<para>
|
||
At creation time, the following rules apply.
|
||
On most Unix systems, when a new filesystem object is created via creat(2)
|
||
or open(2), the FSO UID is set to the process' EUID and the FSO's GID is
|
||
set to the process' EGID.
|
||
Linux works slightly differently due to its FSUID
|
||
extensions; the FSO's UID is set to the process' FSUID, and the FSO GID
|
||
is set to the process' FSGUID; if the
|
||
containing directory's setgid bit is set or the filesystem's
|
||
``GRPID'' flag is set, the FSO GID is actually set to the
|
||
GID of the containing directory.
|
||
Many systems, including Sun Solaris and Linux, also support the
|
||
setgid directory extensions.
|
||
As noted earlier,
|
||
this special case supports ``project'' directories: to make a ``project''
|
||
directory, create a special group for the project,
|
||
create a directory for the project owned by that group, then make the
|
||
directory setgid: files placed there
|
||
are automatically owned by the project.
|
||
Similarly, if a new subdirectory is created inside a directory with the
|
||
setgid bit set (and the filesystem GRPID isn't set), the new subdirectory
|
||
will also have its setgid bit set (so that project subdirectories will
|
||
``do the right thing''.); in all other cases the setgid is clear for a new file.
|
||
This is the rationale for Red Hat Linux's ``user-private group'' scheme,
|
||
in which
|
||
every user is a member of a ``private'' group with just them as members,
|
||
so their defaults can permit the group to read and write any file
|
||
(since they're the only member of the group).
|
||
Thus, when the file's group membership
|
||
is transferred this way, read and write privileges
|
||
are transferred too.
|
||
<!-- http://www.redhat.com/support/manuals/RHL-6.2-Manual/ref-guide/s1-sysadmin-usr-grps.html -->
|
||
FSO basic access control values (read, write, execute) are computed from
|
||
(requested values & ~ umask of process).
|
||
New files always start with a clear sticky bit and clear setuid bit.
|
||
</para>
|
||
|
||
</sect2>
|
||
|
||
<sect2>
|
||
<title>Changing Access Control Attributes</title>
|
||
|
||
<para>
|
||
You can set most of these values with chmod(2), fchmod(2), or chmod(1)
|
||
but see also chown(1), and chgrp(1).
|
||
In Linux, some the Linux-unique attributes are manipulated using chattr(1).
|
||
</para>
|
||
|
||
<para>
|
||
Note that in Linux, only root can change the owner of a given file.
|
||
Some Unix-like systems allow ordinary users to transfer ownership of their
|
||
files to another, but this causes complications and is forbidden by Linux.
|
||
For example, if you're trying to limit disk usage,
|
||
allowing such operations would allow users to claim that large files
|
||
actually belonged to some other ``victim''.
|
||
</para>
|
||
|
||
</sect2>
|
||
|
||
<sect2>
|
||
<title>Using Access Control Attributes</title>
|
||
|
||
<para>
|
||
Under Linux and most Unix-like systems, reading and writing
|
||
attribute values are only checked when the file is opened; they
|
||
are not re-checked on every read or write.
|
||
Still, a large number of calls do check these attributes,
|
||
since the filesystem is so central to Unix-like systems.
|
||
Calls that check these attributes
|
||
include open(2), creat(2), link(2), unlink(2), rename(2),
|
||
mknod(2), symlink(2), and socket(2).
|
||
</para>
|
||
|
||
</sect2>
|
||
|
||
<sect2>
|
||
<title>Filesystem Hierarchy</title>
|
||
|
||
<para>
|
||
Over the years conventions have been built on ``what files to place where''.
|
||
Where possible,
|
||
please follow conventional use when placing information in the hierarchy.
|
||
For example, place global configuration information in /etc.
|
||
The Filesystem Hierarchy Standard (FHS) tries to
|
||
define these conventions in a logical manner, and is widely used by
|
||
Linux systems.
|
||
The FHS is an update to the previous
|
||
Linux Filesystem Structure standard (FSSTND), incorporating lessons
|
||
learned and approaches from Linux, BSD, and System V systems.
|
||
See <ulink
|
||
url="http://www.pathname.com/fhs">http://www.pathname.com/fhs</ulink> for more information about the FHS.
|
||
A summary of these conventions is in hier(5) for Linux
|
||
and hier(7) for Solaris.
|
||
Sometimes different conventions disagree; where possible, make these
|
||
situations configurable at compile or installation time.
|
||
</para>
|
||
|
||
</sect2>
|
||
|
||
</sect1>
|
||
|
||
<sect1>
|
||
<title>System V IPC</title>
|
||
|
||
<para>
|
||
Many Unix-like systems, including
|
||
Linux and System V systems, support System V interprocess communication
|
||
(IPC) objects.
|
||
Indeed System V IPC is required by the
|
||
Open Group's Single UNIX Specification, Version 2
|
||
[Open Group 1997].
|
||
<!-- ???: how about BSD variants? -->
|
||
System V IPC objects can be one of three kinds:
|
||
System V message queues, semaphore sets, and shared memory segments.
|
||
Each such object has the following attributes:
|
||
|
||
<itemizedlist>
|
||
<listitem>
|
||
|
||
<para>
|
||
read and write permissions for each of creator, creator group, and
|
||
others.
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
|
||
<para>
|
||
creator UID and GID - UID and GID of the creator of the object.
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
|
||
<para>
|
||
owning UID and GID - UID and GID of the owner of the
|
||
object (initially equal to the creator UID).
|
||
</para>
|
||
</listitem>
|
||
|
||
</itemizedlist>
|
||
|
||
</para>
|
||
|
||
<para>
|
||
When accessing such objects, the rules are as follows:
|
||
|
||
<itemizedlist>
|
||
<listitem>
|
||
|
||
<para>
|
||
if the process has root privileges, the access is granted.
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
|
||
<para>
|
||
if the process' EUID is the owner or creator UID of the object,
|
||
then the appropriate creator permission bit is
|
||
checked to see if access is granted.
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
|
||
<para>
|
||
if the process' EGID is the owner or creator GID of the object,
|
||
or one of the process' groups is the owning or creating GID of the object,
|
||
then the appropriate creator group permission bit is checked for access.
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
|
||
<para>
|
||
otherwise, the appropriate ``other'' permission bit is checked
|
||
for access.
|
||
</para>
|
||
</listitem>
|
||
|
||
</itemizedlist>
|
||
|
||
</para>
|
||
|
||
<para>
|
||
Note that root, or a process with the EUID of either the owner or creator,
|
||
can set the owning UID and owning GID and/or remove the object.
|
||
More information is available in ipc(5).
|
||
</para>
|
||
|
||
</sect1>
|
||
|
||
<sect1>
|
||
<title>Sockets and Network Connections</title>
|
||
|
||
<para>
|
||
<!-- Sockets are supported by System V according to Linux's socket(2) -->
|
||
Sockets are used for communication, particularly over a network.
|
||
Sockets were originally developed by the
|
||
BSD branch of Unix systems, but they are generally portable to other
|
||
Unix-like systems: Linux and System V variants support sockets as well, and
|
||
socket support is required by the Open Group's
|
||
Single Unix Specification [Open Group 1997].
|
||
System V systems traditionally used a different (incompatible) network
|
||
communication interface, but it's worth noting that systems like Solaris
|
||
include support for sockets.
|
||
Socket(2) creates an endpoint for communication and returns a descriptor,
|
||
in a manner similar to open(2) for files.
|
||
The parameters for socket specify the protocol family and type,
|
||
such as the Internet domain (TCP/IP version 4), Novell's IPX,
|
||
or the ``Unix domain''.
|
||
A server then typically calls bind(2), listen(2), and accept(2) or select(2).
|
||
A client typically calls bind(2) (though that may be omitted) and
|
||
connect(2).
|
||
See these routine's respective man pages for more information.
|
||
It can be difficult to understand how to use sockets from their man pages;
|
||
you might want to consult other papers such as
|
||
Hall "Beej" [1999]
|
||
to learn how these calls are used together.
|
||
</para>
|
||
|
||
<para>
|
||
The ``Unix domain sockets'' don't actually represent a network protocol; they
|
||
can only connect to sockets on the same machine.
|
||
(at the time of this writing for the standard Linux kernel).
|
||
When used as a stream, they are fairly similar to named pipes, but with
|
||
significant advantages.
|
||
In particular, Unix domain socket is connection-oriented; each new connection to
|
||
the socket results in a new communication channel, a very different situation
|
||
than with named pipes.
|
||
Because of this property, Unix domain sockets are often used instead of
|
||
named pipes to implement IPC for many important services.
|
||
Just like you can have unnamed pipes, you can have unnamed Unix domain sockets
|
||
using socketpair(2); unnamed Unix domain sockets
|
||
are useful for IPC in a way similar to unnamed pipes.
|
||
</para>
|
||
|
||
<para>
|
||
There are several interesting security implications of Unix domain sockets.
|
||
First, although Unix domain sockets can appear in the filesystem and can have
|
||
stat(2) applied to them, you can't use open(2) to open them (you have
|
||
to use the socket(2) and friends interface).
|
||
Second, Unix domain sockets can be used to pass
|
||
file descriptors between processes (not just the file's contents).
|
||
This odd capability, not available in any other IPC mechanism, has been used
|
||
to hack all sorts of schemes (the descriptors can basically
|
||
be used as a limited version of the
|
||
``capability'' in the computer science sense of the term).
|
||
File descriptors are sent using sendmsg(2), where the msg (message)'s
|
||
field msg_control points to an array of control message headers
|
||
(field msg_controllen must specify the number of bytes contained in the array).
|
||
Each control message is a struct cmsghdr followed by data, and for this purpose
|
||
you want the cmsg_type set to SCM_RIGHTS.
|
||
A file descriptor is retrieved through recvmsg(2) and then tracked down in
|
||
the analogous way.
|
||
Frankly, this feature is quite baroque, but it's worth knowing about.
|
||
</para>
|
||
|
||
<para>
|
||
Linux 2.2 supports an addition feature in Unix domain sockets: you can
|
||
acquire the peer's ``credentials'' (the pid, uid, and gid).
|
||
Here's some sample code:
|
||
<programlisting width="61">
|
||
<![CDATA[
|
||
/* fd= file descriptor of Unix domain socket connected
|
||
to the client you wish to identify */
|
||
|
||
struct ucred cr;
|
||
int cl=sizeof(cr);
|
||
|
||
if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &cr, &cl)==0) {
|
||
printf("Peer's pid=%d, uid=%d, gid=%d\n",
|
||
cr.pid, cr.uid, cr.gid);
|
||
]]>
|
||
</programlisting>
|
||
</para>
|
||
|
||
<para>
|
||
Standard Unix convention is that binding to
|
||
TCP and UDP local port numbers less than 1024 requires
|
||
root privilege, while any process can bind to an unbound port number
|
||
of 1024 or greater.
|
||
Linux follows this convention,
|
||
more specifically, Linux requires a process to have the
|
||
capability CAP_NET_BIND_SERVICE to bind to a port number less than 1024;
|
||
this capability is normally only held by processes with an euid of 0.
|
||
The adventurous can check this in Linux by examining its Linux's source;
|
||
in Linux 2.2.12, it's file <filename>/usr/src/linux/net/ipv4/af_inet.c</filename>,
|
||
function inet_bind().
|
||
</para>
|
||
|
||
</sect1>
|
||
|
||
<sect1>
|
||
<title>Signals</title>
|
||
|
||
<para>
|
||
Signals are a simple form of ``interruption'' in the Unix-like OS world,
|
||
and are an ancient part of Unix.
|
||
A process can set a ``signal'' on another process (say using
|
||
kill(1) or kill(2)), and that other process would receive and
|
||
handle the signal asynchronously.
|
||
For a process to have permission to send a signal to some other process,
|
||
the sending process must either have root privileges, or
|
||
the real or effective user ID of the sending process
|
||
must equal the real or saved set-user-ID of the receiving process.
|
||
</para>
|
||
|
||
<para>
|
||
Although signals are an ancient part of Unix, they've had different
|
||
semantics in different implementations.
|
||
Basically, they involve questions such as ``what happens when a signal
|
||
occurs while handling another signal''?
|
||
The older Linux libc 5 used a different set of semantics for some signal
|
||
operations than the newer GNU libc libraries.
|
||
For more information, see the glibc FAQ (on some systems a local
|
||
copy is available at <filename>/usr/doc/glibc-*/FAQ</filename>).
|
||
</para>
|
||
|
||
<para>
|
||
For new programs, just use the POSIX signal system
|
||
(which in turn was based on BSD work); this set is widely supported
|
||
and doesn't have the problems that some of the older signal systems did.
|
||
The POSIX signal system is based on using the sigset_t datatype, which can
|
||
be manipulated through a set of operations: sigemptyset(),
|
||
sigfillset(), sigaddset(), sigdelset(), and sigismember().
|
||
You can read about these in sigsetops(3).
|
||
Then use sigaction(2), sigaction(2), sigprocmask(2),
|
||
sigpending(2), and sigsuspend(2) to set up an manipulate signal handling
|
||
(see their man pages for more information).
|
||
</para>
|
||
|
||
<para>
|
||
In general, make any signal handlers very short and simple, and
|
||
look carefully for race conditions.
|
||
Signals, since they are by nature asynchronous,
|
||
can easily cause race conditions.
|
||
</para>
|
||
|
||
<para>
|
||
A common convention exists for servers: if you receive SIGHUP, you should
|
||
close any log files, reopen and reread configuration files, and then
|
||
re-open the log files.
|
||
This supports reconfiguration without halting the server and
|
||
log rotation without data loss.
|
||
If you are writing a server where this convention makes sense,
|
||
please support it.
|
||
</para>
|
||
|
||
</sect1>
|
||
|
||
<sect1>
|
||
<title>Quotas and Limits</title>
|
||
|
||
<para>
|
||
Many Unix-like systems have
|
||
mechanisms to support filesystem quotas and process resource limits.
|
||
This certainly includes Linux.
|
||
These mechanisms are particularly useful for preventing denial of service
|
||
attacks; by limiting the resources available to each user, you can make
|
||
it hard for a single user to use up all the system resources.
|
||
Be careful with terminology here, because both filesystem quotas
|
||
and process resource limits have ``hard'' and
|
||
``soft'' limits but the terms mean slightly different things.
|
||
</para>
|
||
|
||
<para>
|
||
You can define storage (filesystem) quota limits on each mountpoint
|
||
for the number of blocks of storage and/or the number of unique files
|
||
(inodes) that can be used, and you can set such limits for a given user
|
||
or a given group.
|
||
A ``hard'' quota limit is a never-to-exceed limit, while a
|
||
``soft'' quota can be temporarily exceeded.
|
||
See quota(1), quotactl(2), and quotaon(8).
|
||
</para>
|
||
|
||
<para>
|
||
The rlimit mechanism supports a large number of process quotas, such as
|
||
file size, number of child processes, number of open files, and so on.
|
||
There is a ``soft'' limit (also called the current limit) and a
|
||
``hard limit'' (also called the upper limit).
|
||
The soft limit cannot be exceeded at any time, but through calls it can
|
||
be raised up to the value of the hard limit.
|
||
See getrlimit(), setrlimit(), and getrusage().
|
||
Note that there are several ways to set these limits, including the
|
||
PAM module pam_limits.
|
||
</para>
|
||
|
||
</sect1>
|
||
|
||
<sect1>
|
||
<title>Dynamically Linked Libraries</title>
|
||
|
||
<para>
|
||
Practically all programs depend on libraries to execute.
|
||
In most modern Unix-like systems, including Linux,
|
||
programs are by default compiled to use <emphasis remap="it">dynamically linked libraries</emphasis>
|
||
(DLLs).
|
||
That way, you can update a library and all the programs using that library
|
||
will use the new (hopefully improved) version if they can.
|
||
</para>
|
||
|
||
<para>
|
||
Dynamically linked libraries are typically placed in one a few special
|
||
directories. The usual directories include
|
||
<filename>/lib</filename>, <filename>/usr/lib</filename>, <filename>/lib/security</filename>
|
||
for PAM modules,
|
||
<filename>/usr/X11R6/lib</filename> for X-windows, and <filename>/usr/local/lib</filename>.
|
||
</para>
|
||
|
||
<para>
|
||
There are special conventions for naming libraries and having symbolic
|
||
links for them, with the result that you can update libraries and still
|
||
support programs that want to use old, non-backward-compatible versions
|
||
of those libraries.
|
||
There are also ways to override specific libraries or even just
|
||
specific functions in a library when executing a particular program.
|
||
This is a real advantage of Unix-like systems over
|
||
Windows-like systems; I believe Unix-like systems have a much better system
|
||
for handling library updates, one reason that Unix and Linux systems are reputed
|
||
to be more stable than Windows-based systems.
|
||
</para>
|
||
|
||
<para>
|
||
On GNU glibc-based systems, including all Linux systems,
|
||
the list of directories automatically searched during program start-up is
|
||
stored in the file /etc/ld.so.conf.
|
||
Many Red Hat-derived distributions don't normally
|
||
include <filename>/usr/local/lib</filename>
|
||
in the file <filename>/etc/ld.so.conf</filename>.
|
||
I consider this a bug, and adding <filename>/usr/local/lib</filename> to
|
||
<filename>/etc/ld.so.conf</filename>
|
||
is a common ``fix'' required to run many programs on Red Hat-derived systems.
|
||
If you want to just override a few functions in a library, but keep the
|
||
rest of the library, you can enter the names of overriding libraries
|
||
(.o files) in <filename>/etc/ld.so.preload</filename>;
|
||
these ``preloading'' libraries will take precedence over the standard set.
|
||
This preloading file is typically used for emergency patches;
|
||
a distribution usually won't include such a file when delivered.
|
||
Searching all of these directories at program start-up would be too
|
||
time-consuming, so a caching arrangement is actually used.
|
||
The program ldconfig(8) by default reads in the file /etc/ld.so.conf,
|
||
sets up the appropriate symbolic links in the dynamic link directories
|
||
(so they'll follow the standard conventions),
|
||
and then writes a cache to /etc/ld.so.cache that's then used by other
|
||
programs.
|
||
So, ldconfig has to be run whenever a DLL is added, when a DLL is removed,
|
||
or when the set of DLL directories changes; running ldconfig is often
|
||
one of the steps performed by package managers
|
||
when installing a library.
|
||
On start-up, then, a program uses the dynamic loader to
|
||
read the file /etc/ld.so.cache and then load the libraries it needs.
|
||
</para>
|
||
|
||
<para>
|
||
Various environment variables can control this process, and in fact
|
||
there are environment variables that permit you to
|
||
override this process (so, for example, you can temporarily
|
||
substitute a different library for this particular execution).
|
||
In Linux,
|
||
the environment variable
|
||
LD_LIBRARY_PATH is a colon-separated set of directories where libraries
|
||
should be searched for first, before the standard set of directories;
|
||
this is useful when debugging a new library or using a nonstandard
|
||
library for special purposes.
|
||
The variable LD_PRELOAD lists object files with functions that override
|
||
the standard set, just as /etc/ld.so.preload does.
|
||
</para>
|
||
|
||
<para>
|
||
Permitting user control over dynamically linked libraries
|
||
would be disastrous for setuid/setgid programs if special measures
|
||
weren't taken.
|
||
Therefore, in the GNU glibc implementation, if the program is setuid or setgid
|
||
these variables (and other similar variables) are ignored or greatly
|
||
limited in what they can do.
|
||
The GNU glibc library determines if a program is setuid or setgid
|
||
by checking the program's credentials;
|
||
if the uid and euid differ, or the gid and the egid differ, the
|
||
library presumes the program is setuid/setgid (or descended from one)
|
||
and therefore greatly limits its abilities to control linking.
|
||
If you load the GNU glibc libraries, you can see this; see especially
|
||
the files elf/rtld.c and sysdeps/generic/dl-sysdep.c.
|
||
This means that if you cause the uid and gid to equal the euid and egid,
|
||
and then call a program, these variables will have full effect.
|
||
Other Unix-like systems handle the situation differently but for the
|
||
same reason: a setuid/setgid program should not be unduly affected
|
||
by the environment variables set.
|
||
</para>
|
||
|
||
</sect1>
|
||
|
||
<sect1>
|
||
<title>Audit</title>
|
||
|
||
<para>
|
||
Different Unix-like systems handle auditing differently.
|
||
In Linux, the most common ``audit'' mechanism is syslogd(8), usually working
|
||
in conjuction with klogd(8).
|
||
You might also want to look at wtmp(5), utmp(5), lastlog(8), and acct(2).
|
||
Some server programs (such as the Apache web server)
|
||
also have their own audit trail mechanisms.
|
||
According to the FHS, audit logs should be stored in /var/log or its
|
||
subdirectories.
|
||
</para>
|
||
|
||
</sect1>
|
||
|
||
<sect1>
|
||
<title>PAM</title>
|
||
|
||
<para>
|
||
Sun Solaris and nearly all Linux systems use the
|
||
Pluggable Authentication Modules (PAM) system for authentication.
|
||
PAM permits run-time configuration of authentication methods
|
||
(e.g., use of passwords, smart cards, etc.).
|
||
PAM will be discussed more fully later in this document.
|
||
</para>
|
||
|
||
</sect1>
|
||
|
||
</chapter>
|
||
|
||
<chapter>
|
||
<title>Validate All Input</title>
|
||
|
||
<epigraph>
|
||
<attribution>Proverbs 2:12 (NIV)</attribution>
|
||
<para>
|
||
Wisdom will save you from the ways of wicked men,
|
||
from men whose words are perverse...
|
||
</para>
|
||
</epigraph>
|
||
|
||
<para>
|
||
Some inputs are from untrustable users, so those inputs must be validated
|
||
(filtered) before being used.
|
||
You should determine what is legal and reject anything that does
|
||
not match that definition.
|
||
Do not do the reverse (identify what is illegal and reject those cases),
|
||
because you are likely to forget to handle an important case.
|
||
Limit the maximum character length (and minimum length if appropriate),
|
||
and be sure to not lose control when such lengths are exceeded
|
||
(see the buffer overflow section below for more about this).
|
||
</para>
|
||
|
||
<para>
|
||
For strings, identify the legal characters or legal patterns
|
||
(e.g., as a regular expression) and reject anything not matching that form.
|
||
There are special problems when strings contain control characters
|
||
(especially linefeed or NIL) or shell metacharacters; it is often
|
||
best to ``escape'' such metacharacters immediately when the input is received so
|
||
that such characters are not accidentally sent.
|
||
CERT goes further and recommends escaping all characters
|
||
that aren't in a list of characters not needing escaping [CERT 1998, CMU 1998].
|
||
See the section on ``limit call-outs to valid values'', below, for more
|
||
information.
|
||
</para>
|
||
|
||
<para>
|
||
Limit all numbers to the minimum (often zero) and maximum allowed values.
|
||
Filenames should be checked; usually you will want to not include ``..''
|
||
(higher directory) as a legal value.
|
||
In filenames it's best to prohibit any change in directory, e.g., by not
|
||
including ``/'' in the set of legal characters.
|
||
A full email address checker is actually quite complicated, because there
|
||
are legacy formats that greatly complicate validation if you need
|
||
to support all of them; see mailaddr(7) and IETF RFC 822 [RFC 822]
|
||
for more information if such checking is necessary.
|
||
</para>
|
||
|
||
<para>
|
||
The legal character patterns must not include characters
|
||
or character sequences that have special meaning to the program internals
|
||
or the eventual output unless you account for them.
|
||
In particular, if you store data (internally or externally) in delimited
|
||
strings, make sure that the delimeters are not permitted data values.
|
||
Here are two common cases:
|
||
<itemizedlist>
|
||
<listitem><para>
|
||
A character sequence may have special meaning to the program's internal
|
||
storage format.
|
||
A number of programs
|
||
store data in comma (,) or colon (:) delimited text files;
|
||
inserting such values
|
||
in the input can be problem unless the program accounts for it.
|
||
Other characters often causing these problems include single and double quotes
|
||
(used for surrounding strings)
|
||
and the less-than sign
|
||
(used in SGML, XML, and HTML to indicate a tag's beginning).
|
||
Most data formats have an escape sequence to handle these cases; use it,
|
||
or filter such data on input.
|
||
</para></listitem>
|
||
<listitem><para>
|
||
A character sequence may have special meaning if sent back out to the user.
|
||
Another common case is permitting HTML tags in data input that will later
|
||
be posted to other readers (e.g., in a guestbook or ``reader comment'' area).
|
||
These tags can be used by malicious users to attack other users by inserting
|
||
Java references (including references to hostile applets), DHTML tags,
|
||
early document endings (via </HTML>), absurd font size requests,
|
||
and so on,
|
||
causing anything from unreadable pages to destructive attacks.
|
||
It's safest to strip or escape all HTML tags, but at least identify a list
|
||
of ``safe'' HTML commands and only permit those commands.
|
||
Common safe HTML tags that might be useful for guestbook or
|
||
other applications supporting short comments include
|
||
<P> (paragraph),
|
||
<B> (bold),
|
||
<I> (italics),
|
||
<EM> (emphasis),
|
||
<STRONG> (strong emphasis),
|
||
<PRE> (preformatted text),
|
||
<BR> (forced line break),
|
||
and
|
||
<A HREF="safe URI"> (hypertext link),
|
||
as well as all their ending tags.
|
||
You might even consider supporting the list-oriented tags, such as
|
||
<OL> (ordered list),
|
||
<UL> (unordered list),
|
||
and <LI> (list item).
|
||
It's tricky to define ``safe URI''; I'd suggest a pattern like
|
||
``(http|ftp)://[-A-Za-z0-9._]+''
|
||
(this allows ``..'', which is often fine in this application, but
|
||
note that it intentionally prevents most query formats and other
|
||
schemes like ``mailto'').
|
||
There are more HTML tags, but after a certain point you're really permitting
|
||
full publishing (in which case you need to trust them or perform more
|
||
serious checking than will be described here).
|
||
You really should check if the HTML commands are properly nested
|
||
(though supporting an implied </P> where not provided before a
|
||
<P> would be fine), and if you support list tags further checking
|
||
is warranted.
|
||
</para></listitem>
|
||
</itemizedlist>
|
||
</para>
|
||
|
||
<para>
|
||
These tests should usually be centralized in one place so that the
|
||
validity tests can be easily examined for correctness later.
|
||
</para>
|
||
|
||
<para>
|
||
Make sure that your validity test is actually correct; this is particularly
|
||
a problem when checking input that will be used by another program
|
||
(such as a filename, email address, or URL).
|
||
Often these tests are have subtle errors, producing the so-called
|
||
``deputy problem'' (where the checking program
|
||
makes different assumptions than the program that actually uses the data).
|
||
</para>
|
||
|
||
<para>
|
||
While parsing user input, it's a good idea to temporarily drop all privileges,
|
||
or even create separate processes (with the parser having permanently dropped
|
||
privileges, and the other process performing security checks against the
|
||
parser requests).
|
||
This is especially true if the parsing task is complex (e.g., if you use
|
||
a lex-like or yacc-like tool), or if the programming language
|
||
doesn't protect against buffer overflows (e.g., C and C++).
|
||
See the section below on minimizing permissions.
|
||
</para>
|
||
|
||
<para>
|
||
The following subsections discuss different kinds of inputs to a program;
|
||
note that input includes process state such as environment variables,
|
||
umask values, and so on.
|
||
Not all inputs are under the control of an untrusted user, so you need
|
||
only worry about those inputs that are.
|
||
</para>
|
||
|
||
<sect1>
|
||
<title>Command line</title>
|
||
|
||
<para>
|
||
Many programs use the command line as an input interface, accepting
|
||
input by being passed arguments.
|
||
A setuid/setgid program has a command line interface provided to it by
|
||
an untrusted user, so it must defend itself.
|
||
Users have great control over the command line (through calls such
|
||
as the execve(3) call).
|
||
Therefore, setuid/setgid programs must validate the command line inputs and
|
||
must not trust the name of the program reported by command line argument zero
|
||
(the user can set it to any value including NULL).
|
||
</para>
|
||
|
||
</sect1>
|
||
|
||
<sect1>
|
||
<title>Environment Variables</title>
|
||
|
||
<para>
|
||
By default, environment variables are inherited from a process' parent.
|
||
However, when a program executes another program, the calling program
|
||
can set the environment variables to arbitrary values.
|
||
This is dangerous to setuid/setgid programs, because their invoker can
|
||
completely control the environment variables they're given.
|
||
Since they are usually inherited, this also applies transitively; a
|
||
secure program might call some other program and, without special measures,
|
||
would pass potentially dangerous environment variables values on to the
|
||
program it calls.
|
||
</para>
|
||
|
||
<sect2>
|
||
<title>Some Environment Variables are Dangerous</title>
|
||
|
||
<para>
|
||
Some environment variables are dangerous because
|
||
many libraries and programs are controlled by environment
|
||
variables in ways that are obscure, subtle, or undocumented.
|
||
For example, the IFS variable is used by the <emphasis remap="it">sh</emphasis> and <emphasis remap="it">bash</emphasis>
|
||
shell to determine which characters separate command line arguments.
|
||
Since the shell is invoked by several low-level calls
|
||
(like system(3) and popen(3) in C, or the back-tick operator in Perl),
|
||
setting IFS to unusual values can subvert apparently-safe calls.
|
||
This behavior is documented in bash and sh, but it's obscure;
|
||
many long-time users only know about IFS because of its use in breaking
|
||
security, not because it's actually used very often for its intended purpose.
|
||
What is worse is that not all environment variables are documented, and
|
||
even if they are, those other programs may change and add dangerous
|
||
environment variables.
|
||
Thus, the only real solution (described below) is to select the ones you
|
||
need and throw away the rest.
|
||
</para>
|
||
|
||
</sect2>
|
||
|
||
<sect2>
|
||
<title>Environment Variable Storage Format is Dangerous</title>
|
||
|
||
<para>
|
||
Normally, programs should use the standard access routines to access
|
||
environment variables.
|
||
For example, in C, you should get values
|
||
using getenv(3), set them using the
|
||
POSIX standard routine putenv(3) or the BSD extension setenv(3)
|
||
and eliminate environment variables using unsetenv(3).
|
||
I should note here that setenv(3) is implemented in Linux, too.
|
||
However, crackers need not be so nice; crackers can directly control the
|
||
environment variable data area passed to a program using execve(2).
|
||
This permits some nasty attacks, which can only be understood by
|
||
understanding how environment variables really work.
|
||
In Linux, you can see environ(5) for a summary how about environment variables
|
||
really work.
|
||
In short, environment variables are internally stored as a pointer to
|
||
an array of pointers to characters; this array is stored in order and
|
||
terminated by a NULL pointer (so you'll know when the array ends).
|
||
The pointers to characters, in turn, each
|
||
point to a NIL-terminated string value of the form ``NAME=value''.
|
||
This has several implications, for example, environment variable names
|
||
can't include the equal sign, and neither the name nor value can have
|
||
embedded NIL characters.
|
||
However, a more dangerous implication of this format is that it allows
|
||
multiple entries with the same variable name, but with different values
|
||
(e.g., more than one value for SHELL).
|
||
While typical command shells prohibit doing this,
|
||
a locally-executing cracker can create such a situation using execve(2).
|
||
</para>
|
||
|
||
<para>
|
||
The problem with this storage format (and the way it's set)
|
||
is that a program might check one of these values
|
||
(to see if it's valid) but actually use a different one.
|
||
In Linux,
|
||
the GNU glibc libraries try to shield programs from this;
|
||
glibc 2.1's implementation of getenv will always get the first matching
|
||
entry, setenv and putenv will always set the first matching entry, and
|
||
unsetenv will actually unset <emphasis remap="it">all</emphasis> of the matching entries
|
||
(congratulations to the GNU glibc implementors for implementing
|
||
unsetenv this way!).
|
||
However, some programs go directly to the environ variable and iterate
|
||
across all environment variables; in this case,
|
||
they might use the last matching entry instead of the first one.
|
||
As a result, if checks were made against the first matching entry instead,
|
||
but the actual value used is the last matching entry,
|
||
a cracker can use this fact to circumvent the protection routines.
|
||
</para>
|
||
|
||
</sect2>
|
||
|
||
<sect2>
|
||
<title>The Solution - Extract and Erase</title>
|
||
|
||
<para>
|
||
For secure setuid/setgid programs, the short list of environment variables
|
||
needed as input (if any) should be carefully extracted.
|
||
Then the entire environment should be erased,
|
||
followed by resetting a small set of necessary environment
|
||
variables to safe values.
|
||
There really isn't a better way if you make any calls to subordinate
|
||
programs; there's no practical
|
||
method of listing ``all the dangerous values''.
|
||
Even if you reviewed the source code of every program you call
|
||
directly or indirectly,
|
||
someone may add new undocumented environment variables after you
|
||
write your code, and one of them may be exploitable.
|
||
</para>
|
||
|
||
<para>
|
||
The simple way to erase the environment is by setting the global variable
|
||
<emphasis remap="it">environ</emphasis>
|
||
to NULL.
|
||
The global variable environ is defined in <unistd.h>; C/C++ users will
|
||
want to #include this header file.
|
||
You will need to manipulate this value before spawning threads, but that's
|
||
rarely a problem, since you want to do these manipulations very early in
|
||
the program's execution.
|
||
Another way is to use the undocumented clearenv() function.
|
||
clearenv() has an odd history; it was supposed to be defined in POSIX.1, but
|
||
somehow never made it into that standard.
|
||
However, clearenv() is defined in POSIX.9
|
||
(the Fortran 77 bindings to POSIX), so there is a quasi-official status for it.
|
||
clearenv() is defined in <stdlib.h>, but before using #include
|
||
to include it you must make sure that __USE_MISC is #defined.
|
||
</para>
|
||
|
||
<para>
|
||
One value you'll almost certainly re-add is PATH,
|
||
the list of directories to search for programs; PATH should
|
||
<emphasis remap="it">not</emphasis> include the current directory and usually be something simple like
|
||
``/bin:/usr/bin''.
|
||
Typically you'll also set
|
||
IFS (to its default of `` \t\n'') and TZ (timezone).
|
||
Linux won't die if you don't supply either IFS or TZ,
|
||
but some System V based systems have problems if you don't supply a TZ value,
|
||
and it's rumored that some shells need the IFS value set.
|
||
In Linux, see environ(5) for a list of common environment variables that you
|
||
<emphasis remap="it">might</emphasis> want to set.
|
||
</para>
|
||
|
||
<para>
|
||
If you really need user-supplied values, check the values first
|
||
(to ensure that the values match a pattern for legal values and that they
|
||
are within some reasonable maximum length).
|
||
Ideally there would be some standard trusted file in /etc with the
|
||
information for ``standard safe environment variable values'',
|
||
but at this time there's no standard file defined for this purpose.
|
||
For something similar, you might want to examine the PAM module pam_env
|
||
on those systems which have that module.
|
||
</para>
|
||
|
||
<para>
|
||
If you're programming a setuid/setgid program in a language
|
||
that doesn't allow you to reset the environment directly,
|
||
one approach is to create a ``wrapper'' program.
|
||
The wrapper sets the environment program to safe values, and then
|
||
calls the other program.
|
||
Beware: make sure the wrapper will actually invoke the intended program;
|
||
if it's an interpreted program, make sure there's no race condition possible
|
||
that would allow the interpreter to load a different program than the one
|
||
that was granted the special setuid/setgid privileges.
|
||
</para>
|
||
|
||
</sect2>
|
||
|
||
</sect1>
|
||
|
||
<sect1>
|
||
<title>File Descriptors</title>
|
||
|
||
<para>
|
||
A program is passed a set of ``open file descriptors'', that is,
|
||
pre-opened files.
|
||
A setuid/setgid program must deal with the fact that the user gets to
|
||
select what files are open and to what (within their permission limits).
|
||
A setuid/setgid program must not assume that opening a new file will always
|
||
open into a fixed file descriptor id.
|
||
It must also not assume that standard input (stdin),
|
||
standard output (stdout), and standard error (stderr)
|
||
refer to a terminal or are even open.
|
||
</para>
|
||
|
||
<para>
|
||
The rationale behind this is easy; since an attacker can open or
|
||
close a file descriptor before starting the program,
|
||
the attacker could create an unexpected situation.
|
||
If the attacker closes the standard output, when the program opens
|
||
the next file it will be opened as though it were standard output,
|
||
and then it will send all standard output to that file as well.
|
||
Some C libraries will automatically open stdin, stdout, and stderr
|
||
if they aren't already open (to /dev/null), but this isn't true on
|
||
all Unix-like systems.
|
||
</para>
|
||
|
||
</sect1>
|
||
|
||
<sect1>
|
||
<title>File Contents</title>
|
||
|
||
<para>
|
||
If a program takes directions from a file, it must not trust that file
|
||
specially unless only a trusted user can control its contents.
|
||
Usually this means that an untrusted user must not be able to modify the file,
|
||
its directory, or any of its ancestor directories.
|
||
Otherwise, the file must be treated as suspect.
|
||
</para>
|
||
|
||
<para>
|
||
If the directions in the file are supposed to be from an untrusted user,
|
||
then make sure that the inputs from the file are protected as describe
|
||
throughout this document.
|
||
In particular, check that values match the set of legal values, and that
|
||
buffers are not overflowed.
|
||
</para>
|
||
|
||
</sect1>
|
||
|
||
<sect1>
|
||
<title>Web-Based Applications (Especially CGI Scripts)</title>
|
||
|
||
<para>
|
||
Web-based applications (such as CGI scripts) run on some trusted
|
||
server and must get their
|
||
input data somehow through the web.
|
||
Since the input data generally come from untrusted users,
|
||
this input data must be validated.
|
||
For example, CGI scripts
|
||
are passed this information
|
||
through a standard set of environment variables and through standard input.
|
||
The rest of this text will specifically discuss CGI, because it's
|
||
the most common technique for implementing dynamic web content, but
|
||
the general issues are the same for most other dynamic web content techniques.
|
||
</para>
|
||
|
||
<para>
|
||
One additional complication is that many CGI inputs are provided in
|
||
so-called ``URL-encoded'' format, that is, some values are written in the
|
||
format %HH where HH is the hexadecimal code for that byte.
|
||
You or your CGI library must handle these inputs correctly by
|
||
URL-decoding the input and then checking
|
||
if the resulting byte value is acceptable.
|
||
You must correctly handle all values, including problematic
|
||
values such as %00 (NIL) and %0A (newline).
|
||
Don't decode inputs more than once, or input such as ``%2500''
|
||
will be mishandled (the %25 would be translated to ``%'', and the resulting
|
||
``%00'' would be erroneously translated to the NIL character).
|
||
</para>
|
||
|
||
<para>
|
||
CGI scripts are commonly attacked by including special characters in their
|
||
inputs; see the comments above.
|
||
</para>
|
||
|
||
<para>
|
||
Some HTML forms include client-side checking to prevent some illegal values.
|
||
This checking can be helpful for the user but is useless for security, because
|
||
attackers can send such ``illegal'' values directly to the web server.
|
||
As noted below (in the section on trusting only trustworthy channels),
|
||
servers must perform all of their own input checking.
|
||
</para>
|
||
|
||
</sect1>
|
||
|
||
<sect1>
|
||
<title>Other Inputs</title>
|
||
|
||
<para>
|
||
Programs must ensure that all inputs are controlled; this is particularly
|
||
difficult for setuid/setgid programs because they have so many such inputs.
|
||
Other inputs programs must consider include the current directory,
|
||
signals, memory maps (mmaps), System V IPC, and the umask (which determines
|
||
the default permissions of newly-created files).
|
||
Consider explicitly changing directories (using chdir(2)) to an appropriately
|
||
fully named directory at program startup.
|
||
</para>
|
||
|
||
</sect1>
|
||
|
||
<sect1>
|
||
<title>Human Language (Locale) Selection</title>
|
||
|
||
<para>
|
||
As more people have computers and the Internet available to them, there
|
||
has been increasing pressure for programs
|
||
to support multiple human languages and cultures.
|
||
This combination of language and other cultural factors is usually called
|
||
a ``locale''.
|
||
The process of modifying a program so it can support multiple locales
|
||
is called ``internationalization'' (i18n), and the process of providing
|
||
the information for a particular locale to a program is called
|
||
``localization'' (l10n).
|
||
</para>
|
||
|
||
<para>
|
||
Overall, internationalization
|
||
is a good thing, but this process provides another opportunity
|
||
for a security exploit.
|
||
Since a potentially untrusted user provides information on the desired
|
||
locale, locale selection becomes another input that,
|
||
if not properly protected, can be exploited.
|
||
</para>
|
||
|
||
<sect2>
|
||
<title>How Locales are Selected</title>
|
||
|
||
<para>
|
||
In locally-run programs (including setuid/setgid programs),
|
||
locale information is provided by an environment
|
||
variable.
|
||
Thus, like all other environment variables, these values
|
||
must be extracted and checked against valid patterns before use.
|
||
</para>
|
||
|
||
<para>
|
||
For web applications, this information can be obtained from the web
|
||
browser (via the Accept-Language request header).
|
||
However, since not all web browsers properly pass this information
|
||
(and not all users configure their browsers properly),
|
||
this is used less often than you might think.
|
||
Often, the language requested in a web browser
|
||
is simply passed in as a form value.
|
||
Again, these values must be checked for validity before use, as with
|
||
any other form value.
|
||
</para>
|
||
|
||
<para>
|
||
In either case, locale information is
|
||
really just a special case of input discussed in the previous sections.
|
||
However, because this input is so rarely considered,
|
||
I'm discussing it separately.
|
||
In particular,
|
||
when combined with format strings (discussed later), user-controlled
|
||
strings can permit attackers to force other programs to run
|
||
arbitrary instructions,
|
||
corrupt data, and do other unfortunate actions.
|
||
</para>
|
||
|
||
</sect2>
|
||
|
||
<sect2>
|
||
<title>Locale Support Mechanisms</title>
|
||
|
||
<para>
|
||
There are two major library interfaces for supporting locale-selected
|
||
messages on Unix-like systems,
|
||
one called ``catgets'' and the other called ``gettext''.
|
||
In the catgets approach, every string is assigned a unique number, which
|
||
is used as an index into a table of messages.
|
||
In contrast,
|
||
in the gettext approach, a string (usually in English) is used to
|
||
look up a table that translates the original string.
|
||
catgets(3) is an accepted standard
|
||
(via the X/Open Portability Guide, Volume 3 and
|
||
Single Unix Specification),
|
||
<!-- http://www.opengroup.org/onlinepubs/007908799/xsh/catopen.html -->
|
||
so it's possible your program uses it.
|
||
The ``gettext'' interface is not an official standard,
|
||
(though it was originally a UniForum proposal), but I believe it's the
|
||
more widely used interface
|
||
(it's used by Sun and essentially all GNU programs).
|
||
</para>
|
||
|
||
<para>
|
||
In theory, catgets should be slightly faster, but this is at best
|
||
marginal on today's machines, and the bookkeeping effort to keep
|
||
unique identifiers valid in catgets() makes the gettext() interface
|
||
much easier to use.
|
||
I'd suggest using gettext(), just because it's easier to use.
|
||
However, don't take my word for it; see GNU's documentation on gettext
|
||
(info:gettext#catgets) for a longer and more descriptive comparison.
|
||
</para>
|
||
|
||
<para>
|
||
The catgets(3) call (and its associated catopen(3) call)
|
||
in particular is vulnerable
|
||
to security problems, because the environment variable NLSPATH can be
|
||
used to control the filenames used to acquire internationalized messages.
|
||
The GNU C library ignores NLSPATH for setuid/setgid programs, which helps,
|
||
but that doesn't protect programs running on other implementations, nor
|
||
other programs (like CGI scripts) which don't ``appear'' to
|
||
require such protection.
|
||
</para>
|
||
|
||
<para>
|
||
The widely-used ``gettext'' interface is at least not
|
||
vulnerable to a malicious NLSPATH setting to my knowledge.
|
||
However, it appears likely to me that malicious settings of
|
||
LC_ALL or LC_MESSAGES could cause problems.
|
||
Also, if you use gettext's bindtextdomain() routine in its file cat-compat.c,
|
||
that does depend on NLSPATH.
|
||
</para>
|
||
</sect2>
|
||
|
||
<sect2>
|
||
<title>Legal Values</title>
|
||
|
||
<para>
|
||
For the moment, if you must permit untrusted users to set information on
|
||
their desired locales, make sure the provided internationalization information
|
||
meets a narrow filter that only permits legitimate locale names.
|
||
For user programs (especially setuid/setgid programs), these values
|
||
will come in via NLSPATH, LANGUAGE, LANG, the old LINGUAS, LC_ALL, and
|
||
the other LC_* values (especially LC_MESSAGES, but also including
|
||
LC_COLLATE, LC_CTYPE, LC_MONETARY, LC_NUMERIC, and LC_TIME).
|
||
For web applications, this user-requested set of language information
|
||
would be done via the Accept-Language request header or a form value
|
||
(the application should indicate the actual language setting of the
|
||
data being returned via the Content-Language heading).
|
||
You can check this value as part of your environment variable filtering if
|
||
your users can set your environment variables (i.e., setuid/setgid
|
||
programs) or as part of your input filtering (e.g., for CGI scripts).
|
||
I have not found any guidance on filtering language settings,
|
||
so here are my suggestions based on my own research into the issue.
|
||
</para>
|
||
|
||
<para>
|
||
First, a few words about the legal values of these settings.
|
||
Language settings are generally set using the standard tags defined
|
||
in IETF RFC 1766 (which uses two-letter country codes as its basic tag,
|
||
followed by an optional subtag separated by a dash; I've found that
|
||
environment variable settings use the underscore instead).
|
||
However, some find this insufficiently flexible, so three-letter country
|
||
codes may soon be used as well.
|
||
Also, there are two major not-quite compatible extended formats, the
|
||
X/Open Format and the CEN Format (European Community Standard);
|
||
you'd like to permit both.
|
||
Typical values include
|
||
``C'' (the C locale), ``EN'' (English''),
|
||
and ``FR_fr'' (French using the territory of France's conventions).
|
||
Also, so many people use nonstandard names that programs have had to develop
|
||
``alias'' systems to cope with them
|
||
(for GNU gettext, see /usr/share/locale/locale.aliases, and for X11, see
|
||
/usr/lib/X11/locale/locale.aliases); they should usually be
|
||
permitted as well.
|
||
Libraries like gettext() have to accept all these variants and find an
|
||
appropriate value, where possible.
|
||
One source of further information is FSF [1999].
|
||
However, a filter should not permit characters that aren't needed,
|
||
in particular ``/'' (which might permit escaping out of the trusted
|
||
directories) and ``..'' (which might permit going up one directory).
|
||
Other dangerous characters in NLSPATH
|
||
include ``%'' (which indicates substitution) and ``:''
|
||
(which is the directory separator); the documentation I have for other
|
||
machines suggests that some implementations may use them for other values,
|
||
so it's safest to prohibit them.
|
||
<!-- The Sun man page for "man locale" is disturbingly ambiguous on whether
|
||
or not these characters affect values other than NLSPATH -->
|
||
</para>
|
||
</sect2>
|
||
|
||
<sect2>
|
||
<title>Bottom Line</title>
|
||
|
||
<para>
|
||
In short, I suggest
|
||
simply erasing or re-setting the NLSPATH, unless you have a trusted user
|
||
supplying the value.
|
||
For the Accept-Language heading in HTTP (if you use it),
|
||
form values specifying the locale, and the environment variables
|
||
LANGUAGE, LANG, the old LINGUAS, LC_ALL, and the other LC_* values listed
|
||
above,
|
||
filter the locales from untrusted users to permit null (empty) values or
|
||
to only permit values matching this pattern:
|
||
<programlisting width="61">
|
||
[A-Za-z][A-Za-z0-9_,+@\-\.]*
|
||
</programlisting>
|
||
I haven't found any legitimate locale which doesn't match this pattern,
|
||
but this pattern does appear to protect against locale attacks.
|
||
Of course, there's no guarantee that there are messages available
|
||
in the requested locale,
|
||
but in such a case these routines will fall back to the default
|
||
messages (usually in English), which at least is not a security problem.
|
||
<!-- I developed this pattern, after looking at the GLIBC specs in
|
||
http://www.netppl.fi/~pp/glibc21/libc_8.html and the aliases on
|
||
Red Hat 6.2 -->
|
||
<!-- John Levon was investigating this -->
|
||
</para>
|
||
|
||
<!-- ???: Can internationalization lookups be controlled by an
|
||
untrusted user? Obviously, the language can be selected, but can the
|
||
user supply "their own" strings? If so, that's a security hole!
|
||
See John Levon's Bugtraq post on July 26, 2000.
|
||
-->
|
||
|
||
<para>
|
||
Of course, languages cannot be supported without a
|
||
standard way to represent their written symbols, which brings
|
||
us to the issue of character encoding.
|
||
</para>
|
||
|
||
</sect2>
|
||
|
||
</sect1>
|
||
|
||
<sect1>
|
||
<title>Character Encoding</title>
|
||
|
||
<para>
|
||
For many years Americans have been using the ASCII encoding of characters,
|
||
permitting easy exchange of English texts.
|
||
Unfortunately, ASCII is completely inadequate in handling the character
|
||
sets of most other languages.
|
||
For many years different countries have adopted different techniques for
|
||
exchanging text in different languages.
|
||
More recently, ISO has developed ISO 10646, a single 31-bit encoding for
|
||
all of the world's characters termed the
|
||
Universal Character Set (UCS).
|
||
Characters fitting into 16 bits (the first 65536 values of the UCS)
|
||
are termed the ``Basic Multilingual Plane''
|
||
(BMP), and the BMP is intended to cover nearly all spoken languages.
|
||
The Unicode forum develops the Unicode standard, which concentrates on
|
||
the 16-bit set and adds some additional conventions to aid interoperability.
|
||
</para>
|
||
|
||
<para>
|
||
However, most software is not designed to handle 16 bit or 32 bit characters,
|
||
so a special format called ``UTF-8'' was developed to encode these
|
||
potentially international
|
||
characters in a format more easily handled by existing programs and libraries.
|
||
UTF-8 is defined, among other places, in IETF RFC 2279, so it's a
|
||
well-defined standard that can be freely read and used.
|
||
UTF-8 is a variable-width encoding; characters numbered 0 to 0x7f (127)
|
||
encode to themselves as a single byte,
|
||
while characters with larger values are encoded into 2 to 6 bytes of
|
||
information (depending on their value).
|
||
The encoding has been specially designed to have the following
|
||
nice properties (this information is from the RFC and Linux utf-8 man page):
|
||
|
||
<itemizedlist>
|
||
<listitem><para>
|
||
The classical US ASCII characters (0 to 0x7f) encode as themselves,
|
||
so files and strings which contain only 7-bit ASCII characters
|
||
have the same encoding under both ASCII and UTF-8.
|
||
This is fabulous for backwards compatibility with the many existing
|
||
U.S. programs and data files.
|
||
</para></listitem>
|
||
|
||
<listitem><para>
|
||
All UCS characters beyond 0x7f are encoded as a multibyte
|
||
sequence consisting only of bytes in the range 0x80 to 0xfd.
|
||
This means that no ASCII byte can appear as part of another
|
||
character. Many other encodings permit characters such as an
|
||
embedded NIL, causing programs to fail.
|
||
</para></listitem>
|
||
|
||
<listitem><para>
|
||
It's easy to convert between UTF-8 and a 2-byte or 4-byte
|
||
fixed-width representations of characters (these are called
|
||
UCS-2 and UCS-4 respectively).
|
||
</para></listitem>
|
||
|
||
<listitem><para>
|
||
The lexicographic sorting order of UCS-4 strings is preserved,
|
||
and the Boyer-Moore fast search algorithm can be used directly
|
||
with UTF-8 data.
|
||
</para></listitem>
|
||
|
||
<listitem><para>
|
||
All possible 2^31 UCS codes can be encoded using UTF-8.
|
||
</para></listitem>
|
||
|
||
<listitem><para>
|
||
The first byte of a multibyte sequence which represents
|
||
a single non-ASCII UCS character is always in the range
|
||
0xc0 to 0xfd and indicates how long this multibyte
|
||
sequence is. All further bytes in a multibyte sequence
|
||
are in the range 0x80 to 0xbf. This allows easy resynchronization;
|
||
if a byte is missing, it's easy to skip forward to the ``next''
|
||
character, and it's always easy to skip forward and back to the
|
||
``next'' or ``preceding'' character.
|
||
</para></listitem>
|
||
|
||
</itemizedlist>
|
||
</para>
|
||
|
||
|
||
<para>
|
||
In short, the UTF-8 transformation format is becoming a dominant method
|
||
for exchanging international text information because it can support all of the
|
||
world's languages, yet it is backward compatible with U.S. ASCII files
|
||
as well as having other nice properties.
|
||
For many purposes I recommend its use, particularly when storing data
|
||
in a ``text'' file.
|
||
</para>
|
||
|
||
<para>
|
||
The reason to mention UTF-8 is that
|
||
some byte sequences are not legal UTF-8, and
|
||
this might be an exploitable security hole. The RFC notes the following:
|
||
|
||
<blockquote>
|
||
<para>
|
||
Implementors of UTF-8 need to consider the security aspects of how
|
||
they handle illegal UTF-8 sequences. It is conceivable that in some
|
||
circumstances an attacker would be able to exploit an incautious
|
||
UTF-8 parser by sending it an octet sequence that is not permitted by
|
||
the UTF-8 syntax.
|
||
</para>
|
||
|
||
<para>
|
||
A particularly subtle form of this attack could be carried out
|
||
against a parser which performs security-critical validity checks
|
||
against the UTF-8 encoded form of its input, but interprets certain
|
||
illegal octet sequences as characters. For example, a parser might
|
||
prohibit the NUL character when encoded as the single-octet sequence
|
||
00, but allow the illegal two-octet sequence C0 80 and interpret it
|
||
as a NUL character. Another example might be a parser which
|
||
prohibits the octet sequence 2F 2E 2E 2F ("/../"), yet permits the
|
||
illegal octet sequence 2F C0 AE 2E 2F.
|
||
</para>
|
||
</blockquote>
|
||
|
||
</para>
|
||
|
||
<para>
|
||
A longer discussion about this is available at
|
||
Markus Kuhn's
|
||
<emphasis remap="it">UTF-8 and Unicode FAQ for Unix/Linux</emphasis> at
|
||
<ulink
|
||
url="http://www.cl.cam.ac.uk/~mgk25/unicode.html">http://www.cl.cam.ac.uk/~mgk25/unicode.html</ulink>.
|
||
</para>
|
||
|
||
<para>
|
||
The UTF-8 character set is one case where it's possible to
|
||
enumerate all illegal values (and prove that you've enumerated them all).
|
||
If you need to determine if you have a legal UTF-8 sequence, you need
|
||
to check for two things: (1) is the initial sequence legal, and
|
||
(2) if it is, is the first byte followed by the required number of valid
|
||
continuation characters?
|
||
Performing the first check is easy; the following is provably
|
||
the complete list of all illegal UTF-8 initial sequences:
|
||
|
||
<table>
|
||
<title>Illegal UTF-8 initial sequences</title>
|
||
<tgroup cols="2">
|
||
<colspec colname="coln1">
|
||
<colspec colname="coln2">
|
||
<thead>
|
||
<row><entry>UTF-8 Sequence</entry><entry>Reason for Illegality</entry></row>
|
||
</thead>
|
||
<tbody>
|
||
<row><entry>10xxxxxx</entry> <entry>illegal as initial byte of character (80..BF)</entry></row>
|
||
<row><entry>1100000x </entry><entry>illegal, overlong (C0 80..BF)</entry></row>
|
||
<row><entry>11100000 100xxxxx </entry><entry>illegal, overlong (E0 80..9F)</entry></row>
|
||
<row><entry>11110000 1000xxxx </entry><entry>illegal, overlong (F0 80..8F)</entry></row>
|
||
<row><entry>11111000 10000xxx </entry><entry>illegal, overlong (F8 80..87)</entry></row>
|
||
<row><entry>11111100 100000xx </entry><entry>illegal, overlong (FC 80..83)</entry></row>
|
||
<row><entry>1111111x </entry><entry>illegal; prohibited by spec</entry></row>
|
||
</tbody>
|
||
</tgroup>
|
||
</table>
|
||
|
||
</para>
|
||
|
||
<para>
|
||
I should note that in some cases, you might want to cut slack (or use
|
||
internally) the hexadecimal sequence C0 80. This is an overlong sequence
|
||
that could represent ASCII NUL (NIL). Since C/C++ have trouble
|
||
including a NIL character in an ordinary string, some people have taken
|
||
to using this sequence when they want to represent NIL as part of the
|
||
data stream; Java even enshrines the practice.
|
||
Feel free to use C0 80 internally while processing data, but technically
|
||
you really should translate this back to 00 before saving the data.
|
||
Depending on your needs, you might decide to be ``sloppy'' and accept
|
||
C0 80 as input in a UTF-8 data stream.
|
||
</para>
|
||
|
||
<para>
|
||
The second step is to check
|
||
if the correct number of continuation characters
|
||
are included in the string.
|
||
If the first byte has the top 2 bits set, you count the number of
|
||
``one'' bits set after the top one, and then check that there are that many
|
||
continuation bytes which begin with the bits ``10''.
|
||
So, binary 11100001 requires two more continuation bytes.
|
||
</para>
|
||
|
||
<para>
|
||
A related issue is that some phrases can be expressed in more than one
|
||
way in ISO 10646/Unicode.
|
||
For example, some accented characters can be represented as a single
|
||
character (with the accent) and also as a set of characters
|
||
(e.g., the base character plus a separate composing accent).
|
||
These two forms may appear identical.
|
||
There's also a zero-width space that could be inserted, with the
|
||
result that apparently-similar items are considered different.
|
||
Beware of situations where such hidden text could interfere with the program.
|
||
</para>
|
||
|
||
</sect1>
|
||
|
||
|
||
<sect1>
|
||
<title>Limit Valid Input Time and Load Level</title>
|
||
|
||
<para>
|
||
Place timeouts and load level limits, especially on incoming network data.
|
||
Otherwise, an attacker might be able to easily cause a denial of service
|
||
by constantly requesting the service.
|
||
</para>
|
||
|
||
</sect1>
|
||
|
||
</chapter>
|
||
|
||
<chapter>
|
||
<title>Avoid Buffer Overflow</title>
|
||
|
||
<epigraph>
|
||
<attribution>Amos 3:11 (NIV)</attribution>
|
||
<para>
|
||
An enemy will overrun the land;
|
||
he will pull down your strongholds and
|
||
plunder your fortresses.
|
||
</para>
|
||
</epigraph>
|
||
|
||
<para>
|
||
An extremely common security flaw is the ``buffer overflow''.
|
||
Technically, a buffer overflow is a problem with the program's internal
|
||
implementation, but it's such a common and serious problem that
|
||
I've placed this information in its own chapter.
|
||
To give you an idea of how important this subject is,
|
||
at the CERT, 9 of 13 advisories in 1998 and at least half of
|
||
the 1999 advisories involved buffer overflows.
|
||
An informal survey on Bugtraq found that approximately 2/3 of the
|
||
respondents felt that buffer overflows were the leading cause of
|
||
security vulnerability (the remaining respondents identified
|
||
``misconfiguration'' as the leading cause) [Cowan 1999].
|
||
This is an old, well-known problem, yet it continues to resurface
|
||
[McGraw 2000].
|
||
<!-- ???: Get the stats from the libsafe paper -->
|
||
</para>
|
||
|
||
<para>
|
||
A buffer overflow occurs when you write a set of values
|
||
(usually a string of characters) into a fixed length buffer
|
||
and write at least one value outside that buffer's boundaries
|
||
(usually past its end).
|
||
A buffer overflow can occur when reading input from the user into a buffer,
|
||
but it can also occur during other kinds of processing in a program.
|
||
</para>
|
||
|
||
<para>
|
||
If a secure program permits a buffer overflow, the overflow can often be
|
||
exploited by an adversary.
|
||
If the buffer is a local C variable, the overflow can be used to
|
||
force the function to run code of an attackers' choosing.
|
||
This specific variation is often called a ``stack smashing'' attack.
|
||
A buffer in the heap isn't much better; attackers may be able to
|
||
use such overflows to control other variables in the program.
|
||
More details can be found from Aleph1 [1996], Mudge [1995],
|
||
or the Nathan P. Smith's
|
||
"Stack Smashing Security Vulnerabilities" website at
|
||
<ulink
|
||
url="http://destroy.net/machines/security/">http://destroy.net/machines/security/</ulink>.
|
||
</para>
|
||
|
||
<para>
|
||
Most programming languages are essentially immune to this problem, either
|
||
because they automatically resize arrays (e.g., Perl), or because they normally
|
||
detect and prevent buffer overflows (e.g., Ada95).
|
||
However, the C language provides no protection against
|
||
such problems, and C++ can be easily used in ways to cause this problem too.
|
||
</para>
|
||
|
||
<sect1>
|
||
<title>Dangers in C/C++</title>
|
||
|
||
<para>
|
||
C users must avoid using dangerous functions that do not check bounds
|
||
unless they've ensured that the bounds will never get exceeded.
|
||
Functions to avoid in most cases (or ensure protection) include
|
||
the functions strcpy(3), strcat(3), sprintf(3)
|
||
(with cousin vsprintf(3)), and gets(3).
|
||
These should be replaced with functions such as strncpy(3), strncat(3),
|
||
snprintf(3), and fgets(3) respectively, but see the discussion below.
|
||
The function strlen(3) should be avoided unless you can ensure that there
|
||
will be a terminating NIL character to find.
|
||
The scanf() family (scanf(3), fscanf(3), sscanf(3), vscanf(3),
|
||
vsscanf(3), and vfscanf(3)) is often dangerous to use; do not use it
|
||
to send data to a string without controlling the maximum length
|
||
(the format %s is a particularly common problem).
|
||
Other dangerous functions that may permit buffer overruns (depending on their
|
||
use) include
|
||
realpath(3), getopt(3), getpass(3),
|
||
streadd(3), strecpy(3), and strtrns(3).
|
||
You must careful with getwd(3); the buffer sent to getwd(3) must be
|
||
at least PATH_MAX bytes long.
|
||
</para>
|
||
|
||
<para>
|
||
Unfortunately, snprintf()'s variants have additional problems.
|
||
Officially, snprintf() is not a standard C function in the ISO 1990
|
||
(ANSI 1989) standard, though sprintf() is,
|
||
so not all systems include snprintf().
|
||
Even worse, some systems' snprintf() do not actually protect
|
||
against buffer overflows; they just call sprintf directly.
|
||
Old versions of Linux's libc4 depended on a ``libbsd'' that did this
|
||
horrible thing, and I'm told that some old HP systems did the same.
|
||
Linux's current version of snprintf is known to work correctly, that is, it
|
||
does actually respect the boundary requested.
|
||
The return value of snprintf() varies as well;
|
||
the Single Unix Specification (SUS) version 2
|
||
and the upcoming C99 standard differ on what is returned by snprintf().
|
||
Finally, it appears that at least some versions of
|
||
snprintf don't guarantee that its string will end in NIL; if the
|
||
string is too long, it won't include NIL at all.
|
||
Note that the glib library (the basis of GTK, and not the same as the
|
||
GNU C library glibc) has a g_snprintf(), which
|
||
has a consistent return semantic, always NIL-terminates, and
|
||
most importantly always respects the buffer length.
|
||
<!-- libsafe protects:
|
||
[vf]scanf(const char *format, ...)
|
||
May overflow its arguments.
|
||
realpath(char *path, char resolved_path[])
|
||
May overflow the path buffer.
|
||
[v]sprintf(char *str, const char *format, ...)
|
||
May overflow the str buffer.
|
||
-->
|
||
</para>
|
||
|
||
</sect1>
|
||
|
||
<sect1>
|
||
<title>Library Solutions in C/C++</title>
|
||
|
||
<para>
|
||
One solution in C/C++ is to use library functions that do not have
|
||
buffer overflow problems.
|
||
The first subsection describes the ``standard C library'' solution, which
|
||
can work but has its disadvantages.
|
||
The next subsection describes the general security issues of both
|
||
fixed length and dynamically reallocated approaches to buffers.
|
||
The following subsections describe various alternative libraries,
|
||
such as strlcpy and libmib.
|
||
</para>
|
||
|
||
<sect2>
|
||
<title>Standard C Library Solution</title>
|
||
|
||
<para>
|
||
The ``standard'' solution to prevent buffer overflow in C
|
||
is to use the standard C library calls that defend against these
|
||
problems.
|
||
This approach depends heavily on the standard library functions
|
||
strncpy(3) and strncat(3).
|
||
If you choose this approach, beware: these calls have somewhat surprising
|
||
semantics and are hard to use correctly.
|
||
The function strncpy(3) does not NIL-terminate the destination string
|
||
if the source string length is at least equal to the destination's, so
|
||
be sure to set the last character of the destination string to NIL after
|
||
calling strncpy(3).
|
||
If you're going to reuse the same buffer many times,
|
||
an efficient approach is to tell strncpy() that the buffer is one
|
||
character shorter than it actually is and set the last character to
|
||
NIL once before use.
|
||
Both strncpy(3) and strncat(3) require that you pass
|
||
the amount of space left available, a computation
|
||
that is easy to get wrong (and getting it wrong could permit a
|
||
buffer overflow attack).
|
||
Neither provide a simple mechanism to determine if an overflow has occurred.
|
||
Finally, strncpy(3) has a significant performance penalty compared
|
||
to the strcpy(3) it supposedly replaces,
|
||
because <emphasis remap="it">strncpy(3) NIL-fills the remainder of the destination</emphasis>.
|
||
I've gotten emails expressing surprise over this last point, but this is
|
||
clearly stated in Kernighan and Ritchie second edition
|
||
[Kernighan 1988, page 249], and this behavior is clearly documented in
|
||
the man pages for Linux, FreeBSD, and Solaris.
|
||
This means that just changing from strcpy to strncpy can cause a severe
|
||
reduction in performance, for no good reason in most cases.
|
||
</para>
|
||
|
||
<para>
|
||
<!-- from Hudin Lucian, BUGTRAQ - 29 Jun 2000 -->
|
||
<!-- David A. Wheeler checked it and found that it was WRONG - 18 July 2000 -->
|
||
One posting on bugtraq claimed that you can use sprintf()
|
||
without buffer overflows by using the ``field width'' capability of sprintf().
|
||
Unfortunately, this isn't true; the field width specifies a minimum
|
||
width, not a maximum, so overlong strings can still overflow a
|
||
fixed-length buffer even with field width specifiers.
|
||
Here's an example of this approach that doesn't work:
|
||
<programlisting width="61">
|
||
/* WARNING: This DOES NOT WORK. */
|
||
char buf[BUFSIZ];
|
||
sprintf(buf, "%.*s", BUFSIZ, "big-long-string");
|
||
</programlisting>
|
||
</para>
|
||
|
||
</sect2>
|
||
|
||
<sect2>
|
||
<title>Static and Dynamically Allocated Buffers</title>
|
||
|
||
<para>
|
||
strncpy and friends are an example of statically allocated buffers, that
|
||
is, once the buffer is allocated it stays a fixed size.
|
||
The alternative is to dynamically reallocate buffer sizes as you need them.
|
||
It turns out that both approaches have security implications.
|
||
</para>
|
||
|
||
<para>
|
||
<!-- Thanks to Ryan McCabe (thanks.odin@numb.org) for the comment
|
||
that fixed-length buffers have their own exploitable problems. -->
|
||
There is a general security problem when using fixed-length buffers: the fact
|
||
that the buffer is a fixed length may be exploitable.
|
||
This is a problem with strncpy(3) and strncat(3), snprintf(3),
|
||
strlcpy(3), strlcat(3), and other such functions.
|
||
The basic idea is that the attacker sets up a really long string so that,
|
||
when the string is truncated, the final result will be what the
|
||
attacker wanted (instead of what the developer intended).
|
||
Perhaps the string is catenated from several smaller
|
||
pieces; the attacker might make the first piece as long as the entire
|
||
buffer, so all later attempts to concatenate strings do nothing.
|
||
Here are some specific examples:
|
||
|
||
<itemizedlist>
|
||
<listitem>
|
||
|
||
<para>
|
||
Imagine code that calls gethostbyname(3) and, if
|
||
successful, immediately copies hostent->h_name to a
|
||
fixed-size buffer using strncpy or snprintf.
|
||
Using strncpy or snprintf protects against an overflow of an excessively
|
||
long fully-qualified domain name (FQDN), so you might think you're done.
|
||
However, this could result in chopping off the end of the FQDN.
|
||
This may be very undesirable, depending on what happens next.
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
|
||
<para>
|
||
Imagine code that uses strncpy, strncat, snprintf, etc., to copy the
|
||
full path of a filesystem object to some buffer.
|
||
Further imagine that the original value was provided by an
|
||
untrusted user, and that the copying is part of a process to pass a
|
||
resulting computation to a function.
|
||
Sounds safe, right?
|
||
Now imagine that an attacker pads a path
|
||
with a large number of '/'s at the beginning. This could
|
||
result in future operations being performed on the file ``/''.
|
||
If the program appends values in the belief that the result will be safe,
|
||
the program may be exploitable.
|
||
Or, the attacker could devise a long filename near the buffer length, so that
|
||
attempts to append to the filename would silently fail to occur
|
||
(or only partially occur in ways that may be exploitable).
|
||
</para>
|
||
</listitem>
|
||
|
||
</itemizedlist>
|
||
|
||
</para>
|
||
|
||
<para>
|
||
When using statically-allocated buffers,
|
||
you really need to consider the length of the source and destination arguments.
|
||
Sanity checking the input and the resulting intermediate computation might
|
||
deal with this, too.
|
||
</para>
|
||
|
||
<para>
|
||
Another alternative is to dynamically reallocate all strings instead of using
|
||
fixed-size buffers.
|
||
This general approach is recommended by the GNU programming guidelines,
|
||
since it permits programs to handle arbitrarily-sized inputs
|
||
(until they run out of memory).
|
||
Of course, the major problem with dynamically allocated strings is that you
|
||
may run out of memory. The memory may even be exhausted at some other
|
||
point in the program than the portion where you're worried about buffer
|
||
overflows; any memory allocation can fail.
|
||
Also, since dynamic reallocation may cause memory to be inefficiently
|
||
allocated, it is entirely possible to run out of memory even though
|
||
technically there is enough virtual memory available to the program
|
||
to continue.
|
||
In addition, before running out of memory the program will probably
|
||
use a great deal of virtual memory; this can easily result in
|
||
``thrashing'', a situation in which the computer spends all its time
|
||
just shuttling information between the disk and memory (instead of
|
||
doing useful work).
|
||
This can have the effect of a denial of service attack.
|
||
Some rational limits on input size can help here.
|
||
In general, the program must be designed to
|
||
fail safely when memory is exhausted if you use dynamically allocated strings.
|
||
</para>
|
||
|
||
</sect2>
|
||
|
||
<sect2>
|
||
<title>strlcpy and strlcat</title>
|
||
|
||
<para>
|
||
An alternative, being employed by OpenBSD, is the
|
||
strlcpy(3) and strlcat(3) functions by Miller and de Raadt [Miller 1999].
|
||
This is a minimalist, statically-sized buffer approach that provides C string
|
||
copying and concatenation with a different (and less error-prone) interface.
|
||
Source and documentation of these functions
|
||
are available under a newer BSD-style open source license at
|
||
<ulink
|
||
url="ftp://ftp.openbsd.org/pub/OpenBSD/src/lib/libc/string/strlcpy.3">ftp://ftp.openbsd.org/pub/OpenBSD/src/lib/libc/string/strlcpy.3</ulink>.
|
||
</para>
|
||
|
||
<para>
|
||
First, here are their prototypes:
|
||
|
||
<screen width="61">
|
||
size_t strlcpy (char *dst, const char *src, size_t size);
|
||
size_t strlcat (char *dst, const char *src, size_t size);
|
||
</screen>
|
||
|
||
Both strlcpy and strlcat
|
||
take the full size of the destination buffer as a parameter
|
||
(not the maximum number of characters to be copied) and guarantee to
|
||
NIL-terminate the result (as long as size is larger than 0).
|
||
Remember that you should include a byte for NIL in the size.
|
||
</para>
|
||
|
||
<para>
|
||
The strlcpy function copies up to
|
||
size-1 characters from the NUL-terminated string src to dst,
|
||
NIL-terminating the result.
|
||
The strlcat
|
||
function appends the NIL-terminated string
|
||
src to the end of dst.
|
||
It will append at most
|
||
size - strlen(dst) - 1 bytes, NIL-terminating the result.
|
||
</para>
|
||
|
||
<para>
|
||
One minor disadvantage of strlcpy(3) and strlcat(3) is that they are
|
||
not, by default, installed in most Unix-like systems.
|
||
In OpenBSD, they are part of <string.h>.
|
||
This is not that difficult a problem; since they are small functions, you can
|
||
even include them in your own program's source (at least as an option),
|
||
and create a small separate package to load them.
|
||
You can even use autoconf to handle this case automatically.
|
||
If more programs use these functions, it won't be long before these are
|
||
standard parts of Linux distributions and other Unix-like systems.
|
||
</para>
|
||
|
||
</sect2>
|
||
|
||
<sect2>
|
||
<title>libmib</title>
|
||
|
||
<para>
|
||
One toolset for C that dynamically reallocates strings automatically
|
||
is the ``libmib allocated string functions'' by
|
||
Forrest J. Cavalier III, available at
|
||
<ulink
|
||
url="http://www.mibsoftware.com/libmib/astring">http://www.mibsoftware.com/libmib/astring</ulink>.
|
||
There are two variations of libmib; ``libmib-open'' appears to be clearly
|
||
open source under its own X11-like license that
|
||
permits modification and redistribution, but redistributions must choose
|
||
a different name, however, the developer states that it
|
||
``may not be fully tested.''
|
||
To continuously get libmib-mature, you must pay for a subscription.
|
||
The documentation is not open source, but it is freely available.
|
||
</para>
|
||
|
||
</sect2>
|
||
|
||
<sect2>
|
||
<title>Libsafe</title>
|
||
|
||
<para>
|
||
Arash Baratloo, Timothy Tsai, and Navjot Singh
|
||
(of Lucent Technologies)
|
||
have developed Libsafe, a wrapper of several library functions known to be
|
||
vulnerable to stack smashing attacks.
|
||
This wrapper (which they call a kind of ``middleware'')
|
||
is a simple dynamically loaded library that contains modified versions
|
||
of C library functions such as strcpy(3).
|
||
These modified versions
|
||
implement the original functionality, but in a manner that ensures
|
||
that any buffer overflows are contained within the current stack frame.
|
||
Their initial performance analysis suggests that this
|
||
library's overhead is very small.
|
||
Libsafe papers and source code are available at
|
||
<ulink url="http://www.bell-labs.com/org/11356/libsafe.html">http://www.bell-labs.com/org/11356/libsafe.html</ulink>.
|
||
The Libsafe source code is available under the completely
|
||
open source LGPL license,
|
||
and there are indications that many Linux distributors are interested
|
||
in using it.
|
||
</para>
|
||
|
||
<para>
|
||
Libsafe's approach appears somewhat useful.
|
||
Libsafe should certainly be considered for inclusion by Linux
|
||
distributors, and its approach is worth considering by others as well.
|
||
However, as a software developer, Libsafe is a useful mechanism
|
||
to support defense-in-depth but it does not really prevent buffer
|
||
overflows.
|
||
Here are several reasons why you shouldn't depend just on Libsafe
|
||
during code development:
|
||
<itemizedlist>
|
||
|
||
<listitem><para>
|
||
Libsafe only protects a small set of known functions with obvious
|
||
buffer overflow issues.
|
||
At the time of this writing, this list is significantly shorter than
|
||
the list of functions in this paper known to have this problem.
|
||
It also won't protect against code you write yourself (e.g., in
|
||
a while loop) that causes buffer overflows.
|
||
</para></listitem>
|
||
|
||
<listitem><para>
|
||
Even if libsafe is installed in a distribution, the way it is installed
|
||
impacts its use.
|
||
The documentation recommends setting LD_PRELOAD
|
||
to cause libsafe's protections to be enabled, but the problem
|
||
is that users can unset this environment variable... causing the
|
||
protection to be disabled for programs they execute!
|
||
</para></listitem>
|
||
|
||
<listitem><para>
|
||
Libsafe only protects against buffer overflows of the stack onto the
|
||
return address;
|
||
you can still overrun the heap or other variables in that procedure's frame.
|
||
</para></listitem>
|
||
|
||
<listitem><para>
|
||
Unless you can be assured that all deployed platforms will use libsafe
|
||
(or something like it), you'll have to protect your program as though
|
||
it wasn't there.
|
||
</para></listitem>
|
||
|
||
|
||
<listitem><para>
|
||
LibSafe seems to assume that saved frame pointers are at the beginning of
|
||
each stack frame. This isn't always true.
|
||
Compilers (such as gcc) can optimize away things, and in particular the
|
||
option "-fomit-frame-pointer" removes the information that libsafe
|
||
seems to need.
|
||
Thus, libsafe may fail to work for some programs.
|
||
<!-- More info at:
|
||
http://msgs.securepoint.com/cgi-bin/get/bugtraq0004/109/1.html
|
||
http://www2.merton.ox.ac.uk/~security/security-audit-200004/0069.html -->
|
||
</para></listitem>
|
||
</itemizedlist>
|
||
</para>
|
||
|
||
<para>
|
||
The libsafe developers themselves acknowledge that software developers
|
||
shouldn't just depend on libsafe.
|
||
In their words:
|
||
|
||
<blockquote><para>
|
||
It is generally accepted that the best solution to
|
||
buffer overflow attacks is to fix the defective programs.
|
||
However, fixing defective programs requires knowing that
|
||
a particular program is defective.
|
||
The true benefit of using libsafe and other alternative
|
||
security measures is protection against future attacks
|
||
on programs that are not yet known to be vulnerable.
|
||
</para></blockquote>
|
||
</para>
|
||
</sect2>
|
||
|
||
<sect2>
|
||
<title>Other Libraries</title>
|
||
|
||
<para>
|
||
The glib (not glibc) library is a widely-available
|
||
open source library that provides
|
||
a number of useful functions for C programmers.
|
||
GTK+ and GNOME both use glib, for example.
|
||
I have hope that glib version 2.0 will include strlcpy() and strlcat()
|
||
(I've submitted a patch to do this),
|
||
making it easier to portably use those functions.
|
||
At this time I do not have an analysis showing definitively that the
|
||
glib library functions protect against buffer overflow.
|
||
However, many of the glib functions automatically allocate memory,
|
||
and those functions automatically
|
||
<emphasis>fail with no reasonable way to intercept the failure</emphasis>
|
||
(e.g., to try something else instead).
|
||
As a result, in many cases most glib functions cannot
|
||
be used in most secure programs.
|
||
The GNOME guidelines recommend using functions such as
|
||
g_strdup_printf(), which is fine as long as it's okay if your program
|
||
immediately crashes if an out-of-memory condition occurs.
|
||
However, if you can't do this, then using such routines isn't approriate.
|
||
</para>
|
||
|
||
<!--
|
||
??? Need to investigate if standard demands safety.
|
||
C++ has a set of string classes and templates as well
|
||
(see basic_string and string)
|
||
-->
|
||
|
||
</sect2>
|
||
|
||
</sect1>
|
||
|
||
<sect1>
|
||
<title>Compilation Solutions in C/C++</title>
|
||
|
||
<para>
|
||
A completely different approach is to use compilation methods that perform
|
||
bounds-checking (see [Sitaker 1999] for a list).
|
||
In my opinion, such tools are very useful in having multiple layers of
|
||
defense, but it's not wise to use this technique as your sole defense.
|
||
There are at least two reasons for this.
|
||
First of all, most such tools only provide partial defense against
|
||
buffer overflows (and the ``complete'' defenses are generally
|
||
12-30 times slower); C and C++ were simply not designed to protect
|
||
against buffer overflow.
|
||
Second of all, for open source programs you cannot be certain what tools
|
||
will be used to compile the program; using the default ``normal'' compiler
|
||
for a given system might suddenly open security flaws.
|
||
</para>
|
||
|
||
<para>
|
||
One of the more useful tools is ``StackGuard'', a modification of the
|
||
standard GNU C compiler gcc.
|
||
StackGuard works by inserting a ``guard'' value (called a ``canary'')
|
||
in front of the return address; if a buffer overflow
|
||
overwrites the return address, the canary's value (hopefully) changes
|
||
and the system detects this before using it.
|
||
This is quite valuable, but note that this does not protect against
|
||
buffer overflows overwriting other values (which they may still be able
|
||
to use to attack a system).
|
||
There is work to extend StackGuard to be able to add canaries to other
|
||
data items, called ``PointGuard''.
|
||
PointGuard will automatically protect certain values (e.g., function
|
||
pointers and longjump buffers).
|
||
However, protecting other variable types using PointGuard
|
||
requires specific programmer intervention (the programmer
|
||
has to identify which data values must be protected with canaries).
|
||
This can be valuable, but it's easy to accidentally omit
|
||
protection for a data value you didn't think needed protection -
|
||
but needs it anyway.
|
||
More information on StackGuard, PointGuard, and other alternatives
|
||
is in Cowan [1999].
|
||
</para>
|
||
|
||
<para>
|
||
As a related issue, in Linux you could modify the Linux kernel so that
|
||
the stack segment is not executable; such a patch to Linux does exist
|
||
(see Solar Designer's patch, which includes this, at
|
||
<ulink
|
||
url="http://www.openwall.com/linux/">http://www.openwall.com/linux/</ulink>
|
||
However, as of this writing this is not built into the Linux kernel.
|
||
Part of the rationale is that this is less protection than it seems;
|
||
attackers can simply force the system to call other ``interesting'' locations
|
||
already in the program (e.g., in its library, the heap,
|
||
or static data segments).
|
||
Also, sometimes Linux does require executable code in the stack,
|
||
e.g., to implement signals and to implement GCC ``trampolines''.
|
||
Solar Designer's patch does handle these cases, but this does
|
||
complicate the patch.
|
||
Personally, I'd like to see this merged into the main Linux
|
||
distribution, since it does make attacks somewhat more difficult and
|
||
it defends against a range of existing attacks.
|
||
However, I agree with Linus Torvalds and others
|
||
that this does not add the amount of protection it would appear to and
|
||
can be circumvented with relative ease.
|
||
You can read Linus Torvalds' explanation for not including this support at
|
||
<ulink
|
||
url="http://lwn.net/980806/a/linus-noexec.html">http://lwn.net/980806/a/linus-noexec.html</ulink>.
|
||
</para>
|
||
|
||
<para>
|
||
In short, it's better to work first on developing a correct program
|
||
that defends itself against buffer overflows.
|
||
Then, after you've done this, by all means use techniques and tools
|
||
like StackGuard as an additional safety net.
|
||
If you've worked hard to eliminate buffer overflows in the code itself,
|
||
then StackGuard is likely to be more effective because there will be
|
||
fewer ``chinks in the armor'' that StackGuard will be called on to protect.
|
||
</para>
|
||
|
||
</sect1>
|
||
|
||
<sect1>
|
||
<title>Other Languages</title>
|
||
|
||
<para>
|
||
The problem of buffer overflows is an excellent argument for using
|
||
other programming languages
|
||
such as Perl, Python, Java, and Ada95.
|
||
After all, nearly all other programming languages used today
|
||
(other than assembly language) protect against buffer overflows.
|
||
Using those other languages does not eliminate all problems, of course;
|
||
in particular see the discussion under ``limit call-outs to valid values''
|
||
regarding the NIL character.
|
||
There is also the problem of ensuring that those other languages'
|
||
infrastructure (e.g., run-time library) is available and secured.
|
||
Still, you should certainly consider using other programming languages
|
||
when developing secure programs to protect against buffer overflows.
|
||
</para>
|
||
|
||
</sect1>
|
||
|
||
</chapter>
|
||
|
||
<chapter>
|
||
<title>Structure Program Internals and Approach</title>
|
||
|
||
<epigraph>
|
||
<attribution>Proverbs 25:28 (NIV)</attribution>
|
||
<para>
|
||
Like a city whose walls are broken down is a man who lacks self-control.
|
||
</para>
|
||
</epigraph>
|
||
|
||
<sect1>
|
||
<title>Secure the Interface</title>
|
||
|
||
<para>
|
||
Interfaces should be minimal (simple as possible), narrow
|
||
(provide only the functions needed), and non-bypassable.
|
||
Trust should be minimized.
|
||
Consider limiting the data that the user can see.
|
||
</para>
|
||
|
||
<para>
|
||
Applications and data viewers may be used to
|
||
display files developed externally, so in general don't allow them
|
||
to accept programs (also known as ``scripts'' or ``macros'')
|
||
unless you're willing to do the
|
||
extensive work necessary to create a secure sandbox.
|
||
The most dangerous kind is an auto-executing macro that executes
|
||
when the application is loaded and/or when the data is initially
|
||
displayed; from a security point-of-view this is
|
||
a disaster waiting to happen unless you have extremely strong control
|
||
over what the macro can do (a ``sandbox''), and past experience has
|
||
shown that real sandboxes are hard to implement.
|
||
</para>
|
||
|
||
</sect1>
|
||
|
||
<sect1>
|
||
<title>Minimize Privileges</title>
|
||
|
||
<para>
|
||
As noted earlier, it is an important general
|
||
principle that programs have the minimal amount of privileges
|
||
necessary to do its job (this is termed ``least privilege'').
|
||
That way, if the program is broken, its damage is limited.
|
||
The most extreme example is to simply not write a secure program at all -
|
||
if this can be done, it usually should be.
|
||
For example, don't make your program setuid or setgid if you can; just
|
||
make it an ordinary program, and require the administrator to log in as such
|
||
before running it.
|
||
</para>
|
||
|
||
<para>
|
||
In Linux and Unix, the primary determiner of a process' privileges is the set of
|
||
id's associated with it:
|
||
each process has a real, effective and saved id for both the user and group.
|
||
Linux also has the filesystem uid and gid.
|
||
Manipulating these values is critical to keeping privileges minimized,
|
||
and there are several ways to minimize them (discussed below).
|
||
You can also use chroot(2) to minimize the files visible to a program.
|
||
</para>
|
||
|
||
<sect2>
|
||
<title>Minimize the Privileges Granted</title>
|
||
|
||
<para>
|
||
Perhaps the most effective technique is to simply minimize the
|
||
the highest privilege granted.
|
||
In particular, avoid granting a program root privilege if possible.
|
||
Don't make a program <emphasis remap="it">setuid root</emphasis> if it only needs access
|
||
to a small set of files;
|
||
consider creating separate user or group accounts for different function.
|
||
</para>
|
||
|
||
<para>
|
||
A common technique is to
|
||
create a special group, change a file's group ownership to that group,
|
||
and then make the program <emphasis remap="it">setgid</emphasis> to that group.
|
||
It's better to make a program <emphasis remap="it">setgid</emphasis> instead of <emphasis remap="it">setuid</emphasis>
|
||
where you can,
|
||
since group membership grants fewer rights (in particular, it does not
|
||
grant the right to change file permissions).
|
||
</para>
|
||
|
||
<para>
|
||
This is commonly done for game high scores.
|
||
Games are usually setgid <emphasis remap="it">games</emphasis>,
|
||
the score files are owned by the group <emphasis remap="it">games</emphasis>,
|
||
and the programs themselves and their configuration files
|
||
are owned by someone else (say root).
|
||
Thus, breaking into a game allows the perpetrator to change high scores but
|
||
doesn't grant the privilege to change the game's executable or
|
||
configuration file.
|
||
The latter is important; if an attacker could change a game's executable
|
||
or its configuration files (which might control what the executable runs),
|
||
then they might be able to gain control of a user who ran the game.
|
||
</para>
|
||
|
||
<para>
|
||
If creating a new group isn't sufficient, consider creating a
|
||
new pseudouser (really, a special role) to manage a set of resources.
|
||
Web servers typically do this; often web servers are set up with a special
|
||
user (``nobody'') so that they can be isolated from other users.
|
||
Indeed, web servers are instructive here: web servers typically need
|
||
root privileges to start up (so they can attach to port 80), but once
|
||
started they usually shed all their privileges and
|
||
run as the user ``nobody''.
|
||
Again, usually the pseudouser doesn't own the primary program it runs,
|
||
so breaking into the account doesn't allow for changing the program itself.
|
||
As a result, breaking into a running web server normally does not
|
||
automatically break the whole system's security.
|
||
</para>
|
||
|
||
<para>
|
||
If you <emphasis remap="it">must</emphasis> give a program root privileges,
|
||
consider using the POSIX capability features available in Linux 2.2 and
|
||
greater to minimize them immediately on program startup.
|
||
By calling cap_set_proc(3) or the Linux-specific capsetp(3)
|
||
routines immediately after starting, you can permanently
|
||
reduce the abilities of your program to just those abilities it actually needs.
|
||
Note that <emphasis remap="it">not</emphasis> all Unix-like systems implement POSIX capabilities,
|
||
so this is an approach that can lose portability; however, if you use it
|
||
merely as an optional safeguard only where it's available, using this
|
||
approach will not really limit portability.
|
||
Also, while the Linux kernel version 2.2 and greater includes the low-level
|
||
calls, the C-level libraries to make their use easy are not installed
|
||
on some Linux distributions, slightly complicating their use in applications.
|
||
For more information on Linux's implementation of POSIX capabilities, see
|
||
<ulink
|
||
url="http://linux.kernel.org/pub/linux/libs/security/linux-privs">http://linux.kernel.org/pub/linux/libs/security/linux-privs</ulink>.
|
||
</para>
|
||
|
||
<para>
|
||
One Linux-unique tool you can use to simplify minimizing granted privileges
|
||
is the ``compartment'' tool developed by SuSE.
|
||
This tool sets the fileystem root, uid, gid, and/or the
|
||
capability set, then runs the given program.
|
||
This is particularly handy for running some other program without
|
||
modifying it.
|
||
Here's the syntax of version 0.5:
|
||
|
||
<screen width="61">
|
||
|
||
Syntax: compartment [options] /full/path/to/program
|
||
|
||
Options:
|
||
--chroot path chroot to path
|
||
--user user change uid to this user
|
||
--group group change gid to this group
|
||
--init program execute this program before doing anything
|
||
--cap capset set capset name. You can specify several
|
||
--verbose be verbose
|
||
--quiet do no logging (to syslog)
|
||
</screen>
|
||
|
||
</para>
|
||
|
||
<para>
|
||
Thus, you could start a more secure anonymous ftp server using:
|
||
|
||
<screen width="61">
|
||
compartment --chroot /home/ftp --cap CAP_NET_BIND_SERVICE anon-ftpd
|
||
</screen>
|
||
|
||
</para>
|
||
|
||
<para>
|
||
At the time of this writing, the tool is immature and not available on
|
||
typical Linux distributions, but this may quickly change.
|
||
You can download the program via
|
||
<ulink
|
||
url="http://www.suse.de/~marc">http://www.suse.de/~marc</ulink>.
|
||
</para>
|
||
|
||
</sect2>
|
||
|
||
<sect2>
|
||
<title>Minimize the Time the Privilege Can Be Used</title>
|
||
|
||
<para>
|
||
As soon as possible, permanently give up privileges.
|
||
Some Unix-like systems, including Linux,
|
||
implement ``saved'' IDs which store the ``previous'' value.
|
||
The simplest approach is to set the other id's twice to an untrusted id.
|
||
In setuid/setgid programs, you should usually set the effective gid and uid
|
||
to the real ones, in particular right after a fork(2),
|
||
unless there's a good reason not to.
|
||
Note that you have to change the gid first when dropping from root to another
|
||
privilege or it won't work - once you drop root privileges, you won't
|
||
be able to change much else.
|
||
</para>
|
||
|
||
<para>
|
||
It's worth noting that there's a well-known related bug that
|
||
uses POSIX capabilities to interfere with this minimization.
|
||
This bug affects Linux kernel 2.2.0 through 2.2.15, and possibly a number
|
||
of other Unix-like systems with POSIX capabilities.
|
||
See Bugtraq id 1322 on http://www.securityfocus.com for more information.
|
||
Here is their summary:
|
||
<blockquote><para>
|
||
POSIX "Capabilities" have recently been implemented in the Linux kernel.
|
||
These "Capabilities" are an additional form of privilege control to enable
|
||
more specific control over what priviliged processes can do. Capabilities are
|
||
implemented as three (fairly large) bitfields, which each bit representing a
|
||
specific action a privileged process can perform. By setting specific bits, the
|
||
actions of priviliged processes can be controlled -- access can be granted for
|
||
various functions only to the specific parts of a program that require them.
|
||
It is a security measure. The problem is that capabilities are copied with
|
||
fork() execs, meaning that if capabilities are modified by a parent process,
|
||
they can be carried over. The way that this can be exploited is by setting all
|
||
of the capabilities to zero (meaning, all of the bits are off) in each of the
|
||
three bitfields and then executing a setuid program that attempts to drop
|
||
priviliges before executing code that could be dangerous if run as root, such
|
||
as what sendmail does. When sendmail attempts to drop priviliges using
|
||
setuid(getuid()), it fails not having the capabilities required to do so in its
|
||
bitfields and with no checks on its return value . It continues executing with
|
||
superuser priviliges, and can run a users .forward file as root leading to a
|
||
complete compromise.
|
||
</para></blockquote>
|
||
One approach, used by sendmail, is to attempt to do
|
||
setuid(0) after a setuid(getuid()); normally this should fail.
|
||
If it succeeds, the program should stop.
|
||
For more information, see
|
||
http://sendmail.net/?feed=000607linuxbug.
|
||
In the short term this might be a good idea in
|
||
other programs, though clearly the better
|
||
long-term approach is to upgrade the underlying system.
|
||
</para>
|
||
|
||
</sect2>
|
||
|
||
<sect2>
|
||
<title>Minimize the Time the Privilege is Active</title>
|
||
|
||
<para>
|
||
Use setuid(2), seteuid(2), and related functions to ensure that the program
|
||
only has these privileges active when necessary.
|
||
As noted above, you might want ensure that these privileges are disabled
|
||
while parsing user input, but more generally, only turn on privileges when
|
||
they're actually needed.
|
||
Note that some buffer overflow attacks, if successful, can force a program
|
||
to run arbitrary code, and that code could re-enable privileges that were
|
||
temporarily dropped.
|
||
Thus, it's always better to completely drop privileges as soon as
|
||
possible.
|
||
Still, temporarily disabling these permissions
|
||
prevents a whole class of attacks,
|
||
such as techniques to convince a program to write into a file that
|
||
perhaps it didn't intent to write into.
|
||
Since this technique prevents many attacks,
|
||
it's worth doing if completely dropping the privileges can't be done
|
||
at that point in the program.
|
||
</para>
|
||
|
||
</sect2>
|
||
|
||
<sect2>
|
||
<title>Minimize the Modules Granted the Privilege</title>
|
||
|
||
<para>
|
||
If only a few modules are granted the privilege, then it's much
|
||
easier to determine if they're secure.
|
||
One way to do so is to have a single module use the
|
||
privilege and then drop it, so that other modules called later cannot misuse
|
||
the privilege.
|
||
Another approach is to have separate commands in separate
|
||
executables; one command might be a complex
|
||
tool that can do a vast number of tasks for a privileged user (e.g., root),
|
||
while the other tool is setuid but is a small, simple tool that
|
||
only permits a small command subset.
|
||
The small, simple tool checks to see if the input meets various criteria for
|
||
acceptability, and then if it determines the input is acceptable, it
|
||
passes the input is passed to the tool.
|
||
This can even be layerd several ways, for example,
|
||
a complex user tool could call a simple setuid
|
||
``wrapping'' program (that checks its inputs for secure values)
|
||
that then passes on information to another complex trusted tool.
|
||
This approach is especially helpful for GUI-based systems; have the GUI portion
|
||
run as a normal user, and then pass security-relevant
|
||
requests on to another program
|
||
that has the special privileges for actual execution.
|
||
</para>
|
||
|
||
<para>
|
||
Some operating systems have the concept of multiple
|
||
layers of trust in a single process, e.g., Multics' rings.
|
||
Standard Unix and Linux don't have a way of separating multiple levels of trust
|
||
by function inside a single process
|
||
like this; a call to the kernel increases privileges,
|
||
but otherwise a given process has a single level of trust.
|
||
Linux and other Unix-like systems can sometimes
|
||
simulate this ability by forking a process into
|
||
multiple processes, each of which has different privilege.
|
||
To do this, set up a secure communication channel
|
||
(usually unnamed pipes or unnamed sockets are used),
|
||
then fork into different processes and have each process
|
||
drop as many privileges as possible.
|
||
Then use a simple protocol to allow the less trusted processes
|
||
to request actions from the more trusted process(es), and ensure that the more
|
||
trusted processes only support a limited set of requests.
|
||
</para>
|
||
|
||
<para>
|
||
This is one area where technologies like Java 2 and Fluke have an advantage.
|
||
For example,
|
||
Java 2 can specify fine-grained permissions such as the permission to
|
||
only open a specific file.
|
||
However, general-purpose operating systems do not typically
|
||
have such abilities at this time; this may change in the near future.
|
||
</para>
|
||
|
||
</sect2>
|
||
|
||
<sect2>
|
||
<title>Consider Using FSUID To Limit Privileges</title>
|
||
|
||
<para>
|
||
Each Linux process has two Linux-unique state values called
|
||
filesystem user id (fsuid) and filesystem group id (fsgid).
|
||
These values are used when checking against the filesystem permissions.
|
||
If you're building a program that operates as a file server for arbitrary
|
||
users (like an NFS server), you might consider using these Linux extensions.
|
||
To use them, while holding root privileges change
|
||
just fsuid and fsgid before accessing files on behalf of a normal user.
|
||
This extension is fairly useful, and provides a mechanism for limiting
|
||
filesystem access rights without removing other (possibly necessary) rights.
|
||
By only setting the fsuid (and not the euid), a local user cannot send
|
||
a signal to the process.
|
||
Also, avoiding race conditions is much easier in this situation.
|
||
However, a disadvantage of this approach
|
||
is that these calls are not portable to other Unix-like systems.
|
||
</para>
|
||
|
||
</sect2>
|
||
|
||
<sect2>
|
||
<title>Consider Using Chroot to Minimize Available Files</title>
|
||
|
||
<para>
|
||
You can use chroot(2) to limit the files visible to your program.
|
||
This requires carefully setting up a directory (called the ``chroot jail'')
|
||
and correctly entering it.
|
||
This can be a fairly effective technique for improving a program's
|
||
security - it's hard to interfere with files you can't see.
|
||
However, it depends on a whole bunch of assumptions, in particular,
|
||
the program must lack root privileges, it must not have any way to get
|
||
root privileges, and the chroot jail must be properly set up.
|
||
I recommend using chroot(2) where it makes sense to do so, but don't depend
|
||
on it alone; instead, make it part of a layered set of defenses.
|
||
Here are a few notes about the use of chroot(2):
|
||
|
||
<itemizedlist>
|
||
<listitem>
|
||
|
||
<para>
|
||
The program can still use non-filesystem objects that are shared
|
||
across the entire machine
|
||
(such as System V IPC objects and network sockets).
|
||
It's best to also
|
||
use separate pseudousers and/or groups, because all Unix-like systems include
|
||
the ability to isolate users; this will at least limit the damage
|
||
a subverted program can do to other programs.
|
||
Note that current most Unix-like systems (including Linux)
|
||
won't isolate intentionally cooperating programs; if you're worried about
|
||
malicious programs cooperating, you need to get a system that implements
|
||
some sort of mandatory access control and/or limits covert channels.
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
|
||
<para>
|
||
Be sure to close any filesystem descriptors to outside files if you
|
||
don't want them used later.
|
||
In particular, don't have any descriptors open to directories outside
|
||
the chroot jail, or set up a situation where such a descriptor could be
|
||
given to it (e.g., via Unix sockets or an old implementation of /proc).
|
||
If the program is given a descriptor to a directory outside the chroot jail,
|
||
it could be used to escape out of the chroot jail.
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
|
||
<para>
|
||
The chroot jail has to be set up to be secure.
|
||
Don't use a normal user's home directory (or subdirectory) as a chroot jail;
|
||
use a separate location or ``home'' directory specially set aside
|
||
for the purpose.
|
||
<!-- http://msgs.securepoint.com/cgi-bin/get/bugtraq0004/64/1/1/2.html -->
|
||
Place the absolute minimum number of files there.
|
||
Typically you'll have a /bin, /etc/, /lib, and maybe one or two others
|
||
(e.g., /pub if it's an ftp server).
|
||
Place in /bin only what you need to run after doing the chroot(); sometimes
|
||
you need nothing at all (try to avoid placing a shell there, though sometimes
|
||
that can't be helped).
|
||
You may need a /etc/passwd and /etc/group so file listings can show
|
||
some correct names, but if so, try not to include the real system's
|
||
values, and certainly replace all passwords with "*".
|
||
In /lib, place only what you need; use ldd(1) to query each program in /bin
|
||
to find out what it needs, and only include them.
|
||
On Linux, you'll probably need a few basic libraries like ld-linux.so.2, and
|
||
not much else.
|
||
It's usually wiser to completely copy in all files, instead of making
|
||
hard links; while this wastes some time and disk space, it makes it so that
|
||
attacks on the chroot jail files do not automatically propogate into the
|
||
regular system's files.
|
||
Mounting a /proc filesystem, on systems where this is supported, is
|
||
generally unwise. In fact, in 2.0.x versions of Linux it's a
|
||
known security flaw, since there are pseudodirectories in /proc that
|
||
would permit a chroot'ed program to escape.
|
||
Linux kernel 2.2 fixed this known problem, but there may be others; if
|
||
possible, don't do it.
|
||
</para>
|
||
|
||
</listitem>
|
||
<listitem>
|
||
|
||
<para>
|
||
Chroot really isn't effective if
|
||
the program can acquire root privilege.
|
||
For example, the program could use calls like mknod(2) to create a device
|
||
file that can view physical memory, and then use the resulting
|
||
device file to modify kernel memory to give itself
|
||
whatever privileges it desired.
|
||
Another example of how a root program can break out of chroot
|
||
is demonstrated at
|
||
<ulink
|
||
url="http://www.suid.edu/source/breakchroot.c">http://www.suid.edu/source/breakchroot.c</ulink>.
|
||
In this example, the program opens a file descriptor for
|
||
the current directory, creates and chroots into a subdirectory, sets
|
||
the current directory to the previously-opened current directory,
|
||
repeatedly cd's up from the current directory (which since it is
|
||
outside the current chroot succeeds in moving up to the real filesystem
|
||
root), and then calls chroot on the result.
|
||
By the time you read this, these weaknesses may have been plugged,
|
||
but the reality is that root privilege has traditionally meant ``all
|
||
privileges'' and it's hard to strip them away.
|
||
It's better to assume that a program requiring continuous root privileges
|
||
will only be mildly helped using chroot().
|
||
Of course, you may be able to break your program into parts, so that
|
||
at least part of it can be in a chroot jail.
|
||
</para>
|
||
</listitem>
|
||
|
||
</itemizedlist>
|
||
|
||
</para>
|
||
|
||
</sect2>
|
||
<sect2>
|
||
<title>Consider Minimizing the Accessible Data</title>
|
||
|
||
<para>
|
||
Consider minimizing the amount of data that can be accessed by the user.
|
||
For example, in CGI scripts, place all data used by the CGI script
|
||
outside of the document tree unless there is a reason the user needs to
|
||
see the data directly.
|
||
Some people have the false notion that, by not publically providing a
|
||
link, no one can access the data, but this is simply not true.
|
||
</para>
|
||
|
||
</sect2>
|
||
</sect1>
|
||
|
||
<sect1>
|
||
<title>Avoid Creating Setuid/Setgid Scripts</title>
|
||
<para>
|
||
Many Unix-like systems, in particular Linux, simply ignore the
|
||
setuid and setgid bits on scripts to avoid the race condition
|
||
described earlier.
|
||
Since support for setuid scripts varies on Unix-like systems,
|
||
they're best avoided in new applications where possible.
|
||
As a special case, Perl includes a special setup to support setuid Perl
|
||
scripts, so using setuid and setgid is acceptable in Perl if you
|
||
truly need this kind of functionality.
|
||
If you need to support this kind of functionality in your own
|
||
interpreter, examine how Perl does this.
|
||
Otherwise, a simple approach is to ``wrap'' the script with a small
|
||
setuid/setgid executable that creates a safe environment
|
||
(e.g., clears and sets environment variables) and then
|
||
calls the script (using the script's full path).
|
||
Make sure that the script cannot be changed by an attacker!
|
||
Shell scripting languages have additional problems, and really should
|
||
not be setuid/setgid; see the language-specific section below.
|
||
</para>
|
||
</sect1>
|
||
|
||
<sect1>
|
||
<title>Configure Safely and Use Safe Defaults</title>
|
||
|
||
<para>
|
||
Configuration is considered to currently be the number one security problem.
|
||
Therefore, you should spend some effort to (1) make the initial installation
|
||
secure, and (2) make it easy to reconfigure the system while keeping it secure.
|
||
</para>
|
||
|
||
<para>
|
||
A program should have the most restrictive access policy
|
||
until the administrator has a chance to configure it.
|
||
Please don't create ``sample'' working users or
|
||
``allow access to all'' configurations as the starting configuration;
|
||
many users just ``install everything'' (installing all available services)
|
||
and never get around to configuring many services.
|
||
In some cases the program may be able to determine that a more generous
|
||
policy is reasonable by depending on the existing authentication system,
|
||
for example, an ftp server could legitimately determine that a user who
|
||
can log into a user's directory should be allowed to access that user's files.
|
||
Be careful with such assumptions, however.
|
||
</para>
|
||
|
||
<para>
|
||
Have installation scripts install a program as safely as possible.
|
||
By default, install all files as owned by root or some other
|
||
system user and make them unwriteable by others;
|
||
this prevents non-root users from installing viruses.
|
||
Indeed, it's best to make them unreadable by all but the trusted user.
|
||
Allow non-root installation where possible as well, so that users without
|
||
root privilages and administrators who do not fully trust the
|
||
installer can still use the program.
|
||
</para>
|
||
|
||
<para>
|
||
Try to make configuration as easy and clear as possible, including
|
||
post-installation configuration.
|
||
Make using the ``secure'' approach as easy as possible, or many users
|
||
will use an insecure approach without understanding the risks.
|
||
On Linux,
|
||
take advantage of tools like linuxconf, so that users can easily configure
|
||
their system using an existing infrastructure.
|
||
</para>
|
||
|
||
<para>
|
||
If there's a configuration language, the default should be to deny access
|
||
until the user specifically grants it.
|
||
Include many clear comments in the sample configuration file, if there is one,
|
||
so the administrator understands what the configuration does.
|
||
</para>
|
||
|
||
</sect1>
|
||
|
||
<sect1>
|
||
<title>Fail Safe</title>
|
||
|
||
<para>
|
||
A secure program should always ``fail safe'', that is,
|
||
it should be designed so that if the program does fail, the safest
|
||
result should occur.
|
||
For security-critical programs, that usually means that
|
||
if some sort of misbehavior is detected (malformed input,
|
||
reaching a ``can't get here'' state, and so on), then the program
|
||
should immediately deny service and stop processing that request.
|
||
Don't try to ``figure out what the user wanted'': just deny the service.
|
||
Sometimes this can decrease reliability or usability
|
||
(from a user's perspective), but it increases security.
|
||
There are a few cases where this might not be desired (e.g., where denial of
|
||
service is much worse than loss of confidentiality or integrity), but
|
||
such cases are quite rare.
|
||
</para>
|
||
|
||
<para>
|
||
Note that I recommend ``stop processing the request'', not ``fail altogether''.
|
||
In particular, most servers should not completely halt when given malformed
|
||
input, because that creates a trivial opportunity for a denial of service
|
||
attack (the attacker just sends garbage bits to prevent you from using the
|
||
service).
|
||
Sometimes taking the whole server down is necessary, in particular,
|
||
reaching some ``can't get here'' states may signal a problem so drastic
|
||
that continuing is unwise.
|
||
</para>
|
||
|
||
<para>
|
||
Consider carefully what error message you send back when a failure is detected.
|
||
if you send nothing
|
||
back, it may be hard to diagnose problems, but sending back too much
|
||
information may unintentionally aid an attacker.
|
||
Usually the best approach is to reply with ``access denied'' or
|
||
``miscellaneous error encountered'' and then
|
||
write more detailed information to an audit log (where you can have more
|
||
control over who sees the information).
|
||
</para>
|
||
|
||
</sect1>
|
||
|
||
<sect1>
|
||
<title>Avoid Race Conditions</title>
|
||
|
||
<para>
|
||
A ``race condition'' can be defined as
|
||
``Anomolous behavior due to unexpected critical dependence
|
||
on the relative timing of events''
|
||
[FOLDOC].
|
||
Race conditions generally involve one or more processes
|
||
accessing a shared resource (such a file or variable), where this
|
||
multiple access has not been properly controlled.
|
||
</para>
|
||
|
||
<para>
|
||
In general, processes do not execute atomically;
|
||
another process may interrupt it between essentially any two instructions.
|
||
If a secure program's process is not prepared for these interruptions,
|
||
another process may be able to interfere with the secure program's process.
|
||
Any pair of operations must not fail if another process's code arbitrary
|
||
code is executed between them.
|
||
</para>
|
||
|
||
<para>
|
||
Race condition problems can be notionally divided into two categories:
|
||
<itemizedlist>
|
||
<listitem><para>
|
||
Interference caused by untrusted processes.
|
||
Some security taxonomies call this problem a
|
||
``sequence'' or ``non-atomic'' condition.
|
||
These are conditions caused by processes running other, different programs,
|
||
which ``slip in'' other actions between steps of the secure program.
|
||
These other programs might be invoked by an attacker specifically
|
||
to cause the problem.
|
||
This paper will call these sequencing problems.
|
||
</para></listitem>
|
||
<listitem><para>
|
||
Interference caused by trusted processes (from the secure program's
|
||
point of view).
|
||
Some taxonomies call these deadlock, livelock, or locking failure conditions.
|
||
These are conditions caused by processes running the ``same'' program.
|
||
Since these different processes may have the ``same'' privileges, if
|
||
not properly controlled they may be able to interfere with each other in
|
||
a way other programs can't.
|
||
Sometimes this kind of interference can be exploited.
|
||
This paper will call these locking problems.
|
||
</para></listitem>
|
||
</itemizedlist>
|
||
</para>
|
||
|
||
|
||
<!-- http://webreview.com/wr/pub/97/08/08/bookshelf Suggested
|
||
this kind of division:
|
||
|
||
Sequence conditions: Be aware that your program does not
|
||
execute atomatically. That is, the program can be interrupted
|
||
between any two operations to let another program run for a
|
||
while-including one that is trying to abuse yours. Thus, check
|
||
your code carefully for any pair of operations that might fail if
|
||
arbitrary code is executed between them.
|
||
|
||
Deadlock conditions: Remember, more than one copy of your
|
||
program may be running at the same time. Use file locking for
|
||
any files that you modify.
|
||
Provide a way to recover the locks in
|
||
the event that the program crashes while a lock is held. Avoid
|
||
deadlocks or "deadly embraces," which can occur when one
|
||
program attempts to lock file A and then file B, while another
|
||
program already holds a lock for file B and then attempts to
|
||
lock file A.
|
||
-->
|
||
|
||
<sect2>
|
||
<title>Sequencing (Non-Atomic) Problems</title>
|
||
|
||
<para>
|
||
In general,
|
||
you must check your code for any pair of operations that might fail if
|
||
arbitrary code is executed between them.
|
||
</para>
|
||
|
||
<para>
|
||
Note that loading and saving a shared variable are usually implemented
|
||
as separate operations and are not atomic.
|
||
This means that an ``increment variable'' operation is usually converted into
|
||
loading, incrementing, and saving operation, so if the variable memory
|
||
is shared the other process may interfere with the incrementing.
|
||
</para>
|
||
|
||
<para>
|
||
<!-- ??? Extend this. -->
|
||
Secure programs must determine if a request should be granted, and if
|
||
so, act on that request.
|
||
There must be no way for an untrusted user to change anything used in
|
||
this determination before the program acts on it.
|
||
This kind of race condition is sometimes termed a
|
||
``time of check - time of use'' (TOCTOU) race condition.
|
||
</para>
|
||
|
||
<para>
|
||
This issue repeatedly comes up in the filesystem.
|
||
Programs should generally avoid using access(2) to determine
|
||
if a request should be granted, followed later by open(2), because users
|
||
may be able to move files around between these calls, possibly creating
|
||
symbolic links or files of their own choosing instead.
|
||
A secure program should instead set its effective id or filesystem id,
|
||
then make the open call directly.
|
||
It's possible to use access(2) securely, but only when a user cannot affect
|
||
the file or any directory along its path from the filesystem root.
|
||
</para>
|
||
|
||
<!-- From http://java.sun.com/security/seccodeguide.html:
|
||
For example, it's often better to use fchmod() and
|
||
fchown() instead of chmod(), chown(), and chgrp().
|
||
If you close a file and then use chmod() to change the permissions, and
|
||
the file or a directory in the directory's path is writeable by another,
|
||
an attacker may be able to remove the file and create a symbolic link
|
||
to another file (say /etc/passwd, to add/remove interesting values, or
|
||
to /dev/zero, to provide an infinitely-long data stream of input to
|
||
your program).
|
||
|
||
From http://webreview.com/wr/pub/97/08/08/bookshelf:
|
||
In particular, when you are performing a series of operations on a
|
||
file, such as changing its owner, stat ing the file, or changing its
|
||
mode, first open the file and then use the fchown( ), fstat( ), or
|
||
fchmod( ) system calls. Doing so will prevent the file from being
|
||
replaced while your program is running (a possible race condition).
|
||
Also avoid the use of the access( ) function to determine your ability
|
||
to access a file: using the access( ) function followed by an open( ) is
|
||
a race condition, and almost always a bug.
|
||
-->
|
||
|
||
|
||
<para>
|
||
<!-- Based on http://java.sun.com/security/seccodeguide.html and
|
||
http://webreview.com/wr/pub/97/08/08/bookshelf: -->
|
||
For example, when performing a series of operations on a file's
|
||
metainformation (such as changing its owner, stat-ing the file, or
|
||
changing its permission bits), first open the file and then use the
|
||
operations on open files.
|
||
This means use the fchown( ), fstat( ), or fchmod( ) system calls,
|
||
instead of the functions taking filenames
|
||
such as chown(), chgrp(), and chmod().
|
||
Doing so will prevent the file from being
|
||
replaced while your program is running (a possible race condition).
|
||
For example, if you close a file and then use chmod()
|
||
to change its permissions,
|
||
an attacker may be able to remove the file between those
|
||
two steps and create a symbolic link to another file
|
||
(say /etc/passwd).
|
||
Other interesting files include /dev/zero, which can
|
||
provide an infinitely-long data stream of input to a program.
|
||
Also, avoid the use of the access( ) function to determine your ability
|
||
to access a file: using the access( ) function followed by an open( ) is
|
||
a race condition, and almost always a bug.
|
||
This is only necessary if it's possible for an untrusted process
|
||
to modify the relevant directory its ancestors.
|
||
</para>
|
||
|
||
<para>
|
||
This issue particularly comes up in the /tmp and /var/tmp directories,
|
||
which are shared by all users. Avoid using these directories
|
||
and their subdirectories if possible.
|
||
In particular, imagine what would happen if users created files
|
||
(including symbolic links) at arbitrary times in directories you intend to use
|
||
(for example, between the time you compute a filename
|
||
and the time you try to open it).
|
||
</para>
|
||
|
||
<para>
|
||
The general problem when creating files in these shared directories is that
|
||
you must guarantee that the filename you plan to use don't already
|
||
exist at time of creation.
|
||
Using an ``unpredictable'' or ``unique'' filename doesn't work, because
|
||
another process can often repeatedly guess what that value will be.
|
||
The GNOME programming guidelines recommend the following C code when
|
||
creating filesystem objects in shared (temporary) directories
|
||
to counteract this problem [Quintero 2000]:
|
||
<programlisting width="68">
|
||
char *filename;
|
||
int fd;
|
||
|
||
do {
|
||
filename = tempnam (NULL, "foo");
|
||
fd = open (filename, O_CREAT | O_EXCL | O_TRUNC | O_RDWR, 0600);
|
||
free (filename);
|
||
} while (fd == -1);
|
||
</programlisting>
|
||
Note that you need to free() the filename.
|
||
You should close() and unlink() the file after you are done.
|
||
If you want to use the Standard C I/O library,
|
||
you can use fdopen() to transform the file descriptor into a FILE *.
|
||
Note that this won't work over NFS version 2 (v2) systems, because older
|
||
NFS doesn't correctly support O_EXCL.
|
||
<!-- They also say you can use tmpfile() to do it in one step; I want
|
||
to verify this before saying so. I'm concerned that some
|
||
implementations may not "do it correctly", and it's better to
|
||
re-implement than be insecure. -->
|
||
<!-- http://developer.gnome.org/doc/guides/programming-guidelines/security.html -->
|
||
</para>
|
||
|
||
|
||
<!-- ???: I need to completely rewrite this race condition section -->
|
||
|
||
<!-- Not quite the right idea:
|
||
You can't even just check to see if the given file is a symbolic link;
|
||
if it's owned by an untrusted user, the user could change this after
|
||
the check.
|
||
One possible tool is the O_NOFOLLOW option for open(), a
|
||
FreeBSD extension also supported by Linux; this option says to not
|
||
follow symbolic links if the link the final portion of the path.
|
||
Unfortunately at this time this option is not portable.
|
||
-->
|
||
|
||
|
||
</sect2>
|
||
|
||
|
||
<sect2>
|
||
<title>Locking</title>
|
||
|
||
<para>
|
||
There are often situations in which a program must ensure that it has
|
||
exclusive rights to something (e.g., a file, a device, and/or
|
||
existence of a particular server process).
|
||
Any system which locks resources must deal with the standard problems
|
||
of locks, namely, deadlocks (``deadly embraces''), livelocks,
|
||
and releasing ``stuck'' locks if a program doesn't clean up its locks.
|
||
A deadlock can occur if programs are stuck waiting for each other to
|
||
release resources.
|
||
For example, a deadlock would occur if
|
||
process 1 locks resources A and waits for resource B,
|
||
while process 2 locks resource B and waits for resource A.
|
||
Many deadlocks can be prevented by simply requiring all processes
|
||
that lock multiple resources to lock them
|
||
in the same order (e.g., alphabetically by lock name).
|
||
</para>
|
||
|
||
<sect3>
|
||
<title>Using Files as Locks</title>
|
||
|
||
<para>
|
||
On Unix-like systems resource locking has traditionally been done by creating
|
||
a file to indicate a lock, because this is very portable.
|
||
It also makes it easy to ``fix'' stuck locks, because an administrator
|
||
can just look at the filesystem to see what locks have been set.
|
||
Stuck locks can occur because the program failed to clean up after
|
||
itself (e.g., it crashed or malfunctioned) or because the whole system crashed.
|
||
Note that these are ``advisory'' (not ``mandatory'') locks - all processes
|
||
needed the resource must cooperate to use these locks.
|
||
<!-- ??? Discuss various approaches to resolve this, e.g.,
|
||
There are some standard tricks to simplify clean-up for these
|
||
conditions.
|
||
For example, a parent process can set a lock,
|
||
call a child to do the work (make sure only the parent can call the child
|
||
in a way that it can work), and when the child returns the parent releases
|
||
the lock.
|
||
Or, a cron job can look at the locks (which contain a process id); if
|
||
the process isn't alive, it would erase the lock and restart the process.
|
||
Finally, the lock file can be erased as part of system start-up.
|
||
-->
|
||
</para>
|
||
|
||
<para>
|
||
However, there are several traps to avoid.
|
||
First, don't use the technique used by
|
||
very old Unix C programs,
|
||
which is calling creat() or its open() equivalent, the open() mode
|
||
O_WRONLY | O_CREAT | O_TRUNC, with the file mode set to 0 (no permissions).
|
||
For normal users on normal file systems, this works, but
|
||
this approach fails to lock the file when the user has root privileges.
|
||
Root can always perform this operation, even when the file
|
||
already exists.
|
||
In fact, old versions of Unix had this particular problem in the
|
||
old editor ``ed'' -- the symptom was that
|
||
occasionally portions of the password file would be placed in user's files!
|
||
[Rochkind 1985, 22].
|
||
Instead, if you're creating a lock for processes that are on the local
|
||
filesystem, you should use open() with the flags
|
||
O_WRONLY | O_CREAT | O_EXCL (and again, no permissions, so that other
|
||
processes with the same owner won't get the lock).
|
||
Note the use of O_EXCL, which is the official way to
|
||
create ``exclusive'' files; this even works for root on a local filesystem.
|
||
[Rochkind 1985, 27].
|
||
</para>
|
||
|
||
<para>
|
||
Second, if the lock file may be on an NFS-mounted filesystem, then you have
|
||
the problem that NFS version 2 doesn't completely support normal file semantics.
|
||
This can even be a problem for work that's supposed to be ``local'' to a
|
||
client, since some clients don't have local disks and may have <emphasis remap="it">all</emphasis>
|
||
files remotely mounted via NFS.
|
||
The manual for <emphasis remap="it">open(2)</emphasis> explains how to handle things in this case
|
||
(which also handles the case of root programs):
|
||
</para>
|
||
|
||
<para>
|
||
<QUOTE>... programs which rely on [the O_CREAT and O_EXCL flags of open(2)]
|
||
for performing locking tasks will contain a race condition. The solution
|
||
for performing atomic file locking using a lockfile is to create
|
||
a unique file on the same filesystem (e.g., incorporating
|
||
hostname and pid), use link(2) to make a link to
|
||
the lockfile and use stat(2) on the unique file to
|
||
check if its link count has increased to 2. Do
|
||
not use the return value of the link(2) call.</QUOTE>
|
||
</para>
|
||
|
||
<para>
|
||
Obviously, this solution only works if all programs doing the locking
|
||
are cooperating, and if all non-cooperating programs aren't allowed to
|
||
interfere.
|
||
In particular, the directories you're using for file locking
|
||
must not have permissive file permissions for creating and removing files.
|
||
</para>
|
||
|
||
<para>
|
||
NFS version 3 added support for O_EXCL mode in open(2);
|
||
see IETF RFC 1813,
|
||
in particular the "EXCLUSIVE" value to the "mode" argument of "CREATE".
|
||
Sadly, not everyone has switched to NFS version 3 or higher at the time of this
|
||
writing, so you you can't depend on this yet in portable programs.
|
||
Still, in the long run there's hope that this issue will go away.
|
||
</para>
|
||
|
||
<para>
|
||
If you're locking a device or the existence of a process on a local
|
||
machine, try to use standard conventions.
|
||
I recommend using the Filesystem Hierarchy Standard (FHS);
|
||
it is widely referenced by Linux systems, but it also tries to incorporate
|
||
the ideas of other Unix-like systems.
|
||
The FHS describes
|
||
standard conventions for such locking files, including naming, placement,
|
||
and standard contents of these files [FHS 1997].
|
||
If you just want to be sure that your server doesn't execute more than once
|
||
on a given machine, you should usually create a process identifier as
|
||
/var/run/NAME.pid with the pid as its contents.
|
||
In a similar vein, you should place lock files for things
|
||
like device lock files in /var/lock.
|
||
This approach has the minor disadvantage of leaving files hanging around
|
||
if the program suddenly halts,
|
||
but it's standard practice and that problem is
|
||
easily handled by other system tools.
|
||
</para>
|
||
|
||
<para>
|
||
It's important that the programs which are cooperating using files to
|
||
represent the locks use the same
|
||
directory, not just the same directory name.
|
||
This is an issue with networked systems: the FHS explicitly notes that
|
||
/var/run and /var/lock are unshareable, while /var/mail is shareable.
|
||
Thus, if you want the lock to work on a single machine, but not interfere
|
||
with other machines, use unshareable directories like /var/run
|
||
(e.g., you want to permit each machine to run its own server).
|
||
However, if you want all machines sharing files in a network to obey the
|
||
lock, you need to use a directory that they're sharing; /var/mail is
|
||
one such location. See FHS section 2 for more information on this subject.
|
||
</para>
|
||
|
||
</sect3>
|
||
|
||
<sect3>
|
||
<title>Other Approaches to Locking</title>
|
||
|
||
<para>
|
||
Of course, you need not use files to represent locks.
|
||
Network servers often need not bother; the mere act of binding to a port
|
||
acts as a kind of lock, since if there's an existing server bound to a given
|
||
port, no other server will be able to bind to that port.
|
||
</para>
|
||
|
||
<para>
|
||
Another approach to locking
|
||
is to use POSIX record locks, implemented through fcntl(2) as a
|
||
``discretionary lock''.
|
||
These are discretionary, that is, using them requires the cooperation of the
|
||
programs needing the locks (just as the approach to using files to
|
||
represent locks does).
|
||
There's a lot to recommend POSIX record locks:
|
||
POSIX record locking is supported on nearly all Unix-like platforms
|
||
(it's mandated by POSIX.1), it
|
||
can lock portions of a file (not just a whole file), and it can handle the
|
||
difference between read locks and write locks.
|
||
Even more usefully, if a process dies, its locks are automatically removed,
|
||
which is usually what is desired.
|
||
<!-- ???: What about locking across NFS, flock, lockf?
|
||
XBoing doc file "problems.txt" says that lockf() works over NFS when
|
||
lockd daemon is running. -->
|
||
</para>
|
||
|
||
<para>
|
||
You can also use mandatory locks, which are based on System V's
|
||
mandatory locking scheme.
|
||
These only apply to files where the locked file's setgid bit is set, but
|
||
the group execute bit is not set.
|
||
Also, you must mount the filesystem to permit mandatory file locks.
|
||
In this case, every read(2) and write(2) is checked for locking;
|
||
while this is more thorough than advisory locks, it's also slower.
|
||
Also, mandatory locks don't port as widely to other Unix-like systems
|
||
(they're available on Linux and System V-based systems, but not necessarily
|
||
on others).
|
||
Note that processes with root privileges
|
||
can be held up by a mandatory lock, too, making it possible that
|
||
this could be the basis of a denial-of-service attack.
|
||
</para>
|
||
|
||
</sect3>
|
||
|
||
</sect2>
|
||
|
||
</sect1>
|
||
|
||
<sect1>
|
||
<title>Trust Only Trustworthy Channels</title>
|
||
|
||
<para>
|
||
In general, do not trust results from untrustworthy channels.
|
||
</para>
|
||
|
||
<para>
|
||
In most computer networks (and certainly for the Internet at large),
|
||
no unauthenticated transmission is trustworthy.
|
||
For example,
|
||
on the Internet arbitrary packets can be forged, including header values,
|
||
so don't use their values as your primary criteria for security decisions
|
||
unless you can authenticate them.
|
||
In some cases you can assert that a packet claiming to come from the
|
||
``inside'' actually does, since the local firewall would prevent such
|
||
spoofs from outside, but broken firewalls, alternative paths, and
|
||
mobile code make even this assumption suspect.
|
||
In a similar vein, do not assume that low port numbers (less than 1024)
|
||
are trustworthy; in most networks such requests can be forged or
|
||
the platform can be made to permit use of low-numbered ports.
|
||
</para>
|
||
|
||
<para>
|
||
If you're implementing a standard and inherently insecure protocol
|
||
(e.g., ftp and rlogin), provide safe defaults and document clearly
|
||
the assumptions.
|
||
</para>
|
||
|
||
<para>
|
||
The Domain Name Server (DNS) is widely used on the Internet to maintain
|
||
mappings between the names of computers and their IP (numeric) addresses.
|
||
The technique called ``reverse DNS'' eliminates some simple
|
||
spoofing attacks, and is useful for determining a host's name.
|
||
However, this technique is not trustworthy for authentication
|
||
decisions.
|
||
The problem is that, in the end, a DNS request will be sent eventually
|
||
to some remote system that may be controlled by an attacker.
|
||
Therefore, treat DNS results as an input that needs
|
||
validation and don't trust it for serious access control.
|
||
</para>
|
||
|
||
<para>
|
||
If asking for a password, try to set up trusted path (e.g.,
|
||
require pressing an unforgeable key
|
||
before login, or display unforgeable pattern such as flashing LEDs).
|
||
Otherwise, an ``evil'' program could create a display that ``looks like''
|
||
the expected display for a password (e.g., a log-in) and intercept
|
||
that password.
|
||
Unfortunately, stock Linux and most other Unixes don't
|
||
have a trusted path even for
|
||
its normal login sequence, and
|
||
since currently normal users can change the LEDs, the LEDs
|
||
can't currently be used to confirm a trusted path.
|
||
When handling a password over a network, encrypt it between trusted endpoints.
|
||
</para>
|
||
|
||
<para>
|
||
Arbitrary email (including the ``from'' value of addresses)
|
||
can be forged as well.
|
||
Using digital signatures is a method to thwart many such attacks.
|
||
A more easily thwarted approach is to require emailing back and forth
|
||
with special randomly-created values, but for low-value transactions
|
||
such as signing onto a public mailing list this is usually acceptable.
|
||
</para>
|
||
|
||
<para>
|
||
If you need a trustworthy channel over an untrusted network,
|
||
you need some sort of cryptologic
|
||
service (at the very least, a cryptologically safe hash);
|
||
see the section below on cryptographic algorithms and protocols.
|
||
</para>
|
||
|
||
<para>
|
||
Note that in any client/server model, including CGI, that the server
|
||
must assume that the client can modify any value.
|
||
For example, so-called ``hidden fields'' and cookie values can be
|
||
changed by the client before being received by CGI programs.
|
||
These cannot be trusted unless special precautions are taken.
|
||
For example, the hidden fields could be signed in a way the client
|
||
cannot forge as long as the server checks the signature.
|
||
The hidden fields could also be encrypted using a key only the trusted
|
||
server could decrypt (this latter approach is the basic idea behind the
|
||
Kerberos authentication system).
|
||
InfoSec labs has further discussion about hidden fields and applying
|
||
encryption at
|
||
<ulink url="http://www.infoseclabs.com/mschff/mschff.htm">http://www.infoseclabs.com/mschff/mschff.htm</ulink>.
|
||
In general, you're better off keeping data you care about at the server end
|
||
in a client/server model.
|
||
In the same vein,
|
||
don't depend on HTTP_REFERER for authentication in a CGI program, because
|
||
this is sent by the user's browser (not the web server).
|
||
</para>
|
||
|
||
<para>
|
||
The routines getlogin(3) and ttyname(3) return information that can be
|
||
controlled by a local user, so don't trust them for security purposes.
|
||
</para>
|
||
|
||
<para>
|
||
This issue applies to data referencing other data, too.
|
||
For example, HTML or XML allow you to include by reference other files
|
||
(e.g., DTDs and style sheets) that may be stored remotely.
|
||
However, those external references could be modified so that users
|
||
see a very different document than intended;
|
||
a style sheet could be modified to ``white out'' words at critical
|
||
locations, deface its appearance, or insert new text.
|
||
External DTDs could be modified to prevent use of the document
|
||
(by adding declarations that break validation) or insert different
|
||
text into documents [St. Laurent 2000].
|
||
</para>
|
||
|
||
</sect1>
|
||
|
||
<sect1>
|
||
<title>Use Internal Consistency-Checking Code</title>
|
||
|
||
<para>
|
||
The program should check to ensure that its call arguments and basic state
|
||
assumptions are valid.
|
||
In C, macros such as assert(3) may be helpful in doing so.
|
||
</para>
|
||
|
||
</sect1>
|
||
|
||
<sect1>
|
||
<title>Self-limit Resources</title>
|
||
|
||
<para>
|
||
In network daemons, shed or limit excessive loads.
|
||
Set limit values (using setrlimit(2)) to limit the resources that will be used.
|
||
At the least, use setrlimit(2) to disable creation of ``core'' files.
|
||
For example, by default
|
||
Linux will create a core file that saves all program memory if the
|
||
program fails abnormally, but such a file might include passwords or
|
||
other sensitive data.
|
||
</para>
|
||
|
||
</sect1>
|
||
|
||
|
||
</chapter>
|
||
|
||
<chapter>
|
||
<title>Carefully Call Out to Other Resources</title>
|
||
|
||
<epigraph>
|
||
<attribution>Psalms 146:3 (NIV)</attribution>
|
||
<para>
|
||
Do not put your trust in princes, in mortal men, who cannot save.
|
||
</para>
|
||
</epigraph>
|
||
|
||
<sect1>
|
||
<title>Limit Call-outs to Valid Values</title>
|
||
|
||
<para>
|
||
Ensure that any call out to another program only permits valid
|
||
and expected values for every parameter.
|
||
This is more difficult than it sounds, because there are many
|
||
library calls or commands call lower-level routines in potentially
|
||
surprising ways.
|
||
For example, several system calls, such as popen(3) and system(3),
|
||
are implemented by calling the command shell, meaning that they will
|
||
be affected by shell metacharacters.
|
||
Similarly, execlp(3) and execvp(3) may cause the shell to be called.
|
||
Many guidelines suggest avoiding popen(3), system(3), execlp(3), and execvp(3)
|
||
entirely and use execve(3) directly in C when trying to spawn
|
||
a process [Galvin 1998b].
|
||
At the least, avoid using system(3) when you can use the execve(3);
|
||
since system(3) uses the shell to expand characters, there is more
|
||
opportunity for mischief in system(3).
|
||
In a similar manner the Perl and shell backtick (`) also call a command shell;
|
||
see the section on Perl.
|
||
<!-- ???: need to cross-reference to the Perl section -->
|
||
</para>
|
||
|
||
<para>
|
||
One of the nastiest examples of this problem are shell metacharacters.
|
||
The standard Unix-like command shell (stored in /bin/sh)
|
||
interprets a number of characters specially.
|
||
If these characters are sent to the shell, then their special interpretation
|
||
will be used unless escaped; this fact can be used to break programs.
|
||
According to the WWW Security FAQ [Stein 1999, Q37], these metacharacters are:
|
||
|
||
<screen width="61">
|
||
& ; ` ' \ " | * ? ~ < > ^ ( ) [ ] { } $ \n \r
|
||
</screen>
|
||
</para>
|
||
|
||
<para>
|
||
Unfortunately, in real life this isn't a complete list.
|
||
Here are some other characters that can be problematic:
|
||
<!-- Martin Douda provided this list of ! through *; I added the note
|
||
about control characters -->
|
||
<itemizedlist>
|
||
<listitem><para>
|
||
'!' means ``not'' in an expression (as it does in C);
|
||
if the return value of a program is tested, prepending !
|
||
could fool a script into thinking something had failed when it
|
||
succeeded or vice versa.
|
||
In some shells, the "!" also accesses the command history, which can
|
||
cause real problems.
|
||
In bash, this only occurs for interactive mode, but tcsh
|
||
(a csh clone found in some Linux distributions) uses "!" even in scripts.
|
||
In csh, bash, and some other shells, if you can fool them i
|
||
Also new bash seems to use '!' for accessing command history - but
|
||
this probably only in interactive mode.
|
||
</para></listitem>
|
||
|
||
<listitem><para>
|
||
'#' is the comment character; all further text is ignored.
|
||
</para></listitem>
|
||
|
||
<listitem><para>
|
||
'-' can be misinterpreted as leading an option (or, as --, disabling
|
||
all further options). Even if it's in the ``middle'' of a filename,
|
||
if it's preceeded by what the shell considers as whitespace you may
|
||
have a problem.
|
||
</para></listitem>
|
||
|
||
<listitem><para>
|
||
' ' (space) and other whitespace characters may turn a ``single'' filename
|
||
into multiple arguments.
|
||
</para></listitem>
|
||
|
||
<listitem><para>
|
||
Other control characters (in particular, NIL) may cause problems for
|
||
some shell implementations.
|
||
</para></listitem>
|
||
|
||
<listitem><para>
|
||
Depending on your usage, it's even conceivable that ``.''
|
||
(the ``run in current shell'') and ``='' (for setting variables) might
|
||
be worrisome characters.
|
||
However, any example I've found so far where these
|
||
are issues have other (much worse) security problems.
|
||
</para></listitem>
|
||
|
||
<!--
|
||
'.' run in current shell - also could be harmful alloving to modify
|
||
execution environment
|
||
|
||
'=' for variables, again modifying execution environment
|
||
|
||
(*) depending on programs called from script any other character can cause
|
||
problems.
|
||
-->
|
||
</itemizedlist>
|
||
|
||
</para>
|
||
|
||
|
||
<para>
|
||
Forgetting one of these characters can be disastrous, for example,
|
||
many programs omit backslash as a metacharacter [rfp 1999].
|
||
As discussed in the section on validating input, a recommended approach
|
||
by some
|
||
is to immediately escape at least all of these characters when they are input.
|
||
But again, by far and away the best approach is to identify which
|
||
characters you wish to permit, and use a filter to only permit
|
||
those characters.
|
||
</para>
|
||
|
||
<para>
|
||
A number of programs have ``escape'' codes that
|
||
perform ``extra'' activities; make sure that these can't be included
|
||
(unless you intend for them to be in the message).
|
||
For example, many line-oriented mail programs (such as mail or mailx) use
|
||
tilde (~) as an escape character, which can then be used to send a number
|
||
of commands.
|
||
As a result, apparantly-innocent commands such as
|
||
``mail admin < file-from-user'' can be used to execute arbitrary programs.
|
||
Interactive programs such as vi and emacs have ``escape'' mechanisms
|
||
that normally allow users to run arbitrary shell commands from their session.
|
||
Always examine the documentation of programs you call to search for
|
||
escape mechanisms.
|
||
</para>
|
||
|
||
<para>
|
||
The issue of avoiding
|
||
escape codes even goes down to low-level hardware components
|
||
and emulators of them.
|
||
Most modems implement the so-called ``Hayes'' command set, in which
|
||
the sequence ``+++'', a delay, and then ``+++'' again forces the modem
|
||
to switch modes (and interpret following text as commands to it).
|
||
This can be used to implement denial-of-service attacks or even forcing
|
||
a user to connect to someone else.
|
||
</para>
|
||
|
||
<para>
|
||
Many ``terminal'' interfaces implement the escape
|
||
codes of ancient, long-gone physical terminals like the VT100.
|
||
These codes can be useful, for example, for bolding characters,
|
||
changing font color, or moving to a particular location
|
||
in a terminal interface.
|
||
However, do not allow arbitrary untrusted data to be sent directly
|
||
to a terminal screen, because some of those codes can cause serious problems.
|
||
On some systems you can remap keys (e.g., so when a user presses
|
||
"Enter" or a function key it sends the command you want them to run).
|
||
On some you can even send codes to
|
||
clear the screen, display a set of commands you'd like the victim to run,
|
||
and then send that set ``back'', forcing the victim to run
|
||
the commands of the attacker's choosing without even waiting for a keystroke.
|
||
This is typically implemented using ``page-mode buffering''.
|
||
This security problem is why emulated tty's (represented as device files,
|
||
usually in /dev/) should only be writeable by
|
||
their owners and never anyone else - they should never have
|
||
``other write'' permission set, and unless only the user is a member of
|
||
the group (i.e., the ``user-private group'' scheme), the ``group write''
|
||
permission should not be set either for the terminal [Filipski 1986].
|
||
If you're displaying data to the user at a (simulated) terminal, you probably
|
||
need to filter out all control characters (characters with values less
|
||
than 32) from data sent back to
|
||
the user unless they're identified by you as safe.
|
||
Worse comes to worse, you can identify tab and newline (and maybe
|
||
carriage return) as safe, removing all the rest.
|
||
Characters with their high bits set (i.e., values greater than 127)
|
||
are in some ways trickier to handle; some old systems implement them as
|
||
if they weren't set, but simply filtering them inhibits much international
|
||
use.
|
||
In this case, you need to look at the specifics of your situation.
|
||
</para>
|
||
|
||
<para>
|
||
A related problem is that the NIL character (character 0) can have
|
||
surprising effects.
|
||
Most C and C++ functions assume
|
||
that this character marks the end of a string, but string-handling routines
|
||
in other languages (such as Perl and Ada95) can handle strings containing NIL.
|
||
Since many libraries and kernel calls use the C convention, the result
|
||
is that what is checked is not what is actually used [rfp 1999].
|
||
</para>
|
||
|
||
<para>
|
||
When calling another program or referring to a file
|
||
always specify its full path (e.g, <filename>/usr/bin/sort</filename>).
|
||
For program calls,
|
||
this will eliminate possible errors in calling the ``wrong'' command,
|
||
even if the PATH value is incorrectly set.
|
||
For other file referents, this reduces problems from ``bad'' starting
|
||
directories.
|
||
</para>
|
||
|
||
</sect1>
|
||
|
||
<sect1>
|
||
<title>Check All System Call Returns</title>
|
||
|
||
<para>
|
||
Every system call that can return an error condition must have that
|
||
error condition checked.
|
||
One reason is that nearly all system calls require limited system resources,
|
||
and users can often affect resources in a variety of ways.
|
||
Setuid/setgid programs can have limits set on them through calls such as
|
||
setrlimit(3) and nice(2).
|
||
External users of server programs and CGI scripts
|
||
may be able to cause resource exhaustion simply by making a large number
|
||
of simultaneous requests.
|
||
If the error cannot be handled gracefully, then fail open as discussed earlier.
|
||
</para>
|
||
|
||
</sect1>
|
||
|
||
</chapter>
|
||
|
||
<chapter>
|
||
<title>Send Information Back Judiciously</title>
|
||
|
||
<epigraph>
|
||
<attribution>Proverbs 26:4 (NIV)</attribution>
|
||
<para>
|
||
Do not answer a fool according to his folly,
|
||
or you will be like him yourself.
|
||
</para>
|
||
</epigraph>
|
||
|
||
<sect1>
|
||
<title>Minimize Feedback</title>
|
||
|
||
<para>
|
||
Avoid giving much information to untrusted users; simply succeed or fail,
|
||
and if it fails just say it failed and minimize information on why it failed.
|
||
Save the detailed information for audit trail logs.
|
||
For example:
|
||
|
||
<itemizedlist>
|
||
<listitem>
|
||
|
||
<para>
|
||
If your program requires some sort of user authentication
|
||
(e.g., you're writing a network service or login program),
|
||
give the user as little information as possible before they authenticate.
|
||
In particular, avoid giving away the version number of your program
|
||
before authentication.
|
||
Otherwise,
|
||
if a particular version of your program is found to have a vulnerability,
|
||
then users who don't upgrade from that version advertise to attackers that
|
||
they are vulnerable.
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
|
||
<para>
|
||
If your program accepts a password, don't echo it back;
|
||
this creates another way passwords can be seen.
|
||
</para>
|
||
</listitem>
|
||
|
||
</itemizedlist>
|
||
|
||
</para>
|
||
|
||
</sect1>
|
||
|
||
<sect1>
|
||
<title>Handle Full/Unresponsive Output</title>
|
||
|
||
<para>
|
||
It may be possible for a user to clog or make unresponsive a secure
|
||
program's output channel back to that user.
|
||
For example, a web browser could be intentionally halted or have its
|
||
TCP/IP channel response slowed.
|
||
The secure program should handle such cases, in particular it should release
|
||
locks quickly (preferably before replying) so that this will not create
|
||
an opportunity for a Denial-of-Service attack.
|
||
Always place timeouts on outgoing network-oriented write requests.
|
||
</para>
|
||
|
||
</sect1>
|
||
|
||
<sect1>
|
||
<title>Control Data Formatting</title>
|
||
|
||
<para>
|
||
A number of output routines in computer languages have a
|
||
parameter that controls the generated format.
|
||
In C, the most obvious example is the printf() family of routines
|
||
(including printf(), sprintf(), snprintf(), fprintf(), and so on).
|
||
Other examples in C include syslog() (which writes system log information)
|
||
and setproctitle() (which sets the string used to display
|
||
process identifier information).
|
||
Many functions with names beginning with ``err'' or ``warn'', containing
|
||
``log'' , or ending in ``printf'' are worth considering.
|
||
<!-- log() style functions calling v* in particular -->
|
||
<!-- Some info from 7/21/2000, Theo de Raadt on Bugtraq -->
|
||
<!-- OpenBSD docs for setproctitle() is at
|
||
http://www.rocketaware.com/man/man3/setproctitle.3.htm -->
|
||
Python includes the "%" operation, which on strings controls formatting
|
||
in a similar manner.
|
||
Many programs and libraries define formatting functions, often by
|
||
calling built-in routines and doing additional processing
|
||
(e.g., glib's g_snprintf() routine).
|
||
</para>
|
||
|
||
<para>
|
||
Surprisingly, many people seem to forget the power of these formatting
|
||
capabilities and use data from untrusted users as the formatting parameter.
|
||
Never use unfiltered data from an untrusted user as the format parameter.
|
||
Perhaps this is best shown by example:
|
||
<programlisting width="61">
|
||
/* Wrong ways: */
|
||
printf(string_from_untrusted_user);
|
||
/* Right ways: */
|
||
printf("%s %d", string_from_untrusted_user); /* or just */
|
||
fputs(string_from_untrusted_user);
|
||
</programlisting>
|
||
</para>
|
||
|
||
<para>
|
||
Otherwise, an attacker can cause all sorts of mischief by carefully
|
||
selecting the formatting string.
|
||
The case of C's printf() is a good example -
|
||
there are lots of ways to possibly exploit user-controlled format strings
|
||
in printf().
|
||
These include
|
||
buffer overruns by creating a long formatting string (this can
|
||
result in the attacker having complete control over the program),
|
||
conversion specifications that use unpassed parameters
|
||
(causing unexpected data to be inserted), and
|
||
creating formats which produce totally unanticipated result values
|
||
(say by prepending or appending awkward data,
|
||
causing problems in later use).
|
||
A particularly nasty case is printf's
|
||
%n conversion specification, which writes the
|
||
number of characters written so far into the pointer argument;
|
||
using this, an attacker can overwrite a value that was intended for printing!
|
||
An attacker can even overwrite almost arbitrary locations, since the attacker
|
||
can specify a ``parameter'' that wasn't actually passed.
|
||
Since in many cases the results are sent back to the user,
|
||
this attack can also be used to expose internal information about the stack.
|
||
This information can then be used to circumvent stack protection systems
|
||
such as StackGuard; StackGuard uses constant ``canary'' values
|
||
to detect attacks, but if the stack's contents can be displayed,
|
||
the current value of the canary will be
|
||
exposed and made vulnerable.
|
||
<!-- Fri, 21 Jul 2000 12:21:20 -0400,
|
||
From: Alan DeKok <aland@STRIKER.OTTAWA.ON.CA>
|
||
Subject: StackGuard with ... Re: [Paper] Format bugs.
|
||
-->
|
||
</para>
|
||
|
||
<para>
|
||
A formatting string should almost always be a constant string,
|
||
possibly involving a function call to implement a
|
||
lookup for internationalization (e.g., via gettext's _()); note that this
|
||
lookup must be limited to values that the program controls, i.e., the
|
||
user must be allowed to only select from the message files controlled
|
||
by the program.
|
||
It's possible to filter user data before using it (e.g., by designing
|
||
a filter listing legal characters for the format string such as [A-Za-z0-9]),
|
||
but it's usually better to simply prevent the problem
|
||
by using a constant format string or fputs() instead.
|
||
Note that although I've listed this as an ``output'' problem, this can
|
||
cause problems internally to a program before output
|
||
(since the output routines may be saving to a file, or even just generating
|
||
internal state such as via snprintf()).
|
||
</para>
|
||
|
||
<para>
|
||
The problem of input formatting causing security problems is
|
||
is not an idle possibility; see CERT Advisory CA-2000-13
|
||
for an example of an exploit using this weakness.
|
||
For more information on how these problems can be exploited, see
|
||
Pascal Bouchareine's email article titled ``[Paper] Format bugs'',
|
||
published in the July 18, 2000 edition of
|
||
<ulink url="http://www.securityfocus.com">Bugtraq</ulink>.
|
||
<!-- This paper can be hard to extract, but it's there -->
|
||
</para>
|
||
|
||
<!-- ???: Can internationalization lookups be controlled by an
|
||
untrusted user? Obviously, the language can be selected, but can the
|
||
user supply "their own" strings? If so, that's a security hole! -->
|
||
<para>
|
||
Of course, this all begs the question as to whether or not the
|
||
internationalization lookup is, in fact, secure.
|
||
If you're creating your own internationalization lookup routines,
|
||
make sure that an untrusted user can only specify a legal locale and not
|
||
something else like an arbitrary path.
|
||
Clearly, you want to limit the strings created through internationalization
|
||
to ones you can trust.
|
||
Otherwise, an attacker could use this ability to exploit the
|
||
weaknesses in format strings, particularly in C/C++ programs.
|
||
This has been an item of discussion in Bugtraq (e.g., see
|
||
John Levon's Bugtraq post on July 26, 2000).
|
||
For more information,
|
||
see the discussion in this paper (in input filtering) on
|
||
on permitting only legal values for user (natural) languages.
|
||
</para>
|
||
|
||
<para>
|
||
Although it's really a programming bug, it's worth mentioning that
|
||
different countries notate numbers in different ways, in particular,
|
||
both the period (.) and comma (,) are used to separate an integer
|
||
from its fractional part. If you save or load data, you need to make sure
|
||
that the active locale does not interfere with data handling.
|
||
Otherwise, a French user may not be able to exchange data with an
|
||
English user, because the data stored and retrieved will use
|
||
different separators.
|
||
I'm unaware of this being used as a security problem, but it's conceivable.
|
||
</para>
|
||
|
||
|
||
|
||
|
||
</sect1>
|
||
|
||
</chapter>
|
||
|
||
<chapter>
|
||
<title>Language-Specific Issues</title>
|
||
<epigraph>
|
||
<attribution>1 Corinthians 14:10 (NIV)</attribution>
|
||
<para>
|
||
Undoubtedly there are all sorts of languages in the world,
|
||
yet none of them is without meaning.
|
||
</para>
|
||
</epigraph>
|
||
|
||
<para>
|
||
There are many language-specific security issues.
|
||
Many of them can be summarized as follows:
|
||
<itemizedlist>
|
||
<listitem><para>
|
||
Turn on all relevant warnings and protection mechanisms available to you
|
||
where practical.
|
||
For compiled languages, this includes
|
||
both compile-time mechanisms and run-time mechanisms.
|
||
In general, security-relevant programs should compile cleanly with
|
||
all warnings turned on.
|
||
</para></listitem>
|
||
|
||
<listitem><para>
|
||
Avoid dangerous and deprecated operations in the language.
|
||
By ``dangerous'', I mean operations which are difficult to use correctly.
|
||
</para></listitem>
|
||
|
||
<listitem><para>
|
||
Ensure that the languages'
|
||
infrastructure (e.g., run-time library) is available and secured.
|
||
</para></listitem>
|
||
|
||
<listitem><para>
|
||
Languages that automatically garbage-collect strings should be
|
||
especially careful to immediately erase secret data
|
||
(in particular secret keys and passwords).
|
||
</para></listitem>
|
||
|
||
<listitem><para>
|
||
Know precisely the semantics of the operations that you are using.
|
||
Look up operation's semantics in its documentation.
|
||
Do not ignore return values unless you're sure they cannot be relevant.
|
||
This is particularly difficult in languages which don't support exceptions,
|
||
like C, but that's the way it goes.
|
||
</para></listitem>
|
||
</itemizedlist>
|
||
</para>
|
||
|
||
<sect1>
|
||
<title>C/C++</title>
|
||
<para>
|
||
One of the biggest security problems with C and C++ programs is
|
||
buffer overflow; see the chapter on buffer overflow
|
||
for more information.
|
||
C has the additional weakness of not supporting exceptions, which makes
|
||
it easy to write programs that ignore critical error situations.
|
||
</para>
|
||
|
||
<para>
|
||
<!-- The example is from Sebastian (Bugtraq, 26 June 2000) -->
|
||
One complication in C and C++ is that the character type ``char'' can be
|
||
signed or unsigned (depending on the compiler and machine).
|
||
When a signed char with its high bit set
|
||
is saved in an integer, the result will be a negative number;
|
||
in some cases this can be exploitable.
|
||
In general, use ``unsigned char'' instead of char or signed char for
|
||
buffers, pointers, and casts when
|
||
dealing with character data that may have values greater than 127 (0x7f).
|
||
</para>
|
||
|
||
<para>
|
||
C and C++ are by definition very lax in their type-checking support, but
|
||
there's no need to be lax in your code.
|
||
Turn on as many compiler warnings as you can and change the code to cleanly
|
||
compile with them, and strictly use ANSI prototypes in separate header
|
||
(.h) files to ensure that all function calls use the correct types.
|
||
For C or C++ compilations using gcc, use at least
|
||
the following as compilation flags (which turn on a host of warning messages)
|
||
and try to eliminate all warnings (note that -O2 is used since some
|
||
warnings can only be detected by the data flow analysis performed at
|
||
higher optimization levels):
|
||
<screen width="61">
|
||
gcc -Wall -Wpointer-arith -Wstrict-prototypes -O2
|
||
</screen>
|
||
You might want ``-W -pedantic'' too.
|
||
</para>
|
||
|
||
<para>
|
||
Many C/C++ compilers can detect inaccurate format strings.
|
||
For example,
|
||
gcc can warn about inaccurate format strings for functions you create
|
||
if you use its __attribute__() facility (a C extension) to mark such functions,
|
||
and you can use that facility without making your code non-portable.
|
||
Here is an example of what you'd put in your header (.h) file:
|
||
<programlisting width="61">
|
||
/* in header.h */
|
||
#ifndef __GNUC__
|
||
# define __attribute__(x) /*nothing*/
|
||
#endif
|
||
|
||
extern void logprintf(const char *format, ...)
|
||
__attribute__((format(printf,1,2)));
|
||
extern void logprintva(const char *format, va_list args)
|
||
__attribute__((format(printf,1,0)));
|
||
</programlisting>
|
||
The "format" attribute takes either "printf" or "scanf", and the numbers
|
||
that follow are the parameter number of the format string and the first
|
||
variadic parameter (respectively). The GNU docs talk about this well.
|
||
Note that there are other __attribute__ facilities as well,
|
||
such as "noreturn" and "const".
|
||
<!-- The __attribute__ discussion
|
||
Derived from "Stephen J. Friedl", Sat, 22 Jul 2000 16:21:08 -0700,
|
||
Bugtraq -->
|
||
</para>
|
||
|
||
</sect1>
|
||
|
||
<sect1>
|
||
<title>Perl</title>
|
||
<para>
|
||
Perl programmers should first read the man page perlsec(1),
|
||
which describes a number of issues involved with writing secure programs
|
||
in Perl.
|
||
In particular, perlsec(1) describes the ``taint'' mode, which most
|
||
secure Perl programs should use.
|
||
Taint mode is automatically enabled if the real and effective user or group
|
||
IDs differ, or you can use the -T command line flag
|
||
(use the latter if you're running on behalf of someone else, e.g.,
|
||
a CGI script).
|
||
Taint mode turns on various checks, such as checking
|
||
path directories to make sure they aren't writable by others.
|
||
</para>
|
||
|
||
<para>
|
||
The most obvious affect of taint mode, however, is that
|
||
you may not use data derived from outside your program to
|
||
affect something else outside your program by accident.
|
||
In taint mode,
|
||
all externally-obtained input is marked as ``tainted'', including
|
||
command line arguments, environment variables,
|
||
locale information (see the perllocale(1)),
|
||
results of certain system calls (readdir, readlink,
|
||
the gecos field of getpw* calls), and all file input.
|
||
Tainted data may not be
|
||
used directly or indirectly in any command that invokes a
|
||
sub-shell, nor in any command that modifies files,
|
||
directories, or processes.
|
||
There is one important exception: If you
|
||
pass a list of arguments to either system or exec, the
|
||
elements of that list are NOT checked for taintedness, so
|
||
be especially careful with system or exec while in taint mode.
|
||
</para>
|
||
|
||
<para>
|
||
Any data value derived from tainted data becomes tainted also.
|
||
There is one exception to this; the way to untaint data is to
|
||
extract a substring of the tainted data.
|
||
Don't just use ``.*'' blindly as your substring, though, since this
|
||
would defeat the tainting mechanism's protections.
|
||
Instead, identify patterns that identify the ``safe'' pattern
|
||
allowed by your program, and use them to extract ``good'' values.
|
||
After extracting the value, you may still need to check it
|
||
(in particular for its length).
|
||
</para>
|
||
|
||
<para>
|
||
The open, glob, and backtick functions
|
||
call the shell to expand filename wild card characters; this
|
||
can be used to open security holes.
|
||
You can try to avoid these functions entirely, or use them in a
|
||
less-privileged ``sandbox'' as described in perlsec(1).
|
||
In particular, backticks should be rewritten using the system() call
|
||
(or even better, changed entirely to something safer).
|
||
</para>
|
||
|
||
<para>
|
||
The perl open() function comes with, frankly,
|
||
``way too much magic'' for most secure programs; it interprets text
|
||
that, if not carefully filtered, can create lots of security problems.
|
||
Before writing code to open or lock a file, consult the perlopentut(1)
|
||
man page.
|
||
In most cases, sysopen() provides a safer (though more convoluted)
|
||
approach to opening a file.
|
||
<ulink
|
||
url="http://www.xray.mpe.mpg.de/mailing-lists/perl5-porters/2000-03/msg02596.html">
|
||
The new Perl 5.6 adds an open() call
|
||
with 3 parameters to turn off the magic behavior
|
||
without requiring the convolutions of sysopen()</ulink>.
|
||
</para>
|
||
|
||
<para>
|
||
Perl programs should turn on the warning flag (-w), which warns of
|
||
potentially dangerous or obsolete statements.
|
||
</para>
|
||
|
||
<para>
|
||
You can also run Perl programs in a restricted environment.
|
||
For more information see the ``Safe'' module in the standard Perl
|
||
distribution.
|
||
I'm uncertain of the amount of auditing that this has undergone,
|
||
so beware of depending on this for security.
|
||
You might also investigate the ``Penguin Model for
|
||
Secure Distributed Internet Scripting'', though at the time
|
||
of this writing the code and documentation seems to be unavailable.
|
||
<!-- Search for Penguin FAQ, the Penguin Model for Secure Distributed
|
||
Internet Scripting -->
|
||
</para>
|
||
</sect1>
|
||
|
||
<sect1>
|
||
<title>Python</title>
|
||
<para>
|
||
As with any language,
|
||
beware of any functions which allow data to be executed as parts of
|
||
a program, to make sure an untrusted user can't affect their input.
|
||
This includes exec(), eval(), and execfile()
|
||
(and frankly, you should check carefully any call to compile()).
|
||
The input() statement is also surprisingly dangerous.
|
||
[Watters 1996, 150].
|
||
</para>
|
||
|
||
<para>
|
||
Python programs with privileges that can be invoked by unprivileged users
|
||
(e.g., setuid/setgid programs)
|
||
must <emphasis>not</emphasis> import the ``user'' module.
|
||
The user module causes the pythonrc.py file to be read and executed.
|
||
Since this file would be under the control of an untrusted user,
|
||
importing the user module allows an attacker to force the trusted
|
||
program to run arbitrary code.
|
||
</para>
|
||
|
||
<para>
|
||
Python includes support for ``Restricted Execution'' through
|
||
its RExec class.
|
||
This is primarily intended for executing applets and mobile code, but
|
||
it can also be used to limit privilege in a program even when the
|
||
code has not been provided externally.
|
||
By default, a restricted execution
|
||
environment permits reading (but not writing) of files,
|
||
and does not include operations for network access or GUI interaction.
|
||
These defaults can be changed, but beware of creating loopholes in
|
||
the restricted environment.
|
||
In particular, allowing a user to unrestrictedly add attributes to a
|
||
class permits all sorts of ways to subvert the environment
|
||
because Python's implementation calls many ``hidden'' methods.
|
||
Note that, by default, most Python objects are passed by reference; if you
|
||
insert a reference to a mutable value into a restricted program's environment,
|
||
the restricted program can change the object in a way that's visible
|
||
outside the restricted environment!
|
||
Thus, if you want to give access to a mutable value, in many cases
|
||
you should copy the mutable value or use the Bastion module (which supports
|
||
restricted access to another object).
|
||
For more information, see
|
||
Kuchling [2000].
|
||
I'm uncertain of the amount of auditing that the restricted
|
||
execution capability has undergone, so programmer beware.
|
||
</para>
|
||
</sect1>
|
||
|
||
<sect1>
|
||
<title>Shell Scripting Languages (sh and csh Derivatives)</title>
|
||
<para>
|
||
I strongly recommend against using
|
||
standard command shell scripting languages (such as csh, sh, and bash)
|
||
for setuid/setgid secure code.
|
||
Some systems (such as Linux) completely disable them, so you're
|
||
creating an unnecessary portability problem.
|
||
On some old systems they are fundamentally insecure due to a race condition
|
||
(as discussed in the section on processes).
|
||
Even for other systems, they're not really a good idea.
|
||
Standard command shells are still notorious for being affected by
|
||
nonobvious inputs -
|
||
generally because they were designed to try to do
|
||
things ``automatically'' for an interactive user, not to defend against
|
||
a determined attacker.
|
||
For example,
|
||
``hidden'' environment variables (e.g., the ENV or BASH_ENV variable)
|
||
can affect how they operate or even execute arbitrary user-defined
|
||
code before the script can even execute.
|
||
Even things like filenames of the executable or directory contents can
|
||
affect things.
|
||
For example, on many Bourne shell implementations, doing the following
|
||
will grant root access (thanks to NCSA for describing this
|
||
exploit):
|
||
<!-- http://www.ncsa.uiuc.edu/General/Grid/ACES/security/programming/#setuid-sh-exploit -->
|
||
<programlisting width="61">
|
||
% ln -s /usr/bin/setuid-shell /tmp/-x
|
||
% cd /tmp
|
||
% -x
|
||
</programlisting>
|
||
Some systems may have closed this hole, but the point still stands:
|
||
most command shells aren't intended for writing secure programs.
|
||
For programming purposes, avoid creating setuid shell scripts, even
|
||
on those systems that permit them.
|
||
Instead, write a small program in another language to clean up the
|
||
environment, then have it call other executables (some of which
|
||
might be shell scripts).
|
||
</para>
|
||
|
||
<para>
|
||
If you still insist on using shell scripting languages, at least
|
||
put the script in a directory where it cannot be moved or changed.
|
||
Set PATH and IFS to known values very early in your script.
|
||
</para>
|
||
</sect1>
|
||
|
||
<sect1>
|
||
<title>Ada</title>
|
||
<para>
|
||
In Ada95, the Unbounded_String type is often more flexible than the
|
||
String type because it is automatically resized as necessary.
|
||
However, don't store especially sensitive values such as passwords
|
||
or secret keys in an Unbounded_String, since core dumps and page areas
|
||
might still hold them later.
|
||
Instead, use the String type for this data and overwrite the data as
|
||
soon as possible with some constant value such as others => ' '.
|
||
</para>
|
||
</sect1>
|
||
|
||
<sect1>
|
||
<title>Java</title>
|
||
|
||
<para>
|
||
<!-- Could mention "Core Java 2"; see http://www.amazon.com/
|
||
exec/obidos/ASIN/0130819336/ref=sim_books/102-4729136-4374443 -->
|
||
If you're developing secure programs using Java,
|
||
frankly your first step (after learning Java)
|
||
is to read the two primary texts for Java security, namely
|
||
Gong [1999]
|
||
and
|
||
McGraw [1999] (for the latter, look particularly at section 7.1).
|
||
You should also look at Sun's posted security code guidelines at
|
||
<ulink url="http://java.sun.com/security/seccodeguide.html">http://java.sun.com/security/seccodeguide.html</ulink>.
|
||
A set of slides describing Java's security model are freely available at
|
||
<ulink url="http://www.dwheeler.com/javasec">http://www.dwheeler.com/javasec</ulink>.
|
||
</para>
|
||
|
||
<para>
|
||
The following are a few key guidelines, based on Gong [1999],
|
||
McGraw [1999], and Sun's guidance:
|
||
|
||
<orderedlist>
|
||
|
||
<listitem><para>
|
||
Do not use public fields or variables; declare them as private and
|
||
provide accessors to them so you can limit their accessibility.
|
||
</para></listitem>
|
||
|
||
<listitem><para>
|
||
Make methods private unless these is a good reason to do otherwise
|
||
(and if you do otherwise, document why).
|
||
These non-private methods must protect themselves, because they may
|
||
receive tainted data (unless you've somehow arranged to protect them).
|
||
</para></listitem>
|
||
|
||
<listitem><para>
|
||
Avoid using static field variables. Such variables are attached to the
|
||
class (not class instances), and classes can be located by any other class.
|
||
As a result, static field variables can be found by any other class, making
|
||
them much more difficult to secure.
|
||
</para></listitem>
|
||
|
||
<listitem><para>
|
||
Never return a mutable object to potentially malicious code
|
||
(since the code may decide to change it).
|
||
Note that arrays are mutable (even if the array contents aren't),
|
||
so don't return a reference to an internal array with sensitive data.
|
||
</para></listitem>
|
||
|
||
<listitem><para>
|
||
Never store user given mutable objects (including arrays of objects)
|
||
directly.
|
||
Otherwise, the user could hand the object to the secure code, let the
|
||
secure code ``check'' the object, and change the data while the secure code
|
||
was trying to use the data.
|
||
Clone arrays before saving them internally, and be careful here
|
||
(e.g., beware of user-written cloning routines).
|
||
</para></listitem>
|
||
|
||
<listitem><para>
|
||
Don't depend on initialization.
|
||
There are several ways to allocate uninitialized objects.
|
||
</para></listitem>
|
||
|
||
<listitem><para>
|
||
Make everything final, unless there's a good reason not to.
|
||
If a class or method is non-final, an attacker could try to extend it
|
||
in a dangerous and unforeseen way.
|
||
Note that this causes a loss of extensibility, in exchange for security.
|
||
</para></listitem>
|
||
|
||
<listitem><para>
|
||
Don't depend on package scope for security.
|
||
A few classes, such as java.lang, are closed by default, and some
|
||
Java Virtual Machines (JVMs) let you close off other packages.
|
||
Otherwise, Java classes are not closed.
|
||
Thus, an attacker could introduce a new class inside your package,
|
||
and use this new class to access the things you thought you were protecting.
|
||
</para></listitem>
|
||
|
||
<listitem><para>
|
||
Don't use inner classes.
|
||
When inner classes are translated into byte codes, the inner class
|
||
is translated into a class accesible to any class in the package.
|
||
Even worse, the enclosing class's private fields silently
|
||
become non-private to permit access by the inner class!
|
||
</para></listitem>
|
||
|
||
<listitem><para>
|
||
Minimize privileges.
|
||
Where possible, don't require any special permissions at all.
|
||
McGraw goes further and recommends not signing any code; I say
|
||
go ahead and sign the code (so users can decide to ``run only
|
||
signed code by this list of senders''), but try to write the program
|
||
so that it needs nothing more than the sandbox set of privileges.
|
||
If you must have more privileges, audit that code especially hard.
|
||
</para></listitem>
|
||
|
||
<listitem><para>
|
||
If you must sign your code, put it all in one archive file.
|
||
Here it's best to quote McGraw [1999]:
|
||
<blockquote>
|
||
<para>
|
||
The goal of this rule is to prevent
|
||
an attacker from carrying out a mix-and-match
|
||
attack in which the attacker constructs a new applet
|
||
or library that links some of your signed classes together
|
||
with malicious classes, or links together signed classes that you
|
||
never meant to be used together.
|
||
By signing a group of classes together, you make this attack more difficult.
|
||
Existing code-signing systems do an inadequate job of
|
||
preventing mix-and-match attacks, so this rule cannot
|
||
prevent such attacks completely. But using a single archive can't hurt.
|
||
</para>
|
||
</blockquote>
|
||
</para></listitem>
|
||
|
||
<listitem><para>
|
||
Make your classes uncloneable.
|
||
Java's object-cloning mechanism allows an attacker to
|
||
instantiate a class without running any of its constructors.
|
||
To make your class uncloneable, just define the following method
|
||
in each of your classes:
|
||
<programlisting width="71">
|
||
<![CDATA[
|
||
public final void clone() throws java.lang.CloneNotSupportedException {
|
||
throw new java.lang.CloneNotSupportedException();
|
||
}
|
||
]]>
|
||
</programlisting>
|
||
</para>
|
||
<para>
|
||
If you really need to make your class cloneable, then there are some
|
||
protective measures you can take to prevent attackers from redefining
|
||
your clone method.
|
||
If you're defining your own clone method, just make it final.
|
||
If you're not, you can at least prevent the clone method from
|
||
being maliciously overridden by adding the following:
|
||
<programlisting width="71">
|
||
<![CDATA[
|
||
public final void clone() throws java.lang.CloneNotSupportedException {
|
||
super.clone();
|
||
}
|
||
]]>
|
||
</programlisting>
|
||
</para></listitem>
|
||
|
||
<listitem><para>
|
||
Make your classes unserializeable.
|
||
Serialization allows attackers to view the internal state of your objects,
|
||
even private portions.
|
||
To prevent this, add this method to your classes:
|
||
<programlisting width="66">
|
||
<![CDATA[
|
||
private final void writeObject(ObjectOutputStream out)
|
||
throws java.io.IOException {
|
||
throw new java.io.IOException("Object cannot be serialized");
|
||
}
|
||
]]>
|
||
</programlisting>
|
||
</para>
|
||
<para>
|
||
Even in cases where serialization is okay, be sure to use
|
||
the transient keyword for the fields
|
||
that contain direct handles to system resources and
|
||
that contain information relative to an address space.
|
||
Otherwise, deserializing the class may permit improper access.
|
||
You may also want to identify sensitive information as transient.
|
||
</para>
|
||
|
||
<para>
|
||
If you define your own serializing method for a class,
|
||
it should not pass an internal array to any DataInput/DataOuput
|
||
method that takes an array.
|
||
The rationale: All DataInput/DataOutput methods can be overridden.
|
||
If a Serializable class passes a private array directly to a DataOutput(write(byte [] b)) method, then an attacker
|
||
could subclass ObjectOutputStream and override the write(byte [] b)
|
||
method to enable him to access and modify the private array.
|
||
Note that the default serialization does not expose private
|
||
byte array fields to DataInput/DataOutput byte array methods.
|
||
</para></listitem>
|
||
|
||
<listitem><para>
|
||
Make your classes undeserializeable.
|
||
Even if your class is not serializeable, it may still be deserializeable.
|
||
An attacker can create a sequence of bytes that happens
|
||
to deserialize to an instance of your class with values of the
|
||
attacker's choosing.
|
||
In other words, deserialization is a kind of public constructor, allowing
|
||
an attacker to choose the object's state - clearly a dangerous operation!
|
||
To prevent this, add this method to your classes:
|
||
<programlisting width="66">
|
||
<![CDATA[
|
||
private final void readObject(ObjectInputStream in)
|
||
throws java.io.IOException {
|
||
throw new java.io.IOException("Class cannot be deserialized");
|
||
}
|
||
]]>
|
||
</programlisting>
|
||
</para></listitem>
|
||
|
||
<listitem><para>
|
||
Don't compare classes by name.
|
||
After all, attackers can define classes with identical names, and if
|
||
you're not careful you can cause confusion by granting these classes
|
||
undesirable privileges.
|
||
Thus, here's an example of the <emphasis>wrong</emphasis> way
|
||
to determine if an object has a given class:
|
||
<programlisting width="65">
|
||
<![CDATA[
|
||
if (obj.getClass().getName().equals("Foo")) {
|
||
]]>
|
||
</programlisting>
|
||
</para>
|
||
<para>
|
||
If you need to determine if two objects have exactly the
|
||
same class, instead
|
||
use getClass() on both sides and compare using the == operator,
|
||
Thus, you should use this form:
|
||
<programlisting width="65">
|
||
<![CDATA[
|
||
if (a.getClass() == b.getClass()) {
|
||
]]>
|
||
</programlisting>
|
||
If you truly need to determine if an object has a given classname, you
|
||
need to be pedantic and be sure to use the current namespace
|
||
(of the current class's ClassLoader).
|
||
Thus, you'll need to use this format:
|
||
<programlisting width="65">
|
||
<![CDATA[
|
||
if (obj.getClass() == this.getClassLoader().loadClass("Foo")) {
|
||
]]>
|
||
</programlisting>
|
||
</para>
|
||
<para>
|
||
This guideline is from McGraw and Felten, and it's a good guideline.
|
||
I'll add that, where possible, it's often a good idea to avoid comparing
|
||
class values anyway.
|
||
It's often better to try to design class methods and interfaces so you
|
||
don't need to do this at all.
|
||
However, this isn't always practical, so it's important to know these tricks.
|
||
</para></listitem>
|
||
|
||
<listitem><para>
|
||
Don't store secrets (cryptographic keys, passwords, or
|
||
algorithm) in the code or data.
|
||
Hostile JVMs can quickly view this data.
|
||
Code obfuscation doesn't really hide the code from serious attackers.
|
||
</para></listitem>
|
||
|
||
</orderedlist>
|
||
|
||
</para>
|
||
|
||
</sect1>
|
||
|
||
<sect1>
|
||
<title>TCL</title>
|
||
<para>
|
||
Tcl stands for ``tool command language'' and is pronounced ``tickle.''
|
||
TCL is divided into two parts: a language and a library.
|
||
The language is a simple text language, intended for issuing commands
|
||
to interactive programs and including basic programming capabilities.
|
||
The library can be embedded in application programs.
|
||
</para>
|
||
|
||
<para>
|
||
You can find more information about TCL at sites such as the
|
||
<ulink url="http://www.sco.com/Technology/tcl/Tcl.html">TCL WWW Info</ulink>
|
||
web page.
|
||
Probably of most interest are Safe-TCL (which creates a sandbox in TCL)
|
||
and Safe-TK (which implements a sandboxed portable GUI for Safe-TCL), as
|
||
well as the WebWiseTclTk Toolkit permits TCL packages to be automatically
|
||
located and loaded from anywhere on the World Wide Web.
|
||
You can find more about the latter from
|
||
<ulink url="http://www.cbl.ncsu.edu/software/WebWiseTclTk">http://www.cbl.ncsu.edu/software/WebWiseTclTk</ulink>.
|
||
It's not clear to me how much code review this has received.
|
||
More useful information is available from the comp.lang.tcl FAQ launch
|
||
page at
|
||
<ulink url="http://www.tclfaq.wservice.com/tcl-faq">http://www.tclfaq.wservice.com/tcl-faq</ulink>.
|
||
However, it's worth noting that TCL's desire to be a small, ``simple''
|
||
language results in a language that can be rather limiting;
|
||
see
|
||
<ulink url="http://sdg.lcs.mit.edu/~jchapin/6853-FT97/Papers/stallman-tcl.html">
|
||
Richard Stallman's ``Why You Should Not Use TCL''</ulink>.
|
||
For example, TCL's notion that there is essentially
|
||
only one data type (string) can
|
||
make many programs harder to write (as well as making them slow).
|
||
Also, when I've written TCL programs
|
||
I've found that it's easy to accidentally create TCL programs where
|
||
malicious input strings can cause untoward and unexpected behavior.
|
||
For example, an attackers may be able to cause your TCL program
|
||
to do unexpected things by sending characters with special meaning to TCL
|
||
such as embedded spaces, double-quote, curly braces,
|
||
dollar signs, or brackets (or create input
|
||
to cause these characters to be created during processing).
|
||
Thus, I don't recommend TCL for writing programs which must
|
||
mediate a security boundary.
|
||
If you do choose to do so, be especially careful to ensure that user
|
||
input cannot ``fool'' the program.
|
||
On the other hand, I know of no strong reason (other than
|
||
insufficient review) that TCL programs can't be used to implement mobile code.
|
||
There are certainly TCL advocates who will advocate more use than I do,
|
||
and TCL is one of the few languages with
|
||
a ready-made sandbox implementation.
|
||
</para>
|
||
</sect1>
|
||
|
||
</chapter>
|
||
|
||
<chapter>
|
||
<title>Special Topics</title>
|
||
|
||
<epigraph>
|
||
<attribution>Proverbs 16:22 (NIV)</attribution>
|
||
<para>
|
||
Understanding is a fountain of life to those who have it,
|
||
but folly brings punishment to fools.
|
||
</para>
|
||
</epigraph>
|
||
|
||
<sect1>
|
||
<title>Passwords</title>
|
||
|
||
<para>
|
||
Where possible, don't write code to handle passwords.
|
||
In particular, if the application is local,
|
||
try to depend on the normal login authentication by a user.
|
||
If the application is a CGI script, try to depend on the web server to provide
|
||
the protection.
|
||
If the application is over a network, avoid sending the password as cleartext
|
||
(where possible) since it can
|
||
be easily captured by network sniffers and reused later.
|
||
``Encrypting'' a password using some key fixed in the algorithm or using
|
||
some sort of shrouding algorithm is essentially the same as sending the
|
||
password as cleartext.
|
||
</para>
|
||
|
||
<!-- ???: Show _HOW_ to use PAM to do simple password checking; the PAM
|
||
docs are complex on this score. Also show how to ``fall through''
|
||
if you don't have PAM? -->
|
||
|
||
<para>
|
||
For networks, consider at least using digest passwords.
|
||
Digest passwords are passwords developed from hashes; typically the
|
||
server will send the client some data (e.g., date, time, name of server),
|
||
the client combines this data with the user password, the client hashes
|
||
this value (termed the ``digest pasword'')
|
||
and replies just the hashed result to the server;
|
||
the server verifies this hash value.
|
||
This works, because the password is never actually sent in any form; the
|
||
password is just used to derive the hash value.
|
||
Digest passwords aren't considered ``encryption'' in
|
||
the usual sense and are usually accepted even in countries with laws
|
||
constraining encryption for confidentiality.
|
||
Digest passwords are vulnerable to active attack threats but
|
||
protect against passive network sniffers.
|
||
One weakness is that, for digest passwords
|
||
to work, the server must have all the unhashed passwords, making the server
|
||
a very tempting target for attack.
|
||
</para>
|
||
|
||
<para>
|
||
If your application permits users to set their passwords, check
|
||
the passwords and permit only ``good'' passwords
|
||
(e.g., not in a dictionary, having certain minimal length, etc.).
|
||
You may want to look at information such as
|
||
<ulink
|
||
url="http://consult.cern.ch/writeup/security/security_3.html">http://consult.cern.ch/writeup/security/security_3.html</ulink>
|
||
on how to choose a good password.
|
||
You should use PAM if you can, because it supports pluggable password checkers.
|
||
</para>
|
||
</sect1>
|
||
|
||
<sect1>
|
||
<title>Random Numbers</title>
|
||
|
||
<para>
|
||
``Random'' numbers generated by many library routines are intended to be
|
||
used for simulations, games, and so on; they are
|
||
<emphasis remap="it">not</emphasis> sufficiently random for use in security functions such
|
||
as key generation.
|
||
The problem is that these library routines use algorithms whose future
|
||
values can be easily deduced by an attacker (though they may appear random).
|
||
For security functions, you need random values based on truly unpredictable
|
||
values such as quantum effects.
|
||
</para>
|
||
|
||
<para>
|
||
Failing to correctly generate truly random values for keys has caused
|
||
a number of problems, including holes in Kerberos,
|
||
the X window system, and NFS [Venema 1996].
|
||
</para>
|
||
|
||
<para>
|
||
The Linux kernel (since 1.3.30) includes a random number generator, which
|
||
is sufficient for many security purposes.
|
||
This random number generator gathers environmental noise
|
||
from device drivers and other sources into an entropy pool.
|
||
When accessed as /dev/random, random bytes are only returned
|
||
within the estimated number of bits of noise in the entropy pool
|
||
(when the entropy pool is empty, the call blocks until additional
|
||
environmental noise is gathered).
|
||
When accessed as /dev/urandom, as many bytes as are requested are
|
||
returned even when the entropy pool is exhausted.
|
||
If you are using the random values for cryptographic purposes (e.g.,
|
||
to generate a key), use /dev/random.
|
||
More information is available in the system documentation random(4).
|
||
</para>
|
||
</sect1>
|
||
|
||
<sect1>
|
||
<title>Specially Protect Secrets (Passwords and Keys) in User Memory</title>
|
||
<para>
|
||
If your application must handle passwords or non-public keys
|
||
(such as session keys, private keys, or secret keys), overwrite them
|
||
immediately after using them so they have minimal exposure.
|
||
For example,
|
||
in Java, don't use the type String to store a password because Strings are
|
||
immutable (they will not be overwritten until garbage-collected and
|
||
reused, possibly a far time in the future).
|
||
Instead, in Java use char[] to store a password, so it can be
|
||
immediately overwritten.
|
||
</para>
|
||
|
||
<para>
|
||
Also,
|
||
if your program handles such secret values, be sure to disable creating
|
||
core dumps (via ulimit). Otherwise, an attacker may be able to halt the
|
||
program and find the secret value in the data dump.
|
||
Also, beware - normally processes can monitor other processes through
|
||
the calls for debuggers (e.g., via ptrace(2) and the /proc pseudo-filesystem)
|
||
[Venema 1996]
|
||
Kernels usually protect against these monitoring routines if the process is
|
||
setuid or setgid
|
||
(on the few ancient ones that don't, there really isn't a way to
|
||
defend yourself other than upgrading).
|
||
Thus, if your process manages secret values, you probably should make it
|
||
setgid or setuid (to a different unprivileged group or user) to forceably
|
||
inhibit this kind of monitoring.
|
||
</para>
|
||
|
||
</sect1>
|
||
|
||
<sect1>
|
||
<title>Cryptographic Algorithms and Protocols</title>
|
||
|
||
<para>
|
||
Often cryptographic algorithms and protocols are necessary to keep
|
||
a system secure, particularly when communicating through an untrusted
|
||
network such as the Internet.
|
||
Where possible, use session encryption to foil session hijacking and
|
||
to hide authentication information, as well as to support privacy.
|
||
</para>
|
||
|
||
<para>
|
||
For background information and code, you should probably look at
|
||
the classic text ``Applied Cryptography'' [Schneier 1996].
|
||
Linux-specific resources include the Linux Encryption HOWTO at
|
||
<ulink
|
||
url="http://marc.mutz.com/Encryption-HOWTO/">http://marc.mutz.com/Encryption-HOWTO/</ulink>.
|
||
A discussion on how protocols use the basic algorithms can be
|
||
found in [Opplinger 1998].
|
||
What follows here is just a few comments; these areas are rather
|
||
specialized and covered more thoroughly elsewhere.
|
||
</para>
|
||
|
||
<para>
|
||
It's worth noting that there are many legal hurdles involved with
|
||
cryptographic algorithms.
|
||
First, the use, export, and/or import of implementations of
|
||
encryption algorithms are restricted in many countries.
|
||
Second, a number of algorithms are patented; even if the owners permit
|
||
``free use'' at the moment, without a signed contract they can always
|
||
change their minds later.
|
||
Most of the patent issues can be easily avoided nowadays, once you know
|
||
to watch out for it, so there's little reason to subject yourself to
|
||
the problem.
|
||
</para>
|
||
|
||
<para>
|
||
Cryptographic protocols and algorithms are difficult to get right,
|
||
so do not create your own.
|
||
Instead, use existing protocols and algorithms where you can.
|
||
In particular, do not create your own encryption algorithms unless you are
|
||
an expert in cryptology, know what you're doing, and plan to spend
|
||
years in professional review of the algorithm.
|
||
Creating encryption algorithms (that are any good)
|
||
is a task for experts only.
|
||
</para>
|
||
|
||
<para>
|
||
For protocols, try to use standard-conforming protocols
|
||
such as SSL (soon to be TLS), SSH, IPSec, GnuPG/PGP, and Kerberos.
|
||
Many of these overlap somewhat in functionality, but each has
|
||
a ``specialty'' niche.
|
||
SSL (soon to be TLS) is the primary method for protecting http (web)
|
||
transactions.
|
||
PGP-compatible protocols (implemented in PGP and GnuPG) are a primary
|
||
method for securing email end-to-end.
|
||
Kerberos is a primary method for securing and supporting authentication
|
||
on a LAN.
|
||
SSH is the primary method of securing ``remote terminals'' over an
|
||
internet, e.g., telnet-like and X windows connections, though it's often
|
||
used for securing other data streams too (such as CVS accesses).
|
||
IPSec is the primary method for security lower-level packets and
|
||
``all'' packets, so it's particularly useful for securing
|
||
virtual private networks and remote machines.
|
||
</para>
|
||
|
||
<para>
|
||
For secret key (bulk data) encryption algorithms,
|
||
use only encryption algorithms that have been openly published and withstood
|
||
years of attack, and check on their patent status.
|
||
For encrypting unimportant data, the old DES (56-bit key) algorithm still
|
||
has some value, but with modern hardware it's too easy to break.
|
||
For many applications triple-DES is currently the best encryption algorithm; it
|
||
has a reasonably lengthy key (112 bits), no patent issues, and has
|
||
a long history of withstanding attacks.
|
||
The upcoming AES algorithm may be worth using as well, once it's proven.
|
||
You should probably avoid IDEA due to patent issues
|
||
(it's subject to U.S. and European patents), but I'm unaware of any serious
|
||
technical problems with it.
|
||
Your protocol should support multiple algorithms;
|
||
that way, when an algorithm is broken, users can switch to another one.
|
||
</para>
|
||
|
||
<para>
|
||
For public key cryptography (used, among other things, for
|
||
authentication and sending secret keys), there are only a few
|
||
widely-deployed algorithms.
|
||
One of the most widely-used algorithms is RSA;
|
||
RSA's algorithm is patented, but only in the U.S., and that patent
|
||
expires September 20, 2000.
|
||
The Diffie-Hellman key exchange algorithm is widely used to permit
|
||
two parties to agree on a session key. By itself it doesn't guarantee that
|
||
the parties are who they say they are, or that there is no middleman, but
|
||
it does strongly help defend against passive listeners; its patent
|
||
expired in 1997.
|
||
NIST developed the digital signature standard (DSS) (it's a
|
||
modification of the ElGamal cryptosystem) for digital signature
|
||
generation and verification; one of the conditions for its development
|
||
was for it to be patent-free.
|
||
</para>
|
||
|
||
<para>
|
||
Some programs need a one-way hash algorithm, that is, a function
|
||
that takes an ``arbitrary'' amount of data and generates a fixed-length
|
||
number that hard to invert (e.g., it's difficult for an attacker to
|
||
create a different set of data to generate that same value).
|
||
For a number of years MD5 has been a favorite, but recent efforts have
|
||
shown that its 128-bit length may not be enough
|
||
[van Oorschot 1994]
|
||
and that certain attacks weaken MD5' protection
|
||
[Dobbertin 1996].
|
||
If you're writing new code, you probably ought to use SHA-1 instead.
|
||
</para>
|
||
|
||
<para>
|
||
In a related note, if you must create your own communication
|
||
protocol, examine the problems of what's gone on before.
|
||
Classics such as Bellovin [1989]'s review of security problems
|
||
in the TCP/IP protocol suite might help you, as well as
|
||
Bruce Schneier [1998]
|
||
and Mudge's breaking of Microsoft's PPTP implementation and their
|
||
follow-on work.
|
||
Of course, be sure to give any new protocol widespread review, and
|
||
reuse what you can.
|
||
</para>
|
||
|
||
|
||
</sect1>
|
||
|
||
|
||
<sect1>
|
||
<title>PAM</title>
|
||
|
||
<para>
|
||
Pluggable Authentication Modules (PAM) is
|
||
a flexible mechanism for authenticating users.
|
||
Many Unix-like systems support PAM, including
|
||
Solaris, nearly all Linux distributions
|
||
(e.g., Red Hat Linux, Caldera, and Debian as of version 2.2),
|
||
and FreeBSD as of version 3.1.
|
||
By using PAM, your program can be independent of the
|
||
authentication scheme (passwords, SmartCards, etc.).
|
||
Basically, your program calls PAM, which at run-time determines
|
||
which ``authentication modules'' are required by checking the configuration
|
||
set by the local system administrator.
|
||
If you're writing a program that requires authentication (e.g., entering
|
||
a password), you should include support for PAM.
|
||
You can find out more about the Linux-PAM project at
|
||
<ulink
|
||
url="http://www.kernel.org/pub/linux/libs/pam/index.html">http://www.kernel.org/pub/linux/libs/pam/index.html</ulink>.
|
||
</para>
|
||
|
||
</sect1>
|
||
|
||
|
||
<sect1>
|
||
<title>Tools</title>
|
||
|
||
<para>
|
||
Some tools may help you detect security problems before
|
||
you field the result.
|
||
If you're building a common kind of product where many standard
|
||
potential flaws exist (like an ftp server or firewall), you might
|
||
find standard security scanning tools useful.
|
||
One good one is
|
||
<ulink url="http://www.nessus.org">Nessus</ulink>; there are many others.
|
||
Of course, running a ``secure'' program on an insecure platform
|
||
configuration makes little sense;
|
||
you may want to examine hardening systems such as
|
||
Bastille available at
|
||
<ulink url="http://www.bastille-linux.org">http://www.bastille-linux.org</ulink>.
|
||
</para>
|
||
|
||
<para>
|
||
You may find some auditing tools helpful for finding potential security flaws.
|
||
Here are a few:
|
||
<itemizedlist>
|
||
<listitem><para>
|
||
ITS4 from Reliable Software Technologies (RST)
|
||
statically checks C/C++ code.
|
||
ITS4 works by performing
|
||
pattern-matching on source code, looking for patterns known to be
|
||
possibly dangerous (e.g., certain function calls).
|
||
It is available free for non-commercial use, including its source code
|
||
and with certain modification and redistribution rights.
|
||
One warning; the tool's licensing claims can be initially misleading.
|
||
RST claims that ITS4 is ``open source'' but, in fact, its license
|
||
does not meet the
|
||
<ulink url="http://www.opensource.org/osd.html">Open
|
||
Source Definition</ulink> (OSD).
|
||
In particular, ITS4's license fails point 6, which forbids
|
||
``non-commercial use only'' clauses in open source licenses.
|
||
It's unfortunate that RST insists on using the term
|
||
``open source'' to describe their license.
|
||
ITS4 is a fine tool, released under a
|
||
fairly generous license for commercial software, yet
|
||
using the term this way can give the appearance of a company
|
||
trying to gain the cachet of ``open source'' without actually
|
||
being open source.
|
||
RST says that they simply don't accept the OSD definition and
|
||
that they wish to use a different definition instead.
|
||
Nothing legally prevents this, but the OSD definition is used by
|
||
over 5000 software projects (at least all those hosted by SourceForge
|
||
at http://www.sourceforge.net),
|
||
Linux distributors, Netscape (now AOL), the W3C,
|
||
journalists (such as those of the Economist),
|
||
and many other organizations.
|
||
Most programmers don't want to wade through license agreements,
|
||
so using this other definition can be confusing.
|
||
I do not believe RST has any intention to mislead; they're
|
||
a reputable company with very reputable and honest people.
|
||
It's unfortunate that this particular position of theirs
|
||
leads (in my opinion) to unnecessary confusion.
|
||
In any case, ITS4 is available at
|
||
<ulink url="http://www.rstcorp.com/its4">http://www.rstcorp.com/its4</ulink>.
|
||
</para></listitem>
|
||
<listitem><para>
|
||
LCLint is a tool for statically checking C programs.
|
||
With minimal effort, LCLint can be used as a better lint.
|
||
If additional effort is invested adding annotations to programs,
|
||
LCLint can perform stronger checking than can be done by any standard lint.
|
||
The software is licensed under the GPL and is available from
|
||
<ulink url="http://lclint.cs.virginia.edu">http://lclint.cs.virginia.edu</ulink>.
|
||
</para></listitem>
|
||
<listitem><para>
|
||
BFBTester, the Brute Force Binary Tester, is licensed under the GPL.
|
||
This program does quick security checks of binary programs.
|
||
BFBTester performs checks of single and multiple argument
|
||
command line overflows and environment variable overflows.
|
||
Version 2.0 and higher can also watch for tempfile creation activity
|
||
(to check for using unsafe tempfile names).
|
||
More information is available at
|
||
<ulink url="http://my.ispchannel.com/~mheffner/bfbtester">http://my.ispchannel.com/~mheffner/bfbtester</ulink>.
|
||
</para></listitem>
|
||
</itemizedlist>
|
||
</para>
|
||
|
||
</sect1>
|
||
|
||
<sect1>
|
||
<title>Miscellaneous</title>
|
||
|
||
<para>
|
||
The following are miscellaneous security guidelines that I couldn't
|
||
seem to fit anywhere else:
|
||
</para>
|
||
|
||
<para>
|
||
Have your program check at least some of its assumptions before it uses them
|
||
(e.g., at the beginning of the program).
|
||
For example, if you depend on the ``sticky'' bit being set on a given
|
||
directory, test it; such tests take little time and could prevent
|
||
a serious problem.
|
||
If you worry about the execution time of some tests on each call, at least
|
||
perform the test at installation time, or even better at least
|
||
perform the test on application start-up.
|
||
</para>
|
||
|
||
<para>
|
||
Write audit logs for program startup, session startup, and
|
||
for suspicious activity.
|
||
Possible information of value includes date, time, uid, euid, gid, egid,
|
||
terminal information, process id, and command line values.
|
||
You may find the function syslog(3) helpful for implementing audit logs.
|
||
One awkward problem is that any logging system should be able to record
|
||
a lot of information (since this information could be very helpful), yet
|
||
if the information isn't handled carefully the information itself could be
|
||
used to create an attack.
|
||
After all, the attacker controls some of the input being sent to the program.
|
||
When recording data sent by a possible attacker,
|
||
identify a list of ``expected'' characters and
|
||
escape any ``unexpected'' characters so that the log isn't corrupted.
|
||
Not doing this can be a real problem; users may include characters
|
||
such as control characters (especially NIL or end-of-line) that
|
||
can cause real problems.
|
||
For example, if an attacker embeds a newline, they can then forge
|
||
log entries by following the newline with the desired log entry.
|
||
Sadly, there doesn't seem to be standard convention for escaping these
|
||
characters.
|
||
I'm partial to the URL escaping mechanism
|
||
(%hh where hh is the hexadecimal value of the escaped byte) but there
|
||
are others including the C convention (\ooo for the octal value and \X
|
||
where X is a special symbol, e.g., \n for newline).
|
||
There's also the caret-system (^I is control-I), though that doesn't
|
||
handle byte values over 127 gracefully.
|
||
</para>
|
||
|
||
<para>
|
||
There is the danger that a user could create a denial-of-service attack
|
||
(or at least stop auditing)
|
||
by performing a very large number of events that cut an audit record until
|
||
the system runs out of resources to store the records.
|
||
One approach to counter to this threat is to rate-limit audit record
|
||
recording; intentionally slow down the response rate
|
||
if ``too many'' audit records are being cut.
|
||
You could try to slow the response rate only to the suspected attacker,
|
||
but in many
|
||
situations a single attacker can masquerade as potentially many users.
|
||
</para>
|
||
|
||
<para>
|
||
Selecting what is ``suspicious activity'' is, of course, dependent on
|
||
what the program does and its anticipated use.
|
||
Any input that fails the filtering checks discussed earlier is
|
||
certainly a candidate (e.g., containing NIL).
|
||
Inputs that could not result from normal use should probably be logged,
|
||
e.g., a CGI program where certain required fields are missing
|
||
in suspicious ways.
|
||
Any input with phrases like /etc/passwd or /etc/shadow
|
||
or the like is very suspicious in many cases.
|
||
Similarly, trying to access Windows ``registry'' files or .pwl files
|
||
is very suspicious.
|
||
</para>
|
||
|
||
<para>
|
||
If you have a built-in scripting language, it may be possible for the
|
||
language to set an environment variable which adversely affects the
|
||
program invoking the script.
|
||
Defend against this.
|
||
</para>
|
||
|
||
<para>
|
||
If you need a complex configuration language,
|
||
make sure the language has a comment
|
||
character and include a number of commented-out secure examples.
|
||
Often '#' is used for commenting, meaning ``the rest
|
||
of this line is a comment''.
|
||
</para>
|
||
|
||
<para>
|
||
If possible, don't create setuid or setgid root programs;
|
||
make the user log in as root instead.
|
||
</para>
|
||
|
||
<para>
|
||
Sign your code. That way, others can check to see if what's available
|
||
was what was sent.
|
||
</para>
|
||
|
||
<para>
|
||
Consider statically linking secure programs.
|
||
This counters attacks on the dynamic link library mechanism
|
||
by making sure that the secure programs don't use it.
|
||
</para>
|
||
|
||
<para>
|
||
When reading over code, consider all the cases where a match is not made.
|
||
For example, if there is a switch statement, what happens when none of the
|
||
cases match?
|
||
If there is an ``if'' statement, what happens when the condition is false?
|
||
</para>
|
||
|
||
<!-- ??? maybe someday add Logging discussion -->
|
||
|
||
|
||
</sect1>
|
||
|
||
|
||
</chapter>
|
||
|
||
|
||
<chapter>
|
||
<title>Conclusion</title>
|
||
|
||
<epigraph>
|
||
<attribution>Ecclesiastes 7:8 (NIV)</attribution>
|
||
<para>
|
||
The end of a matter is better than its beginning, and
|
||
patience is better than pride.
|
||
</para>
|
||
</epigraph>
|
||
|
||
<para>
|
||
Designing and implementing a truly secure program
|
||
is actually a difficult task on Unix-like systems such as Linux and Unix.
|
||
The difficulty is that a truly secure program must respond
|
||
appropriately to all possible inputs and environments
|
||
controlled by a potentially hostile user.
|
||
Developers of secure programs must deeply understand their platform,
|
||
seek and use guidelines (such as these), and then use assurance
|
||
processes (such as peer review) to reduce their programs' vulnerabilities.
|
||
</para>
|
||
|
||
<para>
|
||
In conclusion, here are some of the key guidelines from this paper:
|
||
|
||
<itemizedlist>
|
||
<listitem>
|
||
|
||
<para>
|
||
Validate all your inputs, including command line inputs,
|
||
environment variables, CGI inputs, and so on.
|
||
Don't just reject ``bad'' input; define what is an ``acceptable'' input
|
||
and reject anything that doesn't match.
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
|
||
<para>
|
||
Avoid buffer overflow.
|
||
This is the primary programmatic error at this time.
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
|
||
<para>
|
||
Structure Program Internals.
|
||
Secure the interface, minimize privileges, make the initial configuration
|
||
and defaults safe, and fail safe.
|
||
Avoid race conditions and trust only trustworthy channels
|
||
(e.g., most servers must not trust their clients for security checks).
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
|
||
<para>
|
||
Carefully call out to other resources.
|
||
Limit their values to valid values (in particular be concerned about
|
||
metacharacters), and check all system call return values.
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
|
||
<para>
|
||
Reply information judiciously.
|
||
In particular, minimize feedback, and handle full or unresponsive output
|
||
to an untrusted user.
|
||
</para>
|
||
</listitem>
|
||
|
||
</itemizedlist>
|
||
|
||
</para>
|
||
|
||
</chapter>
|
||
|
||
<chapter>
|
||
<title>Bibliography</title>
|
||
|
||
<epigraph>
|
||
<attribution>Ecclesiastes 12:11-12 (NIV)</attribution>
|
||
<para>
|
||
The words of the wise are like goads, their collected sayings like
|
||
firmly embedded nails--given by one Shepherd.
|
||
Be warned, my son, of anything in addition to them.
|
||
Of making many books there is no end, and much study wearies the body.
|
||
</para>
|
||
</epigraph>
|
||
|
||
<para>
|
||
<emphasis remap="it">Note that there is a heavy
|
||
emphasis on technical articles available on the web, since this is where
|
||
most of this kind of technical information is available.</emphasis>
|
||
</para>
|
||
|
||
<para>
|
||
[Advosys 2000]
|
||
Advosys Consulting
|
||
(formerly named Webber Technical Services).
|
||
<emphasis remap="it">Writing Secure Web Applications</emphasis>.
|
||
<ulink url="http://advosys.ca/tips/web-security.html">http://advosys.ca/tips/web-security.html</ulink>
|
||
<!-- was http://www.webbertech.com/tips/web-security.html -->
|
||
</para>
|
||
|
||
<para>
|
||
[Al-Herbish 1999]
|
||
Al-Herbish, Thamer.
|
||
1999.
|
||
<emphasis remap="it">Secure Unix Programming FAQ</emphasis>.
|
||
<ulink
|
||
url="http://www.whitefang.com/sup">http://www.whitefang.com/sup</ulink>.
|
||
</para>
|
||
|
||
<para>
|
||
[Aleph1 1996]
|
||
Aleph1.
|
||
November 8, 1996.
|
||
``Smashing The Stack For Fun And Profit''.
|
||
<emphasis remap="it">Phrack Magazine</emphasis>.
|
||
Issue 49, Article 14.
|
||
<!-- ???: may need to double-escape the ampersand here. -->
|
||
<ulink
|
||
url="http://www.phrack.com/search.phtml?view&article=p49-14">http://www.phrack.com/search.phtml?view&article=p49-14</ulink>
|
||
or alternatively
|
||
<ulink
|
||
url="http://www.2600.net/phrack/p49-14.html">http://www.2600.net/phrack/p49-14.html</ulink>.
|
||
</para>
|
||
|
||
<para>
|
||
[Anonymous 1999]
|
||
Anonymous.
|
||
October 1999.
|
||
Maximum Linux Security:
|
||
A Hacker's Guide to Protecting Your Linux Server and Workstation
|
||
Sams.
|
||
ISBN: 0672316706.
|
||
</para>
|
||
|
||
<para>
|
||
[Anonymous 1998]
|
||
Anonymous.
|
||
September 1998.
|
||
Maximum Security : A Hacker's Guide to Protecting Your
|
||
Internet Site and Network.
|
||
Sams.
|
||
Second Edition.
|
||
ISBN: 0672313413.
|
||
</para>
|
||
|
||
<para>
|
||
[AUSCERT 1996]
|
||
Australian Computer Emergency Response Team (AUSCERT) and O'Reilly.
|
||
May 23, 1996 (rev 3C).
|
||
<emphasis remap="it">A Lab Engineers Check List for Writing Secure Unix Code</emphasis>.
|
||
<ulink
|
||
url="ftp://ftp.auscert.org.au/pub/auscert/papers/secure_programming_checklist">ftp://ftp.auscert.org.au/pub/auscert/papers/secure_programming_checklist</ulink>
|
||
</para>
|
||
|
||
<para>
|
||
[Bach 1986]
|
||
Bach, Maurice J.
|
||
1986.
|
||
<emphasis remap="it">The Design of the Unix Operating System</emphasis>.
|
||
Englewood Cliffs, NJ: Prentice-Hall, Inc.
|
||
ISBN 0-13-201799-7 025.
|
||
</para>
|
||
|
||
<para>
|
||
[Bellovin 1989]
|
||
Bellovin, Steven M.
|
||
April 1989.
|
||
"Security Problems in the TCP/IP Protocol Suite"
|
||
Computer Communications Review 2:19, pp. 32-48.
|
||
<ulink
|
||
url="http://www.research.att.com/~smb/papers/ipext.pdf">http://www.research.att.com/~smb/papers/ipext.pdf</ulink>
|
||
</para>
|
||
|
||
<para>
|
||
[Bellovin 1994]
|
||
Bellovin, Steven M.
|
||
December 1994.
|
||
<emphasis remap="it">Shifting the Odds -- Writing (More) Secure Software</emphasis>.
|
||
Murray Hill, NJ: AT&T Research.
|
||
<ulink
|
||
url="http://www.research.att.com/~smb/talks">http://www.research.att.com/~smb/talks</ulink>
|
||
</para>
|
||
|
||
<para>
|
||
[Bishop 1996]
|
||
Bishop, Matt.
|
||
May 1996.
|
||
``UNIX Security: Security in Programming''.
|
||
<emphasis remap="it">SANS '96</emphasis>. Washington DC (May 1996).
|
||
<ulink
|
||
url="http://olympus.cs.ucdavis.edu/~bishop/secprog.html">http://olympus.cs.ucdavis.edu/~bishop/secprog.html</ulink>
|
||
</para>
|
||
|
||
<para>
|
||
[Bishop 1997]
|
||
Bishop, Matt.
|
||
October 1997.
|
||
``Writing Safe Privileged Programs''.
|
||
<emphasis remap="it">Network Security 1997</emphasis>
|
||
New Orleans, LA.
|
||
<ulink
|
||
url="http://olympus.cs.ucdavis.edu/~bishop/secprog.html">http://olympus.cs.ucdavis.edu/~bishop/secprog.html</ulink>
|
||
</para>
|
||
|
||
<para>
|
||
[CC 1999]
|
||
<emphasis remap="it">The Common Criteria for Information Technology Security Evaluation
|
||
(CC)</emphasis>.
|
||
August 1999.
|
||
Version 2.1.
|
||
Technically identical to International Standard ISO/IEC 15408:1999.
|
||
<ulink
|
||
url="http://csrc.nist.gov/cc/ccv20/ccv2list.htm">http://csrc.nist.gov/cc/ccv20/ccv2list.htm</ulink>
|
||
</para>
|
||
|
||
<para>
|
||
[CERT 1998]
|
||
Computer Emergency Response Team (CERT) Coordination Center (CERT/CC).
|
||
February 13, 1998.
|
||
<emphasis remap="it">Sanitizing User-Supplied Data in CGI Scripts</emphasis>.
|
||
CERT Advisory CA-97.25.CGI_metachar.
|
||
<ulink
|
||
url="http://www.cert.org/advisories/CA-97.25.CGI_metachar.html">http://www.cert.org/advisories/CA-97.25.CGI_metachar.html</ulink>.
|
||
</para>
|
||
|
||
<para>
|
||
[CMU 1998]
|
||
Carnegie Mellon University (CMU).
|
||
February 13, 1998
|
||
Version 1.4.
|
||
``How To Remove Meta-characters From User-Supplied Data In CGI Scripts''.
|
||
<ulink
|
||
url="ftp://ftp.cert.org/pub/tech_tips/cgi_metacharacters">ftp://ftp.cert.org/pub/tech_tips/cgi_metacharacters</ulink>.
|
||
</para>
|
||
|
||
<para>
|
||
[Cowan 1999]
|
||
Cowan, Crispin, Perry Wagle, Calton Pu, Steve Beattie, and
|
||
Jonathan Walpole.
|
||
``Buffer Overflows: Attacks and Defenses for the Vulnerability
|
||
of the Decade''.
|
||
Proceedings of DARPA Information Survivability Conference and Expo (DISCEX),
|
||
<ulink
|
||
url="http://schafercorp-ballston.com/discex">http://schafercorp-ballston.com/discex</ulink>
|
||
To appear at SANS 2000,
|
||
<ulink
|
||
url="http://www.sans.org/newlook/events/sans2000.htm">http://www.sans.org/newlook/events/sans2000.htm</ulink>.
|
||
For a copy, see
|
||
<ulink
|
||
url="http://immunix.org/documentation.html">http://immunix.org/documentation.html</ulink>.
|
||
</para>
|
||
|
||
<para>
|
||
[Dobbertin 1996].
|
||
Dobbertin, H.
|
||
1996.
|
||
The Status of MD5 After a Recent Attack.
|
||
RSA Laboratories' CryptoBytes.
|
||
Vol. 2, No. 2.
|
||
</para>
|
||
|
||
<para>
|
||
[Fenzi 1999]
|
||
Fenzi, Kevin, and Dave Wrenski.
|
||
April 25, 1999.
|
||
<emphasis remap="it">Linux Security HOWTO</emphasis>.
|
||
Version 1.0.2.
|
||
<ulink
|
||
url="http://www.linuxdoc.org/HOWTO/Security-HOWTO.html">http://www.linuxdoc.org/HOWTO/Security-HOWTO.html</ulink>
|
||
</para>
|
||
|
||
<para>
|
||
[FHS 1997]
|
||
Filesystem Hierarchy Standard (FHS 2.0).
|
||
October 26, 1997.
|
||
Filesystem Hierarchy Standard Group, edited by Daniel Quinlan.
|
||
Version 2.0.
|
||
<ulink
|
||
url="http://www.pathname.com/fhs">http://www.pathname.com/fhs</ulink>.
|
||
</para>
|
||
|
||
<para>
|
||
[Filipski 1986]
|
||
Filipski, Alan and James Hanko.
|
||
April 1986.
|
||
``Making Unix Secure.''
|
||
Byte (Magazine).
|
||
Peterborough, NH: McGraw-Hill Inc.
|
||
Vol. 11, No. 4.
|
||
ISSN 0360-5280.
|
||
pp. 113-128.
|
||
</para>
|
||
|
||
<para>
|
||
[FOLDOC]
|
||
Free On-Line Dictionary of Computing.
|
||
<ulink
|
||
url="http://foldoc.doc.ic.ac.uk/foldoc/index.html">
|
||
http://foldoc.doc.ic.ac.uk/foldoc/index.html</ulink>.
|
||
</para>
|
||
|
||
<para>
|
||
[FreeBSD 1999]
|
||
FreeBSD, Inc.
|
||
1999.
|
||
``Secure Programming Guidelines''.
|
||
<emphasis remap="it">FreeBSD Security Information</emphasis>.
|
||
<ulink
|
||
url="http://www.freebsd.org/security/security.html">http://www.freebsd.org/security/security.html</ulink>
|
||
</para>
|
||
|
||
<para>
|
||
[FSF 1998]
|
||
Free Software Foundation.
|
||
December 17, 1999.
|
||
<emphasis remap="it">Overview of the GNU Project</emphasis>.
|
||
<ulink
|
||
url="http://www.gnu.ai.mit.edu/gnu/gnu-history.html">http://www.gnu.ai.mit.edu/gnu/gnu-history.html</ulink>
|
||
</para>
|
||
|
||
<para>
|
||
[FSF 1999]
|
||
Free Software Foundation.
|
||
January 11, 1999.
|
||
<emphasis remap="it">The GNU C Library Reference Manual</emphasis>.
|
||
Edition 0.08 DRAFT, for Version 2.1 Beta of the GNU C Library.
|
||
Available at, for example,
|
||
<ulink url="http://www.netppl.fi/~pp/glibc21/libc_toc.html">http://www.netppl.fi/~pp/glibc21/libc_toc.html</ulink>
|
||
</para>
|
||
|
||
<para>
|
||
[Galvin 1998a]
|
||
Galvin, Peter.
|
||
April 1998.
|
||
``Designing Secure Software''.
|
||
<emphasis remap="it">Sunworld</emphasis>.
|
||
<ulink
|
||
url="http://www.sunworld.com/swol-04-1998/swol-04-security.html">http://www.sunworld.com/swol-04-1998/swol-04-security.html</ulink>.
|
||
</para>
|
||
|
||
<para>
|
||
[Galvin 1998b]
|
||
Galvin, Peter.
|
||
August 1998.
|
||
``The Unix Secure Programming FAQ''.
|
||
<emphasis remap="it">Sunworld</emphasis>.
|
||
<ulink
|
||
url="http://www.sunworld.com/sunworldonline/swol-08-1998/swol-08-security.html">http://www.sunworld.com/sunworldonline/swol-08-1998/swol-08-security.html</ulink>
|
||
</para>
|
||
|
||
<para>
|
||
[Garfinkel 1996]
|
||
Garfinkel, Simson and Gene Spafford.
|
||
April 1996.
|
||
<emphasis remap="it">Practical UNIX & Internet Security, 2nd Edition</emphasis>.
|
||
ISBN 1-56592-148-8.
|
||
Sebastopol, CA: O'Reilly & Associates, Inc.
|
||
<ulink
|
||
url="http://www.oreilly.com/catalog/puis">http://www.oreilly.com/catalog/puis</ulink>
|
||
</para>
|
||
|
||
<para>
|
||
[Garfinkle 1997]
|
||
Garfinkle, Simson.
|
||
August 8, 1997.
|
||
21 Rules for Writing Secure CGI Programs.
|
||
<ulink url="http://webreview.com/wr/pub/97/08/08/bookshelf">
|
||
http://webreview.com/wr/pub/97/08/08/bookshelf</ulink>
|
||
</para>
|
||
|
||
<para>
|
||
[Graham 1999]
|
||
Graham, Jeff.
|
||
May 4, 1999.
|
||
<emphasis remap="it">Security-Audit's Frequently Asked Questions (FAQ)</emphasis>.
|
||
<ulink
|
||
url="http://lsap.org/faq.txt">http://lsap.org/faq.txt</ulink>
|
||
</para>
|
||
|
||
<para>
|
||
[Gong 1999]
|
||
Gong, Li.
|
||
June 1999.
|
||
<emphasis remap="it">Inside Java 2 Platform Security</emphasis>.
|
||
Reading, MA: Addison Wesley Longman, Inc.
|
||
ISBN 0-201-31000-7.
|
||
</para>
|
||
|
||
<para>
|
||
[Gundavaram Unknown]
|
||
Gundavaram, Shishir, and Tom Christiansen.
|
||
Date Unknown.
|
||
<emphasis remap="it">Perl CGI Programming FAQ</emphasis>.
|
||
<ulink
|
||
url="http://language.perl.com/CPAN/doc/FAQs/cgi/perl-cgi-faq.html">http://language.perl.com/CPAN/doc/FAQs/cgi/perl-cgi-faq.html</ulink>
|
||
</para>
|
||
|
||
<para>
|
||
[Hall "Beej" 1999]
|
||
Hall, Brian "Beej".
|
||
Beej's Guide to Network Programming Using Internet Sockets.
|
||
13-Jan-1999.
|
||
Version 1.5.5.
|
||
<ulink url="http://www.ecst.csuchico.edu/~beej/guide/net">http://www.ecst.csuchico.edu/~beej/guide/net</ulink>
|
||
</para>
|
||
|
||
<para>
|
||
[Kernighan 1988]
|
||
Kernighan, Brian W., and Dennis M. Ritchie.
|
||
1988.
|
||
<emphasis remap="it">The C Programming Language</emphasis>.
|
||
Second Edition.
|
||
Englewood Cliffs, NJ: Prentice-Hall.
|
||
ISBN 0-13-110362-8.
|
||
</para>
|
||
|
||
<para>
|
||
[Kim 1996]
|
||
Kim, Eugene Eric.
|
||
1996.
|
||
<emphasis remap="it">CGI Developer's Guide</emphasis>.
|
||
SAMS.net Publishing.
|
||
ISBN: 1-57521-087-8
|
||
<ulink
|
||
url="http://www.eekim.com/pubs/cgibook">http://www.eekim.com/pubs/cgibook</ulink>
|
||
</para>
|
||
|
||
<para>
|
||
Kuchling [2000].
|
||
Kuchling, A.M.
|
||
2000.
|
||
Restricted Execution HOWTO.
|
||
<ulink url="http://www.python.org/doc/howto/rexec/rexec.html">http://www.python.org/doc/howto/rexec/rexec.html</ulink>
|
||
</para>
|
||
|
||
<para>
|
||
[McClure 1999]
|
||
McClure, Stuart, Joel Scambray, and George Kurtz.
|
||
1999.
|
||
<emphasis remap="it">Hacking Exposed: Network Security Secrets and Solutions</emphasis>.
|
||
Berkeley, CA: Osbourne/McGraw-Hill.
|
||
ISBN 0-07-212127-0.
|
||
</para>
|
||
|
||
<para>
|
||
[McKusick 1999]
|
||
McKusick, Marshall Kirk.
|
||
January 1999.
|
||
``Twenty Years of Berkeley Unix: From AT&T-Owned to
|
||
Freely Redistributable.''
|
||
<emphasis remap="it">Open Sources: Voices from the Open Source Revolution</emphasis>.
|
||
<ulink
|
||
url="http://www.oreilly.com/catalog/opensources/book/kirkmck.html">http://www.oreilly.com/catalog/opensources/book/kirkmck.html</ulink>.
|
||
</para>
|
||
|
||
<para>
|
||
[McGraw 1999]
|
||
McGraw, Gary, and Edward W. Felten.
|
||
January 25, 1999.
|
||
Securing Java: Getting Down to Business with Mobile Code, 2nd Edition
|
||
John Wiley & Sons.
|
||
ISBN 047131952X.
|
||
<ulink url="http://www.securingjava.com">http://www.securingjava.com</ulink>.
|
||
</para>
|
||
|
||
<para>
|
||
[McGraw 2000]
|
||
McGraw, Gary and John Viega.
|
||
March 1, 2000.
|
||
Make Your Software Behave: Learning the Basics of Buffer Overflows.
|
||
<ulink
|
||
url="http://www-4.ibm.com/software/developer/library/overflows/index.html">http://www-4.ibm.com/software/developer/library/overflows/index.html</ulink>.
|
||
</para>
|
||
|
||
<para>
|
||
[Miller 1995]
|
||
Miller, Barton P.,
|
||
David Koski, Cjin Pheow Lee, Vivekananda Maganty,
|
||
Ravi Murthy, Ajitkumar Natarajan, and Jeff Steidl.
|
||
1995.
|
||
Fuzz Revisited: A Re-examination of the Reliability of
|
||
UNIX Utilities and Services.
|
||
<ulink url="ftp://grilled.cs.wisc.edu/technical_papers/fuzz-revisited.pdf">ftp://grilled.cs.wisc.edu/technical_papers/fuzz-revisited.pdf</ulink>.
|
||
</para>
|
||
|
||
<para>
|
||
[Miller 1999]
|
||
Miller, Todd C. and Theo de Raadt.
|
||
``strlcpy and strlcat -- Consistent, Safe, String Copy and Concatenation''
|
||
<emphasis remap="it">Proceedings of Usenix '99</emphasis>.
|
||
<ulink
|
||
url="http://www.usenix.org/events/usenix99/millert.html">http://www.usenix.org/events/usenix99/millert.html</ulink> and
|
||
<ulink
|
||
url="http://www.usenix.org/events/usenix99/full_papers/millert/PACKING_LIST">http://www.usenix.org/events/usenix99/full_papers/millert/PACKING_LIST</ulink>
|
||
</para>
|
||
|
||
<para>
|
||
[Mudge 1995]
|
||
Mudge.
|
||
October 20, 1995.
|
||
<emphasis remap="it">How to write Buffer Overflows</emphasis>.
|
||
l0pht advisories.
|
||
<ulink
|
||
url="http://www.l0pht.com/advisories/bufero.html">http://www.l0pht.com/advisories/bufero.html</ulink>.
|
||
</para>
|
||
|
||
<para>
|
||
[NCSA]
|
||
NCSA Secure Programming Guidelines.
|
||
<ulink url="http://www.ncsa.uiuc.edu/General/Grid/ACES/security/programming">http://www.ncsa.uiuc.edu/General/Grid/ACES/security/programming</ulink>.
|
||
</para>
|
||
|
||
<para>
|
||
[Open Group 1997]
|
||
The Open Group.
|
||
1997.
|
||
<emphasis remap="it">Single UNIX Specification, Version 2 (UNIX 98)</emphasis>.
|
||
<ulink
|
||
url="http://www.opengroup.org/online-pubs?DOC=007908799">http://www.opengroup.org/online-pubs?DOC=007908799</ulink>.
|
||
</para>
|
||
|
||
<para>
|
||
[OSI 1999].
|
||
Open Source Initiative.
|
||
1999.
|
||
<emphasis remap="it">The Open Source Definition</emphasis>.
|
||
<ulink
|
||
url="http://www.opensource.org/osd.html">http://www.opensource.org/osd.html</ulink>.
|
||
</para>
|
||
|
||
<para>
|
||
[Opplinger 1998]
|
||
Oppliger, Rolf.
|
||
1998.
|
||
Internet and Intranet Security.
|
||
Norwood, MA: Artech House.
|
||
ISBN 0-89006-829-1.
|
||
</para>
|
||
|
||
<para>
|
||
[Peteanu 2000]
|
||
Peteanu, Razvan.
|
||
July 18, 2000.
|
||
Best Practices for Secure Web Development.
|
||
<ulink url="http://members.home.net/razvan.peteanu">http://members.home.net/razvan.peteanu</ulink>
|
||
</para>
|
||
|
||
<para>
|
||
[Pfleeger 1997]
|
||
Pfleeger, Charles P.
|
||
1997.
|
||
<emphasis remap="it">Security in Computing.</emphasis>
|
||
Upper Saddle River, NJ: Prentice-Hall PTR.
|
||
ISBN 0-13-337486-6.
|
||
</para>
|
||
|
||
<para>
|
||
[Phillips 1995]
|
||
Phillips, Paul.
|
||
September 3, 1995.
|
||
<emphasis remap="it">Safe CGI Programming</emphasis>.
|
||
<ulink
|
||
url="http://www.go2net.com/people/paulp/cgi-security/safe-cgi.txt">http://www.go2net.com/people/paulp/cgi-security/safe-cgi.txt</ulink>
|
||
</para>
|
||
|
||
<para>
|
||
[Quintero 1999]
|
||
Quintero, Federico Mena,
|
||
Miguel de Icaza, and Morten Welinder
|
||
GNOME Programming Guidelines
|
||
<ulink url="http://developer.gnome.org/doc/guides/programming-guidelines/book1.html">http://developer.gnome.org/doc/guides/programming-guidelines/book1.html</ulink>
|
||
<!-- http://developer.gnome.org/doc/guides/programming-guidelines/security.html -->
|
||
</para>
|
||
|
||
<para>
|
||
[Raymond 1997]
|
||
Raymond, Eric.
|
||
1997.
|
||
<emphasis remap="it">The Cathedral and the Bazaar</emphasis>.
|
||
<ulink
|
||
url="http://www.tuxedo.org/~esr/writings/cathedral-bazaar">http://www.tuxedo.org/~esr/writings/cathedral-bazaar</ulink>
|
||
</para>
|
||
|
||
<para>
|
||
[Raymond 1998]
|
||
Raymond, Eric.
|
||
April 1998.
|
||
<emphasis remap="it">Homesteading the Noosphere</emphasis>.
|
||
<ulink
|
||
url="http://www.tuxedo.org/~esr/writings/homesteading/homesteading.html">http://www.tuxedo.org/~esr/writings/homesteading/homesteading.html</ulink>
|
||
</para>
|
||
|
||
<para>
|
||
[Ranum 1998]
|
||
Ranum, Marcus J.
|
||
1998.
|
||
<emphasis remap="it">Security-critical coding for programmers -
|
||
a C and UNIX-centric full-day tutorial</emphasis>.
|
||
<ulink
|
||
url="http://www.clark.net/pub/mjr/pubs/pdf/">http://www.clark.net/pub/mjr/pubs/pdf/</ulink>.
|
||
</para>
|
||
|
||
<para>
|
||
[RFC 822]
|
||
August 13, 1982
|
||
<emphasis remap="it">Standard for the Format of ARPA Internet Text Messages</emphasis>.
|
||
IETF RFC 822.
|
||
<ulink
|
||
url="http://www.ietf.org/rfc/rfc0822.txt">http://www.ietf.org/rfc/rfc0822.txt</ulink>.
|
||
</para>
|
||
|
||
<para>
|
||
[rfp 1999].
|
||
rain.forest.puppy.
|
||
``Perl CGI problems''.
|
||
<emphasis remap="it">Phrack Magazine</emphasis>.
|
||
Issue 55, Article 07.
|
||
<ulink
|
||
url="http://www.phrack.com/search.phtml?view&article=p55-7">http://www.phrack.com/search.phtml?view&article=p55-7</ulink> or
|
||
<ulink url="http://www.insecure.org/news/P55-07.txt">http://www.insecure.org/news/P55-07.txt</ulink>.
|
||
</para>
|
||
|
||
<para>
|
||
[Rochkind 1985].
|
||
Rochkind, Marc J.
|
||
<emphasis>Advanced Unix Programming</emphasis>.
|
||
Englewood Cliffs, NJ: Prentice-Hall, Inc.
|
||
ISBN 0-13-011818-4.
|
||
</para>
|
||
|
||
<para>
|
||
[St. Laurent 2000]
|
||
St. Laurent, Simon.
|
||
February 2000.
|
||
<emphasis remap="it">XTech 2000 Conference Reports</emphasis>.
|
||
``When XML Gets Ugly''.
|
||
<ulink
|
||
url="http://www.xml.com/pub/2000/02/xtech/megginson.html">http://www.xml.com/pub/2000/02/xtech/megginson.html</ulink>.
|
||
</para>
|
||
|
||
<para>
|
||
[Saltzer 1974]
|
||
Saltzer, J.
|
||
July 1974.
|
||
``Protection and the Control of Information Sharing in MULTICS''.
|
||
<emphasis remap="it">Communications of the ACM</emphasis>.
|
||
v17 n7.
|
||
pp. 388-402.
|
||
</para>
|
||
|
||
<para>
|
||
[Saltzer 1975]
|
||
Saltzer, J., and M. Schroeder.
|
||
September 1975.
|
||
``The Protection of Information in Computing Systems''.
|
||
<emphasis remap="it">Proceedings of the IEEE</emphasis>.
|
||
v63 n9.
|
||
pp. 1278-1308.
|
||
<ulink
|
||
url="http://www.mediacity.com/~norm/CapTheory/ProtInf">http://www.mediacity.com/~norm/CapTheory/ProtInf</ulink>.
|
||
Summarized in [Pfleeger 1997, 286].
|
||
</para>
|
||
|
||
<para>
|
||
[Schneier 1996]
|
||
Schneier, Bruce.
|
||
1996.
|
||
<emphasis remap="it">Applied Cryptography, Second Edition:
|
||
Protocols, Algorithms, and Source Code in C</emphasis>.
|
||
New York: John Wiley and Sons.
|
||
ISBN 0-471-12845-7.
|
||
</para>
|
||
|
||
<para>
|
||
[Schneier 1998]
|
||
Schneier, Bruce and Mudge.
|
||
November 1998.
|
||
<emphasis remap="it">Cryptanalysis of Microsoft's Point-to-Point Tunneling Protocol (PPTP)</emphasis>
|
||
Proceedings of the 5th ACM Conference on Communications and Computer Security,
|
||
ACM Press.
|
||
<ulink
|
||
url="http://www.counterpane.com/pptp.html">http://www.counterpane.com/pptp.html</ulink>.
|
||
</para>
|
||
|
||
<para>
|
||
[Schneier 1999]
|
||
Schneier, Bruce.
|
||
September 15, 1999.
|
||
``Open Source and Security''.
|
||
<emphasis remap="it">Crypto-Gram</emphasis>.
|
||
Counterpane Internet Security, Inc.
|
||
<ulink
|
||
url="http://www.counterpane.com/crypto-gram-9909.html">http://www.counterpane.com/crypto-gram-9909.html</ulink>
|
||
</para>
|
||
|
||
<para>
|
||
[Seifried 1999]
|
||
Seifried, Kurt.
|
||
October 9, 1999.
|
||
<emphasis remap="it">Linux Administrator's Security Guide</emphasis>.
|
||
<ulink
|
||
url="http://www.securityportal.com/lasg">http://www.securityportal.com/lasg</ulink>.
|
||
</para>
|
||
|
||
<para>
|
||
[Shankland 2000]
|
||
Shankland, Stephen.
|
||
``Linux poses increasing threat to Windows 2000''.
|
||
CNET.
|
||
<ulink
|
||
url="http://news.cnet.com/news/0-1003-200-1549312.html">http://news.cnet.com/news/0-1003-200-1549312.html</ulink>
|
||
</para>
|
||
|
||
<para>
|
||
[Shostack 1999]
|
||
Shostack, Adam.
|
||
June 1, 1999.
|
||
<emphasis remap="it">Security Code Review Guidelines</emphasis>.
|
||
<ulink
|
||
url="http://www.homeport.org/~adam/review.html">http://www.homeport.org/~adam/review.html</ulink>.
|
||
</para>
|
||
|
||
<para>
|
||
[Sibert 1996]
|
||
Sibert, W. Olin.
|
||
Malicious Data and Computer Security.
|
||
(NIST) NISSC '96.
|
||
<ulink url="http://www.fish.com/security/maldata.html">http://www.fish.com/security/maldata.html</ulink>
|
||
</para>
|
||
|
||
<para>
|
||
[Sitaker 1999]
|
||
Sitaker, Kragen.
|
||
Feb 26, 1999.
|
||
<emphasis remap="it">How to Find Security Holes</emphasis>
|
||
<ulink
|
||
url="http://www.pobox.com/~kragen/security-holes.html">http://www.pobox.com/~kragen/security-holes.html</ulink> and
|
||
<ulink
|
||
url="http://www.dnaco.net/~kragen/security-holes.html">http://www.dnaco.net/~kragen/security-holes.html</ulink>
|
||
</para>
|
||
|
||
<para>
|
||
[SSE-CMM 1999]
|
||
SSE-CMM Project.
|
||
April 1999.
|
||
<emphasis remap="it">System Security Engineering Capability Maturity Model (SSE CMM)
|
||
Model Description Document</emphasis>.
|
||
Version 2.0.
|
||
<ulink
|
||
url="http://www.sse-cmm.org">http://www.sse-cmm.org</ulink>
|
||
</para>
|
||
|
||
<para>
|
||
[Stein 1999].
|
||
Stein, Lincoln D.
|
||
September 13, 1999.
|
||
<emphasis remap="it">The World Wide Web Security FAQ</emphasis>.
|
||
Version 2.0.1
|
||
<ulink
|
||
url="http://www.w3.org/Security/Faq/www-security-faq.html">http://www.w3.org/Security/Faq/www-security-faq.html</ulink>
|
||
</para>
|
||
|
||
<para>
|
||
[Thompson 1974]
|
||
Thompson, K. and D.M. Richie.
|
||
July 1974.
|
||
``The UNIX Time-Sharing System''.
|
||
<emphasis remap="it">Communications of the ACM</emphasis>
|
||
Vol. 17, No. 7.
|
||
pp. 365-375.
|
||
<!-- Revised and reprinted in Ritchie 1978a; see Bach 1986 -->
|
||
</para>
|
||
|
||
<para>
|
||
[Torvalds 1999]
|
||
Torvalds, Linus.
|
||
February 1999.
|
||
``The Story of the Linux Kernel''.
|
||
<emphasis remap="it">Open Sources: Voices from the Open Source Revolution</emphasis>.
|
||
Edited by Chris Dibona, Mark Stone, and Sam Ockman.
|
||
O'Reilly and Associates.
|
||
ISBN 1565925823.
|
||
<ulink
|
||
url="http://www.oreilly.com/catalog/opensources/book/linus.html">http://www.oreilly.com/catalog/opensources/book/linus.html</ulink>
|
||
</para>
|
||
|
||
<para>
|
||
[Unknown]
|
||
<emphasis remap="it">SETUID(7)</emphasis>
|
||
<ulink
|
||
url="http://www.homeport.org/~adam/setuid.7.html">http://www.homeport.org/~adam/setuid.7.html</ulink>.
|
||
<!-- Claimed to be from Dan Farmer's COPS, but COPS does not include it. -->
|
||
</para>
|
||
|
||
<para>
|
||
[Van Biesbrouck 1996]
|
||
Van Biesbrouck, Michael.
|
||
April 19, 1996.
|
||
<ulink url="http://www.csclub.uwaterloo.ca/u/mlvanbie/cgisec">http://www.csclub.uwaterloo.ca/u/mlvanbie/cgisec</ulink>.
|
||
</para>
|
||
|
||
<para>
|
||
[van Oorschot 1994]
|
||
van Oorschot, P. and M. Wiener.
|
||
November 1994.
|
||
``Parallel Collision Search with Applications to Hash Functions
|
||
and Discrete Logarithms.''
|
||
Proceedings of ACM Conference on Computer and Communications Security.
|
||
</para>
|
||
|
||
<para>
|
||
[Venema 1996]
|
||
Venema, Wietse.
|
||
1996.
|
||
Murphy's law and computer security.
|
||
<ulink url="http://www.fish.com/security/murphy.html">http://www.fish.com/security/murphy.html</ulink>
|
||
</para>
|
||
|
||
<para>
|
||
[Watters 1996]
|
||
Watters, Arron, Guido van Rossum, James C. Ahlstrom.
|
||
1996.
|
||
Internet Programming with Python.
|
||
NY, NY: Henry Hold and Company, Inc.
|
||
</para>
|
||
|
||
<para>
|
||
[Wood 1985]
|
||
Wood, Patrick H. and Stephen G. Kochan.
|
||
1985.
|
||
<emphasis remap="it">Unix System Security</emphasis>.
|
||
Indianapolis, Indiana: Hayden Books.
|
||
ISBN 0-8104-6267-2.
|
||
</para>
|
||
|
||
<para>
|
||
[Wreski 1998]
|
||
Wreski, Dave.
|
||
August 22, 1998.
|
||
<emphasis remap="it">Linux Security Administrator's Guide</emphasis>.
|
||
Version 0.98.
|
||
<ulink
|
||
url="http://www.nic.com/~dave/SecurityAdminGuide/index.html">http://www.nic.com/~dave/SecurityAdminGuide/index.html</ulink>
|
||
</para>
|
||
|
||
<para>
|
||
[Yoder 1998]
|
||
Yoder, Joseph and Jeffrey Barcalow.
|
||
1998.
|
||
Architectural Patterns for Enabling Application Security.
|
||
PLoP '97
|
||
<ulink url="http://st-www.cs.uiuc.edu/~hanmer/PLoP-97/Proceedings/yoder.pdf">
|
||
http://st-www.cs.uiuc.edu/~hanmer/PLoP-97/Proceedings/yoder.pdf</ulink>
|
||
</para>
|
||
|
||
<para>
|
||
[Zoebelein 1999]
|
||
Zoebelein, Hans U.
|
||
April 1999.
|
||
The Internet Operating System Counter.
|
||
<ulink url="http://www.leb.net/hzo/ioscount">http://www.leb.net/hzo/ioscount</ulink>.
|
||
</para>
|
||
|
||
</chapter>
|
||
|
||
<appendix id="history">
|
||
<title>History</title>
|
||
<para>
|
||
Here are a few key events in the development of this document, starting
|
||
from most recent events:
|
||
|
||
<variablelist>
|
||
|
||
<varlistentry><term>
|
||
2000-05-24 David A. Wheeler
|
||
</term>
|
||
<listitem>
|
||
<para>
|
||
Switched to GNU's GFDL license, added more content.
|
||
</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
|
||
<varlistentry><term>
|
||
2000-04-21 David A. Wheeler
|
||
</term>
|
||
<listitem>
|
||
<para>
|
||
Version 2.00 released, dated 21 April 2000, which switching the
|
||
document's internal format from the Linuxdoc DTD to the DocBook DTD.
|
||
Thanks to Jorge Godoy for helping me perform the transition.
|
||
</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
|
||
|
||
<varlistentry><term>
|
||
2000-04-04 David A. Wheeler
|
||
</term>
|
||
<listitem>
|
||
<para>
|
||
Version 1.60 released;
|
||
changed so that it now covers <emphasis>both</emphasis> Linux and Unix.
|
||
Since most of the guidelines covered both, and many/most app developers want
|
||
their apps to run on both, it made sense to cover both.
|
||
</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
|
||
<varlistentry><term>
|
||
2000-02-09 David A. Wheeler
|
||
</term>
|
||
<listitem>
|
||
<para>
|
||
Noted that the document is now part of the Linux Documentation Project (LDP).
|
||
</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
|
||
<varlistentry><term>
|
||
1999-11-29 David A. Wheeler
|
||
</term>
|
||
<listitem>
|
||
<para>
|
||
Initial version (1.0) completed and released to the public.
|
||
</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
|
||
</variablelist>
|
||
</para>
|
||
|
||
<para>
|
||
Note that a more detailed description of changes is available on-line
|
||
in the ``ChangeLog'' file.
|
||
</para>
|
||
</appendix>
|
||
|
||
<appendix id="acknowledgements">
|
||
<title>Acknowledgements</title>
|
||
|
||
<epigraph>
|
||
<attribution>Proverbs 27:17 (NIV)</attribution>
|
||
<para>
|
||
As iron sharpens iron, so one man sharpens another.
|
||
</para>
|
||
</epigraph>
|
||
|
||
<para>
|
||
My thanks to the following people who kept me honest by sending me emails
|
||
noting errors, suggesting areas to cover, asking questions, and so on.
|
||
Where email addresses are included, they've been
|
||
shrouded by prepending my ``thanks.'' so bulk emailers
|
||
won't easily get these addresses; inclusion of people in this list is
|
||
<emphasis>not</emphasis> an authorization to send
|
||
unsolicited bulk email to them.
|
||
|
||
<itemizedlist>
|
||
<listitem><para>
|
||
Neil Brown (thanks.neilb@cse.unsw.edu.au)
|
||
</para></listitem>
|
||
|
||
<listitem><para>
|
||
Martin Douda (thanks.mad@students.zcu.cz)
|
||
</para></listitem>
|
||
|
||
<listitem><para>
|
||
Jorge Godoy
|
||
</para></listitem>
|
||
|
||
<listitem><para>
|
||
Scott Ingram (thanks.scott@silver.jhuapl.edu)
|
||
</para></listitem>
|
||
|
||
<listitem><para>
|
||
Michael Kerrisk
|
||
</para></listitem>
|
||
|
||
<listitem><para>
|
||
Doug Kilpatrick
|
||
</para></listitem>
|
||
|
||
<listitem><para>
|
||
John Levon (moz@compsoc.man.ac.uk)
|
||
</para></listitem>
|
||
|
||
<listitem><para>
|
||
Ryan McCabe (thanks.odin@numb.org)
|
||
</para></listitem>
|
||
|
||
<listitem><para>
|
||
Paul Millar (thanks.paulm@astro.gla.ac.uk)
|
||
</para></listitem>
|
||
|
||
<listitem><para>
|
||
Chuck Phillips (thanks.cdp@peakpeak.com)
|
||
</para></listitem>
|
||
|
||
<listitem><para>
|
||
Martin Pool (thanks.mbp@humbug.org.au)
|
||
</para></listitem>
|
||
|
||
<listitem><para>
|
||
Eric S. Raymond (thanks.esr@snark.thyrsus.com)
|
||
</para></listitem>
|
||
|
||
<listitem><para>
|
||
Marc Welz
|
||
</para></listitem>
|
||
|
||
<listitem><para>
|
||
Eric Werme (thanks.werme@alpha.zk3.dec.com)
|
||
</para></listitem>
|
||
|
||
</itemizedlist>
|
||
|
||
</para>
|
||
|
||
<para>
|
||
If you want to be on this list, please send me a constructive suggestion at
|
||
<ulink
|
||
url="mailto:dwheeler@dwheeler.com">dwheeler@dwheeler.com</ulink>.
|
||
If you send me a constructive suggestion, but do <emphasis remap="it">not</emphasis> want credit,
|
||
please let me know that when you send your suggestion, comment, or
|
||
criticism; normally I expect that people want credit, and I want to give
|
||
them that credit.
|
||
My current process is to add contributor names to this list in the document,
|
||
with more detailed explanation of their comment in the ChangeLog for
|
||
this document (available on-line).
|
||
Note that although these people have sent in ideas, the actual text is my own,
|
||
so don't blame them for any errors that may remain.
|
||
Instead, please send me another constructive suggestion.
|
||
</para>
|
||
|
||
</appendix>
|
||
|
||
<appendix id="about-license">
|
||
<title>About the Documentation License</title>
|
||
|
||
<epigraph>
|
||
<attribution>Esther 3:14 (NIV)</attribution>
|
||
<para>
|
||
A copy of the text of the edict was to be issued as law
|
||
in every province and made known to the people of every
|
||
nationality so they would be ready for that day.
|
||
</para>
|
||
</epigraph>
|
||
|
||
<para>
|
||
This document is Copyright (C) 1999-2000 David A. Wheeler.
|
||
Permission is granted to copy, distribute and/or modify
|
||
this document under the terms of the GNU Free Documentation License (FDL),
|
||
Version 1.1 or any later version published by the Free Software Foundation;
|
||
with the invariant sections being ``About the Author'',
|
||
with no Front-Cover Texts, and no Back-Cover texts.
|
||
A copy of the license is included below.
|
||
</para>
|
||
|
||
<para>
|
||
These terms do permit mirroring by other web sites,
|
||
but be <emphasis remap="it">sure</emphasis> to do the following:
|
||
|
||
<itemizedlist>
|
||
<listitem>
|
||
|
||
<para>
|
||
make sure your mirrors automatically get upgrades from the master site,
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>
|
||
clearly show the location of the master site
|
||
(<ulink
|
||
url="http://www.dwheeler.com/secure-programs">http://www.dwheeler.com/secure-programs</ulink>), with a hypertext link
|
||
to the master site, and
|
||
</para>
|
||
</listitem>
|
||
|
||
<listitem>
|
||
<para>
|
||
give me (David A. Wheeler) credit as the author.
|
||
</para>
|
||
</listitem>
|
||
|
||
</itemizedlist>
|
||
|
||
</para>
|
||
|
||
<para>
|
||
The first two points primarily protect me from repeatedly hearing about
|
||
obsolete bugs.
|
||
I do not want to hear about bugs I fixed a year ago, just because you
|
||
are not properly mirroring the document.
|
||
By linking to the master site,
|
||
users can check and see if your mirror is up-to-date.
|
||
I'm sensitive to the problems of sites which have very
|
||
strong security requirements and therefore cannot risk normal
|
||
connections to the Internet; if that describes your situation,
|
||
at least try to meet the other points
|
||
and try to occasionally sneakernet updates into your environment.
|
||
</para>
|
||
|
||
<para>
|
||
By this license, you may modify the document,
|
||
but you can't claim that what you didn't write is yours (i.e., plagerism)
|
||
nor can you pretend that a modified version is identical to
|
||
the original work.
|
||
Modifying the work does not transfer copyright of the entire work to you;
|
||
this is not a ``public domain'' work in terms of copyright law.
|
||
See the license for details.
|
||
If you have questions about what the license allows, please contact me.
|
||
In most cases, it's better if you send your changes to the master
|
||
integrator (currently David A. Wheeler), so that your changes will be
|
||
integrated with everyone else's changes into the master copy.
|
||
</para>
|
||
</appendix>
|
||
|
||
|
||
<!-- Previously it had label="A" -->
|
||
<appendix id="fdl">
|
||
<title>GNU Free Documentation License</title>
|
||
<para>
|
||
Version 1.1, March 2000
|
||
</para>
|
||
|
||
<para>
|
||
Copyright © 2000
|
||
<address>
|
||
Free Software Foundation, Inc.
|
||
<street>59 Temple Place, Suite 330</street>,
|
||
<city>Boston</city>,
|
||
<state>MA</state>
|
||
<postcode>02111-1307</postcode>
|
||
<country>USA</country>
|
||
</address>
|
||
Everyone is permitted to copy and distribute verbatim copies of this license
|
||
document, but changing it is not allowed.
|
||
</para>
|
||
|
||
<variablelist>
|
||
<varlistentry id="fdl-preamble">
|
||
<term>0. PREAMBLE</term>
|
||
<listitem>
|
||
<para>
|
||
The purpose of this License is to make a manual, textbook, or other
|
||
written document "free" in the sense of freedom: to assure everyone
|
||
the effective freedom to copy and redistribute it, with or without
|
||
modifying it, either commercially or noncommercially. Secondarily,
|
||
this License preserves for the author and publisher a way to get
|
||
credit for their work, while not being considered responsible for
|
||
modifications made by others.
|
||
</para>
|
||
|
||
<para>
|
||
This License is a kind of "copyleft", which means that derivative
|
||
works of the document must themselves be free in the same sense. It
|
||
complements the GNU General Public License, which is a copyleft
|
||
license designed for free software.
|
||
</para>
|
||
|
||
<para>
|
||
We have designed this License in order to use it for manuals for free
|
||
software, because free software needs free documentation: a free
|
||
program should come with manuals providing the same freedoms that the
|
||
software does. But this License is not limited to software manuals; it
|
||
can be used for any textual work, regardless of subject matter or
|
||
whether it is published as a printed book. We recommend this License
|
||
principally for works whose purpose is instruction or reference.
|
||
</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry id="fdl-section1">
|
||
<term>1. APPLICABILITY AND DEFINITIONS</term>
|
||
<listitem>
|
||
<para id="fdl-document">
|
||
This License applies to any manual or other work that contains a
|
||
notice placed by the copyright holder saying it can be distributed
|
||
under the terms of this License. The <link
|
||
linkend="fdl-document">"Document" </link>, below, refers to any such
|
||
manual or work. Any member of the public is a licensee, and is
|
||
addressed as "you".
|
||
</para>
|
||
|
||
<para id="fdl-modified">
|
||
A <link linkend="fdl-modified">"Modified Version"</link> of the
|
||
Document means any work containing the Document or a portion of it,
|
||
either copied verbatim, or with modifications and/or translated into
|
||
another language.
|
||
</para>
|
||
|
||
<para id="fdl-secondary">
|
||
A <link linkend="fdl-secondary">"Secondary Section"</link> is a named
|
||
appendix or a front-matter section of the <link
|
||
linkend="fdl-document">Document</link> that deals exclusively with the
|
||
relationship of the publishers or authors of the <link
|
||
linkend="fdl-document"> Document</link> to the <link
|
||
linkend="fdl-document"> Document's</link> overall subject (or to
|
||
related matters) and contains nothing that could fall directly within
|
||
that overall subject. (For example, if the <link
|
||
linkend="fdl-document">Document</link> is in part a textbook of
|
||
mathematics, a <link linkend="fdl-secondary">Secondary Section</link>
|
||
may not explain any mathematics.) The relationship could be a matter
|
||
of historical connection with the subject or with related matters, or
|
||
of legal, commercial, philosophical, ethical or political position
|
||
regarding them.
|
||
</para>
|
||
|
||
<para id="fdl-invariant">
|
||
The <link linkend="fdl-invariant">"Invariant Sections"</link> are
|
||
certain <link linkend="fdl-secondary"> Secondary Sections</link> whose
|
||
titles are designated, as being those of <link
|
||
linkend="fdl-invariant">Invariant Sections</link>, in the notice that
|
||
says that the <link linkend="fdl-document">Document</link> is released
|
||
under this License.
|
||
</para>
|
||
|
||
<para id="fdl-cover-texts">
|
||
The <link linkend="fdl-cover-texts">"Cover Texts"</link> are certain
|
||
short passages of text that are listed, as <link
|
||
linkend="fdl-cover-texts">Front-Cover Texts</link> or <link
|
||
linkend="fdl-cover-texts">Back-Cover Texts</link>, in the notice that
|
||
says that the <link linkend="fdl-document">Document</link> is released
|
||
under this License.
|
||
</para>
|
||
|
||
<para id="fdl-transparent">
|
||
A <link linkend="fdl-transparent">"Transparent"</link> copy of the
|
||
<link linkend="fdl-document"> Document</link> means a machine-readable
|
||
copy, represented in a format whose specification is available to the
|
||
general public, whose contents can be viewed and edited directly and
|
||
straightforwardly with generic text editors or (for images composed of
|
||
pixels) generic paint programs or (for drawings) some widely available
|
||
drawing editor, and that is suitable for input to text formatters or
|
||
for automatic translation to a variety of formats suitable for input
|
||
to text formatters. A copy made in an otherwise <link
|
||
linkend="fdl-transparent"> Transparent</link> file format whose markup
|
||
has been designed to thwart or discourage subsequent modification by
|
||
readers is not <link linkend="fdl-transparent">Transparent</link>. A
|
||
copy that is not <link linkend="fdl-transparent">"Transparent"</link>
|
||
is called "Opaque".
|
||
</para>
|
||
|
||
<para>
|
||
Examples of suitable formats for <link
|
||
linkend="fdl-transparent">Transparent</link> copies include plain
|
||
ASCII without markup, Texinfo input format, LaTeX input format, SGML
|
||
or XML using a publicly available DTD, and standard-conforming simple
|
||
HTML designed for human modification. Opaque formats include
|
||
PostScript, PDF, proprietary formats that can be read and edited only
|
||
by proprietary word processors, SGML or XML for which the DTD and/or
|
||
processing tools are not generally available, and the
|
||
machine-generated HTML produced by some word processors for output
|
||
purposes only.
|
||
</para>
|
||
|
||
<para id="fdl-title-page">
|
||
The <link linkend="fdl-title-page">"Title Page"</link> means, for a
|
||
printed book, the title page itself, plus such following pages as are
|
||
needed to hold, legibly, the material this License requires to appear
|
||
in the title page. For works in formats which do not have any title
|
||
page as such, <link linkend="fdl-title-page"> "Title Page"</link>
|
||
means the text near the most prominent appearance of the work's title,
|
||
preceding the beginning of the body of the text.
|
||
</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
|
||
<varlistentry id="fdl-section2">
|
||
<term>2. VERBATIM COPYING</term>
|
||
<listitem>
|
||
<para>
|
||
You may copy and distribute the <link
|
||
linkend="fdl-document">Document</link> in any medium, either
|
||
commercially or noncommercially, provided that this License, the
|
||
copyright notices, and the license notice saying this License applies
|
||
to the <link linkend="fdl-document">Document</link> are reproduced in
|
||
all copies, and that you add no other conditions whatsoever to those
|
||
of this License. You may not use technical measures to obstruct or
|
||
control the reading or further copying of the copies you make or
|
||
distribute. However, you may accept compensation in exchange for
|
||
copies. If you distribute a large enough number of copies you must
|
||
also follow the conditions in <link linkend="fdl-section3">section
|
||
3</link>.
|
||
</para>
|
||
|
||
<para>
|
||
You may also lend copies, under the same conditions stated above, and
|
||
you may publicly display copies.
|
||
</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
|
||
<varlistentry id="fdl-section3">
|
||
<term>3. COPYING IN QUANTITY</term>
|
||
<listitem>
|
||
<para>
|
||
If you publish printed copies of the <link
|
||
linkend="fdl-document">Document</link> numbering more than 100, and
|
||
the <link linkend="fdl-document">Document's</link> license notice
|
||
requires <link linkend="fdl-cover-texts">Cover Texts</link>, you must
|
||
enclose the copies in covers that carry, clearly and legibly, all
|
||
these <link linkend="fdl-cover-texts">Cover Texts</link>: Front-Cover
|
||
Texts on the front cover, and Back-Cover Texts on the back cover. Both
|
||
covers must also clearly and legibly identify you as the publisher of
|
||
these copies. The front cover must present the full title with all
|
||
words of the title equally prominent and visible. You may add other
|
||
material on the covers in addition. Copying with changes limited to
|
||
the covers, as long as they preserve the title of the <link
|
||
linkend="fdl-document">Document</link> and satisfy these conditions,
|
||
can be treated as verbatim copying in other respects.
|
||
</para>
|
||
|
||
<para>
|
||
If the required texts for either cover are too voluminous to fit
|
||
legibly, you should put the first ones listed (as many as fit
|
||
reasonably) on the actual cover, and continue the rest onto adjacent
|
||
pages.
|
||
</para>
|
||
|
||
<para>
|
||
If you publish or distribute <link
|
||
linkend="fdl-transparent">Opaque</link> copies of the <link
|
||
linkend="fdl-document">Document</link> numbering more than 100, you
|
||
must either include a machine-readable <link
|
||
linkend="fdl-transparent">Transparent</link> copy along with each
|
||
<link linkend="fdl-transparent">Opaque</link> copy, or state in or
|
||
with each <link linkend="fdl-transparent">Opaque</link> copy a
|
||
publicly-accessible computer-network location containing a complete
|
||
<link linkend="fdl-transparent"> Transparent</link> copy of the <link
|
||
linkend="fdl-document">Document</link>, free of added material, which
|
||
the general network-using public has access to download anonymously at
|
||
no charge using public-standard network protocols. If you use the
|
||
latter option, you must take reasonably prudent steps, when you begin
|
||
distribution of <link linkend="fdl-transparent">Opaque</link> copies
|
||
in quantity, to ensure that this <link
|
||
linkend="fdl-transparent">Transparent</link> copy will remain thus
|
||
accessible at the stated location until at least one year after the
|
||
last time you distribute an <link
|
||
linkend="fdl-transparent">Opaque</link> copy (directly or through your
|
||
agents or retailers) of that edition to the public.
|
||
</para>
|
||
|
||
<para>
|
||
It is requested, but not required, that you contact the authors of the
|
||
<link linkend="fdl-document">Document</link> well before
|
||
redistributing any large number of copies, to give them a chance to
|
||
provide you with an updated version of the <link
|
||
linkend="fdl-document">Document</link>.
|
||
</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
|
||
<varlistentry id="fdl-section4">
|
||
<term>4. MODIFICATIONS</term>
|
||
<listitem>
|
||
<para>
|
||
You may copy and distribute a <link linkend="fdl-modified">Modified
|
||
Version</link> of the <link linkend="fdl-document">Document</link>
|
||
under the conditions of sections <link linkend="fdl-section2">2</link>
|
||
and <link linkend="fdl-section3">3</link> above, provided that you
|
||
release the <link linkend="fdl-modified">Modified Version</link> under
|
||
precisely this License, with the <link linkend="fdl-modified">Modified
|
||
Version</link> filling the role of the <link
|
||
linkend="fdl-document">Document</link>, thus licensing distribution
|
||
and modification of the <link linkend="fdl-modified">Modified
|
||
Version</link> to whoever possesses a copy of it. In addition, you
|
||
must do these things in the <link linkend="fdl-modified">Modified
|
||
Version</link>:
|
||
</para>
|
||
|
||
<orderedlist numeration="upperalpha">
|
||
<listitem>
|
||
<para>
|
||
Use in the <link linkend="fdl-title-page">Title Page</link> (and
|
||
on the covers, if any) a title distinct from that of the <link
|
||
linkend="fdl-document">Document</link>, and from those of
|
||
previous versions (which should, if there were any, be listed in
|
||
the History section of the <link
|
||
linkend="fdl-document">Document</link>). You may use the same
|
||
title as a previous version if the original publisher of that
|
||
version gives permission.
|
||
</para>
|
||
</listitem>
|
||
|
||
<listitem>
|
||
<para>
|
||
List on the <link linkend="fdl-title-page">Title Page</link>, as
|
||
authors, one or more persons or entities responsible for
|
||
authorship of the modifications in the <link
|
||
linkend="fdl-modified">Modified Version</link>, together with at
|
||
least five of the principal authors of the <link
|
||
linkend="fdl-document">Document</link> (all of its principal
|
||
authors, if it has less than five).
|
||
</para>
|
||
</listitem>
|
||
|
||
<listitem>
|
||
<para>
|
||
State on the <link linkend="fdl-title-page">Title Page</link>
|
||
the name of the publisher of the <link
|
||
linkend="fdl-modified">Modified Version</link>, as the
|
||
publisher.
|
||
</para>
|
||
</listitem>
|
||
|
||
<listitem>
|
||
<para>
|
||
Preserve all the copyright notices of the <link
|
||
linkend="fdl-document">Document</link>.
|
||
</para>
|
||
</listitem>
|
||
|
||
<listitem>
|
||
<para>
|
||
Add an appropriate copyright notice for your modifications
|
||
adjacent to the other copyright notices.
|
||
</para>
|
||
</listitem>
|
||
|
||
<listitem>
|
||
<para>
|
||
Include, immediately after the copyright notices, a license
|
||
notice giving the public permission to use the <link
|
||
linkend="fdl-modified">Modified Version</link> under the terms
|
||
of this License, in the form shown in the Addendum below.
|
||
</para>
|
||
</listitem>
|
||
|
||
<listitem>
|
||
<para>
|
||
Preserve in that license notice the full lists of <link
|
||
linkend="fdl-invariant"> Invariant Sections</link> and required
|
||
<link linkend="fdl-cover-texts">Cover Texts</link> given in the
|
||
<link linkend="fdl-document">Document's</link> license notice.
|
||
</para>
|
||
</listitem>
|
||
|
||
<listitem>
|
||
<para>
|
||
Include an unaltered copy of this License.
|
||
</para>
|
||
</listitem>
|
||
|
||
<listitem>
|
||
<para>
|
||
Preserve the section entitled "History", and its title, and add
|
||
to it an item stating at least the title, year, new authors, and
|
||
publisher of the <link linkend="fdl-modified">Modified Version
|
||
</link>as given on the <link linkend="fdl-title-page">Title
|
||
Page</link>. If there is no section entitled "History" in the
|
||
<link linkend="fdl-document">Document</link>, create one stating
|
||
the title, year, authors, and publisher of the <link
|
||
linkend="fdl-document">Document</link> as given on its <link
|
||
linkend="fdl-title-page">Title Page</link>, then add an item
|
||
describing the <link linkend="fdl-modified">Modified
|
||
Version</link> as stated in the previous sentence.
|
||
</para>
|
||
</listitem>
|
||
|
||
<listitem>
|
||
<para>
|
||
Preserve the network location, if any, given in the <link
|
||
linkend="fdl-document">Document</link> for public access to a
|
||
<link linkend="fdl-transparent">Transparent</link> copy of the
|
||
<link linkend="fdl-document">Document</link>, and likewise the
|
||
network locations given in the <link
|
||
linkend="fdl-document">Document</link> for previous versions it
|
||
was based on. These may be placed in the "History" section. You
|
||
may omit a network location for a work that was published at
|
||
least four years before the <link
|
||
linkend="fdl-document">Document</link> itself, or if the
|
||
original publisher of the version it refers to gives permission.
|
||
</para>
|
||
</listitem>
|
||
|
||
<listitem>
|
||
<para>
|
||
In any section entitled "Acknowledgements" or "Dedications",
|
||
preserve the section's title, and preserve in the section all
|
||
the substance and tone of each of the contributor
|
||
acknowledgements and/or dedications given therein.
|
||
</para>
|
||
</listitem>
|
||
|
||
<listitem>
|
||
<para>
|
||
Preserve all the <link linkend="fdl-invariant">Invariant
|
||
Sections</link> of the <link
|
||
linkend="fdl-document">Document</link>, unaltered in their text
|
||
and in their titles. Section numbers or the equivalent are not
|
||
considered part of the section titles.
|
||
</para>
|
||
</listitem>
|
||
|
||
<listitem>
|
||
<para>
|
||
Delete any section entitled "Endorsements". Such a section may
|
||
not be included in the <link linkend="fdl-modified">Modified
|
||
Version</link>.
|
||
</para>
|
||
</listitem>
|
||
|
||
<listitem>
|
||
<para>
|
||
Do not retitle any existing section as "Endorsements" or to
|
||
conflict in title with any <link
|
||
linkend="fdl-invariant">Invariant Section</link>.
|
||
</para>
|
||
</listitem>
|
||
</orderedlist>
|
||
|
||
<para>
|
||
If the <link linkend="fdl-modified">Modified Version</link> includes
|
||
new front-matter sections or appendices that qualify as <link
|
||
linkend="fdl-secondary">Secondary Sections</link> and contain no
|
||
material copied from the Document, you may at your option designate
|
||
some or all of these sections as invariant. To do this, add their
|
||
titles to the list of <link linkend="fdl-invariant">Invariant
|
||
Sections</link> in the <link linkend="fdl-modified">Modified
|
||
Version's</link> license notice. These titles must be distinct from
|
||
any other section titles.
|
||
</para>
|
||
|
||
<para>
|
||
You may add a section entitled "Endorsements", provided it contains
|
||
nothing but endorsements of your <link linkend="fdl-modified">Modified
|
||
Version</link> by various parties--for example, statements of peer
|
||
review or that the text has been approved by an organization as the
|
||
authoritative definition of a standard.
|
||
</para>
|
||
|
||
<para>
|
||
You may add a passage of up to five words as a <link
|
||
linkend="fdl-cover-texts">Front-Cover Text</link>, and a passage of up
|
||
to 25 words as a <link linkend="fdl-cover-texts">Back-Cover
|
||
Text</link>, to the end of the list of <link
|
||
linkend="fdl-cover-texts">Cover Texts</link> in the <link
|
||
linkend="fdl-modified">Modified Version</link>. Only one passage of
|
||
<link linkend="fdl-cover-texts">Front-Cover Text</link> and one of
|
||
<link linkend="fdl-cover-texts">Back-Cover Text</link> may be added by
|
||
(or through arrangements made by) any one entity. If the <link
|
||
linkend="fdl-document">Document</link> already includes a cover text
|
||
for the same cover, previously added by you or by arrangement made by
|
||
the same entity you are acting on behalf of, you may not add another;
|
||
but you may replace the old one, on explicit permission from the
|
||
previous publisher that added the old one.
|
||
</para>
|
||
|
||
<para>
|
||
The author(s) and publisher(s) of the <link
|
||
linkend="fdl-document">Document</link> do not by this License give
|
||
permission to use their names for publicity for or to assert or imply
|
||
endorsement of any <link linkend="fdl-modified">Modified Version
|
||
</link>.
|
||
</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
|
||
<varlistentry id="fdl-section5">
|
||
<term>5. COMBINING DOCUMENTS</term>
|
||
<listitem>
|
||
<para>
|
||
You may combine the <link linkend="fdl-document">Document</link> with
|
||
other documents released under this License, under the terms defined
|
||
in <link linkend="fdl-section4">section 4</link> above for modified
|
||
versions, provided that you include in the combination all of the
|
||
<link linkend="fdl-invariant">Invariant Sections</link> of all of the
|
||
original documents, unmodified, and list them all as <link
|
||
linkend="fdl-invariant">Invariant Sections</link> of your combined
|
||
work in its license notice.
|
||
</para>
|
||
|
||
<para>
|
||
The combined work need only contain one copy of this License, and
|
||
multiple identical <link linkend="fdl-invariant">Invariant
|
||
Sections</link> may be replaced with a single copy. If there are
|
||
multiple <link linkend="fdl-invariant"> Invariant Sections</link> with
|
||
the same name but different contents, make the title of each such
|
||
section unique by adding at the end of it, in parentheses, the name of
|
||
the original author or publisher of that section if known, or else a
|
||
unique number. Make the same adjustment to the section titles in the
|
||
list of <link linkend="fdl-invariant">Invariant Sections</link> in the
|
||
license notice of the combined work.
|
||
</para>
|
||
|
||
<para>
|
||
In the combination, you must combine any sections entitled "History"
|
||
in the various original documents, forming one section entitled
|
||
"History"; likewise combine any sections entitled "Acknowledgements",
|
||
and any sections entitled "Dedications". You must delete all sections
|
||
entitled "Endorsements."
|
||
</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
|
||
<varlistentry id="fdl-section6">
|
||
<term>6. COLLECTIONS OF DOCUMENTS</term>
|
||
<listitem>
|
||
<para>
|
||
You may make a collection consisting of the <link
|
||
linkend="fdl-document">Document</link> and other documents released
|
||
under this License, and replace the individual copies of this License
|
||
in the various documents with a single copy that is included in the
|
||
collection, provided that you follow the rules of this License for
|
||
verbatim copying of each of the documents in all other respects.
|
||
</para>
|
||
|
||
<para>
|
||
You may extract a single document from such a collection, and
|
||
distribute it individually under this License, provided you insert a
|
||
copy of this License into the extracted document, and follow this
|
||
License in all other respects regarding verbatim copying of that
|
||
document.
|
||
</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
|
||
<varlistentry id="fdl-section7">
|
||
<term>7. AGGREGATION WITH INDEPENDENT WORKS</term>
|
||
<listitem>
|
||
<para>
|
||
A compilation of the <link linkend="fdl-document">Document</link> or
|
||
its derivatives with other separate and independent documents or
|
||
works, in or on a volume of a storage or distribution medium, does not
|
||
as a whole count as a <link linkend="fdl-modified">Modified
|
||
Version</link> of the <link linkend="fdl-document"> Document</link>,
|
||
provided no compilation copyright is claimed for the compilation.
|
||
Such a compilation is called an "aggregate", and this License does not
|
||
apply to the other self-contained works thus compiled with the <link
|
||
linkend="fdl-document">Document</link> , on account of their being
|
||
thus compiled, if they are not themselves derivative works of the
|
||
<link linkend="fdl-document">Document</link>. If the <link
|
||
linkend="fdl-cover-texts">Cover Text</link> requirement of <link
|
||
linkend="fdl-section3">section 3</link> is applicable to these copies
|
||
of the <link linkend="fdl-document">Document</link>, then if the <link
|
||
linkend="fdl-document">Document</link> is less than one quarter of the
|
||
entire aggregate, the <link linkend="fdl-document">Document's</link>
|
||
<link linkend="fdl-cover-texts">Cover Texts</link> may be placed on
|
||
covers that surround only the <link
|
||
linkend="fdl-document">Document</link> within the aggregate. Otherwise
|
||
they must appear on covers around the whole aggregate.
|
||
</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
|
||
<varlistentry id="fdl-section8">
|
||
<term>8. TRANSLATION</term>
|
||
<listitem>
|
||
<para>
|
||
Translation is considered a kind of modification, so you may
|
||
distribute translations of the <link
|
||
linkend="fdl-document">Document</link> under the terms of <link
|
||
linkend="fdl-section4">section 4</link>. Replacing <link
|
||
linkend="fdl-invariant"> Invariant Sections</link> with translations
|
||
requires special permission from their copyright holders, but you may
|
||
include translations of some or all <link
|
||
linkend="fdl-invariant">Invariant Sections</link> in addition to the
|
||
original versions of these <link linkend="fdl-invariant">Invariant
|
||
Sections</link>. You may include a translation of this License
|
||
provided that you also include the original English version of this
|
||
License. In case of a disagreement between the translation and the
|
||
original English version of this License, the original English version
|
||
will prevail.
|
||
</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
|
||
<varlistentry id="fdl-section9">
|
||
<term>9. TERMINATION</term>
|
||
<listitem>
|
||
<para>
|
||
You may not copy, modify, sublicense, or distribute the <link
|
||
linkend="fdl-document">Document</link> except as expressly provided
|
||
for under this License. Any other attempt to copy, modify, sublicense
|
||
or distribute the <link linkend="fdl-document">Document</link> is
|
||
void, and will automatically terminate your rights under this
|
||
License. However, parties who have received copies, or rights, from
|
||
you under this License will not have their licenses terminated so long
|
||
as such parties remain in full compliance.
|
||
</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
|
||
<varlistentry id="fdl-section10">
|
||
<term>10. FUTURE REVISIONS OF THIS LICENSE</term>
|
||
<listitem>
|
||
<para>
|
||
The <ulink type="http" url="http://www.gnu.org/fsf/fsf.html">Free
|
||
Software Foundation</ulink> may publish new, revised versions of the
|
||
GNU Free Documentation License from time to time. Such new versions
|
||
will be similar in spirit to the present version, but may differ in
|
||
detail to address new problems or concerns. See <ulink type="http"
|
||
url="http://www.gnu.org/copyleft">http://www.gnu.org/copyleft/</ulink>.
|
||
</para>
|
||
|
||
<para>
|
||
Each version of the License is given a distinguishing version
|
||
number. If the <link linkend="fdl-document">Document</link> specifies
|
||
that a particular numbered version of this License "or any later
|
||
version" applies to it, you have the option of following the terms and
|
||
conditions either of that specified version or of any later version
|
||
that has been published (not as a draft) by the Free Software
|
||
Foundation. If the <link linkend="fdl-document">Document</link> does
|
||
not specify a version number of this License, you may choose any
|
||
version ever published (not as a draft) by the Free Software
|
||
Foundation.
|
||
</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
|
||
<varlistentry id="fdl-using">
|
||
<term>Addendum</term>
|
||
<listitem>
|
||
<para>
|
||
To use this License in a document you have written, include a copy of
|
||
the License in the document and put the following copyright and
|
||
license notices just after the title page:
|
||
</para>
|
||
|
||
<para>
|
||
Copyright © YEAR YOUR NAME.
|
||
</para>
|
||
|
||
<para>
|
||
Permission is granted to copy, distribute and/or modify this document
|
||
under the terms of the GNU Free Documentation License, Version 1.1 or
|
||
any later version published by the Free Software Foundation; with the
|
||
<link linkend="fdl-invariant">Invariant Sections</link> being LIST
|
||
THEIR TITLES, with the <link linkend="fdl-cover-texts">Front-Cover
|
||
Texts</link> being LIST, and with the <link
|
||
linkend="fdl-cover-texts">Back-Cover Texts</link> being LIST. A copy
|
||
of the license is included in the section entitled <quote>GNU Free
|
||
Documentation License</quote>.
|
||
</para>
|
||
|
||
<para>
|
||
If you have no <link linkend="fdl-invariant">Invariant
|
||
Sections</link>, write "with no Invariant Sections" instead of saying
|
||
which ones are invariant. If you have no <link
|
||
linkend="fdl-cover-texts">Front-Cover Texts</link>, write "no
|
||
Front-Cover Texts" instead of "Front-Cover Texts being LIST"; likewise
|
||
for <link linkend="fdl-cover-texts">Back-Cover Texts</link>.
|
||
</para>
|
||
|
||
<para>
|
||
If your document contains nontrivial examples of program code, we
|
||
recommend releasing these examples in parallel under your choice of
|
||
free software license, such as the <ulink type="http"
|
||
url="http://www.gnu.org/copyleft/gpl.html"> GNU General Public
|
||
License</ulink>, to permit their use in free software.
|
||
</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
</variablelist>
|
||
</appendix>
|
||
|
||
<appendix id="endorsements">
|
||
<title>Endorsements</title>
|
||
<para>
|
||
This version of the document is endorsed by the
|
||
original author, David A. Wheeler, as a document that
|
||
should improve the security of programs.
|
||
when applied correctly.
|
||
Modifications (including translations) must remove this appendix
|
||
per the license agreement included above.
|
||
</para>
|
||
</appendix>
|
||
|
||
|
||
<appendix id="about-author">
|
||
<title>About the Author</title>
|
||
<para>
|
||
David A. Wheeler is an expert in computer security and
|
||
has long specialized in development techniques for large and
|
||
high-risk software systems.
|
||
He has been involved in software development
|
||
since the mid-1970s,
|
||
and been involved with Unix and computer security since the early 1980s.
|
||
His areas of knowledge include
|
||
software safety, vulnerability analysis, inspections, Internet technologies,
|
||
software-related standards (including POSIX),
|
||
real-time software development techniques,
|
||
and numerous computer languages
|
||
(including Ada, C, C++, Perl, Python, and Java).
|
||
</para>
|
||
|
||
<para>
|
||
Mr. Wheeler is co-author and lead editor of the IEEE book
|
||
<emphasis>Software Inspection: An Industry Best Practice</emphasis>,
|
||
author of the book
|
||
<emphasis>Ada95: The Lovelace Tutorial</emphasis>,
|
||
and co-author of the
|
||
<emphasis>GNOME User's Guide</emphasis>.
|
||
He is also the author of many smaller papers and articles, including the
|
||
Linux <emphasis>Program Library HOWTO</emphasis>.
|
||
</para>
|
||
|
||
<para>
|
||
Mr. Wheeler hopes that, by making this document available, other
|
||
developers will make their software more secure.
|
||
You can reach him by email at dwheeler@dwheeler.com (no spam please),
|
||
and you can also see his web site at
|
||
<ulink url="http://www.dwheeler.com">http://www.dwheeler.com</ulink>.
|
||
</para>
|
||
</appendix>
|
||
|
||
|
||
<!--Miscellaneous quotes:
|
||
Do not deprive the alien or the fatherless of justice,
|
||
or take the cloak of the widow as a pledge.
|
||
Deuteronomy 24:17
|
||
|
||
|
||
Words from a wise man's mouth are gracious, but a fool is consumed
|
||
by his own lips. At the beginning his words are folly;
|
||
at the end they are wicked madness
|
||
Ecclesiastes 10:12-13
|
||
|
||
|
||
|
||
I took the deed of purchase - the sealed copy containing the
|
||
terms and conditions, as well as the unsealed copy -
|
||
Jeremiah 32:11 (English-NIV)
|
||
|
||
|
||
Esther had not revealed her nationality and family background,
|
||
because Mordecai had forbidden her to do so.
|
||
Esther 2:10
|
||
|
||
|
||
When the righteous thrive, the people rejoice;
|
||
when the wicked rule, the people groan.
|
||
Proverbs 29:2
|
||
|
||
When words are many, sin is not absent, but he who holds his tongue is wise.
|
||
Proverbs 10:19
|
||
|
||
|
||
Reckless words pierce like a sword,
|
||
but the tongue of the wise brings healing.
|
||
Proverbs 12:18
|
||
|
||
|
||
"Go and inquire of the LORD for me and for the people and for all Judah
|
||
about what is written in this book that has been found.
|
||
Great is the LORD's anger that burns against us because our fathers
|
||
have not obeyed the words of this book; they have not acted in
|
||
accordance with all that is written there concerning us."
|
||
2 Kings 22:13
|
||
|
||
Only be careful, and watch yourselves closely so that you do not forget
|
||
the things your eyes have seen or let them slip from your heart
|
||
as long as you live. Teach them to your children and to their
|
||
children after them.
|
||
Deuteronomy 4:9
|
||
|
||
You prepare a table before me
|
||
in the presence of my enemies.
|
||
You anoint my head with oil;
|
||
my cup overflows. Psalm 23:5 (NIV)
|
||
|
||
An enemy will overrun the land; he will pull down your strongholds and
|
||
plunder your fortresses."
|
||
Amos 3:11
|
||
|
||
But my brothers are as undependable as intermittent streams,
|
||
as the streams that overflow
|
||
Job 6:15
|
||
|
||
???: http://soledad.cs.ucdavis.edu/
|
||
describes Linux BSM, an auditing project.
|
||
|
||
|
||
-->
|
||
|
||
|
||
</book>
|