6.11. 信頼できる経路だけ信じること

一般的に、信頼できる経路からの情報(入力や結果)だけを信頼してください。 たとえば、ローカル・ユーザは、getlogin(3) や ttyname(3)が返す情報を制御 できるので、セキュリティ目的では信用してはいけません。

コンピュータで構成されたネットワーク(インターネット全体にも当てはまります) の大部分において、伝送の正当さが証明されていなければ、信頼するに値しません。 たとえば、公開されたインターネット越しにやってくるパケットは、経路上のどの 場所でも見ることも、修正することも可能です。また、新しいどのパケットも改竄可能 です。 改竄されたパケットは、送り手や受け手の改竄した情報(マシンのアドレス(IP)や ポート)が入っているかもしれません。 したがって、認証(たとえば、暗号を使って)できない限りは、その情報を第 1 の 基準として、セキュリティ上の判断をしないでください。

つまり特殊な事情がない限り、TCP/IP でユーザ認証を行う場合は、認証の仕組み として下記の 2 つの古臭いテクニックを単独では使用しないようにしてください。 テクニックの 1 つは、ユーザを「あるマシン」に制限する方法で、データパケット 中のマシンの「始点」アドレスをチェックします。もう一つの方法は、送り手が 「信頼できる」ポート番号(1024 番以下)の利用を要求することによって、アクセス 制限をかけます。 問題は、多くの環境下において、攻撃者がこれらの値を改竄できる点にあります。

ある環境下では、これらの値(送り手のマシンの IP アドレスやポート番号)の チェックに意味がある場合もありますので、プログラムでそのようなチェックを オプションとしてサポートするのは悪くない考えです。 たとえば、ファイアーウォールの背後にあるシステムで、ファイアーウォール が破られたり、迂回されたりできない環境です。内部からきていると装っているが、 実は外部からやってきているパケットを抑えているなら、内部からやってきて いることになっているパケットは、すべて本当に内部からきているといえます。 パケットは、実際にそのマシンがあるとしている場所からきていると確認できない 点に注意してください。したがって、対処できるのは外部からの脅威だけで、内部 からの脅威には対処できません。 しかし、ファイアーウォールがいかれていたり、別の経路があったり、モバイル用 の接続口があったりすると、この前提さえも疑わしいものになってしまいます。

問題は、誰かを認証する唯一の手段が、信頼できない情報である点です。 信頼できないネットワーク越しに、信頼できる経路が必要ならば、普通は何らかの 暗号作成技術(最低限でも暗号的に安全なハッシュ技術)の助けが必要となります。 暗号アルゴリズムと通信プロトコルについてさらに詳しい情報は、Section 10.5 を見てください。 標準的に使われているものの、本来安全でないプロトコル(たとえば ftp とか rlogin)を実行しているなら、デフォルトを安全にしておき、ドキュメントには 前提条件を明記しておいてください。

ドメイン・ネーム・サーバ(DNS)は広くインターネット上で利用されており、 コンピュータ名と IP アドレス(数値)の組合せを維持管理しています。 「DNS の逆引き」という方法を使えば、単純なスプーフィング攻撃の一部を 排除できますし、ホスト名を見つける時にも役立ちます。 しかしこのやり方は、認証を決めるほどの信頼性がありません。 つまるところ問題なのは、DNS のリクエストが、結局は攻撃者がコントロールして いるかもしれないどこかのシステムに対して送られている可能性がある、という 点にあります。 したがって、DNS から得られた結果が正しい入力かどうかを確認する必要がある ので、重要なアクセス制御の手段として信用できません。

電子メール(「From」に書いてあるアドレスを含む)も改竄できます。 そのような攻撃は、電子署名を使えば防げる場合が多くあります。 もっと簡単な防御は、電子メールにランダムに発生させた値を添付してやりとり する方法です。小額の金銭取引きもないような、公開メーリングリストへの 登録ならば十分利用できます。

CGI を含むクライアント・サーバモデルでは、クライアント(もしくはクライアント とサーバを仲介する何か)が、どんな値も変更できてしまう点に注意してください。 サーバ側はいつもこの点に気をつけていなければなりません。 例を挙げると、いわゆる「隠れフィールド」、クッキー等は、CGI プログラムが 値を受け取る前にクライアント側で値を変更できてしまいます。 特に予防処置をとらない限り、これらは信頼できません。 たとえば、隠しフィールドはサーバが署名をチェックしているなら、クライアントが 改竄できないように署名できるはずです。 隠しフィールドは、信頼できるサーバだけが復号できる鍵を使って暗号化もできます (後者の解決方法は、Kerberos 認証機構が基本的な考えとして背景にあります)。 InfoSec labs(http://www.infoseclabs.com/mschff/mschff.htm)では隠しフィールドや 暗号化についてさらに突っ込んだ議論がされています。 一般的にクライアント・サーバモデルでは、サーバ側に配慮が必要なデータをとって おいた方が賢明です。 同じ流れで、CGI プログラムで認証を行う場合、HTTP_REFERER に頼らないようにして ください。これはユーザのブラウザが送ってくるものだからです(Web サーバでは ありません)。

この問題は、他のデータが参照するデータにも当てはまります。 たとえば、HTML や XML は他のファイル(たとえば、DTD やスタイル・シート) がリモートにあったとしても、参照ができるようになっています。 しかし、外部参照は変更できてしまうので、ユーザは意図したものとはまったく 違ったドキュメントを見ることになります。 スタイル・シートは重要な部分の単語を「白く塗りつぶして」変更できてしまい ますので、見た目を汚くしたり、新しいテキストを挿入できたりしてしまいます。 外部の DTD は特定のドキュメントの使用を抑えたり(DTD の妥当さを崩す宣言を 加えることで)、ドキュメントに別のテキストを挿入したりして、変更が可能です [St. Laurent 2000]。