メインコンテンツへスキップ
見出し画像

ログインできれば、安全なのか——セッション・Cookie・JWT・APIキー・スマホアプリを午後の問われ方で読む|支援士解説2の4

    この記事の重要度:Sランク(午後で繰り返し主役になる最重要の分野)

    この記事で分かること:

    • セッション管理・Cookieの属性・APIのトークンとJWTで、何を確かめ、どこが破られるか

    • スマートフォンアプリで秘密を守る設計、乱数とノンスによるリプレイ対策、パスワードの保存、製品の評価認証

    • 解答欄に書く「原因」と「対策」の型

    シラバスとの対応:小項目2-4「セキュリティ機能の設計・実装」。認証と認可の考え方、OAuth・OIDC・SAMLは支援士解説3の8、XSS・CSRF・IDORなどプログラムの脆弱性は支援士解説2の5、暗号と鍵の管理・証明書の検証は支援士解説3の1、ログの保管と読み方は支援士解説3の4で扱います。


    午後のWebアプリやスマートフォンアプリの問題では、「ログインの仕組みはある。それでも破られる」場面がよく問われます。ログイン後に発行したセッションIDが盗まれる、ログインの前と後で同じIDを使い続ける、APIが受け取ったトークンの署名を正しく確かめていない、アプリの中に秘密の鍵が入っている。どれも、認証そのものではなく、認証の結果を、その後どう引き継ぎ、どう確かめるかの設計の不備です。

    この記事では、セキュリティ機能を「備える」から「どの条件で許し、どの条件で断るか」へ具体化する考え方を押さえたうえで、セッション管理とCookie、APIのトークンとJWT、スマートフォンアプリ、乱数とリプレイ対策、パスワードの保存、製品の評価認証を順に整理します。

    1. 機能の名前を、許可・拒否・証拠に変える

    仕様書に「認証機能を備える」「アクセス制御を行う」と書いても、誰に、いつ、何を許すかは決まりません。セキュリティ機能を設計するときは、次の六つを一組にして書きます。

    • 主体:誰が(住民、職員、委託先の保守員、ほかのシステム)

    • 対象:何に(申請データ、添付資料、管理画面)

    • 操作:何をするか(閲覧、変更、承認、出力)

    • 許可条件:どの条件なら許すか(本人の担当案件、有効なセッション、期限内のトークン)

    • 拒否条件:どの条件なら断るか(他人の案件、期限切れ、権限変更後の古いセッション)

    • 記録:結果をどう残すか(許可も拒否も、いつ・誰が・何に)

    ログインできることだけでは、安全性を確認したことになりません。例えば、架空の申請システムで職員が申請資料を開く処理なら、職員本人であることを確かめ、その時点の所属と役割、担当案件を調べ、資料を返すか拒否し、結果をログへ記録します。申請番号はリクエストの中の値なので、利用者が書き換えられます。画面で別の課の案件を非表示にしても、担当外の申請番号を送るAPIへの直接要求は止まりません(このような認可の不備はIDORと呼ばれます。詳しくは支援士解説2の5)。担当を外れた職員の古い権限や、発行済みのセッションが残っていないかも、設計の対象です。

    午後の問題も、この組で読むと解きやすくなります。問題文の仕様には「何を確かめているか」が書かれ、設問は「何を確かめていないか」を問います。ログインに成功した後の処理で、誰が発行した値を、誰が、いつ、何と照らして確かめているかを追ってください。設計と試験を照合するときも、同じ組を使います(図1)。

    機能名を、許可・拒否・証拠へ変える
    【図1】機能名を、許可・拒否・証拠へ変える


    2. セッション管理:セッションIDは「ログイン済みの証明」

    なぜセッションIDが必要か

    HTTPは、1回の要求と応答で完結し、前後のやり取りを覚えていません。そこでWebアプリは、ログインに成功した利用者にセッションIDを発行し、以後の要求に付けて送らせます。サーバは、受け取ったセッションIDで「どの利用者の要求か」を判断します。

    セッションIDの受け渡し方には、主に次の三つがあります。

    • Cookie:ブラウザが自動で付けて送る。現在の主流

    • URLのパラメータ:URLに含めて渡す。リンク先のサイトへRefererヘッダ(参照元)で送られる、アクセスログやブラウザの履歴に残る、URLを共有したときに一緒に渡ってしまう、といった漏えいの経路があるので避ける

    • hiddenフィールド:画面のフォームに埋め込んで送る

    どの方法でも、セッションIDを手に入れた人は、その利用者になりすませます。これがセッションハイジャックです。セッションIDは、パスワードと同じくらい大切な秘密情報として扱います。

    セッションIDが奪われる四つの経路

    • 推測される:連番、時刻、利用者IDなど、規則のある値から作ると、他人のIDを推測される

    • 盗聴される:HTTPで送ると、通信経路の途中で読み取られる

    • スクリプトで盗まれる:XSSの脆弱性があると、スクリプトでCookieを読み取られ、外部へ送られる

    • 攻撃者が用意したIDを使わされる:セッション固定(次の項)

    対策の基本は、セッション管理を自作せず、実績のあるフレームワークやアプリケーションサーバの機能を使うことです。自作する場合は、暗号論的擬似乱数生成器で十分な長さの推測困難なIDを作ります(乱数は8.)。通信は、ログイン画面だけでなくサイト全体をTLSで暗号化します。

    セッション固定:攻撃者が知っているIDで、ログインさせる

    セッション固定(セッションフィクセーション)は、既にあるセッションIDを盗むのではなく、攻撃者が事前に入手したセッションIDのまま、利用者にログインさせる攻撃です。

    1. 攻撃者が、標的のサイトにアクセスし、ログイン前のセッションIDを入手する

    2. そのIDを使わせる仕掛け(IDを含むURLや、罠のページ)を利用者に送る

    3. 利用者が、そのIDのままログインする

    4. ログイン後もIDが変わらなければ、同じIDを知っている攻撃者も、ログイン済みの利用者として操作できる

    成立の条件は、ログインの前と後で、同じセッションIDを使い続けることです。対策は、ログインに成功したら新しいセッションIDを発行し、古いIDを使えなくすることです。攻撃者が事前に入手できるのは、ログイン前の、何の権限もないIDだけです。ログインの時点で作り直せば、攻撃者の知っているIDは役に立たなくなります。ログイン時だけでなく、管理者の画面に切り替えるなどの権限上昇時も、同じようにIDを更新し、旧IDを拒否します。

    なお、匿名時のセッションIDがあること自体は、欠陥ではありません。買い物かごのように、ログイン前の状態を管理するために使うことがあるからです。攻撃成功の条件は、そのIDをログイン後も使い続けることです。

    終わらせ方まで設計する

    セッションは、始め方だけでなく終わらせ方も設計します。

    • 無操作の時間切れ:一定時間操作がなければ、サーバ側のセッションを無効にする

    • 最長の有効期間:操作を続けていても、一定時間たったら再ログインを求める

    • ログアウト:ブラウザのCookieを消すだけでなく、サーバ側のセッションを無効にする。ブラウザの表示がログアウトになっても、サーバ側でセッションが有効なら、盗まれたIDはほかの端末から使える

    • アカウントの停止・権限の変更:その利用者の既存のセッションを無効化するか、次の要求から新しい権限を反映して判断する。ログインや権限の変更のような状態変更は、セッションを見直すきっかけになる

    • 重要な操作の前の再認証:パスワードの変更、送金、メールアドレスの変更などは、パスワードを再入力させる。セッションを乗っ取られても、重要な操作までは進ませない

    APIのために別にアクセストークンを発行している場合は、画面のセッションを終えても、API用トークンが期限まで使えることがあります。アプリのセッションとAPI用トークンの終了を分けて決め、ブラウザの表示とサーバ側の失効を、同じ試験で確かめます(図2)。

    セッションは、開始から失効まで守る
    【図2】セッションは、開始から失効まで守る


    午後での問われ方

    • 令和6年度秋期 午後問4:求人サイトの診断報告書が題材でした。サイトは、フォームのhiddenフィールドに入れたセッションIDだけでセッションを管理しており、どの画面遷移でも同じ値を返していました。攻撃者が入手したセッションIDのまま利用者にログインさせ、そのIDで不正にログインする手順が示され、解答例の修正方法は「使用済みのsessionIDを無効にした上で、新しいsessionIDを発行」することです。

    記述の型

    • セッション固定の対策:「ログインに成功したら、使用済みのセッションIDを無効にした上で、新しいセッションIDを発行する」

    • セッション固定が成立する条件:「ログインの前後で、同じセッションIDを使い続けている」

    • セッションIDの生成:「推測困難な乱数で作り、利用者IDや時刻から作らない」

    • ログアウトの処理:「ブラウザのCookieの削除だけでなく、サーバ側のセッションを無効にする」

    • 重要な操作の保護:「操作の前にパスワードを再入力させる」

    3. Cookieの属性:送り先・経路・読み手・期間を絞る

    Set-Cookieヘッダの読み方

    セッションIDをCookieに入れるとき、サーバは応答のSet-Cookieヘッダで、次のようにブラウザへ指示します。

    Set-Cookie: SESSIONID=8f3a9c1e…; Secure; HttpOnly; SameSite=Lax; Path=/

    名前と値の後ろに並ぶのが属性です。属性は、そのCookieを「どこへ」「どの通信で」「誰に読ませて」「いつまで」使うかをブラウザに指示します。午後では、問題文に示されたSet-Cookieヘッダを見て、どの属性が足りないか、その属性で何が防げて、何が防げないかを問う設問がよく出ます。

    Secure属性:HTTPSの通信でだけ送る

    Secure属性を付けると、ブラウザはそのCookieをHTTPSの通信でだけ送ります。付けないと、利用者がHTTPのURLへ誘導されたとき、暗号化されない通信にもCookieが付いて送られ、盗聴されます。サイト全体をHTTPSにしていても、Secure属性がなければこの危険は残ります。HTTPでの接続そのものをさせないHSTSは支援士解説2の5で扱います。

    HttpOnly属性:スクリプトから読めなくする

    HttpOnly属性を付けると、ページの中のスクリプト(JavaScript)からCookieを読み取れなくなります。XSSの脆弱性があっても、スクリプトでセッションIDを盗まれにくくなります。

    ただし、次の二点に注意します。

    • XSSそのものは直らない:スクリプトは動くので、偽の入力フォームを表示して入力内容を攻撃者へ送る、利用者のブラウザから要求を送らせる、といった悪用は残る。根本対策は、出力時のエスケープなどです(支援士解説2の5)

    • サイト自身のスクリプトも読めなくなる:画面のスクリプトがCookieの値を使って動いている場合、HttpOnly属性を付けると動かなくなる。付ける前に、Cookieの値をスクリプトで使っていないかを確かめる

    HttpOnly属性は、スクリプトによるCookieの値の読み取りや書換えを防ぎます。一方、Cookieが要求に自動で付いて送られることは止めません。

    SameSite属性:ほかのサイトからの要求にCookieを付けるか

    SameSite属性は、ほかのサイトを起点とする要求にCookieを付けるかどうかを決めます。罠のサイトから、ログイン中の利用者のブラウザで要求を送らせるCSRFへの、補助的な対策です。

    • Strict:ほかのサイトを起点とする要求には、Cookieを付けない

    • Lax:ほかのサイトからのリンクをたどるようなGETの画面遷移では付けるが、POSTでは付けない

    • None:ほかのサイトからでも付ける。Secure属性が必要

    LaxでもPOSTによるCSRFは防げますが、GETで状態が変わる設計では防げません。SameSite属性を指定しないCookieをLaxとして扱うブラウザもあります。CSRFの対策の中心は、セッションと結び付けたCSRFトークンです(支援士解説2の5)。

    Domain属性とPath属性:どこへ送るか

    Domain属性を省略すると、Cookieは発行したホストにだけ送られます。親のドメインを指定すると、その配下のすべてのサブドメインにも送られます。

    Set-Cookie: SESSIONID=…; Domain=example.jp   (example.jp と配下の全サブドメインに送られる)
    Set-Cookie: SESSIONID=…                      (発行したホストにだけ送られる)

    同じドメインの下に、別の部署が運用するサイトや、管理が行き届いていない検証用のサーバがあると、そこへもセッションIDが送られ、漏えいの原因になります。必要がなければDomain属性は付けません。

    Path属性は、送る先のパスを絞ります。ただし、同じホストのページ同士は互いの内容を読めるので、Path属性を安全の境界として使うことはできません。

    有効期限:いつまで使えるか

    ExpiresやMax-Ageの属性で有効期限を指定しないCookieは、原則としてブラウザを閉じると消えます。長い有効期限を付けると、共用のパソコンで次の人に使われたり、盗まれたIDを長く悪用されたりします。ただし、Cookieの期限はブラウザへの指示にすぎません。本当の期限は、サーバ側のセッションの期限で管理します(2.)。

    Cookieの値を、サーバは信じない

    Cookieは利用者のブラウザに保存されるので、利用者が自由に書き換えられます。例えば、ログインした利用者の権限を、次のようにCookieに入れて判断する作りは危険です。

    Set-Cookie: role=user   (利用者が admin に書き換えて送れば、管理者として扱われる)

    権限や利用者の区分など、サーバが判断に使う情報は、サーバ側のセッションに保存し、Cookieにはセッションの識別子だけを入れます。どうしてもCookieに情報を持たせるなら、サーバだけが持つ鍵でMACや署名を付け、書き換えを検出できるようにします。

    トークンをどこに保存するか

    ブラウザでAPI用のトークンを扱う場合、JavaScriptから読めるブラウザの保存領域(Web Storage)に置くと、XSSがあったときにスクリプトで読み取られます。HttpOnly属性を付けたCookieに置けばスクリプトからは読めませんが、要求に自動で付くので、CSRFへの対策が必要になります。どちらにも弱点があるので、XSSを作り込まないことを前提に、仕組みに合わせて選びます(図3)。

    Cookieの属性は、送り先・経路・読み手・期間を絞る
    【図3】Cookieの属性は、送り先・経路・読み手・期間を絞る


    午後での問われ方

    • 平成29年度秋期 午後I問2:Java/Servletで作るWebアプリのセキュアプログラミングが題材でした。出題趣旨には、Webアプリの通信をTLSにするときに気を付けるべきものとして、Secure属性とHttpOnly属性を取り上げたことが示されています。

    • 平成30年度春期 午後II問1:セキュリティ対策の評価が題材でした。HttpOnly属性を付けると支障が出るのはどのような場合かが問われ、解答例は「Rポータルが利用しているスクリプトがCookieの値を利用している場合」です。

    • 令和5年度春期 午後II問1:Webサイトの脆弱性診断が題材でした。HttpOnly属性で防げることとして「HTML内のスクリプトからcookieへのアクセス」、それでも防げない手口として「偽の入力フォームを表示させ、入力情報を攻撃者サイトに送る手口」が、解答例に示されています。

    • 令和5年度秋期 午後問1:ECサイトの商品レビュー機能のXSSが題材でした。サイトはCookieにHttpOnly属性を付けておらず、攻撃者が投稿したスクリプトが、閲覧した会員のCookieを読み取り、画像ファイルに見せかけてアップロードしていました。攻撃者はその画像をダウンロードしてセッションIDを取り出し、会員になりすまします。

    採点講評で指摘されたつまずき

    • 平成29年度秋期 午後I問2では、Cookieを問う設問で、Secure属性は理解されているが、それに比べてHttpOnly属性の理解が進んでいないようだったと指摘されています。

    • 平成30年度春期 午後II問1では、HttpOnly属性を付けると支障が出る場合を問う設問の正答率が低く、HttpOnly属性がCookieの値を不正に操作されることを防ぐのに有効だと理解してほしい、とされています。

    記述の型

    • Secure属性の効果:「HTTPSの通信でだけCookieを送信する」

    • HttpOnly属性の効果:「スクリプトからCookieにアクセスできなくする」

    • HttpOnly属性で防げないこと:「偽の入力フォームを表示させ、入力情報を攻撃者のサイトに送る」

    • HttpOnly属性を付けると困る場合:「サイトのスクリプトがCookieの値を利用している場合」

    • Domain属性の注意:「親ドメインを指定すると、サブドメインのサーバにもCookieが送られる」

    4. APIの認証:状態をサーバに持つか、トークンに持たせるか

    画面のあるWebアプリでは、サーバがセッションの情報を保存し、ブラウザにはセッションIDだけを渡すのが一般的です。サーバが状態を持つので、ステートフルと呼ばれます。

    一方、スマートフォンのアプリやほかのシステムから呼ばれるWeb APIでは、トークンそのものに「誰か」「いつまで有効か」を書き込んで署名し、サーバは状態を持たずに、要求のたびにトークンを確かめる方式がよく使われます。これをステートレスと呼びます。サーバの台数を増やしても、どのサーバでも同じように確かめられるのが利点です。

    トークンは、HTTPの要求のAuthorizationヘッダに、Bearerという方式で付けて送るのが一般的です。

    GET /api/users/me HTTP/1.1
    Host: api.example.jp
    Authorization: Bearer eyJhbGciOiJSUzI1NiIs…(トークン)

    Bearerは「持参人」という意味で、そのとおり、トークンを持っている人なら誰でも使えます。セッションIDと同じく、盗まれれば、なりすましに使われます。

    ステートレスの弱点は、発行したトークンを途中で無効にしにくいことです。サーバが状態を持たないので、ログアウトしたり、盗まれたことに気付いたりしても、トークンは有効期限まで使えてしまいます。そこで、次のように組み合わせます。

    • アクセストークンの有効期限を短くし、更新にはリフレッシュトークンを使う

    • リフレッシュトークンはサーバ側で管理し、ログアウトや不正の発覚時に無効にする

    • すぐに止める必要がある場合は、無効にしたトークンの一覧をサーバ側で持ち、照合する

    アクセストークン、IDトークン、リフレッシュトークンの役割の違いと、OAuth・OIDCの流れは支援士解説3の8で扱います。

    5. JWT:署名を確かめて、初めて信用できる

    JWTの構成

    JWT(JSON Web Token)は、トークンの代表的な形式です。OIDCのIDトークンや、OAuthのアクセストークンに使われます(ただし、アクセストークンは常にJWTとは限りません)。

    JWTは、ヘッダ、ペイロード、署名の三つを、それぞれbase64urlで符号化し、ドットでつないだものです。符号化を戻すと、次のような中身になります。

    ヘッダ  :{"alg": "RS256", "typ": "JWT"}
    ペイロード:{"sub": "user01", "iss": "https://auth.example.jp",
           "aud": "https://api.example.jp", "iat": 1767139200, "exp": 1767142800}
    署名   :ヘッダとペイロードから計算した署名の値
    • ヘッダ:署名のアルゴリズム(alg)など

    • ペイロード:トークンに含める情報(クレーム)。主なものは、対象者(sub)、発行者(iss)、宛先(aud)、発行時刻(iat)、有効期限(exp)

    • 署名:ヘッダとペイロードから計算した値。改ざんを検出する

    algの値で、検証する側が持つ鍵が変わる

    • HS256:共通鍵を使うHMAC。検証する側も同じ鍵を持つので、検証できる者は、トークンを作ることもできる。複数のサービスで検証する場合は、どのサービスもトークンを偽造できてしまう

    • RS256・ES256:公開鍵暗号による署名。発行する側だけが秘密鍵を持ち、検証する側は公開鍵だけを持てばよい

    • none:署名なし(問題文ではNONEと書かれることもある)

    HMACとデジタル署名の違いは支援士解説3の1で扱います。

    検証する項目

    JWTを受け取る側は、次の項目を確かめます(図4)。

    1. algが、サーバ側で決めておいた方式か。noneは拒否する。トークンの中のalgの値をそのまま信じない

    2. 署名が正しいか。決めておいた鍵で検証する

    3. 発行者(iss)が、信頼する発行元か

    4. 宛先(aud)が、自分(このAPI)か。別のサービス宛てのトークンを受け付けない

    5. 有効期限(exp)が切れていないか

    6. トークンの中の利用者と、要求された対象の持ち主が一致するか。これは認可の確認

    特に重要なのが1です。algはトークンの中に書かれた値なので、攻撃者が自由に書き換えられます。検証するライブラリがヘッダのalgに従って検証方法を選ぶ作りだと、algをnoneに書き換えて署名を外したトークンでも、検証に成功してしまいます。algをRS256からHS256に書き換え、公開されている公開鍵を共通鍵として使って署名させる手口も知られています。受け入れる方式は、トークンではなく、サーバ側で決めておきます。

    ペイロードは誰でも読める

    署名だけのJWTは、base64urlで符号化しているだけで、暗号化されていません。トークンを手に入れた人は誰でも中身を読めます。パスワードや個人情報など、読まれて困る情報は入れません(暗号化するJWEという形式もあります)。

    また、署名の検証は「改ざんされていないこと」の確認です。その利用者に、その対象への操作を許すかは、別に確かめます(上の6)。

    IDトークンを、APIに渡さない

    OIDCのIDトークンは、ログインを依頼したアプリ(クライアント)に宛てた認証の結果です。APIを呼ぶときは、そのAPI宛てのアクセストークンを使います。APIがIDトークンを受け付ける作りだと、別のアプリ宛てに発行されたIDトークンでも、APIを使えてしまうおそれがあります。宛先(aud)を確かめるのは、このためです。

    JWTは、署名を確かめて初めて信用できる
    【図4】JWTは、署名を確かめて初めて信用できる


    午後での問われ方

    • 令和6年度春期 午後問1:スマートフォンのアプリから呼ぶAPIが題材でした。RESTful APIの設計原則の一つであるセッション管理を行わない性質が問われ、解答は「ステートレス」です。APIは、JWTのヘッダに指定されたアルゴリズムに基づいて検証するライブラリを使っており、algのRS256をNONEに変え、利用者IDを他人のものに書き換えたJWTでも検証が成功し、なりすましができました。解答例の対策は、「JWTヘッダ内のalgに指定された値」が「NONEでないことを検証する」ことです。あわせて、パラメータで指定された利用者IDのデータを返していた不備には、「JWTに含まれる利用者IDが」パラメータの値「と一致するかどうかを検証する処理」を加えます(パラメータの改ざんは支援士解説2の5)。

    採点講評で指摘されたつまずき

    • 令和6年度春期 午後問1では、JWTの改ざんにおける検証方法を問う設問の正答率がやや低く、既に実装されている対策を答えるなど、脆弱性を正しく理解していないと思われる解答が散見されたと指摘されています。この問題では、署名は既に検証していました。欠けていたのは、algの値の確認です。

    記述の型

    • JWTの改ざんへの対策:「JWTのヘッダのalgの値がNONEでないことを検証する」

    • algを信じてはいけない理由:「algはトークンの中の値で、攻撃者が書き換えられる」

    • 秘密情報を入れない理由:「ペイロードは暗号化されておらず、誰でも読める」

    • ステートレスの弱点:「発行したトークンを、有効期限まで無効にしにくい」

    • 宛先の確認:「audが、自分宛てであることを検証する」

    6. APIを守る:受け付ける値と、試行の回数を絞る

    仕様にないパラメータを受け付けない

    APIでは、画面がない分、利用者がリクエストを自由に組み立てられます。認可の不備(IDを書き換えると他人のデータが見える)に加えて注意したいのが、仕様にないパラメータを足されることです。

    例えば、利用者情報を更新するAPIが、受け取ったパラメータをすべてそのまま、データベースを更新する処理に渡しているとします。

    PUT /api/users/user01
    {"name": "山田", "age": 30}                     ← 仕様どおりの要求
    {"name": "山田", "age": 30, "status": "paid"}   ← 仕様にない status を足した要求

    更新の処理が利用者の区分(status)も更新できる作りだと、無償の利用者が自分を有償の利用者に変えられます。このような不備は、マスアサインメントと呼ばれます。対策は、APIごとに受け付けるパラメータを決めておき、それ以外は捨てるか、エラーにすることです。利用者の区分や権限のように、サーバが決めるべき項目は、利用者から送られた値で変えられないようにします。

    試行の回数を制限する

    APIは画面を経由しないので、プログラムから高速に何度でも試せます。短い確認コードは、総当たりで突破されます。

    例えば、4桁の数字の確認コードは、0000から9999までの1万通りです。毎回ランダムに作られるなら、平均して半分の5,000回で当たります。1秒に10回試せるなら、5,000÷10=500秒、つまり10分足らずで突破されます。

    対策は、次の組合せです。

    • 連続して失敗した回数がしきい値を超えたら、アカウントをロックする(または、一定時間受け付けない)

    • 確認コードの桁数を増やす。6桁なら100万通り

    • 確認コードの有効期限を短くする

    • APIの呼出し回数を、利用者や接続元ごとに制限する(レート制限)

    アカウントのロックは、攻撃者が他人のアカウントをわざとロックさせる妨害にも使えます。ロックの解除の方法や、一定時間後の自動解除も合わせて決めます。

    APIキーは、システムを識別する秘密

    APIの呼出し元を識別するために、APIキー(秘密の文字列)を使う方式もあります。クラウドのサービスを使うためのアクセスキーも同じ性質です。注意点は次のとおりです。

    • 知っていれば誰でも使える。パスワードと同じように守り、URLに入れてログに残すことは避ける

    • どのシステムからの呼出しかを示すもので、利用者ごとの認可の代わりにはならない

    • 盗まれたときの被害を小さくしておく。使えるAPIと取得できる情報を必要最小限にする、接続元のIPアドレスを限定する、定期的に作り直す

    • 利用者に配るアプリの中に置かない(次の7.)

    午後での問われ方

    • 令和6年度春期 午後問1(5.と同じ問題):利用者情報を更新するAPIで、値「paid」を設定したパラメータ「status」を追加して送ると、無償利用者から有償利用者に変えられる不備が問われました。実装が、指定されたパラメータを検証せず、すべて共通モジュールに送っていたことが原因です。2要素認証に使う4桁の数字の文字列は、1秒間に10回試行する総当たりで、平均500秒で突破されるとされ、対策の一つが「連続失敗回数がしきい値を超えたらアカウントをロックする処理」です(あわせて、文字列を6桁に変更)。

    • 令和6年度秋期 午後問4(2.と同じ問題):求人サイトのWebAPIで使うAPIキーが盗まれた場合に、被害を軽くする改善が問われました。解答例には、「WebAPIのアクセス元IPアドレスを限定して接続を許可するように変更する」、「WebAPIで取得できる求職者属性情報は、個人を特定できないものだけに限定するように変更する」、求職者IDを推測困難なものにして、漏えいをその求人企業への応募者・問合せ者の情報だけに抑える、といった案が示されています。

    採点講評で指摘されたつまずき

    • 令和6年度秋期 午後問4では、APIキーが盗まれたときの被害を軽くする仕様の改善を問う設問の正答率がやや低く、被害を軽減できない誤答が散見されたと指摘されています。扱う情報の機密性に応じた認証やアクセス制限を考えます。

    記述の型

    • 仕様にないパラメータへの対策:「受け付けるパラメータを決め、それ以外のパラメータは無視するか、エラーにする」

    • 総当たりへの対策:「連続失敗回数がしきい値を超えたら、アカウントをロックする」

    • 平均の突破時間の求め方:「組合せの数の半分を、1秒当たりの試行回数で割る」

    • APIキー漏えい時の被害軽減:「接続元のIPアドレスを限定する」「取得できる情報を、個人を特定できないものに限定する」

    7. スマートフォンアプリ:配ったアプリは、解析される

    スマートフォンのアプリは、午後で繰り返し題材になっています。APIとの連携、決済、本人確認など、アプリの中で認証と通信の処理を行うからです。考え方の出発点は一つです。利用者に配ったアプリは、攻撃者も手に入れ、解析できます。

    アプリの中に、秘密を置かない

    アプリのプログラムや、一緒に配るファイル(リソース)は、攻撃者が取り出して調べられます。難読化は解析を遅らせますが、防ぐことはできません。

    例えば、クラウドのストレージを使うためのアクセスキーを暗号化してアプリの中に保存し、復号に使う共通鍵と初期ベクトルをプログラムの中に定数で書いていたとします。攻撃者はアプリを解析して、暗号化されたアクセスキーと、共通鍵・初期ベクトルの両方を取り出せるので、アクセスキーを復号できます。暗号化した値と、それを解く鍵を同じ場所に置いても、守ったことになりません。

    そのアクセスキーがストレージ全体のファイルを操作できるものなら、被害は全利用者に及びます。ファイル名が注文番号のような連番なら、番号を順に変えるだけで、他人のファイルを次々にダウンロードできます。

    秘密を使う処理は、サーバで完結させる

    アプリに秘密を持たせずにストレージを使う方法の一つが、署名付きURLです。サーバが、操作を許すファイルと有効期限を決め、秘密の鍵で署名したURLを作って、アプリに渡します。

    PUT /photos/00000123.zip?Expires=1767142800&Signature=(署名値) HTTP/1.1
    Host: storage.example.jp
    • 署名値は、操作(PUTやGET)、ファイルのパス、有効期限から、アクセスキーを秘密鍵としてHMACで計算する

    • ストレージは、署名値と有効期限を確かめ、正しければそのファイルへのその操作だけを許す

    • アクセスキーはサーバの外に出ないので、アプリを解析されても取り出せない

    • URLが漏れても、使えるのはそのファイルだけで、有効期限が切れれば使えない

    ここで重要なのは、署名付きURLを作る処理もサーバで行うことです。アプリの中で作ると、署名に使うアクセスキーをアプリに持たせることになり、元の問題に戻ります。

    アプリに持たせてよいのは、ログインした利用者ごとに発行した、有効期限のあるトークンなどです。端末に保存するときは、OSが用意する安全な保管の仕組みを使い、ログアウト時に消します。アプリが出力するログ、画面のキャッシュ、端末内の共有の保存領域などに、トークンや個人情報を残さないことも確かめます。ほかのアプリや、端末を手にした人に読まれるおそれがあるからです。

    証明書の検証を、止めない

    アプリとサーバの通信をHTTPSにしていても、アプリがサーバ証明書の検証を正しく行わなければ、中間者攻撃で盗聴も改ざんもされます。攻撃者が自分で作った証明書を提示しても、エラーを無視して通信を続けてしまうからです。

    よくある経緯は、開発中の調査です。通信の内容を調べるために、プロキシとして動く通信解析ツールを使うと、ツールが提示する証明書は、端末が信頼していない認証局のものなので、アプリで検証エラーになります。このとき、エラーを無視するようにアプリを変えてしまうと、その処理が本番のアプリに残ります。

    正しい方法は、通信解析ツールのプライベート認証局のルート証明書を、テスト用の端末にインストールし、信頼する設定にすることです。アプリの検証処理はそのままで、ツールの証明書だけが検証に通ります。OSによっては、利用者が追加したルート証明書をアプリが信頼するかどうかを、アプリ側の設定で決めます。その場合は、テストのときだけ有効になるようにします。

    サーバ証明書で確かめる項目(発行した認証局、有効期間、失効、接続先の名前との一致)は支援士解説3の1で扱います。

    証明書ピンニング:受け入れる証明書を、アプリが決める

    証明書ピンニングは、アプリが接続するサーバの証明書(またはその公開鍵)をあらかじめアプリに登録しておき、それ以外の証明書を受け入れない仕組みです。通常の検証では、端末が信頼する認証局のどれかが発行した証明書なら通ります。ピンニングをすれば、認証局が誤って発行した証明書や、端末に追加されたルート証明書を使う中間者攻撃も防げます。

    一方で、次の点に注意します。

    • サーバの証明書や鍵を更新すると、古いアプリが接続できなくなる。予備の公開鍵も登録しておき、更新の計画とアプリの配布を合わせる

    • 通信解析ツールを使ったテストもできなくなる。テスト用の設定を、本番のアプリに残さない

    ピンニングは、通常の証明書の検証に追加する対策です。検証そのものを省いてよいわけではありません。

    WebViewとアプリの機能をつなぐときの注意

    WebViewは、アプリの画面の中にWebページを表示する、OSの仕組みです。キャンペーンのページなどを、アプリの中で表示するのに使います。WebViewには、次の弱点があります。

    • アドレスバーがないので、利用者は表示しているページのURLを確かめられない。偽のページを表示させられても気付けない

    • アプリの機能を、表示したページのスクリプトから呼べるようにできる。例えば、アプリが保存している認証トークンをページに渡す機能を作ると、攻撃者のページからも呼ばれるおそれがある

    そのため、WebViewで開くURLを、開く前に自社のドメインのものに限定します。アプリの機能を呼べるページも、呼出し元のURLを確かめて限定します。URLの先頭が自社のドメインかを確かめるなら、ドメイン名の後ろのスラッシュまで含めて比べます(比べ方の落とし穴は支援士解説2の5)。

    メールのリンクなどからアプリを起動するカスタムURLスキームは、ほかのアプリも同じ名前を登録できます。受け取ったURLやパラメータは、外部からの入力として検証します。

    端末の紛失・盗難に備える

    スマートフォンは持ち歩くので、紛失・盗難を前提にします。利便性のためにログイン状態を長く保つと、画面ロックを設定していない端末を盗まれたとき、そのままアプリを使われます。ログイン状態を保つなら、アプリの起動時に、PINや生体認証で利用者を確かめる機能を加えます。

    アプリの中で、本人確認(身元確認)を行うこともあります。例えば、マイナンバーカードの署名用電子証明書を使う場合は、署名を検証したうえで、証明書が有効で、失効していないかを確かめます。本人確認書類と顔の画像を撮影して送る方法では、事前に用意した他人の画像を使われないように、アプリが毎回表示するランダムな数字を紙に書いて、一緒に撮影させる工夫があります(8.のリプレイ対策と同じ考え方です)。

    ここまでの分担をまとめると、図5のようになります。

    スマホアプリは、解析される前提で分担する
    【図5】スマホアプリは、解析される前提で分担する


    午後での問われ方

    • 令和7年度春期 午後問3:写真入りのグッズを注文するスマートフォンのアプリが題材で、三つの脆弱性が問われました。

    • サーバ証明書の検証エラーを無視して通信を続ける不備。経緯は、通信解析ツールを使ったときのエラーを避けるためにアプリを変えたことでした。正しい方法として、解答例は「通信解析ツールのプライベート認証局のルート証明書をインストールし、信頼設定を行う」です。問題文では、一方のOSについて、テストのときだけこの設定を有効にする設定をアプリにも加えています

    • ストレージのアクセスキーを暗号化してアプリ内に保存し、共通鍵と初期ベクトルをコードの中に定数で書いていた不備。解答例には、アプリを解析してアクセスキーと共通鍵・初期ベクトルを入手し、復号する手口と、「ファイル名に含まれる注文番号を00000001から順に増やしてダウンロードを試行する」手口が示されています。対策は署名付きURLで、生成する時点として、サーバ側の処理の時点が問われました

    • カスタムURLスキームで受け取ったURLを、WebViewで表示する機能の不備。WebViewには「URLを確認する手段がない」ことが問われ、解答例の対策は、WebViewを呼び出す前に、URLの先頭が自社のWebサーバのURL(スラッシュまで)であるかを検証することです

    • 令和4年度春期 午後I問3:スマートフォン向けQRコード決済サービスが題材でした。ログイン状態を1か月保持する設計で、画面ロックを設定していないと不正利用される場合として「スマートフォンを盗まれた場合」、追加する機能として「Qアプリの起動時に、PINコードで利用者を認証する機能」が、解答例に示されています。本人確認では、署名用電子証明書の「有効性」と「失効の有無」の確認や、毎回表示されるランダムな数字を紙に書いて撮影させる方法も問われました。

    • 令和2年度10月 午後I問1:スマートフォンの決済アプリが題材でした。アプリのサーバ証明書の検証に不備があるという指摘に対し、検証の条件として、subjectAltNameのdNSNameがあれば接続先のFQDNと合致すること、なければsubjectのcommonNameと合致すること、有効期間内であることが示されています(決済のなりすまし対策は8.)。

    採点講評で指摘されたつまずき

    • 令和7年度春期 午後問3では、プライベート認証局のルート証明書を端末にインストールして、サーバ証明書の検証エラーを解消させる方法を問う設問の正答率が低かったとされています。同じ方法は、ネットワーク機器のTLSインスペクションなどでも使われます。

    • 同じ問題で、署名付きURLを生成する場所を問う設問では、攻撃者による解析が容易なスマートフォンのアプリ上と答える解答が散見されたと指摘されています。秘密情報の処理は、サーバ上で完結させます。

    • 同じ問題で、盗んだアクセスキーで全利用者の写真をダウンロードする方法を問う設問の正答率が低く、抽象的な解答が散見されたとされています。「ファイル名の注文番号を順に変えて試す」のように、問題文の仕様に沿って具体的に書きます。

    • 令和4年度春期 午後I問3では、電子証明書の有効性を確認する方法を問う設問の正答率が低かったとされています。署名の検証に加えて、証明書が失効していないかを確かめる必要があります。

    記述の型

    • アプリに秘密を置く危険:「アプリを解析され、暗号化したキーと復号の鍵を取り出される」

    • 秘密を使う処理の場所:「署名付きURLは、サーバで生成してアプリに渡す」

    • 検証エラーを避ける正しい方法:「通信解析ツールのプライベート認証局のルート証明書を、テスト用の端末にインストールして信頼する」

    • WebViewの対策:「WebViewで開く前に、URLが自社のドメインのものかを、スラッシュまで含めて検証する」

    • 盗難への備え:「アプリの起動時に、PINで利用者を認証する」

    8. 乱数・ノンス・リプレイ攻撃:一度きりの値で、使い回しを防ぐ

    予測できない乱数を使う

    セッションID、CSRFトークン、確認コード、ノンスなど、セキュリティ機能の多くは「攻撃者に予測されない値」を前提にしています。プログラム言語が標準で用意する乱数には、統計的にはばらついて見えても、過去の出力から次の値を予測できるものがあります。これらの値には、暗号論的擬似乱数生成器を使います(支援士解説3の1)。

    リプレイ攻撃:正しいデータを、もう一度送る

    リプレイ攻撃(再送攻撃)は、正規の利用者が送ったデータを盗み見たり記録したりして、そのまま送り直す攻撃です。データは本物なので、署名やメッセージ認証コード(MAC)を確かめても、改ざんは見つかりません。暗号化していても、暗号文をそのまま送り直せば成立する場合があります。

    対策は、データを一度きり、短い時間だけ有効にすることです。

    • ノンス(一度だけ使う値):受け取る側が、使用済みの値を記録して、二度目を拒否する

    • 時刻:データに作成時刻を入れ、決めた時間を過ぎたものを拒否する

    • 連番:通信ごとに番号を増やし、古い番号を拒否する

    • チャレンジレスポンス:確かめる側が毎回ランダムな値(チャレンジ)を送り、相手は秘密の情報を使って計算した値(レスポンス)を返す。毎回チャレンジが違うので、前の応答を再送しても通らない

    ノンスや時刻は、MACや署名の計算の対象に含めます。含めないと、攻撃者がノンスや時刻だけを書き換えて再送できるからです。

    決済のコードは、一度きりにする

    スマートフォンの決済アプリで、会員番号をそのままバーコードに表示する仕組みを考えます。バーコードの内容が会員番号だけで、いつまでも使えるなら、攻撃者は他人の会員番号を推測したり盗んだりして、その人のバーコードを作り、決済できてしまいます。

    対策の例が、サーバが作る値とMACを組み合わせたQRコードです。

    1. サーバが、会員番号、サーバが作った乱数、時刻をもとに、サーバだけが持つ秘密鍵でHMAC値を計算する

    2. 会員番号、乱数、時刻、HMAC値からQRコードを作り、アプリに表示させる

    3. 決済のとき、サーバは同じ秘密鍵でHMAC値を計算し直し、QRコードの中のHMAC値と一致するかを確かめる

    4. さらに、時刻から決めた時間(例えば5分)以内であることと、同じQRコードが過去に使われていないことを確かめる

    それぞれの役割は次のとおりです。

    • HMAC値:会員番号などを書き換えた偽のQRコードを見破る。秘密鍵はサーバだけが持つので、アプリを解析されても偽造できない

    • 乱数と使用済みの確認:同じQRコードの使い回し(リプレイ)を防ぐ

    • 時刻:盗み見たQRコードを使える時間を短くする

    7.の本人確認で、毎回ランダムな数字を書いて撮影させるのも、事前に用意した画像の使い回しを防ぐ、同じ考え方です。

    午後での問われ方

    • 令和2年度10月 午後I問1:スマートフォンの決済アプリが題材でした。会員番号をバーコードで表示する仕組みのなりすましの手段として「他者のバーコードを会員番号から推測して表示する」、問題点として「バーコードの内容が会員番号であること」「バーコードが永続的に利用できること」が、解答例に示されています。対策のQRコードの検証手順の空欄は、「HMAC値αとHMAC値βの一致を検証する」です。

    採点講評で指摘されたつまずき

    • 令和2年度10月 午後I問1では、バーコードの仕様のどこが決済のなりすましにつながるのか(問題点)を問う設問の正答率がやや低かったとされています。

    記述の型

    • リプレイ攻撃への対策:「一度だけ使える値を含め、使用済みの値を拒否する」「作成時刻を含め、有効期間を過ぎたものを拒否する」

    • なりすましが成功する原因:「コードの内容が会員番号だけで、永続的に使える」

    • MACの検証:「受け取った値から計算し直したMAC値と、付いてきたMAC値の一致を確かめる」

    9. パスワードの保存:漏れても、元のパスワードを割り出しにくくする

    パスワードを保存するときは、データベースが漏えいすることを前提に考えます。

    • 平文で保存する:漏れた瞬間に、すべてのパスワードが分かる

    • 復号できる暗号化で保存する:鍵も一緒に漏れれば、すべて復号される。管理者も元のパスワードを見られる

    • 高速なハッシュ関数を1回かけるだけ:同じパスワードは同じハッシュ値になる。よく使われるパスワードのハッシュ値をまとめた表(レインボーテーブル)や、高速な総当たりで、元のパスワードを割り出される

    そこで、次の二つを組み合わせます。

    • ソルト:利用者ごとに異なるランダムな値を、パスワードに加えてからハッシュ化する。同じパスワードでも保存値が変わるので、事前に計算した表が使えず、同じパスワードを使っている利用者も分からない。ソルトは秘密ではなく、ハッシュ値と一緒に保存してよい

    • ストレッチング:ハッシュの計算を何度も繰り返して、1回の照合にかかる時間を長くする。正しい利用者の照合はわずかに遅くなるだけだが、総当たりする攻撃者には大きな負担になる

    実際には、ソルトとストレッチングを組み込んだ、パスワード保存専用の方式(PBKDF2、bcrypt、scrypt、Argon2など)を使います。

    保存するもの:利用者ID、ソルト、方式と計算の回数、ハッシュ値
    照合するとき:入力されたパスワードに、保存してあるソルトを加えて同じ方式で計算し、
           保存してあるハッシュ値と一致するかを確かめる

    ソルトもストレッチングも、弱いパスワードを強くするものではありません。辞書に載っている短いパスワードは、時間がかかっても割り出されます。パスワードの長さ、使い回しの防止、漏えいしたパスワードの拒否は支援士解説3の8で扱います。

    記述の型

    • ソルトの効果:「同じパスワードでも、利用者ごとに異なるハッシュ値になる」

    • ストレッチングの効果:「ハッシュ値の計算に時間がかかるので、総当たりに時間がかかる」

    • 平文で保存する危険:「データベースが漏えいすると、パスワードがそのまま知られる」

    10. ログ:アプリが残す記録を、機能と一緒に決める

    ログは、機能を作るときに一緒に設計します。後から足そうとしても、必要な情報がアプリの中にしかなく、取れないことがあるからです。

    • 何を記録するか:ログインの成功・失敗、アクセスの拒否、権限の変更、管理者の操作、重要なデータの閲覧・出力

    • 各記録の項目:いつ、誰が、どこから、何に、何をして、結果はどうだったか。拒否した操作も残す

    • 記録しないもの:パスワード、セッションID、アクセストークン、秘密鍵。ログが漏れると、そのままなりすましに使われる

    • 守り方:時刻を合わせる、アプリの権限では消せない場所へ送る、取得が止まったら気付けるようにする

    ログの保管の設計と、攻撃の痕跡の読み方は支援士解説3の4で扱います。

    11. 製品の評価認証と、実装を狙う攻撃

    CCとJISEC:製品の、決められた範囲を評価する

    CC(Common Criteria、ISO/IEC 15408)は、IT製品のセキュリティ機能と、その作り方の確かさ(保証)を評価する国際基準です。評価の方法はCEM(ISO/IEC 18045)が定めています。日本で、CCに基づいて製品を評価・認証する制度が、IPAが運営するJISECです。

    CCで押さえる用語は次のとおりです。

    • TOE(評価対象):評価を受けた製品の範囲。製品全体とは限らない

    • ST(セキュリティターゲット):そのTOEが、どの脅威に、どの機能で対抗するか、どの運用の条件を前提にするかを示した文書

    • PP(プロテクションプロファイル):製品の分野ごとに、求めるセキュリティ要件をまとめた文書

    • EAL(評価保証レベル):保証の厳しさを示す段階。EAL1からEAL7まである

    認証を受けた製品でも、評価の対象は、TOEとSTに書かれた範囲、版、構成に限られます。評価対象外の設定や機能を使ったり、別の版を使ったりすれば、認証の結果はそのまま当てはまりません。接続した業務システムまで、自動的に認証されるわけでもありません。導入構成全体の安全を、認証マークの有無だけで判断しないことが大切です。

    FIPS 140-3とJCMVP:暗号モジュールを評価する

    FIPS 140-3は、暗号モジュールのセキュリティ要件を定めた米国の規格です。暗号の処理が正しく実装されているかに加えて、鍵の管理や、物理的な攻撃からの保護も評価範囲に含みます。日本で暗号モジュールを試験・認証する制度が、IPAが運営するJCMVPで、ISO/IEC 19790(JIS X 19790)などを基準に使います。

    CC/JISECは製品の決められた評価対象を、FIPS 140-3/JCMVPは暗号モジュールを評価します。同じ認証を別の名前で呼んでいるわけではありません。調達では、認証マークの有無だけで判断せず、証明書の条件(対象の版と構成)が、導入するものと一致するかを確認します。

    耐タンパ性:中を開けられても、秘密を守る

    耐タンパ性は、分解や物理的な操作による内部情報の読出しや改ざんに耐える性質です。ICカードや、鍵を保護するHSMに求められます。耐タンパ性があっても、絶対に漏れないという意味ではありません。どのような物理的攻撃を想定しているかを確かめます。

    耐タンパ性には、こじ開けにくくするだけでなく、異常を検知したら、中の秘密を消す仕組みも含まれます。例えば、筐体を開けられた、電源電圧が決められた範囲を外れた、といった異常をセンサが検知すると、装置が中の鍵を消して、使えない状態になります。裏を返せば、運搬中の静電気のような思わぬ異常でも装置が使えなくなるので、運用の手順で配慮が必要です。

    機器の記憶装置を取り出して別のパソコンにつなげば、中のデータや鍵を読めてしまう、というのも物理的な攻撃です。利用者の手元に置く機器(IoT機器など)では、鍵を取り出せない部品(TPMなど)の利用を考えます(支援士解説3の1)。

    サイドチャネル攻撃と故障注入

    サイドチャネル攻撃は、暗号の計算そのものではなく、処理にかかる時間、消費電力、電磁波、音などを観測して、秘密の鍵を推測する攻撃です。暗号の方式が数学的に強くても、実装や装置から漏れる情報で破られます。対策には、処理時間が秘密の値によって変わらない実装や、電磁波の遮へいなどがあります。出題例は支援士解説3の1で扱います。

    故障注入攻撃は、電圧やクロックを乱したり、レーザを当てたりして装置に誤動作を起こさせ、その結果から秘密を推測したり、確認の処理を飛ばさせたりする攻撃です。観測するだけのサイドチャネル攻撃と違い、装置に干渉します(図6)。

    評価の対象と、実装への攻撃を読む
    【図6】評価の対象と、実装への攻撃を読む


    午後での問われ方

    • 平成29年度秋期 午後II問2:データベースの暗号化と鍵の管理が題材で、ハードウェア暗号モジュール(HSM)の製品が登場しました。製品の仕様によって実現される暗号モジュールの性質として「耐タンパ性」が問われています。また、運搬時に静電気防止シートで覆う規程の理由として、解答例には、静電気の放電で規定の範囲を超える電源電圧が発生し、その事象をセンサが検知して、製品自身を使用不能で戻せない状態にすることが示されています。

    • 平成31年度春期 午後I問3:家庭用ゲーム機の開発が題材でした。クライアント証明書と秘密鍵を、広く流通しているSSDに格納する設計に対し、攻撃者がゲーム機を購入して鍵を不正に使う方法として「SSDを取り出し、PCなどにつなげる」が、対策に使う部品に求められる性質として「耐タンパ性」が、解答例に示されています。

    記述の型

    • 耐タンパ性の説明:「内部の情報を、不正に読み出されたり改ざんされたりしにくい性質」

    • 異常の検知:「センサが異常を検知し、内部の鍵を消去して、使用できない状態にする」

    • サイドチャネル攻撃の手法:「処理時間や消費電力、電磁波を観測し、鍵を推測する」

    • 認証製品の確認:「TOEとSTに書かれた範囲・版・構成が、導入する構成と一致するかを確かめる」

    12. 設計書とテスト計画書を、拒否条件で結ぶ

    設計のレビューでは、採用する製品名より先に、許可する条件と拒否する条件が、同じ細かさで書かれているかを見ます。この記事の内容を、レビューの観点にまとめます。

    1. 本人確認:入口ごとに認証の方法が決まっているか。失敗が続いたときに、ロックや遅延で止められるか

    2. 対象ごとの認可:API側で、要求ごとに、その利用者が扱ってよい対象かを判定しているか

    3. セッション:ログイン時にIDを作り直すか。時間切れとログアウトで、サーバ側のセッションを無効にするか。Cookieの属性は適切か

    4. トークン:alg・署名・発行者・宛先・有効期限を確かめるか。途中で止める方法があるか

    5. 受け付ける値:仕様にないパラメータを捨てるか。サーバが決める項目を、利用者が変えられないか

    6. 秘密の置き場所:アプリやソースコードの中に、鍵やアクセスキーがないか。鍵を誰が管理するか

    7. ログ:許可と拒否が記録され、秘密の情報が出ていないか。取得が止まったときに気付けるか

    8. 評価認証の範囲:製品の認証範囲として証明書に書かれた範囲・版・設定が、導入する構成と一致するか

    テスト計画書は、「正しい利用者なら動いた」という正常系の確認で終えません。例えば申請資料の閲覧なら、担当者は取得でき、他課や異動後の職員は拒否されることを、画面とAPIの両方の結果と監査ログで確かめます。期限切れのトークン、別の宛先のトークン、権限変更の直後の要求、ログアウト後の旧セッションのID、仕様にないパラメータ、鍵やログの保存先が使えない状態など、拒否されるべき条件を並べ、境目を変えて同じ要求を繰り返し、その結果と記録まで確かめます(図7)。完成後の脆弱性診断とテストの方法は支援士解説2の6で扱います。

    設計書と試験を、拒否条件で結ぶ
    【図7】設計書と試験を、拒否条件で結ぶ


    13. 午前II(科目A-2)で正誤を見分けるポイント

    • 「HttpOnly属性を付けたCookieは、HTTPSの通信でだけ送られる」→ 誤り。それはSecure属性

    • 「Secure属性を付けたCookieは、スクリプトから読み取れない」→ 誤り。それはHttpOnly属性

    • 「SameSite属性がLaxのCookieは、ほかのサイトからのPOSTの要求にも付けて送られる」→ 誤り。POSTでは送られない

    • 「Domain属性を省略すると、サブドメインにもCookieが送られる」→ 誤り。発行したホストにだけ送られる

    • 「セッション固定攻撃への対策として、ログイン成功後に新しいセッションIDを発行する」→ 正しい

    • 「署名付きJWTのペイロードは暗号化されているので、秘密情報を入れてよい」→ 誤り。符号化しているだけで、誰でも読める

    • 「ソルトは、利用者ごとに秘密に管理する鍵である」→ 誤り。ランダムな値で、ハッシュ値と一緒に保存してよい

    • 「ストレッチングは、ハッシュ値の計算を繰り返し、総当たりにかかる時間を増やす」→ 正しい

    • 「リプレイ攻撃は、通信を暗号化すれば防げる」→ 誤り。暗号文の再送も成立しうる。ノンスや時刻で一度きりにする

    • 「ISO/IEC 15408は、暗号モジュールのセキュリティ要件を定める規格である」→ 誤り。IT製品の評価基準(CC)。暗号モジュールはFIPS 140-3など

    • 「サイドチャネル攻撃は、暗号アルゴリズムの数学的な弱点を突く」→ 誤り。処理時間や消費電力などの観測から推測する

    • 「耐タンパ性とは、内部の情報を不正に読み出されにくい性質である」→ 正しい

    理解度チェック

    本文の理解を確かめるためのオリジナル問題です。実際の過去問ではありません。

    問1 セッション固定

    ログイン前に発行したセッションIDが、ログイン後もそのまま使われることが分かった。最も適切な対策はどれか。

    • ア:ログインに成功したら、新しいセッションIDを発行し、古いIDを無効にする

    • イ:セッションIDの桁数を増やす

    • ウ:Cookieの有効期限を長くする

    • エ:ログイン画面の通信にだけ、TLSを使う

    正解:ア。攻撃者が事前に入手できるのは、ログイン前のIDです。ログインの時点で作り直せば、そのIDは使えなくなります。イは推測への対策で、攻撃者がIDを既に知っている場合には効きません。

    問2 Cookieの属性

    XSSの脆弱性が見つかった。修正までの間、スクリプトでセッションIDを盗まれる危険を下げたい。Cookieに付ける属性として最も適切なものはどれか。

    • ア:Secure

    • イ:HttpOnly

    • ウ:Domain

    • エ:Path

    正解:イ。HttpOnly属性は、スクリプトからCookieを読めなくします。ただし、XSSそのものは残るので、偽の入力フォームの表示などは防げません。アは、HTTPSの通信でだけ送る属性です。

    問3 JWTの検証

    APIが、JWTのヘッダに書かれたアルゴリズムに従って署名を検証している。攻撃者がalgをnoneに書き換え、ペイロードの利用者IDを他人のものに変えたJWTを送ると、検証に成功した。最も適切な対策はどれか。

    • ア:ペイロードを暗号化する

    • イ:受け入れるアルゴリズムをサーバ側で決め、algがnoneのJWTを拒否する

    • ウ:JWTの有効期限を長くする

    • エ:JWTを、URLのパラメータで送る

    正解:イ。algはトークンの中の値なので、攻撃者が書き換えられます。アは中身を隠すだけで、署名を外されることは防げません。

    問4 アプリの中の秘密

    スマートフォンのアプリが、クラウドストレージのアクセスキーを暗号化してアプリ内に保存し、復号の鍵をプログラムの中に定数で書いている。最も適切な改善はどれか。

    • ア:暗号の方式を、鍵の長いものに変える

    • イ:プログラムを難読化する

    • ウ:サーバが、ファイルと有効期限を限った署名付きURLを生成して、アプリに渡す

    • エ:アプリの中で、アクセスキーを使って署名付きURLを生成する

    正解:ウ。アクセスキーをアプリに持たせないことが重要です。ア・イでは、解析されれば鍵ごと取り出されます。エは、アプリにアクセスキーを持たせたままです。

    問5 リプレイ攻撃

    決済用のQRコードに、会員番号、サーバが作った乱数、時刻と、それらのHMAC値を含めている。サーバが「同じQRコードが過去に使われていないか」を確かめる目的として、最も適切なものはどれか。

    • ア:会員番号の書換えを見破るため

    • イ:盗み見たQRコードの再送(リプレイ)を防ぐため

    • ウ:HMACの秘密鍵を守るため

    • エ:QRコードを読み取る時間を短くするため

    正解:イ。HMAC値は書換えを見破りますが、本物のQRコードをそのまま再送されると通ってしまいます。使用済みの確認と時刻の確認で、使い回しを防ぎます。アはHMAC値の役割です。

    実務と国・自治体では

    実務では、セキュリティ機能を「ある・ない」で調達しがちです。仕様書に「多要素認証に対応」「通信を暗号化」とだけ書くと、時間切れの長さ、ログアウトの処理、Cookieの属性、トークンの検証、アプリに秘密を置かないことは、受注者の判断に任されます。調達仕様と受入れの試験では、拒否されるべき条件(他人の申請番号、期限切れ、ログアウト後、異動後)を具体的に示し、その結果と記録を確かめます。委託先が作るスマートフォンのアプリも、鍵がアプリの中にないか、証明書の検証を省いていないかを、納品前の診断で確かめます。

    政府機関等の統一基準は、情報システムのセキュリティ機能として、主体認証、アクセス制御、権限の管理、ログの取得・管理、暗号・電子署名を別々に定めています。自治体向けのガイドラインも、アクセス制御やログの取得の例文を示しています。資料の位置付けは支援士解説1の1で整理しています。

    まとめ

    • セキュリティ機能は、許可と拒否の条件で書く。 主体・対象・操作・許可条件・拒否条件・記録を一組にし、拒否されるべき要求で試す。

    • セッションIDはログイン済みの証明。 推測困難な値で作り、ログイン時に作り直し、サーバ側で終わらせる。CookieにはSecure・HttpOnly・SameSiteを付け、Domainを広げない。

    • JWTは、サーバ側で決めた方式で署名を確かめる。 algを信じず、noneを拒否し、発行者・宛先・期限を確かめる。署名の確認と認可は別。

    • 配ったアプリは解析される。 鍵やアクセスキーをアプリに置かず、秘密を使う処理はサーバで行う。証明書の検証は止めない。

    • 本物のデータも、再送されれば攻撃になる。 ノンス・時刻・使用済みの確認で、一度きりにする。

    さらに深く学ぶなら

    この記事の範囲を超えて、仕組みをもっと深く知りたい人向けの本です(試験対策の本ではありません)。

    • セッション管理や認証の脆弱性が生まれる原理と対策を、サンプルで確かめられる

    • OAuth 2.0の仕組みと、各構成要素の脆弱性と回避策を詳しく学べる

    関連記事

    2026年10月改訂:午後の出題例と記述の型を加え、セッション管理・Cookie・JWT・APIの保護・スマートフォンアプリ・リプレイ対策・パスワードの保存の節を新設し、ID連携・暗号・ログの詳細は関連する回へ移して、構成を見直しました。

     
     
    以下に記載の経歴を活かして、都庁の情報を発信します。 2012年に入都(Ⅰ類A採用※Ⅰ類Bも合格)し、主任試験合格後、管理職選考で口頭試問まで受験(記述考査・論文・勤務評定の成績が一定基準以上に到達)。 残念ながら最終合格には至らず、都庁での働き方に疑問を感じ、2021年度に退職

    あなたへのおすすめ