%includes;
]>
FreeBSD セキュリティガイド
FreeBSD セキュリティガイド
Last Updated: $Date: 1997-11-23 22:23:04 $
このガイドは多くの FreeBSD セキュリティの達人がシステムを安全にしたり
安全なコードを書くために使っている Tips や Tricks をドキュメント化しようと
したものです. 外部の攻撃から FreeBSD システムを守るための数多くの方法と,
もしそういった攻撃が行われた時にいかに復旧すればいいのかということを学ぶ
ための手助けとなるようにデザインされています. また, システムプログラマが
よりセキュリティを意識し, セキュリティホールを作ってしまうようなことを初期
段階で防ぐための方法も載せてあります.
このページについてのコメントや訂正の指摘はいつでも歓迎しています. もし
ここに載せたい変更がある時は,
FreeBSD セキュリティ担当者 までメールを送って下さい.
FreeBSD システムを安全にするための方法
セキュリティ問題から回復するための方法
プログラマのためのべきべからず集
- どんな入力ソースも信用しないこと. つまり, コマンド
ライン引数, 環境変数, 設定ファイル, 到着した UDP パケット, ホスト名参照,
関数引数など, どれも信用してはいけません. そもそも, 受け取ったデータ長や
内容が各プログラムや関数のコントロール外のものなら, プログラムや関数はそ
のデータをコピーする時に注意をはらうべきです. この種のセキュリティ問題を
挙げると:
- データ境界を越えるような
strcpy(3) や
sprintf(3) 関数の呼び出し. もしデータ長が分かっているのなら,
strncpy(3) や
snprintf(3) 関数を使う ( あるいは, それが使えないのなら境界チェックを
施した別の物を組み込む ) ようにして下さい. 実際,
gets(3)
や
sprintf(3) は今後決して使われることはありません.
-
strvis(3)
や getenv(3)
の乱用に気をつける
こと.
strvis(3)
は間違ったコピー先文字列を簡単に作ってしまいますし,
getenv(3)
は想定される長さをはるかに越える文字列を返すこともあります.
これらはプログラムへの攻撃でしばしば使われる重要な方法の一つで,
環境変数を予想もしなかった値に設定してスタックや変数を上書きさせる
のです. あなたの
プログラムが環境変数を読んでいるのなら, 偏執的にならないといけません.
-
open(2)
や
stat(2)
関数を見つけるたびに, "アクセスしようとしているファイルが
シンボリックリンクだったらどうなるだろう?" と自問してください.
-
mktemp(3),
tempnam,
mkstemp(3), などを使用しているところでは代わりに
mkstemp(3) が使われていることを確認して下さい.
加えて, /tmp の中でアトミックになることはほとんどないということに気づ
いて, /tmp 中の競合が発生していないか探してみて下さい:
- ディレクトリの作成. これは成功するか失敗するかのどちらかです.
- O_CREAT | O_EXCL モードでのファイルのオープン
mkstemp(3) はこういったことをあなたのために正しくやってのけてくれま
す. そう, 競合を起こさないで正しい許可権でテンポラリファイルが作成される
ことを保証するには mkstemp() を使わなければいけないのです.
- 攻撃者が適当な別のシステムからパケットを
投げたり, パケットを受け取ったりするように強いることができるのなら,
私達が受けるデータを完全にコントロールすることができますし, それらの
いずれも信用できないものとなります.
- 2.1 と 2.2 における UID, EUID, SVUID の
違いを理解して下さい. 私たちも理解していません. [XXX しかし Bruce と
話し合った後で理解してここを埋めなければいけません]
- 設定ファイルが正しいフォーマットに
なっている, あるいは関連ユーティリティで作成されている, などとは思って
はいけません. 変なことをするチャンスさえあれば, ひねくれたクラッカーが
きっとその変なことをしでかしてしまうでしょう: 端末名や言語文字列など
パス名の中に '/' や '../../...' といったフリースタイルの文字が入る時
はユーザの入力を信用してはいけません.
root 権限で setuid がセットされているような状態のときはユーザから
与えられる *どんな* パス名も信用してはいけません.
- データの格納される方法に関してのセキュリティ
ホールや弱点に気をつけて下さい. テンポラリファイルの許可権はどれも 600 に
なっていないといけません.
- 高い権限で実行する可能性のあるプログラム
からおきまりの問題のコードを見つけるのに grep してはいけません.
strcpy(3) のような関数がオーバフローをおこすといったことよりも数
多くのオーバーフローのケースがあるので, 1行1行コードを追っていくよ
うにしなければいけません.
- 必要のない(訳注 root などの)特権を使
わないからといって, (侵入者に)悪用される可能性がなくなるわけではあ
りません. 攻撃者は必要な実行コードをスタックに積んでから /bin/sh を
実行しようとするかもしれません.
- UID を管理するようにして下さい. そう, できる
だけはやく特権を完全に捨て去るのです. EUID と UID とを切替える必要は
ありません.
setuid(2)
を使えるうちに使えばいいのです.
- エラーのあった設定ファイルの内容を絶対に
画面に表示しないようにして下さい. 行番号, それから桁数が分かれば十分です.
ライブラリと SUID/SGID が設定されているプログラムにこれらのことが言えます.
- セキュリティ問題に関しての, 現存するコードの
レビューのための Tips:
- セキュリティフィックスについてあなたが確信を
持てないのなら, 目を通してもらうためにあなたが整えたコードをレビュー
する人に送って下さい. 安全の名において, かなり厄介な問題を引き起こさ
ないことを確信できないうちはコミットしてはいけません. :)
- CVS コミットの権限のないものは, 変更の
レビューを最後に行った人にその権限があることを確認すべきです. その人
はレビューと最終バージョンのツリーへの取り込みの両方をすることになり
ます.
- レビューする人に変更点を送る時, 簡単に
patch(1)
を当てられるようにするために context か unidiff 形式の diff を使うよう
にして下さい. ファイルまるごと送らないで下さい! Diff は簡単に読むことが
できるし, (とくに複数の場所で同時に行われる変更の時) ローカルのソース
に専念できます. 特定のインスタンスにともなうような特別な理由でもない
限り, 共通の環境をベースにして作業を簡単にするために, どんな変更も
3.0-current への変更とするようにしてください.
- コードを変更をするたびに, レビューする
人達に送る前に直接テストを行う (つまりビルドして該当するモジュールを
実行する) ようにしてください. 明らかに壊れているものをレビューしたい
と思う人はいません. ちゃんとテストするために 2.1, 2.2 や 3.0 上での
アカウントが必要なら言って下さい - プロジェクトはその目的でこれらの環
境を用意してあります.
- コミットする方々へ:
-current パッチが 2.2 や 2.1 ブランチにも合うように必ず心がけて下さい.
- 不必要にあなた好みのスタイルにコードを
書き換えないで下さい - それはレビューする人にとって, 必要のない, より
難解な仕事を作るだけです. それをするのに明確な技術上の理由がある時に
だけ行うようにしてください.
- 単一のハンドラで複雑な処理を行うような
プログラムに気をつけて下さい. いろいろなライブラリ中の多くの関数は,
そのような処理を安全に行えるほど充分にリエントラントではありません.
-
realloc(3) の使い方には細心の注意を払って下さい
- 正しく使われていないことは, ないわけではなくむしろ頻繁に起こっている
ことです.
- 固定長バッファを使う場合, バッファサイズが変更されたにもかかわらず
コードが sizeof() を使っていないがために発生する問題を防ぐために,
sizeof() を使用するようにして下さい. 例を挙げると:
char buf[1024];
struct foo { ... };
...
BAD:
xxx(buf, 1024)
xxx(yyy, sizeof(struct foo))
GOOD:
xxx(buf, sizeof(buf))
xxx(yyy, sizeof(yyy))
- "char foo[###]" を見つけるたびに, foo の使い方をチェックしてオーバー
フローを起こさないことを確認して下さい. オーバーフローを回避できない
(か, オーバーフローが起こり得る) ときは, 最低でもスタックを食い潰さない
ようにするために malloc(3) でバッファ領域をとるようにして下さい.
- できるだけ早い段階でファイル記述子をクローズするようにして下さい.
これは標準入出力バッファの内容を捨て去ることよりも大切なことです.
ライブラリルーチンの中で, あなたが開いたファイル記述子を常に閉じる
ようにしてください。
&footer;