top | item 6574624

Node v0.10.21 Stable has critical security fix

132 points| aaronblohowiak | 12 years ago |blog.nodejs.org | reply

49 comments

order
[+] meritt|12 years ago|reply
HTTP Pipelining is designed so a client can send multiple requests without waiting on a response and then the server sends all the responses in order. This is helpful on high latency links since it can combine numerous HTTP requests into fewer packets. The exploit is the client never stops to read and just writes requests nonstop. Meanwhile node's http.Server continually populates a response buffer which is never consumed.

Node uses Stream[1] objects for reading/writing streams of data. The Stream object has a 'needsDrain' boolean which is set once its internal buffer surpasses the highWaterMark (defaults to 16kb). Subsequent writes will return false[2] and code should wait until the 'drain' event is emitted, signaling it's safe to write again[3]. The documentation even warns about this scenario:

> However, writes will be buffered in memory, so it is best not to do this excessively. Instead, wait for the drain event before writing more data.

http.Server[4] uses a writeable stream to send responses to a client. Until this patch[5] it was ignoring the needsDrain/highWaterMark status and just writing to the stream. It fills up the buffer of the writeable stream, far beyond the high water mark and eventually runs out of memory.

The patch resolves this by checking when needsDrain is set, then it stops writing and stops reading/parsing incoming data. It then waits until the 'drain' event is fired and then proceeds as normal.

[1] http://nodejs.org/api/stream.html

[2] http://nodejs.org/api/stream.html#stream_writable_write_chun...

[3] http://nodejs.org/api/stream.html#stream_event_drain

[4] http://nodejs.org/api/http.html#http_class_http_server

[5] https://github.com/joyent/node/commit/085dd30e93da67362f044a...

[+] xs_kid|12 years ago|reply
- No CVE.

- Distributions weren't contacted prior the release.

- Everyone can see the diff for the fix in the codebase.

- There are a PoC as test-case in the code.

- The release was done in the start of weekend when everyone in America is leaving the office and everyone in Europe is sleeping.

- A big part of the community is in two conferences right now.

IMHO that was the worst way to provide a security update.

[+] glenjamin|12 years ago|reply
The initial report was made publicly, including a proof of concept exploit, and is currently viewable via google cache. The censored issue report is referenced with a metasploit pull request containing code that can be used to exploit.

Given this, I'd say sooner is better than later.

It would be prudent to mention making your load balancer limit the number of requests than can be pipelined down a single connection should resolve any issue.

[+] ehsanu1|12 years ago|reply
While the security update protocol leaves something to be desired, the possibility of a DoS attach is not quite as bad as a vulnerability that leaks real information. If that were to happen, I'd hope all the steps you've outlined would be followed.
[+] microb|12 years ago|reply
What conferences?
[+] rmrfrmrf|12 years ago|reply
Boohoo; 1 or 2 Hubots and Ghost blogs might crash over the weekend. If you're as paranoid as you seem to be, you have someone on call to fix this and wouldn't have dared to have put such an untested technology out in the wild.
[+] jared314|12 years ago|reply
Apparently, a trivial DoS vulnerability for any Node serving HTTP:

https://groups.google.com/forum/#!msg/nodejs/NEbweYB0ei0/gWv...

The odd thing about non-disclosure in an open source project is: I can diff the code bases before and after the fix.

https://github.com/joyent/node/issues/6214

https://github.com/joyent/node/commit/085dd30e93da67362f044a...

And, they have a test script:

https://github.com/joyent/node/blob/085dd30e93da67362f044ad1...

[+] jph|12 years ago|reply
Node team: you're censoring the original ticket, which is unwise IHMO.

Your approach makes it impossible for an honest sysadmin to quickly find a way to block the attack using a firewall, but your approach doesn't stop an attacker from building an exploit based on the public commit.

Someone will come up with a proof of concept exploit quickly, and post it, probably here.

Please do the right thing: un-censor the GitHub ticket so we can understand what's happening.

[+] benatkin|12 years ago|reply
I'm sure they're well aware of this argument.

> Your approach makes it impossible for an honest sysadmin to quickly find a way to block the attack using a firewall, but your approach doesn't stop an attacker from building an exploit based on the public commit.

This is unfair. You're implying that sysadmins don't have access to programming resources, but that attackers do, without actually coming out and saying it.

Once it's expressed this way, it seems wrongheaded. The phrase "script kiddies" comes out of attackers doing a lot without knowing much about programming. There are many sysadmins who code, and many attackers who don't. Furthermore, I think attackers are more likely to act alone than sysadmins, who often have developers working with them whom they can ask to help.

Finally, as far as I can tell this is self-censorship. The people who created the ticket participated in the decision to hide it, or aren't loudly objecting to it. This type of "censorship" is not to be confused with more serious forms of censorship.

[+] xs_kid|12 years ago|reply
PoC is in codebase, it was published as a test-case for the fix.
[+] viraptor|12 years ago|reply
So what they did is: release a new version with security and other changes mixed, on Friday, and didn't provide any details so you can't check if you're vulnerable post-upgrade. They could really handle it a bit better.
[+] revelation|12 years ago|reply
They did provide plenty detail, just not to the guy on call who has to read the announcement and react quickly.

Meanwhile, they have the changelog and a test PoC for the one looking to exploit it.

[+] hackula1|12 years ago|reply
Give me the TLDR. Being Friday 9pm on the east coast, do I need to go home right now and upgrade my production servers?
[+] AndyKelley|12 years ago|reply
Nah. It's a DoS vulnerability, which, in general, you're always vulnerable to. It's just that this one can be done by a single person with relatively low bandwidth.
[+] xs_kid|12 years ago|reply
Yes, you should do it
[+] rdtsc|12 years ago|reply
Would putting node behind a proxy like nginx mitigate it?
[+] mathrawka|12 years ago|reply
With these nginx settings, it does mitigate it for me.

    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Protocol http;
    proxy_set_header Host $http_host;
    proxy_pass http://127.0.0.1:8000;
    proxy_redirect off;
[+] swills|12 years ago|reply
A CVE would be nice.
[+] mathrawka|12 years ago|reply
With a pretty default nginx setup as a proxy in front of node, it does not affect earlier versions for me.
[+] lazyjones|12 years ago|reply
Someone should benchmark the infamous for its speed node.js again after this (it should be slower)...