Compare commits

...

2 Commits
2.4.0 ... 2.4.1

Author SHA1 Message Date
Damien Arrachequesne
e6b869738c chore(release): 2.4.1
Diff: https://github.com/socketio/socket.io/compare/2.4.0...2.4.1
2021-01-07 10:59:46 +01:00
Damien Arrachequesne
a169050947 revert: fix(security): do not allow all origins by default
This reverts commit f78a575f66.

This commit contains a breaking change which deviates from semver,
which we try to follow as closely as possible. That's why this change
is reverted and we will rather suggest users to upgrade to v3.

Related: https://github.com/socketio/socket.io/discussions/3741
2021-01-07 10:51:55 +01:00
5 changed files with 57 additions and 25 deletions

View File

@@ -1,3 +1,11 @@
## [2.4.1](https://github.com/socketio/socket.io/compare/2.4.0...2.4.1) (2021-01-07)
### Reverts
* fix(security): do not allow all origins by default ([a169050](https://github.com/socketio/socket.io/commit/a1690509470e9dd5559cec4e60908ca6c23e9ba0))
# [2.4.0](https://github.com/socketio/socket.io/compare/2.3.0...2.4.0) (2021-01-04)

View File

@@ -54,7 +54,7 @@ function Server(srv, opts){
this.parser = opts.parser || parser;
this.encoder = new this.parser.Encoder();
this.adapter(opts.adapter || Adapter);
this.origins(opts.origins || []);
this.origins(opts.origins || '*:*');
this.sockets = this.of('/');
if (srv) this.attach(srv, opts);
}
@@ -67,18 +67,31 @@ function Server(srv, opts){
*/
Server.prototype.checkRequest = function(req, fn) {
const origin = req.headers.origin;
var origin = req.headers.origin || req.headers.referer;
if (typeof this._origins === 'function') {
return this._origins(origin, fn);
}
// file:// URLs produce a null Origin which can't be authorized via echo-back
if ('null' == origin || null == origin) origin = '*';
if (!!origin && typeof(this._origins) == 'function') return this._origins(origin, fn);
if (this._origins.indexOf('*:*') !== -1) return fn(null, true);
if (origin) {
fn(null, this._origins.includes(origin));
} else {
const noOriginIsValid = this._origins.length === 0;
fn(null, noOriginIsValid);
try {
var parts = url.parse(origin);
var defaultPort = 'https:' == parts.protocol ? 443 : 80;
parts.port = parts.port != null
? parts.port
: defaultPort;
var ok =
~this._origins.indexOf(parts.protocol + '//' + parts.hostname + ':' + parts.port) ||
~this._origins.indexOf(parts.hostname + ':' + parts.port) ||
~this._origins.indexOf(parts.hostname + ':*') ||
~this._origins.indexOf('*:' + parts.port);
debug('origin %s is %svalid', origin, !!ok ? '' : 'not ');
return fn(null, !!ok);
} catch (ex) {
}
}
fn(null, false);
};
/**
@@ -224,7 +237,7 @@ Server.prototype.adapter = function(v){
Server.prototype.origins = function(v){
if (!arguments.length) return this._origins;
this._origins = typeof v === 'string' ? [v] : v;
this._origins = v;
return this;
};

2
package-lock.json generated
View File

@@ -1,6 +1,6 @@
{
"name": "socket.io",
"version": "2.4.0",
"version": "2.4.1",
"lockfileVersion": 1,
"requires": true,
"dependencies": {

View File

@@ -1,6 +1,6 @@
{
"name": "socket.io",
"version": "2.4.0",
"version": "2.4.1",
"description": "node.js realtime framework server",
"keywords": [
"realtime",

View File

@@ -73,7 +73,7 @@ describe('socket.io', function(){
it('should be able to set origins to engine.io', function() {
var srv = io(http());
srv.set('origins', 'http://hostname.com:*');
expect(srv.origins()).to.eql(['http://hostname.com:*']);
expect(srv.origins()).to.be('http://hostname.com:*');
});
it('should be able to set authorization and send error packet', function(done) {
@@ -262,6 +262,17 @@ describe('socket.io', function(){
});
});
it('should allow request when origin defined an the same is specified', function(done) {
var sockets = io({ origins: 'http://foo.example:*' }).listen('54015');
request.get('http://localhost:54015/socket.io/default/')
.set('origin', 'http://foo.example')
.query({ transport: 'polling' })
.end(function (err, res) {
expect(res.status).to.be(200);
done();
});
});
it('should allow request when origin defined as function and same is supplied', function(done) {
var sockets = io({ origins: function(origin,callback){
if (origin == 'http://foo.example') {
@@ -296,7 +307,7 @@ describe('socket.io', function(){
it('should allow request when origin defined as function and no origin is supplied', function(done) {
var sockets = io({ origins: function(origin,callback){
if (origin === undefined) {
if (origin == '*') {
return callback(null, true);
}
return callback(null, false);
@@ -309,6 +320,17 @@ describe('socket.io', function(){
});
});
it('should default to port 443 when protocol is https', function(done) {
var sockets = io({ origins: 'https://foo.example:443' }).listen('54036');
request.get('http://localhost:54036/socket.io/default/')
.set('origin', 'https://foo.example')
.query({ transport: 'polling' })
.end(function (err, res) {
expect(res.status).to.be(200);
done();
});
});
it('should allow request if custom function in opts.allowRequest returns true', function(done){
var sockets = io(http().listen(54022), { allowRequest: function (req, callback) {
return callback(null, true);
@@ -345,17 +367,6 @@ describe('socket.io', function(){
done();
});
});
it('should disallow any origin by default', (done) => {
io().listen('54025');
request.get('http://localhost:54025/socket.io/default/')
.set('origin', 'https://foo.example')
.query({ transport: 'polling' })
.end((err, res) => {
expect(res.status).to.be(403);
done();
});
});
});
describe('close', function(){