HTTP Server Security Vulnerability: Please upgrade to 0.6.17

tl;dr

  • A carefully crafted attack request can cause the contents of the HTTP parser’s buffer to be appended to the attacking request’s header, making it appear to come from the attacker. Since it is generally safe to echo back contents of a request, this can allow an attacker to get an otherwise correctly designed server to divulge information about other requests. It is theoretically possible that it could enable header-spoofing attacks, though such an attack has not been demonstrated.

  • Versions affected: All versions of the 0.5/0.6 branch prior to 0.6.17, and all versions of the 0.7 branch prior to 0.7.8. Versions in the 0.4 branch are not affected.
  • Fix: Upgrade to v0.6.17, or apply the fix in c9a231d to your system.

Details

A few weeks ago, Matthew Daley found a security vulnerability in Node's HTTP implementation, and thankfully did the responsible thing and reported it to us via email. He explained it quite well, so I’ll quote him here:

There is a vulnerability in node's http_parser binding which allows information disclosure to a remote attacker:

In node::StringPtr::Update, an attempt is made at an optimization on certain inputs (node_http_parser.cc, line 151). The intent is that if the current string pointer plus the current string size is equal to the incoming string pointer, the current string size is just increased to match, as the incoming string lies just beyond the current string pointer. However, the check to see whether or not this can be done is incorrect; "size" is used whereas "size_" should be used. Therefore, an attacker can call Update with a string of certain length and cause the current string to have other data appended to it. In the case of HTTP being parsed out of incoming socket data, this can be incoming data from other sockets.

Normally node::StringPtr::Save, which is called after each execution of http_parser, would stop this from being exploitable as it converts strings to non-optimizable heap-based strings. However, this is not done to 0-length strings. An attacker can therefore exploit the mistake by making Update set a 0-length string, and then Update past its boundary, so long as it is done in one http_parser execution. This can be done with an HTTP header with empty value, followed by a continuation with a value of certain length.

The attached files demonstrate the issue:

$ ./node ~/stringptr-update-poc-server.js &
[1] 11801
$ ~/stringptr-update-poc-client.py
HTTP/1.1 200 OK
Content-Type: text/plain
Date: Wed, 18 Apr 2012 00:05:11 GMT
Connection: close
Transfer-Encoding: chunked

64
X header:
 This is private data, perhaps an HTTP request with a Cookie in it.
0

The fix landed on 7b3fb22 and c9a231d, for master and v0.6, respectively. The innocuous commit message does not give away the security implications, precisely because we wanted to get a fix out before making a big deal about it.

The first releases with the fix are v0.7.8 and 0.6.17. So now is a good time to make a big deal about it.

If you are using node version 0.6 in production, please upgrade to at least v0.6.17, or at least apply the fix in c9a231d to your system. (Version 0.6.17 also fixes some other important bugs, and is without doubt the most stable release of Node 0.6 to date, so it's a good idea to upgrade anyway.)

I'm extremely grateful that Matthew took the time to report the problem to us with such an elegant explanation, and in such a way that we had a reasonable amount of time to fix the issue before making it public.

This entry was posted in vulnerability. Bookmark the permalink.

11 Responses to HTTP Server Security Vulnerability: Please upgrade to 0.6.17

  1. Bruno Windels says:

    Hey, what about node 0.4.x, is it not affected? That is what I understand from the post, but since it is not mentioned explicitly I thought I’d ask.

    • No, 0.4 is not affected. I add a tl;dr section just how stating this. Thanks 🙂

      Note that 0.4 has many problems of its own, but as far as we know, there are no security-related issues.

  2. I totally don’t intend to troll or sound ungrateful here — I’m just genuinely curious:

    Why publicize the details of the issue before production apps have a chance to upgrade? Why not first just announce the critical security update and recommend everyone upgrade, and wait maybe a week or so to share the details after?

    Regardless of this, great work to Matt and the team for finding and fixing this!

    • That’s a tricky question. The reasoning behind explaining the details of the issue is to give production apps the ability to determine whether they’re affected, how badly they’re affected, and whether it’s best to upgrade their node installation or refactor their app to reduce their exposure to the problem.

      That can’t be done without explaining exactly what the issue is. The alternative would be to contact all the affected users directly, but since we don’t keep track of who uses node, that’s not possible. And, since so many people do use it, it would be effectively the same as a public announcement.

    • Mike D. says:

      Even if you don’t disclose the details, the commits to fix the problem are public anyway, so it’s trivial to reverse engineer (which people do).

      • In this case, I’d argue that the commits don’t really give away too much about how the error happens, unless you knew what to go look for, and were willing to spend a lot of time reading the code through carefully.

        That’s why it’s so great that Matthew found it 🙂

  3. exortech says:

    What’s the checksum for the release package? It’s not mentioned in the changelog for this release.

    • Shasums:

      ad990b7076672ec3e9f4a05400d6059d3805b4a2  node-v0.6.17.msi
      0e3a5475b7ba622de31a0cf52b6ee830770e3d89  node-v0.6.17.pkg
      24974f8d07559e68dec2aaeb077dd52233b7d57e  node-v0.6.17.tar.gz
      fcc62d0b96517614f50c3967f29f6c8c73b27ec0  node.exe
      deb82c24884d5829a863cdb94b47d7b81b233c7a  node.exp
      e5b19a16599f4afda01142d6d15b03b5f57037b1  node.lib
      0eea33ea114610e241a8c1a9d8452e836e1f2624  node.pdb
      aafdc61ea34d2a5ae2f978bdd5ee818563568f47  npm-1.1.21.tgz
      d7efb888f8bb533449f6cb542021b4c32b889ac1  npm-1.1.21.zip
      eabe23e04a4dc483698572264a3671e35591cf0e  x64/node-v0.6.17.msi
      74ccb6a0e0264fee1d63544e604aba873e9dc9ee  x64/node.exe
      48fafa0b088f15112fbc69aa6f416f91dfe977fa  x64/node.exp
      6ec8b4e0485e4372fced9ff9a21a94ba99763c8c  x64/node.lib
      2a53ea21454779d487802e2a0a61aa32800adeb7  x64/node.pdb
  4. Are there known regressions in this release? I am seeing decreased stability in production over 0.6.16.

Leave a reply to Isaac Schlueter Cancel reply