Skip to content
This repository was archived by the owner on Jan 27, 2026. It is now read-only.

Commit 8cfac2e

Browse files
committed
verify idekey if set on both sides and IP of connecting debug engine
1 parent c861017 commit 8cfac2e

4 files changed

Lines changed: 76 additions & 8 deletions

File tree

README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,20 +46,21 @@ point it to `./php/`. This will be used to serve PHP scripts for the example cli
4646
Configure *Xdebug* in *php.ini*:
4747

4848
xdebug.remote_enable=1
49+
xdebug.idekey=secret-key
4950
xdebug.remote_port=9000 // default
5051
xdebug.remote_host=localhost // default
5152
xdebug.remote_autostart=0 // default
5253

5354
Launch debug proxy server:
5455

55-
node ./example/server --port 9080 --php lib-phpdebug.localhost
56+
node ./example/server --port 9080 --php lib-phpdebug.localhost --idekey secret-key
5657

5758
Test
5859
----
5960

6061
The following will run a bunch of tests to cover all supported use-cases:
6162

62-
node ./test/all --port 9080 --php lib-phpdebug.localhost --skip-browser-tests
63+
node ./test/all --port 9080 --php lib-phpdebug.localhost --skip-browser-tests --idekey secret-key
6364

6465
TIP: If the example client is open at `http://localhost:9080/` it will show the progress of
6566
the tests if the `--skip-browser-tests` argument is omitted.

example/server.js

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,8 @@ var proxyServer = null,
7474
CLI.parse({
7575
port: [false, 'Listen on this port', 'number', PROXY_PORT],
7676
php: [false, 'Hostname for `../php/`', 'string', PHP_VHOST],
77-
test: [false, 'Test mode. Must be pinged to stay alive!']
77+
test: [false, 'Test mode. Must be pinged to stay alive!'],
78+
idekey: [false, 'Secret IDE key (xdebug.idekey)', 'string', null]
7879
});
7980

8081
CLI.main(function(args, options)
@@ -152,7 +153,15 @@ function startServer(options)
152153
NET: NET,
153154
XML2JS: XML2JS
154155
},
155-
xdebugPort: XDEBUG_PORT
156+
xdebugPort: XDEBUG_PORT,
157+
// Authorized IDE keys (only validated if set on both sides)
158+
idekeys: [
159+
options.idekey
160+
],
161+
// Authorized xdebug engines
162+
ips: [
163+
"127.0.0.1"
164+
]
156165
}));
157166

158167
proxyServer.hook({

lib/xdebug.js

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -473,6 +473,62 @@ console.log('status', packet);
473473
else
474474
if (self.status === "init")
475475
{
476+
// Authorize connecting debugger engine by IP if applicable
477+
if (self.options.ips && self.options.ips.length > 0)
478+
{
479+
var found = self.options.ips.indexOf(self.socket.remoteAddress);
480+
if (found === -1)
481+
{
482+
console.log("Error: IDEKEY mismatch!", self.socket.remoteAddress, self.options.ips);
483+
return;
484+
}
485+
}
486+
487+
// Fix the init packet. This is needed due to a bug in Xdebug. Fixing it in Xdebug
488+
// at this stage may break a lot of clients using the DBGP protocol.
489+
// 1) When debugging CLI scripts and environment variables are set to:
490+
// export XDEBUG_CONFIG="idekey=SESSION"
491+
// export XDEBUG_CONFIG="idekey=,session=SESSION"
492+
// export XDEBUG_CONFIG="idekey=IDEKEY,session=SESSION"
493+
// the `packet["@"].idekey` property is set to (respectively):
494+
// `packet["@"].idekey == "SESSION"`
495+
// `packet["@"].idekey == ",session=SESSION"`
496+
// `packet["@"].idekey == "IDEKEY,session=SESSION"`
497+
// 2) If debugging a MOD_APACHE script and cookies are set to:
498+
// `XDEBUG_SESSION_START=SESSION`
499+
// the `packet["@"].idekey` property is set to:
500+
// `packet["@"].idekey == "SESSION"`
501+
// and the `xdebug.idekey` php.ini config option is ignored.
502+
// Because we do not always get an `idekey` we need to restrict debug engines
503+
// from connecting by IP whitelist and/or use a hash for the session ID.
504+
505+
var idekey = packet["@"].idekey.split(",");
506+
packet["@"].idekey = undefined;
507+
if (idekey.length === 1) {
508+
packet["@"].session = idekey[0];
509+
} else {
510+
if (idekey.length != 2)
511+
throw new Error("`idekey` property in init packet does not have correct format (1)!");
512+
if (idekey[0]) {
513+
packet["@"].idekey = idekey[0];
514+
}
515+
var session = idekey[1].split("=");
516+
if (session.length != 2 || session[0] !== "session")
517+
throw new Error("`idekey` property in init packet does not have correct format (2)!");
518+
packet["@"].session = session[1];
519+
}
520+
521+
// If `idekey` is set we authorize it
522+
if (packet["@"].idekey && self.options.idekeys && self.options.idekeys.length > 0)
523+
{
524+
var found = self.options.idekeys.indexOf(packet["@"].idekey);
525+
if (found === -1)
526+
{
527+
console.log("Error: IDEKEY mismatch!", packet["@"].idekey, self.options.idekeys);
528+
return;
529+
}
530+
}
531+
476532
// 5.2 Connection Initialization
477533
// @see http://www.xdebug.org/docs-dbgp.php#id18
478534
self.id = "session-" + (++sessionCounter);

test/_helper.js

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -125,8 +125,9 @@ exports.getXdebugClientOptions = function()
125125
exports.debugScript = function(name, sessionName)
126126
{
127127
EXEC([
128-
'export XDEBUG_CONFIG="idekey=' + sessionName + '"',
129-
";",
128+
// export XDEBUG_CONFIG="idekey=,session=SESSION"
129+
// export XDEBUG_CONFIG="idekey=IDEKEY,session=SESSION"
130+
'export XDEBUG_CONFIG="' + 'idekey=' + ((serverInfo.idekey)?serverInfo.idekey:'') + ',session=' + sessionName + '";',
130131
"php " + PATH.dirname(PATH.dirname(module.id)) + "/php/scripts/" + name + ".php"
131132
].join(" "), function (error, stdout, stderr) {
132133
// console.log("[debugScript][stdout] " + stdout);
@@ -141,7 +142,8 @@ exports.ready = function(callback)
141142
CLI.parse({
142143
port: [false, 'Listen on this port', 'number', PROXY_PORT],
143144
php: [false, 'Hostname for `../php/`', 'string', PHP_VHOST],
144-
'skip-browser-tests': [false, 'Skip browser tests?', 'boolean', false]
145+
'skip-browser-tests': [false, 'Skip browser tests?', 'boolean', false],
146+
'idekey': [false, 'Secret IDE key (xdebug.idekey)', 'string', null]
145147
});
146148

147149
CLI.main(function(args, options)
@@ -212,7 +214,7 @@ function startServer()
212214

213215
ourServer = true;
214216

215-
var command = "node " + PATH.normalize(__dirname + "/../example/server --test --port " + serverInfo.port + " --php " + serverInfo.php);
217+
var command = "node " + PATH.normalize(__dirname + "/../example/server --test --idekey " + serverInfo.idekey + " --port " + serverInfo.port + " --php " + serverInfo.php);
216218

217219
console.log("Starting proxy server: " + command);
218220

0 commit comments

Comments
 (0)