Socket
Socket
Sign inDemoInstall

hawk

Package Overview
Dependencies
0
Maintainers
1
Versions
85
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 0.0.1 to 0.0.2

47

lib/hawk.js

@@ -61,3 +61,3 @@ // Load modules

if (!req.headers.authorization) {
return callback(new Error('No authentication'), false, null);
return callback(new Error('Missing Authorization header'), false, null);
}

@@ -71,4 +71,4 @@

if (!attributes) {
return callback(new Error('Incorrect authentication scheme'), false, null);
if (attributes instanceof Error) {
return callback(attributes, false, null);
}

@@ -87,3 +87,3 @@

var hostHeaderRegex = /^(?:(?:\r\n)?[\t ])*([^:]+)(?::(\d+))*(?:(?:\r\n)?[\t ])*$/; // Does not support IPv6
var hostHeaderRegex = /^(?:(?:\r\n)?[\t ])*([^:]+)(?::(\d+))?(?:(?:\r\n)?[\t ])*$/; // Does not support IPv6
var hostParts = hostHeader.match(hostHeaderRegex);

@@ -185,11 +185,11 @@

var headerRegex = /^[Hh][Aa][Ww][Kk]\s+(.*)$/;
var headerParts = headerRegex.exec(header);
var headerRegex = /^([Hh][Aa][Ww][Kk])(?:\s+(.*))?$/;
var headerParts = header.match(headerRegex);
if (!headerParts ||
headerParts.length !== 2 ||
!headerParts[1]) {
if (!headerParts) {
return new Error('Incorrect scheme');
}
// Invalid header format
return null;
if (!headerParts[2]) {
return new Error('Invalid header format');
}

@@ -200,3 +200,3 @@

var attributesRegex = /(id|ts|ext|mac)="([^"\\]*)"\s*(?:,\s*|$)/g;
var verify = headerParts[1].replace(attributesRegex, function ($0, $1, $2) {
var verify = headerParts[2].replace(attributesRegex, function ($0, $1, $2) {

@@ -210,4 +210,3 @@ if (attributes[$1] === undefined) {

if (verify !== '') {
// Did not match all parts
return null;
return new Error('Unknown attributes');
}

@@ -225,3 +224,3 @@

exports.getAuthorizationHeader = function (credentials, method, uri, host, port, ext) {
exports.getAuthorizationHeader = function (credentials, method, uri, host, port, ext, timestamp) {

@@ -238,20 +237,16 @@ // Check request

// Generate nonce
// Calculate signature
var timestamp = Math.floor(((new Date()).getTime() / 1000));
timestamp = timestamp || Math.floor(((new Date()).getTime() / 1000));
var mac = exports.calculateMAC(credentials.key, credentials.algorithm, timestamp, method, uri, host, port, ext);
// Calculate signature
if (!mac) {
return '';
}
var mac = exports.calculateMAC(timestamp, nonce, method, uri, host, port, ext, credentials.key, credentials.algorithm);
// Construct header
var header = 'Hawk id="' + credentials.id +
'", ts="' + timestamp +
'", nonce="' + nonce +
(ext ? '", ext="' + ext : '') +
'", mac="' + mac + '"';
var header = 'Hawk id="' + credentials.id + '", ts="' + timestamp + (ext ? '", ext="' + ext : '') + '", mac="' + mac + '"';
return header;
};
{
"name": "hawk",
"description": "HTTP Hawk Authentication Scheme",
"version": "0.0.1",
"version": "0.0.2",
"author": "Eran Hammer <eran@hueniverse.com> (http://hueniverse.com)",
"contributors":[
],
"contributors": [],
"repository": "git://github.com/hueniverse/hawk",

@@ -19,4 +18,3 @@ "main": "index",

},
"dependencies": {
},
"dependencies": {},
"devDependencies": {

@@ -23,0 +21,0 @@ "mocha": "1.x.x",

@@ -5,3 +5,3 @@ // Load modules

var should = require('should');
var Hawk = require('../lib/hawk');
var Hawk = process.env.TEST_COV ? require('../lib-cov/hawk') : require('../lib/hawk');

@@ -11,9 +11,44 @@

var credentialsFunc = function (id, callback) {
var credentials = {
id: id,
key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn',
algorithm: (id === '1' ? 'hmac-sha-1' : 'hmac-sha-256'),
user: 'steve'
};
return callback(null, credentials);
};
it('should generate a header then successfully parse it', function (done) {
var req = {
headers: {
host: 'example.com:8080'
},
method: 'GET',
url: '/resource/4?filter=a'
};
credentialsFunc('123456', function (err, credentials) {
req.headers.authorization = Hawk.getAuthorizationHeader(credentials, req.method, req.url, 'example.com', 8080, null, 1353809207);
Hawk.authenticate(req, credentialsFunc, {}, function (err, isAuthenticated, credentials) {
should.not.exist(err);
credentials.user.should.equal('steve');
done();
});
});
});
describe('#authenticate', function () {
it('should parse a valid authentication header', function (done) {
it('should parse a valid authentication header (hmac-sha-1)', function (done) {
var req = {
headers: {
authentication: 'Hawk id="123", ts="1353788437", mac="", ext="hello"',
authorization: 'Hawk id="1", ts="1353788437", mac="lDdDLlWQhgcxTvYgzzLo3EZExog=", ext="hello"',
host: 'example.com:8080'

@@ -25,7 +60,223 @@ },

Hawk.authenticate(req, credentialsFunc, {}, function (err, isAuthenticated, credentials) {
should.not.exist(err);
credentials.user.should.equal('steve');
done();
});
});
it('should parse a valid authentication header (hmac-sha-256)', function (done) {
var req = {
headers: {
authorization: 'Hawk id="123", ts="1353788437", mac="/qwS4UjfVWMcUyW6EEgUH4jlr7T/wuKe3dKijvTvSos=", ext="hello"',
host: 'example.com:8080'
},
method: 'GET',
url: '/resource/4?filter=a'
};
Hawk.authenticate(req, credentialsFunc, {}, function (err, isAuthenticated, credentials) {
should.not.exist(err);
credentials.user.should.equal('steve');
done();
});
});
it('should fail on an invalid authentication header: wrong scheme', function (done) {
var req = {
headers: {
authorization: 'Basic asdasdasdasd',
host: 'example.com:8080'
},
method: 'GET',
url: '/resource/4?filter=a'
};
Hawk.authenticate(req, credentialsFunc, {}, function (err, isAuthenticated, credentials) {
should.exist(err);
err.message.should.equal('Incorrect scheme');
done();
});
});
it('should fail on an missing authorization header', function (done) {
var req = {
headers: {
host: 'example.com:8080'
},
method: 'GET',
url: '/resource/4?filter=a'
};
Hawk.authenticate(req, credentialsFunc, {}, function (err, isAuthenticated, credentials) {
should.exist(err);
err.message.should.equal('Missing Authorization header');
done();
});
});
it('should fail on an missing host header', function (done) {
var req = {
headers: {
authorization: 'Hawk id="123", ts="1353788437", mac="/qwS4UjfVWMcUyW6EEgUH4jlr7T/wuKe3dKijvTvSos=", ext="hello"'
},
method: 'GET',
url: '/resource/4?filter=a'
};
Hawk.authenticate(req, credentialsFunc, {}, function (err, isAuthenticated, credentials) {
should.exist(err);
err.message.should.equal('Missing Host header');
done();
});
});
it('should fail on an missing authorization attribute', function (done) {
var req = {
headers: {
authorization: 'Hawk ts="1353788437", mac="/qwS4UjfVWMcUyW6EEgUH4jlr7T/wuKe3dKijvTvSos=", ext="hello"',
host: 'example.com:8080'
},
method: 'GET',
url: '/resource/4?filter=a'
};
Hawk.authenticate(req, credentialsFunc, {}, function (err, isAuthenticated, credentials) {
should.exist(err);
err.message.should.equal('Missing attributes');
done();
});
});
it('should fail on an unknown authorization attribute', function (done) {
var req = {
headers: {
authorization: 'Hawk id="123", ts="1353788437", x="3", mac="/qwS4UjfVWMcUyW6EEgUH4jlr7T/wuKe3dKijvTvSos=", ext="hello"',
host: 'example.com:8080'
},
method: 'GET',
url: '/resource/4?filter=a'
};
Hawk.authenticate(req, credentialsFunc, {}, function (err, isAuthenticated, credentials) {
should.exist(err);
err.message.should.equal('Unknown attributes');
done();
});
});
it('should fail on an invalid authorization header format', function (done) {
var req = {
headers: {
authorization: 'Hawk',
host: 'example.com:8080'
},
method: 'GET',
url: '/resource/4?filter=a'
};
Hawk.authenticate(req, credentialsFunc, {}, function (err, isAuthenticated, credentials) {
should.exist(err);
err.message.should.equal('Invalid header format');
done();
});
});
it('should fail on an bad host header', function (done) {
var req = {
headers: {
authorization: 'Hawk id="123", ts="1353788437", mac="/qwS4UjfVWMcUyW6EEgUH4jlr7T/wuKe3dKijvTvSos=", ext="hello"',
host: 'example.com:8080:90'
},
method: 'GET',
url: '/resource/4?filter=a'
};
Hawk.authenticate(req, credentialsFunc, {}, function (err, isAuthenticated, credentials) {
should.exist(err);
err.message.should.equal('Bad Host header');
done();
});
});
it('should fail on credentialsFunc error', function (done) {
var req = {
headers: {
authorization: 'Hawk id="123", ts="1353788437", mac="/qwS4UjfVWMcUyW6EEgUH4jlr7T/wuKe3dKijvTvSos=", ext="hello"',
host: 'example.com:8080'
},
method: 'GET',
url: '/resource/4?filter=a'
};
var credentialsFunc = function (id, callback) {
return callback(new Error('Unknown user'));
};
Hawk.authenticate(req, credentialsFunc, {}, function (err, isAuthenticated, credentials) {
should.exist(err);
err.message.should.equal('Unknown user');
done();
});
});
it('should fail on missing credentials', function (done) {
var req = {
headers: {
authorization: 'Hawk id="123", ts="1353788437", mac="/qwS4UjfVWMcUyW6EEgUH4jlr7T/wuKe3dKijvTvSos=", ext="hello"',
host: 'example.com:8080'
},
method: 'GET',
url: '/resource/4?filter=a'
};
var credentialsFunc = function (id, callback) {
return callback(null, null);
};
Hawk.authenticate(req, credentialsFunc, {}, function (err, isAuthenticated, credentials) {
should.exist(err);
err.message.should.equal('Missing credentials');
done();
});
});
it('should fail on invalid credentials', function (done) {
var req = {
headers: {
authorization: 'Hawk id="123", ts="1353788437", mac="/qwS4UjfVWMcUyW6EEgUH4jlr7T/wuKe3dKijvTvSos=", ext="hello"',
host: 'example.com:8080'
},
method: 'GET',
url: '/resource/4?filter=a'
};
var credentialsFunc = function (id, callback) {
var credentials = {
key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn',
algorithm: 'hmac-sha-256',
user: 'steve'

@@ -37,6 +288,6 @@ };

Hawk.authenticate(req, encryptionPassword, {}, function (err, ticket, attributes) {
Hawk.authenticate(req, credentialsFunc, {}, function (err, isAuthenticated, credentials) {
should.not.exist(err);
attributes.ext.should.equal('"welcome"');
should.exist(err);
err.message.should.equal('Invalid credentials');
done();

@@ -46,38 +297,58 @@ });

it('should return an error for an invalid authentication header', function (done) {
it('should fail on unknown credentials algorithm', function (done) {
// Note: the ticket.id already encodes all the other ticket attributes and they cannot be manually changed
var req = {
headers: {
authorization: 'Hawk id="123", ts="1353788437", mac="/qwS4UjfVWMcUyW6EEgUH4jlr7T/wuKe3dKijvTvSos=", ext="hello"',
host: 'example.com:8080'
},
method: 'GET',
url: '/resource/4?filter=a'
};
var encryptionPassword = 'example';
var credentialsFunc = function (id, callback) {
var ticket = {
id: '4deee737c1810925ace5aa5292c4e761f2325eb1286bc5c69cbf00b3f5de3abc:eL5Zvd2wyIiMc-6Adk2SUy7i4TjZKLnV_KTUYnTri5Q:a5f7aa17320716247dd18fd87f04e7c0495980b3417d94185f0feb6c052e123e:p1BY4SLSY-5fjKuPSz_GwQ:UDPFp5jLSyYZmGrlD111XxNrZzhvWdU32k_05EjPm4vi0pynvYpGGXYTuuxlEj7hwUR4BOmFumASxvZJVRMMERhCtOjqBwUbU9L8MzI2wYYEryFImSwDkxZAamsG37KH6K1w-rTP-UgP8mVpmboA9-vzwRrlaPzvV19VS7kLGEUeDR8DFzwQpMl2lK-dw4KQPPmsKSGFzxlUO-9hpvWdU6lyTdMYAoy8MPTNCMT4NbgRrjitYV-6YKmhJNHMErzs',
key: 'wrong',
algorithm: 'sha256',
app: '123'
};
var credentials = {
key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn',
algorithm: 'hmac-sha-0',
user: 'steve'
};
var request = {
method: 'GET',
resource: '/path?query',
host: 'example.com',
port: 80
return callback(null, credentials);
};
var attributes = {
ext: '"welcome"'
};
Hawk.authenticate(req, credentialsFunc, {}, function (err, isAuthenticated, credentials) {
should.exist(err);
err.message.should.equal('Unknown algorithm');
done();
});
});
it('should fail on unknown bad mac', function (done) {
var req = {
method: request.method,
url: request.resource,
headers: {
authorization: Oz.request.generateHeader(request, ticket, attributes),
host: request.host + ':' + request.port
}
authorization: 'Hawk id="123", ts="1353788437", mac="/qwS4UjfVWMcU4jlr7T/wuKe3dKijvTvSos=", ext="hello"',
host: 'example.com:8080'
},
method: 'GET',
url: '/resource/4?filter=a'
};
Oz.request.authenticate(req, encryptionPassword, {}, function (err, ticket, attributes) {
var credentialsFunc = function (id, callback) {
var credentials = {
key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn',
algorithm: 'hmac-sha-256',
user: 'steve'
};
return callback(null, credentials);
};
Hawk.authenticate(req, credentialsFunc, {}, function (err, isAuthenticated, credentials) {
should.exist(err);
err.message.should.equal('Bad mac');
done();

@@ -87,3 +358,68 @@ });

});
describe('#getWWWAuthenticateHeader', function () {
it('should return a valid Hawk header with error', function (done) {
Hawk.getWWWAuthenticateHeader('boom').should.equal('Hawk error="boom"');
done();
});
it('should return a valid Hawk header without error', function (done) {
Hawk.getWWWAuthenticateHeader().should.equal('Hawk');
done();
});
});
describe('#calculateMAC', function () {
it('should return an empty value on unknown algorithm', function (done) {
Hawk.calculateMAC('dasdfasdf', 'hmac-sha-0', Date.now() / 1000, 'GET', '/resource/something', 'example.com', 8080).should.equal('');
done();
});
});
describe('#getAuthorizationHeader', function () {
it('should return a valid authorization header', function (done) {
var credentials = {
id: '123456',
key: '2983d45yun89q',
algorithm: 'hmac-sha-256'
};
var header = Hawk.getAuthorizationHeader(credentials, 'POST', '/somewhere/over/the/rainbow', 'example.net', 443, 'Bazinga!', 1353809207);
header.should.equal('Hawk id="123456", ts="1353809207", ext="Bazinga!", mac="LYUkYKYkQsQstqNQHcnAzDXce0oHsmS049rv4EalMb8="');
done();
});
it('should return an empty authorization header on invalid credentials', function (done) {
var credentials = {
key: '2983d45yun89q',
algorithm: 'hmac-sha-256'
};
var header = Hawk.getAuthorizationHeader(credentials, 'POST', '/somewhere/over/the/rainbow', 'example.net', 443, 'Bazinga!', 1353809207);
header.should.equal('');
done();
});
it('should return an empty authorization header on invalid algorithm', function (done) {
var credentials = {
id: '123456',
key: '2983d45yun89q',
algorithm: 'hmac-sha-0'
};
var header = Hawk.getAuthorizationHeader(credentials, 'POST', '/somewhere/over/the/rainbow', 'example.net', 443, 'Bazinga!', 1353809207);
header.should.equal('');
done();
});
});
});

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Packages

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc