API のヘッダーとアクセス数制限
OWASP Secure Headers Project・RFC 6648・IETF RateLimit Header Fields を 取得して書いたもの。この2つの主題は推奨が動いたため、原典に当たり直してある。
エンドポイント・レスポンス・ステータスコードの設計は API 設計 にある。
ヘッダー
この節は 2026-08-31 に OWASP Secure Headers Project を取得して更新した。 元のノートにあった推奨のうち2つが、現在では非推奨になっていたため。
| 目的 | ヘッダ |
|---|---|
| HTTPS の強制 | Strict-Transport-Security: max-age=63072000; includeSubDomains |
| 読み込み先の制限 | Content-Security-Policy: script-src 'self' |
| MIME 推測の禁止 | X-Content-Type-Options: nosniff |
| クリックジャッキング対策 | X-Frame-Options: deny |
| リファラの制御 | Referrer-Policy: no-referrer |
| クロスドメインポリシーの制限 | X-Permitted-Cross-Domain-Policies: none |
| ログアウト時のデータ削除 | Clear-Site-Data: "cache","cookies","storage" |
| キャッシュによる露出の防止 | Cache-Control: no-store, max-age=0 |
| DNS 先読みの停止 | X-DNS-Prefetch-Control: off |
| ブラウジング文脈の隔離 | Cross-Origin-Opener-Policy: same-origin |
| 資源の保護 | Cross-Origin-Resource-Policy: same-origin |
| 埋め込みの制限 | Cross-Origin-Embedder-Policy: require-corp |
Content-Security-Policy は、読み込んだ HTML 内の IMG・SCRIPT・LINK 要素などについて、
どこからの読み込みを許可するかを指定するヘッダ。
Permissions-Policy(旧 Feature-Policy)はまだ策定中。
-Report-Only 系があるものは、遮断せずに違反だけ報告させて試せる。
Content-Security-Policy-Report-Only など。
独自ヘッダに X- を付けない
新しく作るヘッダに X- を付けない(RFC 6648)。
新しいパラメータを作る者は、名前に
X-やそれに類する接頭辞を付けるべきではない。
理由が実際に起きたことに基づいている。 実験的なパラメータは、そのうち事実上の標準になる。 後から標準化されると同じものに2つの名前が並び、 古い実装が元の名前を使い続けるので、新しい実装は両方を支え続けることになる。
上の X-RateLimit-* から RateLimit への移行が、まさにこの形。
受け取る側の規則もある。
X- が付いているかどうかだけで、標準か非標準かを判断してはならない。
既にある X- ヘッダを使うな、という話ではない。
RFC は既存の非標準パラメータについては何も推奨していない。
だから X-Content-Type-Options や X-Frame-Options は、そのまま使う。
使ってはいけないもの
元のノートに載っていた推奨が、現在では反転している。
| ヘッダ | 現状 |
|---|---|
X-XSS-Protection | 非推奨。有効にすると、かえってクライアント側に問題を持ち込みうる。 0 にして無効化し、CSP で守る |
Public-Key-Pins(HPKP) | 非推奨。下記 |
Expect-CT | ほぼ役目を終えた。2018年5月以降の証明書は既定で SCT に対応している |
Feature-Policy | Permissions-Policy に置き換わった |
Pragma | HTTP/1.0 の遺物。Cache-Control を使う |
X-XSS-Protection: 1; mode=block は、長く「XSS 対策」として書かれてきた。
現在はそう扱わない。古い資料をそのまま写すと、この種の反転を取り込む。
SSL 証明書が偽造されていないかのチェック
証明書の内容のハッシュ値と有効期限を記録しておき、以降のアクセスでそのハッシュ値を使って 証明書が正しいものか判別する仕組み。
Public-Key-Pins: max-age=2592000;
pin-sha256="E9CZ9INDbd+2eRQozYqqbQ2yXLVKB9+xcprMF+44U1g=";
pin-sha256="LPJNul+wow4m6DsqxbninhsWHlwfp0JecwQzYpOLmCQ="
この方式は使わない。 主要ブラウザが対応をやめている。
やめた理由が仕組みそのものにある。 鍵を失ったり、誤った値を固定したりすると、自分のドメインに自分で到達できなくなる (HPKP Suicide)。攻撃者に固定値を仕込まれる形の脅迫も想定された。 間違えたときに自力で回復できない設計だった。
記録として残すが、新規に採用するものではない。
Set-Cookie とセキュリティ
| 属性 | 効果 |
|---|---|
Secure | そのクッキーは HTTPS の通信のときだけサーバーに送り返される |
HttpOnly | そのクッキーは HTTP の通信でのみ使われ、JavaScript からアクセスできない。XSS でセッション情報が読み出されるのを防げる |
SameSite と __Host- プレフィックスを含めた全体は
セッション管理にある。
アクセス数制限
この節は 2026-08-31 に IETF の RateLimit Header Fields を取得して更新した。
X-RateLimit-*の3本組は標準化の過程で2本に置き換わっている。
標準化されたヘッダ
2つある。役割が違う。
| ヘッダ | 何を伝えるか | 変化 |
|---|---|---|
RateLimit-Policy | どういう制限方針か(静的・準静的) | 応答をまたいで一定であるべき |
RateLimit | いまの残量(動的) | リクエストごとに変わりうる |
RateLimit-Policy: "burst";q=100;w=60,"daily";q=1000;w=86400
RateLimit: "default";r=50;t=30
RateLimit-Policy の項目は q(割り当て量)が必須で、
qu(単位。既定は requests)、w(窓の秒数)、pk(分割キー)が任意。
RateLimit は r(残量)が必須で、t(リセットまでの秒数)と pk が任意。
残量が正でも、次が通る保証にはならない。 仕様がそう明言している。
なぜ置き換わったか
古い3本組は名前が同じでも意味が揃っていなかった。
X-RateLimit-Reset が、ある実装では窓が切れるまでの秒数、
別の実装ではミリ秒や UNIX 時刻や日時を指していた。
同じ名前で違うものを返すので、クライアントが一律に解釈できない。
これは結合の度合いでいう意味の連鎖そのもので、 「複数の要素が、ある値の意味について合意していること」が成立していなかった。
状態コードとの関係
HTTP/1.1 429 Too Many Requests
Retry-After: 3600
429 は例示であって必須ではない。 403 を使う実装もある。
サーバーは状態コードによらず RateLimit を返してよい。
両方返す場合、クライアント側では Retry-After が優先される。
サーバー側は、RateLimit の t が Retry-After と同じ時点を指すようにする。
実装
利用者やアプリケーションごとのアクセス回数を数えておく必要があり、 通常は Redis などの KVS に記録する。
同じ問題への別の入口が分散システムにある。 レートリミットは、過負荷を受け止める手段の1つ。
関連
- API 設計 — エンドポイントとレスポンスの設計
- Web API 設計の要点 — 同じ主題を API Gateway での設定に落とした版
- 分散システム — レートリミットは過負荷を受け止める手段の1つ