LoginSignup
7
3

More than 3 years have passed since last update.

Node.jsのHTTPリクエストヘッダの最大サイズでハマった話

Last updated at Posted at 2019-12-04

現象

  • Node.js(v12.3.1)で立てたWebサーバにアクセスすると、時折HTTPリクエストに失敗する
  • Cookieを削除したり、ブラウザを再起動すると治ることもあるが、根本的な原因がわからない
サンプルコード
const http = require('http');

const server = http.createServer((req, res) => {
    res.writeHead(200, {'Content-Type': 'text/plain'});
    res.end('Hello World');
});

server.listen(8080);

原因

  • Node.jsの最大HTTPリクエストヘッダサイズのデフォルト値である8kBを越えるHTTPリクエストヘッダサイズを送信していたことが原因だった

  • Node.jsは、2018/11にDoS攻撃の脆弱性対応として、デフォルトのHTTPリクエストヘッダの最大サイズを変更前の80kBから8kB(8192Bytes)に変更する修正が加えられた

  • デフォルトでは、HTTPリクエストヘッダのサイズが8kBを越えるとソケットが強制破棄されて「431 Request Header Fields Too Large」を返す


$ npm start

> sample-nodejs-header-overflow@1.0.0 start /../../../sample-nodejs-header-overflow
> node index.js

// curlで8kB以上のHTTPリクエストを送信
ErrorCode:  HPE_HEADER_OVERFLOW
BytesParsed:  8559

// curlで8kB以上のHTTPリクエストを送信
ErrorCode:  HPE_HEADER_OVERFLOW
BytesParsed:  8559

// curlで8kB以上のHTTPリクエストを送信
ErrorCode:  HPE_HEADER_OVERFLOW
BytesParsed:  9085

対策

  • HTTPリクエストヘッダのサイズが超えた場合に起こるclientErrorイベントを補足して、ソケットが強制的に破棄されないようにエラーハンドリングを行う

const http = require('http');

const server = http.createServer((req, res) => {
    res.writeHead(200, {'Content-Type': 'text/plain'});
    res.end('Hello World');
});

server.on('clientError', (err, socket) => {
    console.log('ErrorCode: ', err.code);
    console.log('BytesParsed: ', err.bytesParsed);
    socket.end('HTTP/1.1 400 Bad Request\r\n\r\n');
});

server.listen(8080);

  • アプリケーション起動時に「--max-http-header-size」という起動オプションを設定して、Node.jsが受け取る最大のHTTPリクエストヘッダサイズを増やす
$ node --max-http-header-size=16384 index.js

おわりに

今回リクエストヘッダのサイズが8kBを越えた主な原因は、多数のCookieを使ってWebサーバにアクセスしていたことでした。
仕様上Cookieの数が多くなり、HTTPリクエストのサイズに不安がある場合は、エラーハンドリングを正しく実装して、起動オプションでNode.jsが受け取るHTTPリクエストサイズの最大値を上げておくと良いかと思います。

参考

7
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
3