From 7a5913b8a66f65af4ff59a274ce7304d73d2ee63 Mon Sep 17 00:00:00 2001 From: einaros Date: Tue, 16 Aug 2011 07:46:57 +0200 Subject: [PATCH] Added http referrer verification to manager.js verifyOrigin + tests for origins setting --- lib/manager.js | 19 ++++++---- test/manager.test.js | 85 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 97 insertions(+), 7 deletions(-) diff --git a/lib/manager.js b/lib/manager.js index b5f32dbb10..ee2bf49271 100644 --- a/lib/manager.js +++ b/lib/manager.js @@ -866,7 +866,7 @@ Manager.prototype.handshakeData = function (data) { */ Manager.prototype.verifyOrigin = function (request) { - var origin = request.headers.origin + var origin = request.headers.origin || request.headers.referer , origins = this.get('origins'); if (origin === 'null') origin = '*'; @@ -878,14 +878,19 @@ Manager.prototype.verifyOrigin = function (request) { if (origin) { try { var parts = url.parse(origin); - - return - ~origins.indexOf(parts.host + ':' + parts.port) || - ~origins.indexOf(parts.host + ':*') || + var ok = + ~origins.indexOf(parts.hostname + ':' + parts.port) || + ~origins.indexOf(parts.hostname + ':*') || ~origins.indexOf('*:' + parts.port); - } catch (ex) {} + if (!ok) this.log.warn('illegal origin: ' + origin); + return ok; + } catch (ex) { + this.log.warn('error parsing origin'); + } + } + else { + this.log.warn('origin missing from handshake, yet required by config'); } - return false; }; diff --git a/test/manager.test.js b/test/manager.test.js index 6b8319f85c..93922d38db 100644 --- a/test/manager.test.js +++ b/test/manager.test.js @@ -472,6 +472,91 @@ module.exports = { }); }, + 'test that a referer is accepted for *:* origin': function (done) { + var port = ++ports + , io = sio.listen(port) + , cl = client(port); + + io.configure(function () { + io.set('origins', '*:*'); + }); + + cl.get('/socket.io/{protocol}', { headers: { referer: 'http://foo.bar.com:82/something' } }, function (res, data) { + res.statusCode.should.eql(200); + cl.end(); + io.server.close(); + done(); + }); + }, + + 'test that valid referer is accepted for addr:* origin': function (done) { + var port = ++ports + , io = sio.listen(port) + , cl = client(port); + + io.configure(function () { + io.set('origins', 'foo.bar.com:*'); + }); + + cl.get('/socket.io/{protocol}', { headers: { referer: 'http://foo.bar.com/something' } }, function (res, data) { + res.statusCode.should.eql(200); + cl.end(); + io.server.close(); + done(); + }); + }, + + 'test that erroneous referer is denied for addr:* origin': function (done) { + var port = ++ports + , io = sio.listen(port) + , cl = client(port); + + io.configure(function () { + io.set('origins', 'foo.bar.com:*'); + }); + + cl.get('/socket.io/{protocol}', { headers: { referer: 'http://baz.bar.com/something' } }, function (res, data) { + res.statusCode.should.eql(403); + cl.end(); + io.server.close(); + done(); + }); + }, + + 'test that valid referer port is accepted for addr:port origin': function (done) { + var port = ++ports + , io = sio.listen(port) + , cl = client(port); + + io.configure(function () { + io.set('origins', 'foo.bar.com:81'); + }); + + cl.get('/socket.io/{protocol}', { headers: { referer: 'http://foo.bar.com:81/something' } }, function (res, data) { + res.statusCode.should.eql(200); + cl.end(); + io.server.close(); + done(); + }); + }, + + 'test that erroneous referer port is denied for addr:port origin': function (done) { + var port = ++ports + , io = sio.listen(port) + , cl = client(port); + + io.configure(function () { + io.set('origins', 'foo.bar.com:81'); + }); + + cl.get('/socket.io/{protocol}', { headers: { referer: 'http://foo.bar.com/something' } }, function (res, data) { + res.statusCode.should.eql(403); + cl.end(); + io.server.close(); + done(); + }); + }, + 'test limiting the supported transports for a manager': function (done) { var port = ++ports , io = sio.listen(port)