公開日:2007年9月26日
独立行政法人情報処理推進機構
セキュリティセンター
本ページの情報は2007年9月時点のものです。
記載の資料は資料公開当時のもので、現在は公開されていないものも含みます。
運用の利便性のために、ディレクトリやファイルに緩やかなアクセスパーミッションを与えていると、部外者による読み出しや改ざんのおそれがある。ディレクトリやファイルに設定するアクセスパーミッションは必要最小限のものにする。
アクセスパーミッションは、「アクセス許可」や「アクセス権」とも呼ばれる。ファイルやレジストリキー等、システム上のオブジェクトにどのアカウントからのどの種類のアクセスを許すかという設定である。
アクセスパーミッションの取り扱いは、Unix系およびGNU/Linux系のプラットフォームと、Windows系のプラットフォームとでは異なっている。
Unix系およびGNU/Linux系(POSIX)のプラットフォームのファイルシステムでは、ファイルおよびディレクトリのアクセスパーミッションが管理されていて、ファイルの所有者、所属グループ、それ以外のアカウントの 3種類に対し、r(読出し)、w(書込み)、x(実行)のどのアクセスを許すかを記述するようになっている。
[例 9桁の rwx によるアクセスパーミッションの表現]
グループへの許可内容
↓
---
rwxrw-r--
--- ---
↑ ↑
所有者への許可内容 それ以外への許可内容
アクセスが許されるか否かは、対象のファイルの所有者とアクセスしようとしているアカウントの関係で決まる。ここでは、名指しで特定のアカウントにアクセスを許す、といった記述はできない。
Windows系のプラットフォームでは、使用するファイルシステムによってアクセスパーミッションが管理される場合と管理されない場合がある。FAT32 を使用した場合は、アカウント別にファイルへのアクセス制限をかける、といったことができない。
アクセスパーミッションが管理されない
アクセスパーミッションが管理される
アクセスパーミッションを管理したい場合、Windows系プラットフォームにおいては、システムのインストール時に起動ボリュームのファイルシステムをNTFSにしておく必要がある。
NTFSでは、アクセスパーミッションはアクセスコントロールリスト(ACL)を用い、具体的にどのアカウントにどのアクセス(生成、書込み、読出し、削除等)を許すかを細かく設定する方式をとる。
[例 アクセスコントロールリスト]
ファイル
c:\windows\system32\drivers\etc\hosts
アクセスコントロールリスト
(アカウント) (許可内容)
[Administrators フルコントロール ]
[Power Users 読み取り、実行 ]
[SYSTEM フルコントロール ]
[Users 読み取り、実行 ]
NTFS のアクセスコントロールリストにはアカウントとアクセス許可属性の対を複数収容することができ、それぞれのアクセス許可属性は 32ビットで記述される。そのため、読み・書き・実行といったものよりも複雑なアクセス許可の表現が存在する。
プログラムにあるリソース(ファイル等)へアクセスさせるとき、リソースの側にはプログラムからのアクセスを許可するための何らかのアクセスパーミッションを与えることになる。このときのアクセスパーミッションの与え方には次のような考慮が必要である。
複数の異なるアカウントが、あるひとつのリソース(ファイル等)を共有して使用する必要がある場合を考える。
このときその共有リソースのアクセスパーミッションを「すべての人々からアクセス可能」と設定してしまいがちである。本来アクセスを許すつもりのないアカウントからのアクセスも許してしまうという問題が発生する。
その共有リソースを扱うアカウントを特定のグループに所属させ、そのグループにのみアクセスを許すような設定が必要である。
ソフトウェアの動作に必要なファイルの保護に関する問題である。あるファイルにプログラムからさまざまなアクセスをする必要があるが、そのファイルをユーザが見たり書き変えることがあると都合が悪いというケースである。
例えば、ネットワーク接続のための認証キー、データを保護するための暗号鍵、少しでも値が損なわれるとプログラムの動作に大きな支障をきたす機器制御パラメータ群等が考えられる。
プログラムがユーザのアカウント内で起動されるものであれば、プログラムが読み書きするファイルは、プログラムを起動したユーザ自身も(ほかのソフトウェアを使って)読み書きが可能である。
プログラムには読み書きを許すがユーザには許したくない、という場合、プログラム稼働専用のアカウントを設けて、次のようにクライアントサーバ型でソフトウェアを構成する。
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()関数が存在する。