アーカイブ

第7章 2.最小のアクセスパーミッション

公開日:2007年9月26日

独立行政法人情報処理推進機構
セキュリティセンター

本ページの情報は2007年9月時点のものです。
記載の資料は資料公開当時のもので、現在は公開されていないものも含みます。

アクセスパーミッションは必要最小限に

運用の利便性のために、ディレクトリやファイルに緩やかなアクセスパーミッションを与えていると、部外者による読み出しや改ざんのおそれがある。ディレクトリやファイルに設定するアクセスパーミッションは必要最小限のものにする。

アクセスパーミッション

アクセスパーミッションは、「アクセス許可」や「アクセス権」とも呼ばれる。ファイルやレジストリキー等、システム上のオブジェクトにどのアカウントからのどの種類のアクセスを許すかという設定である。

アクセスパーミッションの取り扱いは、Unix系およびGNU/Linux系のプラットフォームと、Windows系のプラットフォームとでは異なっている。

(1) UnixやGNU/Lnuxのアクセスパーミッション

Unix系およびGNU/Linux系(POSIX)のプラットフォームのファイルシステムでは、ファイルおよびディレクトリのアクセスパーミッションが管理されていて、ファイルの所有者、所属グループ、それ以外のアカウントの 3種類に対し、r(読出し)、w(書込み)、x(実行)のどのアクセスを許すかを記述するようになっている。

[例 9桁の rwx によるアクセスパーミッションの表現]

     グループへの許可内容
         ↓
         ---
       rwxrw-r--
       ---  ---
       ↑   ↑
所有者への許可内容  それ以外への許可内容

アクセスが許されるか否かは、対象のファイルの所有者とアクセスしようとしているアカウントの関係で決まる。ここでは、名指しで特定のアカウントにアクセスを許す、といった記述はできない。

(2) Windowsのアクセスパーミッション

Windows系のプラットフォームでは、使用するファイルシステムによってアクセスパーミッションが管理される場合と管理されない場合がある。FAT32 を使用した場合は、アカウント別にファイルへのアクセス制限をかける、といったことができない。

FAT32

アクセスパーミッションが管理されない

NTFS

アクセスパーミッションが管理される

アクセスパーミッションを管理したい場合、Windows系プラットフォームにおいては、システムのインストール時に起動ボリュームのファイルシステムをNTFSにしておく必要がある。

NTFSでは、アクセスパーミッションはアクセスコントロールリスト(ACL)を用い、具体的にどのアカウントにどのアクセス(生成、書込み、読出し、削除等)を許すかを細かく設定する方式をとる。

[例 アクセスコントロールリスト]

ファイル
    c:\windows\system32\drivers\etc\hosts
アクセスコントロールリスト
      (アカウント)    (許可内容)
    [Administrators  フルコントロール ]
    [Power Users    読み取り、実行 ]
    [SYSTEM     フルコントロール ]
    [Users       読み取り、実行 ]

NTFS のアクセスコントロールリストにはアカウントとアクセス許可属性の対を複数収容することができ、それぞれのアクセス許可属性は 32ビットで記述される。そのため、読み・書き・実行といったものよりも複雑なアクセス許可の表現が存在する。

  • 図25: アクセスパーミッション

アクセスパーミッション付与時の問題

プログラムにあるリソース(ファイル等)へアクセスさせるとき、リソースの側にはプログラムからのアクセスを許可するための何らかのアクセスパーミッションを与えることになる。このときのアクセスパーミッションの与え方には次のような考慮が必要である。

共有リソースの問題

複数の異なるアカウントが、あるひとつのリソース(ファイル等)を共有して使用する必要がある場合を考える。

このときその共有リソースのアクセスパーミッションを「すべての人々からアクセス可能」と設定してしまいがちである。本来アクセスを許すつもりのないアカウントからのアクセスも許してしまうという問題が発生する。

