プログラムの安全性とは
プログラムの安全性とは、想定外の入力や操作があっても、データやシステムを不必要な危険にさらさないように設計することです。安全性は完成後に追加する機能ではなく、設計・実装・テストの各段階で考えます。
入力値をそのまま信頼しない
ユーザーの入力、ファイルの内容、ネットワークから受け取ったデータ、環境変数などは、形式が正しいとは限りません。入力値を使う前に、用途に応じて検証します。
たとえば、年齢を整数として扱うなら、文字列をいきなり数値だと決めつけず、int.TryParse で変換できるか確認します。
using System;
class Program
{
static void Main()
{
string? input = Console.ReadLine();
if (int.TryParse(input, out int age) && age >= 0 && age <= 120)
{
Console.WriteLine("入力を受け付けました。");
}
else
{
Console.WriteLine("入力を確認してください。");
}
}
}
ここでは、次の2段階で確認しています。
- int.TryParse で整数に変換できるか確認する。
- 整数に変換できた場合だけ、アプリケーション上の許容範囲を確認する。
「数値に変換できること」と「その用途で受け入れてよい値であること」は別の条件です。
検証は使う場所に合わせる
入力検証では、単に空文字でないかを見るだけでは不十分です。たとえば、数値なら範囲、文字列なら長さや許可する形式、ファイル名なら保存先の制約などを確認します。
- 型:整数・小数・日付など、必要な型に変換できるか。
- 範囲:許可する最小値・最大値に収まっているか。
- 長さ:文字数やデータサイズが上限を超えていないか。
- 形式:アプリケーションが受け付ける形式になっているか。
- 文脈:その値を使う操作に対して妥当か。
検証に失敗した場合は、安全な既定動作に戻すか、処理を中止します。検証に失敗した値を、確認せずに後続処理へ渡してはいけません。
最小権限の原則
プログラムやユーザーには、目的を達成するために必要な権限だけを与えます。たとえば、読み取りだけでよい処理にファイルの削除権限を与えない、一般ユーザーとして動かせるプログラムを管理者権限で常時実行しない、といった考え方です。
権限を小さくしておけば、プログラムに問題が起きた場合でも、影響範囲を抑えやすくなります。
エラー情報を安全に扱う
エラーは原因を調べるために記録します。ただし、パスワード、APIキー、個人情報、認証トークンなどをログや画面に出してはいけません。
利用者には必要な範囲の説明を表示し、詳細な内部情報はアクセス制御されたログに記録します。例外メッセージをそのまま利用者へ表示する設計も避けましょう。
このページの要点
- 外部から受け取った値は、信頼できると決めつけない。
- 型変換の成功と、値が用途に適していることを分けて検証する。
- 検証に失敗した値は後続処理へ渡さない。
- 必要最小限の権限でプログラムを動かす。
- 秘密情報を画面やログへ出力しない。