---
title: "API不正アクセス対策の実装手順：JPCERT注意喚起に沿うレート制限・認可・トークン失効"
url: "https://www.issoh.co.jp/tech/details/18346/"
published: 2026-10-15
updated: 2026-10-15
categories: ["セキュリティ"]
publisher: "株式会社一創"
---

# API不正アクセス対策の実装手順：JPCERT注意喚起に沿うレート制限・認可・トークン失効

JPCERT/CCが2026年10月8日に公開した注意喚起は、国内の大規模漏えい事案で使われた手口の1つとして、スマートフォンアプリを解析してAPIの入口とキーを特定し、画面からは呼べない内部APIを直接叩く攻撃を挙げました。本記事は、この「ケースB」の各手口に対して、API側で入れるべき実装を設定例とコードつきで並べます。対象はレート制限、管理APIの認可、APIキーとトークンの権限・有効期限・失効、エラー応答の統一、ログでの痕跡確認です。企業として何から点検するかの全体像は[IPA・JPCERTの注意喚起に沿った不正アクセス対策の点検手順](https://www.issoh.co.jp/column/details/18313/)で整理しており、本記事はそのAPI部分を実装者向けに掘り下げます。

## まとめ：API不正アクセス対策で先に実装する5項目と優先順位の判断基準

- **最初に管理APIの認可を閉じる**：権限変更・アカウント作成のエンドポイントに、トークンの有無だけでなくロールの検査が入っているかを確かめます。ケースBの被害はここから起きています。
- **認証系と全体で別々にレート制限をかける**：ログイン、パスワードリセット、SMS送信は全体の上限とは別に低い上限を設けます。nginxなら数行で入ります。
- **アプリに入れたキーは漏れる前提で権限を削る**：配布物に埋め込んだAPIキーで管理系APIが呼べる状態は、その日のうちに解消します。
- **トークンは短命にして失効手段を用意する**：漏えいが疑われたときに特定のトークンを止められない設計は、事故の長期化に直結します。
- **ログで痕跡を探してから強化に入る**：注意喚起のIPアドレスとUser-Agentでアクセスログを絞り込み、すでに侵入されていないかを先に確かめます。

## JPCERT注意喚起ケースBで観測されたAPI不正アクセスの手順と攻撃面

[JPCERT/CCの注意喚起（JPCERT-AT-2026-0030、10月9日更新）](https://www.jpcert.or.jp/at/2026/at260030.html)は、大量の情報漏えいにつながった攻撃をケースA〜Dに分けています。APIが主役になるのはケースBで、管理用APIへの不正なリクエストによって情報が書き換えられたと報告されています。すべての事案で同じ手口が使われたわけではない、と明記されている点は読み違えないでください。

### アプリ解析から管理用APIの直接呼び出しに至る4段階の攻撃手順

注意喚起の記述を実装側の視点で並べ直すと、攻撃は次の順に進みます。

1. 一般公開のスマートフォンアプリを解析し、APIのエンドポイントとキーを特定する
2. 画面操作では呼べない内部APIへリクエストを送り、ユーザー権限の変更や不正アカウントの作成を試みる
3. 認証ヘッダーを外したり、不正な形式の認証トークンを送ったりして、応答の違いから検証の甘い箇所を探す
4. NoSQLインジェクションによるブラインド探索でアカウント情報を特定する

これとは別に、他システムの侵害で盗まれたAPIキーが使われた例も挙がっています。観測されたUser-Agentには `curl/7.88.1` と `python-requests/2.34.2` が含まれていました。どの段階も、アプリの画面ではなくAPIそのものが攻撃面になっています。

### 画面に出ない内部APIと管理用エンドポイントを洗い出す棚卸しの手順

対策の前に、外から届くエンドポイントの一覧を作ります。アプリの画面から逆算すると、管理画面専用のAPIやバッチ用のAPIが一覧から漏れるからです。ルーティング定義、OpenAPIの定義ファイル、APIゲートウェイの設定、ロードバランサーのリスナーの4か所を突き合わせ、「インターネットから到達できるか」「どのロールが呼べるべきか」の2列を埋めます。

[OWASP API Security Top 10 2023のAPI5（機能レベル認可の不備）](https://api-security.owasp.org/editions/2023/en/0xa5-broken-function-level-authorization/)は、URLのパスだけでエンドポイントを一般用か管理用か判断してはいけないと注意しています。`/api/users` の下に管理機能がぶら下がっている例は珍しくありません。棚卸しはパス名ではなく処理内容で分類します。OWASPの10項目全体は[OWASP API Security Top 10 2023の全10項目の解説](https://www.issoh.co.jp/tech/details/4704/)にまとめています。

## nginxとAPI Gatewayで設定するレート制限と認証系APIの個別上限

JPCERT/CCは推奨対策の1番目に、単位時間あたりのリクエスト数の制限を挙げています。加えて、ログイン、パスワードリセット、SMS送信、検索のような悪用されやすい機能には個別の制限を設けるよう求めています。全体の上限だけでは、総当たりの速度を落とせても止めるところまでは届きません。

### nginxのlimit\_reqで送信元IP単位と認証系パス単位の上限を分ける設定

nginxでは [ngx\_http\_limit\_req\_module](https://nginx.org/en/docs/http/ngx%5Fhttp%5Flimit%5Freq%5Fmodule.html) を使います。拒否時のステータスは既定で503なので、`limit_req_status`（1.3.15以降）で429に変えます。429 Too Many Requestsは[RFC 6585](https://www.rfc-editor.org/info/rfc6585/)で定義されたステータスです。以下はAPI全体と認証系を別ゾーンで制限する例で、数値は出発点の目安です。

```
# http ブロック
limit_req_zone $binary_remote_addr zone=api_ip:10m  rate=10r/s;
limit_req_zone $binary_remote_addr zone=auth_ip:10m rate=5r/m;
limit_req_status 429;

server {
    # API 全体：1秒10件、瞬間的な20件の超過までは遅延なしで通す
    location /api/ {
        limit_req zone=api_ip burst=20 nodelay;
        proxy_pass http://app_backend;
    }
    # 認証系：1分5件。ログイン・パスワードリセット・SMS送信を個別に絞る
    location ~ ^/api/(login|password-reset|sms-send)$ {
        limit_req zone=auth_ip burst=3 nodelay;
        proxy_pass http://app_backend;
    }
}
```

本番へ入れる前に `limit_req_dry_run on;`（1.17.1以降）を付けると、実際には拒否せずに超過件数だけを数えられます。正規利用者が引っかかる値かどうかを1週間ほど見てから外す手順が安全です。送信元IP単位の制限は、攻撃者が送信元を分散させると効きにくいのが弱点です。認証後のAPIは、ユーザーIDやトークンをキーにした制限をアプリ側で併用します。方式ごとの得失は[APIレート制限の5方式の比較と429設計](https://www.issoh.co.jp/tech/details/16179/)で比べています。

### AWS API Gatewayのトークンバケットと利用量プランでの4段階の適用順

[AWS API Gatewayのスロットリング](https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-request-throttling.html)はトークンバケット方式で、上限を超えると429を返します。適用順は、利用量プランで設定したクライアント単位・メソッド単位の上限、ステージのメソッド単位の上限、リージョンごとのアカウント上限、AWS全体の上限の4段階です。アカウント上限は全APIで共有されるため、1つのAPIへの大量アクセスが他のAPIまで巻き込みます。

実装上の要点は、認証系のメソッドだけ低い上限を個別に設定することです。ステージ全体の値だけを入れて終わると、ログインAPIもデータ参照APIも同じ速度で叩けます。AWSは上限を「保証された天井ではなく目標値」と説明している点も押さえ、アプリ側の回数制限と二重にしておきます。ゲートウェイを置く構成の判断は[APIゲートウェイの役割と導入判断](https://www.issoh.co.jp/tech/details/13210/)を参照してください。

## 非公開の管理APIを含む全エンドポイントへの機能レベル認可の実装

ケースBでは、画面からは呼べない管理用APIへの直接のリクエストで権限変更や不正アカウント作成が試みられました。画面に出さないことは、守りにはなりません。JPCERT/CCは、非公開APIを含むすべてのエンドポイントでアクセス制御を行い、許可された利用者とHTTPメソッドだけを受け付けるよう求めています。

### OWASP API5に沿う既定拒否の認可ミドルウェアとロール判定の書き方

OWASP API5の防止策は「既定ですべて拒否し、明示的に許可したロールだけを通す」設計です。Express（Node.js）なら、ロールを引数に取るミドルウェアを全ルートに必須で付けます。

```
// 認証ミドルウェアが検証済みトークンから req.user を設定している前提
function requireRole(...roles) {
  return (req, res, next) => {
    if (!req.user) return res.status(401).json({ error: 'unauthorized' });
    if (!roles.includes(req.user.role)) return res.status(403).json({ error: 'forbidden' });
    next();
  };
}

// 管理用 API：画面に出ないエンドポイントほど明示的にロールを絞る
app.patch('/api/users/:id/role', requireRole('admin'), updateUserRole);
app.post('/api/users', requireRole('admin'), createUser);

// 一般 API でも他人のデータを返さないよう、所有者の照合をクエリ条件に含める
app.get('/api/orders/:id', requireRole('user', 'admin'), async (req, res) => {
  const order = await Order.findOne({ _id: req.params.id, userId: req.user.id });
  if (!order) return res.status(404).json({ error: 'not_found' });
  res.json(order);
});
```

付け忘れを防ぐには、起動時にルート一覧を走査して `requireRole` の無いルートがあれば起動を止めるテストを置きます。ロールの判定を通っても、他人のIDを指定すればデータが取れる状態（IDOR）は別の不備です。オブジェクト単位の認可は[認可バイパス（IDOR・権限昇格）をサーバ側で止める実装](https://www.issoh.co.jp/tech/details/16399/)で詳しく扱っています。

### 管理APIを公開経路から外すネットワーク分離と許可メソッドの405応答

認可を入れたうえで、管理用APIをそもそもインターネットから届かない場所に置くと、認可の実装漏れが1つあっても即座に事故へつながる状態にはならない、という二重の守りになります。具体的には、管理用APIを別ホスト名・別ロードバランサーに分け、社内ネットワークかVPN経由の送信元だけを許可する形です。nginxで同居させるなら、管理用のlocationに `allow` と `deny all;` を書きます。

[OWASP REST Security Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/REST%5FSecurity%5FCheat%5FSheet.html)は、許可するHTTPメソッドを列挙し、それ以外を405 Method Not Allowedで拒否するよう勧めています。読み取り専用のはずのエンドポイントが `PUT` や `DELETE` を受け付けていないか、棚卸しの表に1列足して確かめてください。

## APIキーとトークンの最小権限・有効期限設計とRFC 7009による失効

JPCERT/CCの推奨対策のうち3項目はトークンに関するものです。必要最小限の権限、長期間有効なトークンの回避、不要または漏えいが疑われるトークンの速やかな無効化です。3つとも、漏れることを前提に被害の範囲と期間を縮める考え方でそろっています。

### アプリに埋め込んだAPIキーは解析で抜かれる前提での権限の絞り方

スマートフォンアプリやJavaScriptに入れたキーは、難読化しても取り出せます。OWASP REST Security Cheat Sheetも、機密性の高いリソースの保護をAPIキーだけに頼らないよう書いています。配布物に入れてよいのは、利用者を識別して回数を数えるためのキーまでです。データの読み書きは、ログインした利用者ごとに発行するトークンと、サーバ側の認可で守ります。

点検では、アプリに入っているキーで呼べるAPIを一覧にし、管理系や他人のデータに届くものが1つでもあれば即日でキーの権限を削ります。キーをURLのクエリに載せている場合はアクセスログに残るため、ヘッダーへ移すのが先決です。発行・保管・ローテーションの運用は[APIキー管理の発行・保管・失効とローテーションの実装](https://www.issoh.co.jp/tech/details/16300/)にまとめています。

### アクセストークンの短命化とリフレッシュトークンのローテーション設計

OAuth 2.0のセキュリティ実践をまとめた[RFC 9700（2025年1月）](https://www.rfc-editor.org/info/rfc9700/)は、アクセストークンの権限を必要最小限に制限すべき（SHOULD）とし、宛先のリソースサーバーを限定することも勧めています。スマートフォンアプリのような公開クライアントのリフレッシュトークンは、送信者拘束かローテーションのどちらかが必須（MUST）です。

実務上の出発点は、アクセストークンを数分〜1時間程度にし、リフレッシュトークンは使うたびに新しいものへ交換する設計です。古いリフレッシュトークンが再提示されたら、盗用とみなして同じ系列のトークンをまとめて失効させます。寿命の決め方は[リフレッシュトークンのローテーションと寿命設計](https://www.issoh.co.jp/tech/details/16409/)で扱っています。

### 漏えい時に即日止めるためのRFC 7009失効エンドポイントの呼び出し例

トークンを止める手段は、事故が起きてから作っても間に合いません。[RFC 7009（OAuth 2.0 Token Revocation）](https://www.rfc-editor.org/info/rfc7009/)は失効エンドポイントの形式を定めています。クライアント認証を付けてPOSTし、本文に `token` と任意の `token_type_hint` を入れます。

```
curl -X POST https://auth.example.com/oauth/revoke \
  -u "$CLIENT_ID:$CLIENT_SECRET" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "token=$REFRESH_TOKEN" \
  -d "token_type_hint=refresh_token"
```

RFC 7009では、失効に成功したときだけでなく無効なトークンを受け取ったときもHTTP 200を返します。応答から「そのトークンが有効だったか」を読み取らせないためです。リフレッシュトークンを失効させたら、同じ認可に基づくアクセストークンも無効化すべき（SHOULD）とされています。自前でJWTを発行している構成なら、`jti` を失効リストに入れて検証時に照合する処理と、署名鍵を入れ替えて全トークンを一斉に無効化する手順の2つを用意しておきます。

## 認証トークンの応答差とNoSQLインジェクションによる探索を塞ぐ実装

ケースBでは、ヘッダーの有無や形式の崩れたトークンを送って応答の違いを確かめる挙動が観測されています。応答の差は、攻撃者にとって検証ロジックの地図になります。

### トークン欠落・形式不正・期限切れを同じ401で返すエラー応答の統一

OWASP REST Security Cheat Sheetは、エラーメッセージを汎用にして失敗の詳細を必要以上に明かさないよう勧めています。認証の失敗は理由を問わず同じステータス、同じ本文、近い応答時間で返すのが原則です。「トークン形式が不正」「署名が一致しない」「期限切れ」を出し分けると、どの検証が実装されていないかを外から推測できます。

```
// 認証の失敗理由はサーバのログにだけ残し、応答は1種類に統一する
function authenticate(req, res, next) {
  try {
    req.user = verifyAccessToken(req.get('Authorization'));
    next();
  } catch (e) {
    logger.warn({ reason: e.code, path: req.path, ip: req.ip });
    res.status(401).json({ error: 'unauthorized' });
  }
}
```

期限切れだけはクライアントがリフレッシュの判断に使うため区別したい、という要件は出ます。その場合も本文の文言は変えず、`WWW-Authenticate` ヘッダーの `error="invalid_token"` に寄せる程度にとどめます。

### クエリ演算子の混入を止める入力の型検査とNoSQLの条件の組み立て

MongoDB系のNoSQLインジェクションは、JSONの本文に文字列の代わりに `{"$ne": null}` のようなオブジェクトを入れ、検索条件を書き換える手口が典型です。ブラインド探索では `$regex` で1文字ずつ一致を確かめ、応答の差からメールアドレスやパスワードのハッシュを割り出します。

防ぎ方は単純で、条件に入れる値の型を先に確かめます。メールアドレスなら `typeof email === 'string'` でなければ400で返し、オブジェクトや配列を条件に渡しません。リクエスト本文のスキーマ検証（JSON Schemaなど）を全エンドポイントの入口に置けば、型の検査を個別に書き忘れる余地が減ります。`$` で始まるキーを本文から取り除く処理も併用すると二重になります。

## アクセスログでケースBの痕跡を確かめるUser-Agentと送信元の抽出手順

強化の前に、すでに侵入されていないかを確かめます。異常が見つかった場合、ログは調査の証拠になるため、強化作業でサーバを入れ替える前に退避しておきます。

### 注意喚起のIPアドレスとUser-Agentでnginxログを絞り込むコマンド例

注意喚起に掲載された送信元IPアドレスを1行1件でテキストファイルに保存し（掲載表記の `[.]` は `.` に戻す）、nginxのcombined形式のログと照合します。

```
# 注意喚起の送信元IPからのアクセス（ioc_ips.txt に1行1件）
grep -F -f ioc_ips.txt /var/log/nginx/access.log*

# 管理系・内部系APIへの curl / python-requests からの呼び出し
grep -E '"(curl|python-requests)/' /var/log/nginx/access.log* | grep -E ' /api/(admin|internal|users)'

# 401・403 を多く受けた送信元の上位20件（$9 がステータス）
awk '$9 == 401 || $9 == 403 {print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -20
```

注意喚起は、掲載したIPアドレスが調査時点で正規の利用に使われている可能性にも触れています。一致しただけで侵害と決めつけず、その送信元が呼んだエンドポイントと結果のステータスを時系列で追ってください。`curl` や `python-requests` も、自社の監視や連携バッチが使っていることがあります。ログから痕跡を読む手順の全体は[セキュリティログ分析の手法とコマンド例](https://www.issoh.co.jp/tech/details/2788/)を参照してください。

### 権限変更とアカウント作成のAPI呼び出しを監査ログに残す項目の設計

Webサーバのアクセスログには、誰の権限を何に変えたかまでは残りません。ケースBの被害を後から特定できるよう、権限変更・アカウント作成・メールアドレス変更・APIキー発行の4種類は、アプリ側で監査ログを書きます。記録する項目は、実行者のユーザーID、対象のユーザーID、変更前後の値、送信元IP、User-Agent、トークンの識別子（`jti` など）、時刻です。

保存先は、アプリのDBとは別の書き込み専用の場所にします。アプリのDBを書き換えられる攻撃者に、監査ログまで消されないようにするためです。保持期間は、少なくとも直近数か月の遡りに足りる長さを確保します。

## 自社で直せる範囲と脆弱性診断を外部へ依頼する条件・見送ってよい施策

ここまでの実装をすべて同時に進める必要はありません。ケースBを前提にした着手順と、今は手を付けなくてよいものを言い切ります。

### 実装の優先順位はレート制限より先に管理APIの認可から着手する理由

最優先は管理APIの認可です。レート制限は攻撃の速度を落とすだけで、権限変更APIが1回の呼び出しで通るなら防げません。ケースBで実際に起きたのは書き換えであり、件数の多さではなく1回の成功が被害を生みました。順番は、①管理APIの認可とネットワーク分離、②アプリ埋め込みキーの権限削減、③トークンの失効手段、④認証系のレート制限、⑤応答の統一と監査ログ、とします。①と②は数日で着手でき、③以降は設計変更を伴うため計画を立てて進めます。

### WAFの追加購入やAPIゲートウェイ移行を今月は見送ってよい場面

WAFの追加契約やAPIゲートウェイへの移行は、今月の対応としては見送って構いません。WAFはシグネチャに合う攻撃は止めますが、正しい形式のリクエストで権限を変えるケースBの手口は通します。ゲートウェイの移行は数週間〜数か月かかり、その間に認可の穴は残ります。nginxやロードバランサーで入れられるレート制限と送信元制限で当面をしのぎ、認可の修正を先に終えるのが筋です。WAFとゲートウェイの検討は、①〜③が終わってから改めて行います。

### アプリAPIの診断を外部の専門家へ依頼すべき条件と依頼時に渡す資料

次のいずれかに当てはまるなら、自社だけで点検を終えず外部の診断を入れます。アプリが公開されていて内部APIの全体像を社内の誰も把握していない場合、開発を外部に委託しておりソースコードを読める担当者がいない場合、ログで注意喚起の痕跡に一致するアクセスが見つかった場合です。最後の場合は診断より先にインシデント対応として調査を依頼します。

依頼時には、公開しているアプリのバイナリ、OpenAPIの定義かエンドポイント一覧、テスト用のアカウントをロールごとに1つずつ渡すと、ケースBと同じ観点（アプリ解析から内部APIへの到達）での検査が可能です。一創では[脆弱性診断・セキュリティ診断](https://www.issoh.co.jp/service/system/vulnerability/)として、Webアプリケーションとスマートフォンアプリが呼ぶAPIの検査と、見つかった不備の改修までを受けています。診断の種類と費用の目安は[脆弱性診断の種類・費用相場と外注時の判断基準](https://www.issoh.co.jp/column/details/13101/)で比べられます。

## よくある質問

API不正アクセス対策の実装で、開発現場からよく挙がる疑問に答えます。

### APIキーを難読化すればアプリに埋め込んでも安全ですか？

安全にはなりません。難読化は取り出すまでの手間を増やすだけで、アプリの実行時にはキーが復元されて通信に乗るため、通信を観察すれば取得できます。JPCERT/CCの注意喚起でも、公開アプリの解析からキーが特定された手口が報告されています。埋め込むキーは利用者の識別と回数制限のための用途に限り、データの読み書きはログイン後に利用者ごとに発行するトークンとサーバ側の認可で守ってください。

### レート制限の数値はどう決めればよいですか？

正規利用の実測から決めます。アクセスログで利用者1人あたりの1分間のリクエスト数を集計し、上位の正規利用者が引っかからない値に余裕を持たせて設定します。nginxなら `limit_req_dry_run on;` で拒否せずに超過件数だけを数えられるため、1週間ほど観測してから本番の値を決める手順が安全です。ログインやSMS送信は人の操作速度を基準に、1分あたり数件程度まで絞って問題が出ないことがほとんどです。

### JWTを使っているとトークンを失効できないのではありませんか？

JWTは単体では状態を持たないため、署名が正しく期限内なら検証を通ります。失効させたいときは、アクセストークンの寿命を短くしたうえで、リフレッシュトークンをサーバ側で管理して止める方法が基本です。個別のアクセストークンを即時に止める必要があれば、`jti` を失効リストに入れて検証時に照合します。全体を止める最終手段として、署名鍵を入れ替えて発行済みトークンを一斉に無効化する手順も用意しておきます。

### 社内向けの管理画面のAPIも対策の対象になりますか？

対象になります。JPCERT/CCは、管理用システムやBIツールのように不特定多数の利用を想定しないシステムも点検の対象に含めるよう勧めています。ケースBで狙われたのも、画面からは呼べない管理用のAPIでした。社内向けであっても、インターネットから届く場所に置かれていれば攻撃面です。届かない場所へ移すか、ロールの検査を必ず通す実装にしてください。

### OWASP API Security Top 10のどの項目から対応すべきですか？

ケースBを前提にするなら、API5（機能レベル認可の不備）とAPI1（オブジェクトレベル認可の不備）から着手します。権限変更や他人のデータ取得という被害に直結するためです。次にAPI2（認証の不備）でトークンの検証と失効を、API4（リソース消費の制限なし）でレート制限を見直します。10項目を並列に進めると認可の修正が後回しになりがちなので、被害の大きさで順番を付けてください。

## 関連記事

- [APIセキュリティとは？OWASP API Top 10の主要リスクと実装対策を解説](https://www.issoh.co.jp/tech/details/13793/)：APIセキュリティの全体像。本記事はその中から不正アクセスの手口に対応する実装を絞り込んでいます。
- [APIレート制限（レートリミット）とは？5方式の比較と429設計・分散実装](https://www.issoh.co.jp/tech/details/16179/)：トークンバケットや固定ウィンドウなど方式ごとの得失と、複数台構成での実装を比べています。
- [OWASP API Security Top 10 2023の全10項目](https://www.issoh.co.jp/tech/details/4704/)：本記事で触れたAPI1・API2・API4・API5を含む10項目の解説です。
- [セイコーマートの不正アクセスと57万人の会員情報｜アプリAPIの認可を点検する手順](https://www.issoh.co.jp/tech/details/18093/)：アプリのAPIを入口にした実際の事案と、認可の点検手順を扱っています。
- [リフレッシュトークンとは？トークンローテーションの仕組みと更新フロー・寿命設計](https://www.issoh.co.jp/tech/details/16409/)：本記事の短命化とローテーションの設計をさらに掘り下げています。

---

出典: [API不正アクセス対策の実装手順：JPCERT注意喚起に沿うレート制限・認可・トークン失効](<https://www.issoh.co.jp/tech/details/18346/>)（株式会社一創）