その共有リソースを扱うアカウントを特定のグループに所属させ、そのグループにのみアクセスを許すような設定が必要である。

プログラム専用リソースの問題

ソフトウェアの動作に必要なファイルの保護に関する問題である。あるファイルにプログラムからさまざまなアクセスをする必要があるが、そのファイルをユーザが見たり書き変えることがあると都合が悪いというケースである。

例えば、ネットワーク接続のための認証キー、データを保護するための暗号鍵、少しでも値が損なわれるとプログラムの動作に大きな支障をきたす機器制御パラメータ群等が考えられる。

プログラムがユーザのアカウント内で起動されるものであれば、プログラムが読み書きするファイルは、プログラムを起動したユーザ自身も(ほかのソフトウェアを使って)読み書きが可能である。

プログラムには読み書きを許すがユーザには許したくない、という場合、プログラム稼働専用のアカウントを設けて、次のようにクライアントサーバ型でソフトウェアを構成する。

  • ユーザがログインするためのものとは別にプログラム稼働用のアカウントを設ける
  • ユーザに干渉されたくないファイルは、プログラム稼働用アカウントに所有させ、他者からのアクセスを許さないようにする
  • ユーザが当該ソフトウェアを利用する際には、ユーザアカウントで動作するクライアントモジュールと、プログラム稼働用アカウントで動作するサーバモジュールの2つが連携して動作するようにする

UnixやGNU/Linuxのumask

Unix系およびGNU/Linux系のプラットフォームには、プログラムが APIを用いてファイルを新規作成する際、アクセスパーミッションが一定以上の厳しいものに保たれるよう枠をはめるumask()というAPIがある。

例えば、creat()システムコールやopen()システムコールを使ってファイルを新規作成することができるが、その際にアクセスパーミッションを与えるようになっている。

[例]

mode_t permission;
int  filedesc;

permission = 0777;  // アクセスパーミッション rwxrwxrwx
filedesc = creat("パス名", permission);

permission = 0644;  // アクセスパーミッション rw-r--r--
filedesc = open("パス名", O_CREAT|O_EXCL|O_WRONLY, permission);

(注釈)ここに、C言語の古い伝統に則って、0777 や 0644 という表記は 8進数であることにご注意いただきたい。

これらの引数には任意のアクセスパーミッションを指定できるため、プログラムミスによってアクセス制限の緩いファイルができてしまうおそれがある。あらかじめumask()を呼び出しておくことによって、そこに制限をかけることができる。

[例]

mode_t permission;
int  filedesc;
mode_t oldmask;
mode_t newmask;

newmask = 0227;      // アクセスパーミッションから差し引くもの
oldmask = umask(newmask); // マスクの指定

permission = 0777;     // アクセスパーミッション rwxrwxrwx
filedesc = creat("パス名", permission);
              // 0227が差し引かれて0550 r-xr-x--- が適用される

permission = 0644;     // アクセスパーミッション rw-r--r--
filedesc = open("パス名", O_CREAT|O_EXCL|O_WRONLY, permission);
              // 0227が差し引かれて0440 r--r----- が適用される

umask() にはシステムのデフォルト設定が存在する。 多くのプラットフォームにおけるデフォルト値は 0022(所有者以外の書き込み禁止)であり、 これをそのまま利用できるケースもある。

ただし、Android においては注意を要する。ベンダが特段の設定をしておらず、デフォルト値が 0000(制限なし)であることが少なくない。umask の明示的な設定が望ましい。

まとめ

複数のアカウントにリソースを共有させる場合、アクセスパーミッションを緩やかにしすぎることがないよう注意する。プログラムのみにアクセスさせるファイルをユーザの干渉から守るには、プログラム稼働専用アカウントに所属させる。Unix、GNU/Linux には、一定の許可を差し引くことによってファイル生成API呼び出しにおけるアクセスパーミッションの与え過ぎを防ぐ umask()関数が存在する。