VYPR
High severity7.5NVD Advisory· Published Apr 13, 2016· Updated May 6, 2026

CVE-2016-2515

CVE-2016-2515

Description

Hawk before 3.1.3 and 4.x before 4.1.1 allow remote attackers to cause a denial of service (CPU consumption or partial outage) via a long (1) header or (2) URI that is matched against an improper regular expression.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
hawknpm
>= 4.0.0, < 4.1.14.1.1
hawknpm
< 3.1.33.1.3

Affected products

2
  • Hawk Project/Hawk2 versions
    cpe:2.3:a:hawk_project:hawk:3.1.2:*:*:*:*:*:*:*+ 1 more
    • cpe:2.3:a:hawk_project:hawk:3.1.2:*:*:*:*:*:*:*
    • cpe:2.3:a:hawk_project:hawk:4.1.0:*:*:*:*:*:*:*

Patches

1
0833f99ba645

Fix minor DoS attack on long headers or uris. Closes #168

https://github.com/hueniverse/hawkEran HammerJan 19, 2016via ghsa
5 files changed · +86 6
  • lib/server.js+10 2 modified
    @@ -310,6 +310,11 @@ exports.header = function (credentials, artifacts, options) {
      * 'hostHeaderName', 'localtimeOffsetMsec', 'host', 'port'
      */
     
    +
    +//                       1     2             3           4
    +internals.bewitRegex = /^(\/.*)([\?&])bewit\=([^&$]*)(?:&(.+))?$/;
    +
    +
     exports.authenticateBewit = function (req, credentialsFunc, options, callback) {
     
         callback = Hoek.nextTick(callback);
    @@ -327,8 +332,11 @@ exports.authenticateBewit = function (req, credentialsFunc, options, callback) {
     
         // Extract bewit
     
    -    //                                 1     2             3           4
    -    const resource = request.url.match(/^(\/.*)([\?&])bewit\=([^&$]*)(?:&(.+))?$/);
    +    if (request.url.length > Utils.limits.maxMatchLength) {
    +        return callback(Boom.badRequest('Resource path exceeds max length'));
    +    }
    +
    +    const resource = request.url.match(internals.bewitRegex);
         if (!resource) {
             return callback(Utils.unauthorized());
         }
    
  • lib/utils.js+20 3 modified
    @@ -17,6 +17,11 @@ exports.version = function () {
     };
     
     
    +exports.limits = {
    +    maxMatchLength: 4096            // Limit the length of uris and headers to avoid a DoS attack on string matching
    +};
    +
    +
     // Extract host and port from request
     
     //                                            $1                            $2
    @@ -31,6 +36,10 @@ exports.parseHost = function (req, hostHeaderName) {
             return null;
         }
     
    +    if (hostHeader.length > exports.limits.maxMatchLength) {
    +        return null;
    +    }
    +
         const hostParts = hostHeader.match(internals.hostHeaderRegex);
         if (!hostParts) {
             return null;
    @@ -100,6 +109,10 @@ exports.nowSecs = function (localtimeOffsetMsec) {
     };
     
     
    +internals.authHeaderRegex = /^(\w+)(?:\s+(.*))?$/;                                      // Header: scheme[ something]
    +internals.attributeRegex = /^[ \w\!#\$%&'\(\)\*\+,\-\.\/\:;<\=>\?@\[\]\^`\{\|\}~]+$/;   // !#$%&'()*+,-./:;<=>?@[]^_`{|}~ and space, a-z, A-Z, 0-9
    +
    +
     // Parse Hawk HTTP Authorization header
     
     exports.parseAuthorizationHeader = function (header, keys) {
    @@ -110,7 +123,11 @@ exports.parseAuthorizationHeader = function (header, keys) {
             return Boom.unauthorized(null, 'Hawk');
         }
     
    -    const headerParts = header.match(/^(\w+)(?:\s+(.*))?$/);       // Header: scheme[ something]
    +    if (header.length > exports.limits.maxMatchLength) {
    +        return Boom.badRequest('Header length too long');
    +    }
    +
    +    const headerParts = header.match(internals.authHeaderRegex);
         if (!headerParts) {
             return Boom.badRequest('Invalid header syntax');
         }
    @@ -136,9 +153,9 @@ exports.parseAuthorizationHeader = function (header, keys) {
                 return;
             }
     
    -        // Allowed attribute value characters: !#$%&'()*+,-./:;<=>?@[]^_`{|}~ and space, a-z, A-Z, 0-9
    +        // Allowed attribute value characters
     
    -        if ($2.match(/^[ \w\!#\$%&'\(\)\*\+,\-\.\/\:;<\=>\?@\[\]\^`\{\|\}~]+$/) === null) {
    +        if ($2.match(internals.attributeRegex) === null) {
                 errorMessage = 'Bad attribute value: ' + $1;
                 return;
             }
    
  • package.json+1 1 modified
    @@ -1,7 +1,7 @@
     {
       "name": "hawk",
       "description": "HTTP Hawk Authentication Scheme",
    -  "version": "4.1.0",
    +  "version": "4.1.1",
       "author": "Eran Hammer <eran@hammer.io> (http://hueniverse.com)",
       "repository": "git://github.com/hueniverse/hawk",
       "main": "lib/index.js",
    
  • test/server.js+27 0 modified
    @@ -971,6 +971,33 @@ describe('Server', () => {
             });
         });
     
    +    describe('authenticateBewit()', () => {
    +
    +        it('errors on uri too long', (done) => {
    +
    +            let long = '/';
    +            for (let i = 0; i < 5000; ++i) {
    +                long += 'x';
    +            }
    +
    +            const req = {
    +                method: 'GET',
    +                url: long,
    +                host: 'example.com',
    +                port: 8080,
    +                authorization: 'Hawk id="1", ts="1353788437", nonce="k3j4h2", mac="zy79QQ5/EYFmQqutVnYb73gAc/U=", ext="hello"'
    +            };
    +
    +            Hawk.server.authenticateBewit(req, credentialsFunc, {}, (err, credentials, bewit) => {
    +
    +                expect(err).to.exist();
    +                expect(err.output.statusCode).to.equal(400);
    +                expect(err.message).to.equal('Resource path exceeds max length');
    +                done();
    +            });
    +        });
    +    });
    +
         describe('authenticateMessage()', () => {
     
             it('errors on invalid authorization (ts)', (done) => {
    
  • test/utils.js+28 0 modified
    @@ -95,6 +95,34 @@ describe('Utils', () => {
                 expect(host.name).to.equal('[123:123:123]');
                 done();
             });
    +
    +        it('errors on header too long', (done) => {
    +
    +            let long = '';
    +            for (let i = 0; i < 5000; ++i) {
    +                long += 'x';
    +            }
    +
    +            expect(Hawk.utils.parseHost({ headers: { host: long } })).to.be.null();
    +            done();
    +        });
    +    });
    +
    +    describe('parseAuthorizationHeader()', () => {
    +
    +        it('errors on header too long', (done) => {
    +
    +            let long = 'Scheme a="';
    +            for (let i = 0; i < 5000; ++i) {
    +                long += 'x';
    +            }
    +            long += '"';
    +
    +            const err = Hawk.utils.parseAuthorizationHeader(long, ['a']);
    +            expect(err).to.be.instanceof(Error);
    +            expect(err.message).to.equal('Header length too long');
    +            done();
    +        });
         });
     
         describe('version()', () => {
    

Vulnerability mechanics

Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

9

News mentions

0

No linked articles in our index yet.