識別・認証・認可はそれぞれ違うことを確かめる
アクセス制御は3つの段階に分けて考えます。識別(Identification)は「誰だと名乗っているか」を扱います。認証(Authentication)は「その名乗りが本当か」を確かめます。認可(Authorization)は「その人に何を許すか」を決めます。英語では認証をAuthN、認可をAuthZと略すことがあります。
ログイン画面で考えると区別しやすくなります。ユーザーIDを入力するのが識別です。パスワードや多要素認証(MFA)のワンタイムコードで本人かどうかを確かめるのが認証です。ログイン後に何を見せるかを決めるのが認可です。たとえば一般社員には自分の経費申請だけを見せ、経理担当には全社員の申請を見せます。
段階を区別するのは、欠陥がどの段階にあるかで対策も影響も変わるからです。MFAを導入すれば認証は強くなります。しかし認可のチェックが抜けていれば、正しくログインした利用者が他人のデータを見られる状態はそのまま残ります。
OAuthとOpenID Connectは担当する段階が違う
OAuth 2.0は認可のための仕組みです。利用者が「このアプリに自分のカレンダーの読み取りを許す」と同意すると、アプリはその範囲(スコープ)に限ったアクセストークンを受け取ります。アクセストークンはAPIを使う権限を示すものです。利用者がいまログインしていることを証明する目的では設計されていません。
OpenID Connect(OIDC)は、OAuth 2.0に認証の機能を加えた規格です。IDトークンには、誰がいつどの方式で認証されたかが記録されます。「Googleでログイン」のような外部サービスのアカウントでのログインを自社アプリに組み込む場合は注意が必要です。アクセストークンだけで本人確認を済ませてはいけません。IDトークンの署名、発行者(iss)、宛先(aud)を検証します。仕様はOpenID Connect Core 1.0で確認できます。
APIトークンは識別・認証・認可をまとめて処理する
APIトークンやAPIキーは、1つの文字列で3つの段階をまとめて処理します。サーバーはトークンから発行先を特定します(識別)。次に、正規に発行された有効なトークンかを確かめます(認証)。最後に、付与されたスコープで操作を許すかを決めます(認可)。
そのため、漏えいしたときの影響はトークンに付けた権限の範囲でそのまま決まります。CI/CD用に全権限のトークンを発行していれば、漏れた時点で全権限を渡したことになります。発行時は用途ごとに必要最小限のスコープと有効期限を設定します。どのトークンが何に使われているかも台帳で管理します。
IDORは認証が正常でも起きる認可の欠陥
IDOR(Insecure Direct Object Reference、安全でない直接オブジェクト参照)は認可の欠陥の代表例です。たとえば /api/invoices/1001 で自分の請求書を表示する仕組みがあるとします。サーバーが「この請求書の所有者はリクエストした利用者か」を確認していなければ、番号を変えるだけで他人の請求書が見えてしまいます。OWASPはAPIセキュリティの主要リスクの筆頭にBroken Object Level Authorizationを挙げています。
この場合、攻撃者は正しくログインしています。認証は正常に動いているので、MFAでは防げません。対策は、データを返すすべての処理で、所有者や所属組織をサーバー側で照合することです。IDを推測しにくい値に変えても、照合がなければ根本的な対策にはなりません。
アクセスログの401と403で認証と認可を見分ける
HTTPステータスコードも認証と認可を区別しています。定義はRFC 9110にあります。
| コード | 意味 | 段階 |
|---|---|---|
| 401 Unauthorized | 有効な認証情報がない | 認証 |
| 403 Forbidden | 相手は分かったうえで、その操作を許可しない | 認可 |
401の名称は「Unauthorized(未認可)」ですが、実際に示すのは認証の失敗です。名称に引きずられて取り違えやすい点に注意してください。
ログ監視では、次のように読み分けます。同じ送信元から401が大量に続く場合は、パスワードの総当たりやパスワードスプレーを疑います。パスワードスプレーとは、多数のアカウントに対して、よく使われるパスワードを少しずつ試す攻撃です。ログイン済みのセッションから短時間に403が集中する場合は、権限外の機能を探っている可能性があります。
一方、IDORが成功したアクセスは200 OKとして記録されます。認可チェックが抜けている箇所ではエラーがログに残らないことを前提に、監視を設計する必要があります。また、リソースの存在を隠すため、権限がない場合にあえて404を返す実装もあります。自社アプリがどのコードを返すかを確認してから、検知ルールを作ります。
脆弱性情報の「認証不要」「権限昇格」がどの段階の欠陥を指すか
脆弱性のアドバイザリ(ベンダーなどが出すセキュリティ情報)の表現は、欠陥がどの段階にあるかを示しています。「認証前(pre-auth)」や「認証不要」は、攻撃者がログインせずに悪用できることを意味します。CVSSでは、評価項目「必要な特権(Privileges Required)」が「なし」になります。「認証バイパス」は認証の仕組みそのものを迂回される欠陥です。結果として、認証不要と同じ扱いになります。
「権限昇格」は認可の欠陥です。一般ユーザーが管理者の操作を行える「垂直方向」と、同じ権限を持つ他人のデータに触れられる「水平方向」があります。IDORは水平方向の典型例です。OSの脆弱性では、一般ユーザーから管理者権限(Linuxのroot、WindowsのSYSTEM)への昇格を指します。
欠陥の段階と到達可能性から緊急度を決める
緊急度は、欠陥の段階と、攻撃者がその機能に届くかどうかを組み合わせて判断します。認証不要の欠陥が、インターネットに公開された管理画面やVPN機器にあれば最優先で対応します。認証後に悪用される欠陥でも、軽く見てよいとは限りません。誰でもアカウントを作れるサービスや、フィッシングで認証情報が漏れやすい環境では、攻撃の前提となる「ログインできること」の条件は低いと見なします。社内の限られた管理者しか使わない機能であれば、優先度を下げられる場合があります。
ただし、OSの権限昇格は後回しにしないでください。別の脆弱性で侵入された後に、被害を広げる手段として使われるからです。CVSSスコア単独で判断しないようにします。評価項目の定義はCVSS v4.0仕様書で確認できます。個別の製品については、影響を受けるバージョンと悪用の前提条件を、必ずベンダーの公式アドバイザリで確認してください。
自社システムで確認する項目
脆弱性情報を読んだら、次の3点を資産台帳と照らし合わせます。1つ目は、認証不要か認証後か。2つ目は、該当する機能に外部から到達できるか。3つ目は、そのシステムのアカウントを誰が持っているかです。この3点が分かれば、対応の順番を決められます。
自社開発のアプリでは、ログイン機能の強化とは別に、すべてのAPIでデータ単位の認可チェックが行われているかをコードレビューの確認項目に入れます。監視については、401・403の急増を検知できているか、200 OKに紛れた他人のデータへのアクセスを見つける手段があるかを、次の見直しの判断基準にします。