CVE-2017-16025: Improper Authentication (CWE-287)
value: Nes is a websocket extension library for hapi. Hapi is a webserver framework. Versions below and including 6.4.0 have a denial of service vulnerability via an invalid Cookie header. This is only present when websocket authentication is set to `cookie`. Submitting an invalid cookie on the websocket upgrade request will cause the node process to error out.
CWE description: When an actor claims to have a given identity, the product does not prove or insufficiently proves that the claim is correct.
CVSS v3 base score: 5.9
Published: 2018-06-04T19:29Z
Repository: https://github.com/hapijs/nes
Language: JavaScript
Files changed: lib/socket.js, package.json, test/auth.js
Commit date: 2017-03-20 11:30:29 -0700
Commit message: Fix invalid cookie header. Closes #171

Diff: diff --git a/lib/socket.js b/lib/socket.js
index 261156e..5465eaa 100755
--- a/lib/socket.js
+++ b/lib/socket.js
@@ -535,11 +535,16 @@ internals.Socket.prototype._authenticate = function () {
     const cookies = this._ws.upgradeReq.headers.cookie;
     if (!cookies) {
         return;
     }
 
-    this._listener._connection.states.parse(cookies, (ignoreErr, state, failed) => {
+    this._listener._connection.states.parse(cookies, (err, state, failed) => {
+
+        if (err) {
+            this.auth._error = Boom.unauthorized('Invalid nes authentication cookie');
+            return;
+        }
 
         const auth = state[config.cookie];
         if (auth) {
             this.auth._error = this._setCredentials(auth.credentials, auth.artifacts);
         }
diff --git a/package.json b/package.json
index 22f5ec2..45c1a57 100755
--- a/package.json
+++ b/package.json
@@ -1,9 +1,9 @@
 {
   "name": "nes",
   "description": "WebSocket adapter plugin for hapi routes",
-  "version": "6.4.0",
+  "version": "6.4.1",
   "repository": "git://github.com/hapijs/nes",
   "main": "lib/index.js",
   "browser": "dist/client.js",
   "keywords": [
     "hapi",
@@ -29,11 +29,11 @@
   "devDependencies": {
     "babel-cli": "^6.1.2",
     "babel-preset-es2015": "^6.1.2",
     "code": "4.x.x",
     "hapi": "16.x.x",
-    "lab": "11.x.x"
+    "lab": "13.x.x"
   },
   "babel": {
     "presets": ["es2015"]
   },
   "scripts": {
diff --git a/test/auth.js b/test/auth.js
index 11681f3..6eaad48 100755
--- a/test/auth.js
+++ b/test/auth.js
@@ -390,10 +390,45 @@ describe('authentication', () => {
                     });
                 });
             });
         });
 
+        it('errors on invalid cookie', (done) => {
+
+            const server = new Hapi.Server();
+            server.connection();
+
+            server.register({ register: Nes, options: { auth: { type: 'cookie' } } }, (err) => {
+
+                expect(err).to.not.exist();
+
+                server.auth.scheme('custom', internals.implementation);
+                server.auth.strategy('default', 'custom', true);
+
+                server.route({
+                    method: 'GET',
+                    path: '/',
+                    handler: function (request, reply) {
+
+                        return reply('hello');
+                    }
+                });
+
+                server.start((err) => {
+
+                    expect(err).to.not.exist();
+                    const client = new Nes.Client('http://localhost:' + server.info.port, { ws: { headers: { cookie: '"' } } });
+                    client.connect((err) => {
+
+                        expect(err).to.be.an.error('Invalid nes authentication cookie');
+                        client.disconnect();
+                        server.stop(done);
+                    });
+                });
+            });
+        });
+
         it('overrides cookie path', (done) => {
 
             const server = new Hapi.Server();
             server.connection();
 

Vulnerable code:     this._listener._connection.states.parse(cookies, (ignoreErr, state, failed) => {
  "version": "6.4.0",
    "lab": "11.x.x"
Fixed code:     this._listener._connection.states.parse(cookies, (err, state, failed) => {

        if (err) {
            this.auth._error = Boom.unauthorized('Invalid nes authentication cookie');
            return;
        }
  "version": "6.4.1",
    "lab": "13.x.x"
        it('errors on invalid cookie', (done) => {

            const server = new Hapi.Server();
            server.connection();

            server.register({ register: Nes, options: { auth: { type: 'cookie' } } }, (err) => {

                expect(err).to.not.exist();

                server.auth.scheme('custom', internals.implementation);
                server.auth.strategy('default', 'custom', true);

                server.route({
                    method: 'GET',
                    path: '/',
                    handler: function (request, reply) {

                        return reply('hello');
                    }
                });

                server.start((err) => {

                    expect(err).to.not.exist();
                    const client = new Nes.Client('http://localhost:' + server.info.port, { ws: { headers: { cookie: '"' } } });
                    client.connect((err) => {

                        expect(err).to.be.an.error('Invalid nes authentication cookie');
                        client.disconnect();
                        server.stop(done);
                    });
                });
            });
        });