431 HTTPステータスコード、別名「リクエストヘッダーフィールドが大きすぎる」は、クライアント側のエラーで、サーバーがリクエストのヘッダーフィールドが大きすぎるために処理を拒否することを示します。このエラーは、ヘッダーの合計サイズまたは単一のヘッダーフィールドが許可されたサイズを超えているために発生する可能性があります。
HTTP 431ステータスコードは、RFC 6585で初めて導入され、2012年4月に公開されました。これは、HTTP/1.1の追加応答を標準化し、当時の既存のステータスコードでカバーされていなかった問題に対処するための取り組みの一部でした。この特定のエラーコードの導入は、サーバーのセキュリティを強化し、大きなヘッダーを悪用するバッファーオーバーフローアタックなどの悪意のある攻撃を防ぐために重要でした。
HTTP 431エラーの理解
431エラーが発生した場合、それはサーバーが過度に大きいヘッダーフィールドのためにクライアントのリクエストをブロックしたことを意味します。各サーバーには、HTTPヘッダーフィールドの最大許容サイズに関する独自のポリシーがあり、これによりサービス拒否攻撃から保護されます。
HTTP 431エラーの一般的な症状
- リクエストヘッダーの合計サイズが大きすぎる: このエラーは、すべてのリクエストヘッダーの累積サイズが制限を超えた場合に発生します。
- 個々のヘッダーフィールドのサイズが大きすぎる: この場合、単一のヘッダーフィールドが大きすぎて処理できず、431エラーが発生します。
HTTP 431 エラーの一般的な原因
- 過剰なクッキー:過度に大きいまたは多くのクッキーがあると431エラーが発生することがあります。これは同じクッキーが複数回設定されたり、単一のリクエストまたはレスポンスに複数のクッキーが組み合わさったりした場合に起こり得ます。一般的なシナリオは、同じ
localhost
ポートを複数のプロジェクトで再利用し、それらのプロジェクトのクッキーをリクエストとともに送信することです。 - ヘッダーフィールドの不適切なキャッシュ:大きなヘッダーを正しくキャッシュしないと431エラーが発生することがあります。不適切なキャッシュはヘッダーのサイズを増加させ、バッファーオーバーフローを引き起こす可能性があります。
- 不必要または不適切にフォーマットされたリクエストヘッダー:HTTPヘッダーの過剰使用は、サーバーが設定したサイズ制限を超えるリクエストを引き起こし、431レスポンスが返されることがあります。また、ヘッダーが適切にフォーマットされていることを確認してください。
Referer
URLが長すぎると431がトリガーされることがあります。
431エラーを回避する方法
クッキーのクリア
定期的にクライアント側でクッキーをクリアし(Chrome開発者ツール > アプリケーション > クッキー)、サーバーで使用するクッキーの数を制限してください。
ヘッダーのキャッシュ
ヘッダーキャッシュを正しく実装するキャッシュされたヘッダーが実際のリクエストと圧縮レスポンスを反映するようにしてください。条件付きリクエストでETagに大きく依存している場合は、大きなETagがエラーの原因となるため、ETagを調整してください。
HTTPヘッダーを最小限に抑える
HTTPヘッダーを必要な情報のみに簡略化してください。特にAuthorization、Referer、User-Agentなどのヘッダーに冗長なメタデータを含めないようにしてください。
ヘッダーサイズの圧縮
時には、送信するヘッダーが少なすぎず、制御できない制約(例:JWTトークンに大量の情報がエンコードされている)によりヘッダーが肥大化していることがあります。ヘッダー圧縮はリクエストヘッダーのサイズを大幅に削減できます。HTTP/2やHTTP/3などのプロトコルを利用してください。これらはデフォルトでヘッダー圧縮をサポートしており、追加の設定なしにヘッダーのサイズを自動的に削減できます。
サーバーの最大ヘッダーサイズ制限への対応
HTTP仕様ではヘッダーサイズの制限は定義されていませんが、多くのサーバーには制限があります。以下は人気のあるウェブサーバー/ホストの制限です:
- Apache: 8K
- nginx: 4K-8K
- IIS: 8K-16K
- Tomcat: 8K-48K
- Node: (<13) – 8K; (>13) – 16K
- Cloudflare: ヘッダーごとに16K、合計32K
大多数のサーバーは何らかの形での設定を許可しており、サーバーソフトウェアの異なるバージョンによって制限が低い場合や高い場合があります。また、最新のドキュメントを確認して、これらの制限がリクエストの他の部分(例:クッキー)も含まれているか、それとも通常のヘッダーだけに適用されるかを確認する必要があります。
リクエストヘッダーサイズ制限の増加
時には、リクエストヘッダーサイズ制限を増加させる必要があるかもしれません。通常、これはサーバーのウェブコンソールまたはCLIから行うことができます。ローカルで開発している場合、この値を設定できるCLIフラグが通常あります。以下は、Node JSでリクエストヘッダーサイズ制限を設定するフラグです:
--max-http-header-size=16384
注意:ヘッダーサイズ制限の増加は慎重に行うべきです。より大きなヘッダーはより多くのメモリを消費し、パフォーマンスを低下させることがあります。
HTTP 431エラーレスポンスの送信方法
サーバーにリクエストヘッダーサイズ制限を決定させることに依存したくない場合や、APIエンドポイントごとにカスタムヘッダーサイズ制限を強制したい場合があるかもしれません。以下の手順に従って、独自の431エラーを送信する方法を学びましょう。
APIにリクエストヘッダーサイズ制限を組み込む
上述の通り、ホストとサーバーの組み合わせは自動的に制限を強制する可能性が高いです。独自のカスタムリクエストヘッダーサイズ制限機能をAPIに組み込むには、Node.jsのexpress
のようなライブラリを使用できます。以下は、リクエストヘッダーサイズに対する制限を有効にする方法を示す例です:
const express = require("express");
const app = express();
app.get("/", (req, res) => {
const headerSizeInBytes = JSON.stringify(req.headers).length;
const maxHeaderSizeInBytes = 2000; // example limit
if (headerSizeInBytes > maxHeaderSizeInBytes) {
res.status(431).send("Request Header Fields Too Large");
} else {
res.send("Hello World!");
}
});
app.listen(3000, () => {
console.log("Server is running on port 3000");
});
リクエストヘッダーの合計サイズと単一のヘッダーフィールド間のエラーレスポンスを区別する
HTTP 431エラーを処理する際には、以下の2つのシナリオ間でレスポンスを区別してください:
- リクエストヘッダーの合計サイズが大きすぎる:ヘッダーの累積サイズが大きすぎることを示すレスポンスを返します。
- 個別のヘッダーフィールドのサイズが大きすぎる:この場合、どの特定のヘッダーフィールドが許容サイズを超えているかを示すエラーレスポンスを提供します。
前のセクションの例を修正して、区別されたエラーレスポンスを達成します:
const express = require("express");
const app = express();
app.get("/", (req, res) => {
const headerSizeInBytes = JSON.stringify(req.headers).length;
const maxHeaderSizeInBytes = 2000; // example limit
const exceededHeaderField = Object.keys(req.headers).find(
(key) => req.headers[key].length > maxHeaderSizeInBytes * 0.1, // example individual field limit
);
if (exceededHeaderField) {
res
.status(431)
.send(
`Size of Individual Header Field '${exceededHeaderField}' Too Large`,
);
} else if (headerSizeInBytes > maxHeaderSizeInBytes) {
res.status(431).send("Total Size of Request Headers Too Large");
} else else {
res.send("Hello World!");
}
});
app.listen(3000, () => {
console.log("Server is running on port 3000");
});
HTTP 431レスポンスの例
ユーザーに対してProblem Details形式のAPIレスポンスを使用して応答することをお勧めします。
HTTP/1.1 431 Request Header Fields Too Large
Content-Type: application/problem+json
Content-Language: en
{
"type": "https://httpproblems.com/http-status/431",
"title": "Request Header Fields Too Large",
"detail": "Size of individual header field 'referer' too large",
"instance": "/account/12345/msgs/abc",
"trace": {
"requestId": "4d54e4ee-c003-4d75-aba9-e09a6d707b08"
}
}
ゲートウェイでリクエストヘッダーサイズの制限を処理させる
APIゲートウェイを使用している場合、リクエストパイプラインにポリシーを簡単に追加してこれを処理できます。Zuploを使用してこれを行う方法は以下の通りです:
ルートデザイナーでルートに移動し、リクエストパイプラインでポリシーを追加をクリックします。
ポリシーを選択モーダルでは、行いたい操作に応じて2つのオプションがあります。
- リクエスト全体のサイズをリクエストサイズ制限ポリシーで制限します。
- カスタムコードインバウンドポリシーを使用し、上記のコードサンプル(エクスプレスの部分を除く)をポリシーに接続されるTypeScriptモジュールにコピーします。
結論
HTTP 431エラーは、通常、過度に大きいリクエストヘッダーによって引き起こされます。ヘッダーを最適化し、必要に応じて圧縮し、APIでリクエストヘッダーサイズの制限を実装することで、このエラーに遭遇するのを避けることができます。
さらに、APIでヘッダーサイズの制限チェックを実装するのは簡単です。ほとんどのサーバーには既定の設定が含まれており、APIルート内で累積および個別のヘッダーレベルで自分自身で実装することもできます。
Source:
https://dzone.com/articles/understanding-the-http-431-error