Skip to content

Commit a9791c9

Browse files
bnoordhuisrvagg
authored andcommittedNov 24, 2018
src: make debugger listen on 127.0.0.1 by default
CVE-2018-12120 Backport of 8e7cbe2 to v6.x Prepared by Sam Roberts <vieuxtech@gmail.com> Original commit: Commit 2272052 ("net: bind to `::` TCP address by default") from April 2014 seems to have accidentally changed the default listen address from 127.0.0.1 to 0.0.0.0, a.k.a. the "any" address. From a security viewpoint it's undesirable to accept debug agent connections from anywhere so let's change that back. Users can override the default with the `--debug=<host>:<port>` switch. Fixes: #8081 PR-URL: #8106 Reviewed-By: James M Snell <jasnell@gmail.com> PR-URL: nodejs-private/node-private#148 Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: Sam Roberts <vieuxtech@gmail.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Rod Vagg <rod@vagg.org>
1 parent 4beba66 commit a9791c9

8 files changed

+40
-44
lines changed
 

‎src/debug-agent.cc

+1-1
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ Agent::~Agent() {
6767
}
6868

6969

70-
bool Agent::Start(const std::string& host, int port, bool wait) {
70+
bool Agent::Start(const char* host, int port, bool wait) {
7171
int err;
7272

7373
if (state_ == kRunning)

‎src/debug-agent.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ class Agent {
7575
typedef void (*DispatchHandler)(node::Environment* env);
7676

7777
// Start the debugger agent thread
78-
bool Start(const std::string& host, int port, bool wait);
78+
bool Start(const char* host, int port, bool wait);
7979
// Listen for debug events
8080
void Enable();
8181
// Stop the debugger agent

‎src/node.cc

+11-10
Original file line numberDiff line numberDiff line change
@@ -148,9 +148,9 @@ static const bool use_inspector = false;
148148
#endif
149149
static bool use_debug_agent = false;
150150
static bool debug_wait_connect = false;
151-
static std::string debug_host; // NOLINT(runtime/string)
151+
static std::string* debug_host; // coverity[leaked_storage]
152152
static int debug_port = 5858;
153-
static std::string inspector_host; // NOLINT(runtime/string)
153+
static std::string* inspector_host; // coverity[leaked_storage]
154154
static int inspector_port = 9229;
155155
static const int v8_default_thread_pool_size = 4;
156156
static int v8_thread_pool_size = v8_default_thread_pool_size;
@@ -3668,15 +3668,15 @@ static bool ParseDebugOpt(const char* arg) {
36683668
return true;
36693669
}
36703670

3671-
std::string* const the_host = use_inspector ? &inspector_host : &debug_host;
3671+
std::string** const the_host = use_inspector ? &inspector_host : &debug_host;
36723672
int* const the_port = use_inspector ? &inspector_port : &debug_port;
36733673

36743674
// FIXME(bnoordhuis) Move IPv6 address parsing logic to lib/net.js.
36753675
// It seems reasonable to support [address]:port notation
36763676
// in net.Server#listen() and net.Socket#connect().
36773677
const size_t port_len = strlen(port);
36783678
if (port[0] == '[' && port[port_len - 1] == ']') {
3679-
the_host->assign(port + 1, port_len - 2);
3679+
*the_host = new std::string(port + 1, port_len - 2);
36803680
return true;
36813681
}
36823682

@@ -3686,13 +3686,13 @@ static bool ParseDebugOpt(const char* arg) {
36863686
// if it's not all decimal digits, it's a host name.
36873687
for (size_t n = 0; port[n] != '\0'; n += 1) {
36883688
if (port[n] < '0' || port[n] > '9') {
3689-
*the_host = port;
3689+
*the_host = new std::string(port);
36903690
return true;
36913691
}
36923692
}
36933693
} else {
36943694
const bool skip = (colon > port && port[0] == '[' && colon[-1] == ']');
3695-
the_host->assign(port + skip, colon - skip);
3695+
*the_host = new std::string(port + skip, colon - skip);
36963696
}
36973697

36983698
char* endptr;
@@ -4093,17 +4093,18 @@ static void DispatchMessagesDebugAgentCallback(Environment* env) {
40934093
static void StartDebug(Environment* env, const char* path, bool wait) {
40944094
CHECK(!debugger_running);
40954095
if (use_inspector) {
4096+
const char* host = inspector_host ? inspector_host->c_str() : "127.0.0.1";
40964097
debugger_running = v8_platform.StartInspector(env, path,
4097-
inspector_host.c_str(),
4098+
host,
40984099
inspector_port, wait);
40994100
} else {
41004101
env->debugger_agent()->set_dispatch_handler(
41014102
DispatchMessagesDebugAgentCallback);
4103+
const char* host = debug_host ? debug_host->c_str() : "127.0.0.1";
41024104
debugger_running =
4103-
env->debugger_agent()->Start(debug_host, debug_port, wait);
4105+
env->debugger_agent()->Start(host, debug_port, wait);
41044106
if (debugger_running == false) {
4105-
fprintf(stderr, "Starting debugger on %s:%d failed\n",
4106-
debug_host.c_str(), debug_port);
4107+
fprintf(stderr, "Starting debugger on %s:%d failed\n", host, debug_port);
41074108
fflush(stderr);
41084109
return;
41094110
}

‎test/sequential/test-debug-host-port.js

+17-19
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ const assert = require('assert');
55
const spawn = require('child_process').spawn;
66

77
let run = () => {};
8-
function test(args, re) {
8+
function test(args, needle) {
99
const next = run;
1010
run = () => {
1111
const options = {encoding: 'utf8'};
@@ -14,34 +14,32 @@ function test(args, re) {
1414
proc.stderr.setEncoding('utf8');
1515
proc.stderr.on('data', (data) => {
1616
stderr += data;
17-
if (re.test(stderr)) proc.kill();
17+
if (stderr.includes(needle)) proc.kill();
1818
});
1919
proc.on('exit', common.mustCall(() => {
20-
assert(re.test(stderr));
20+
assert(stderr.includes(needle));
2121
next();
2222
}));
2323
};
2424
}
2525

26-
test(['--debug-brk'], /Debugger listening on (\[::\]|0\.0\.0\.0):5858/);
27-
test(['--debug-brk=1234'], /Debugger listening on (\[::\]|0\.0\.0\.0):1234/);
28-
test(['--debug-brk=127.0.0.1'], /Debugger listening on 127\.0\.0\.1:5858/);
29-
test(['--debug-brk=127.0.0.1:1234'], /Debugger listening on 127\.0\.0\.1:1234/);
30-
test(['--debug-brk=localhost'],
31-
/Debugger listening on (\[::\]|127\.0\.0\.1):5858/);
32-
test(['--debug-brk=localhost:1234'],
33-
/Debugger listening on (\[::\]|127\.0\.0\.1):1234/);
26+
test(['--debug-brk'], 'Debugger listening on 127.0.0.1:5858');
27+
test(['--debug-brk=1234'], 'Debugger listening on 127.0.0.1:1234');
28+
test(['--debug-brk=0.0.0.0'], 'Debugger listening on 0.0.0.0:5858');
29+
test(['--debug-brk=0.0.0.0:1234'], 'Debugger listening on 0.0.0.0:1234');
30+
test(['--debug-brk=localhost'], 'Debugger listening on 127.0.0.1:5858');
31+
test(['--debug-brk=localhost:1234'], 'Debugger listening on 127.0.0.1:1234');
3432

3533
if (common.hasIPv6) {
36-
test(['--debug-brk=::'], /Debug port must be in range 1024 to 65535/);
37-
test(['--debug-brk=::0'], /Debug port must be in range 1024 to 65535/);
38-
test(['--debug-brk=::1'], /Debug port must be in range 1024 to 65535/);
39-
test(['--debug-brk=[::]'], /Debugger listening on \[::\]:5858/);
40-
test(['--debug-brk=[::0]'], /Debugger listening on \[::\]:5858/);
41-
test(['--debug-brk=[::]:1234'], /Debugger listening on \[::\]:1234/);
42-
test(['--debug-brk=[::0]:1234'], /Debugger listening on \[::\]:1234/);
34+
test(['--debug-brk=::'], 'Debug port must be in range 1024 to 65535');
35+
test(['--debug-brk=::0'], 'Debug port must be in range 1024 to 65535');
36+
test(['--debug-brk=::1'], 'Debug port must be in range 1024 to 65535');
37+
test(['--debug-brk=[::]'], 'Debugger listening on [::]:5858');
38+
test(['--debug-brk=[::0]'], 'Debugger listening on [::]:5858');
39+
test(['--debug-brk=[::]:1234'], 'Debugger listening on [::]:1234');
40+
test(['--debug-brk=[::0]:1234'], 'Debugger listening on [::]:1234');
4341
test(['--debug-brk=[::ffff:127.0.0.1]:1234'],
44-
/Debugger listening on \[::ffff:127\.0\.0\.1\]:1234/);
42+
'Debugger listening on [::ffff:127.0.0.1]:1234');
4543
}
4644

4745
run(); // Runs tests in reverse order.

‎test/sequential/test-debug-port-cluster.js

+1-2
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,7 @@ child.stderr.setEncoding('utf8');
1616

1717
const checkMessages = common.mustCall(() => {
1818
for (let port = PORT_MIN; port <= PORT_MAX; port += 1) {
19-
const re = RegExp(`Debugger listening on (\\[::\\]|0\\.0\\.0\\.0):${port}`);
20-
assert(re.test(stderr));
19+
assert(stderr.includes(`Debugger listening on 127.0.0.1:${port}`));
2120
}
2221
});
2322

‎test/sequential/test-debug-port-from-cmdline.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,10 @@ function processStderrLine(line) {
3939
function assertOutputLines() {
4040
const expectedLines = [
4141
'Starting debugger agent.',
42-
'Debugger listening on (\\[::\\]|0\\.0\\.0\\.0):' + debugPort,
42+
'Debugger listening on 127.0.0.1:' + debugPort,
4343
];
4444

4545
assert.strictEqual(outputLines.length, expectedLines.length);
4646
for (let i = 0; i < expectedLines.length; i++)
47-
assert(RegExp(expectedLines[i]).test(outputLines[i]));
47+
assert(expectedLines[i].includes(outputLines[i]));
4848
}

‎test/sequential/test-debug-port-numbers.js

+3-5
Original file line numberDiff line numberDiff line change
@@ -52,10 +52,8 @@ function kill(child) {
5252

5353
process.on('exit', function() {
5454
for (const child of children) {
55-
const port = child.test.port;
56-
const one = RegExp(`Debugger listening on (\\[::\\]|0.0.0.0):${port}`);
57-
const two = RegExp(`connecting to 127.0.0.1:${port}`);
58-
assert(one.test(child.test.stdout));
59-
assert(two.test(child.test.stdout));
55+
const { port, stdout } = child.test;
56+
assert(stdout.includes(`Debugger listening on 127.0.0.1:${port}`));
57+
assert(stdout.includes(`connecting to 127.0.0.1:${port}`));
6058
}
6159
});

‎test/sequential/test-debug-signal-cluster.js

+4-4
Original file line numberDiff line numberDiff line change
@@ -61,11 +61,11 @@ process.on('exit', function onExit() {
6161

6262
const expectedLines = [
6363
'Starting debugger agent.',
64-
'Debugger listening on (\\[::\\]|0\\.0\\.0\\.0):' + (port + 0),
64+
'Debugger listening on 127.0.0.1:' + (port + 0),
6565
'Starting debugger agent.',
66-
'Debugger listening on (\\[::\\]|0\\.0\\.0\\.0):' + (port + 1),
66+
'Debugger listening on 127.0.0.1:' + (port + 1),
6767
'Starting debugger agent.',
68-
'Debugger listening on (\\[::\\]|0\\.0\\.0\\.0):' + (port + 2),
68+
'Debugger listening on 127.0.0.1:' + (port + 2),
6969
];
7070

7171
function assertOutputLines() {
@@ -77,5 +77,5 @@ function assertOutputLines() {
7777

7878
assert.strictEqual(outputLines.length, expectedLines.length);
7979
for (let i = 0; i < expectedLines.length; i++)
80-
assert(RegExp(expectedLines[i]).test(outputLines[i]));
80+
assert(expectedLines[i].includes(outputLines[i]));
8181
}

0 commit comments

Comments
 (0)
Please sign in to comment.