Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

hpkp

Package Overview
Dependencies
Maintainers
1
Versions
11
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

hpkp - npm Package Compare versions

Comparing version 0.3.0 to 1.0.0

69

index.js

@@ -1,34 +0,27 @@

var badArgumentsError = new Error('hpkp must be called with a maxAge and at least two SHA-256s (one actually used and another kept as a backup).');
var badArgumentsError = new Error('hpkp must be called with a maxAge and at least two SHA-256s (one actually used and another kept as a backup).')
module.exports = function hpkp(passedOptions) {
var options = parseOptions(passedOptions);
var headerKey = getHeaderKey(options);
var headerValue = getHeaderValue(options);
module.exports = function hpkp (passedOptions) {
var options = parseOptions(passedOptions)
var headerKey = getHeaderKey(options)
var headerValue = getHeaderValue(options)
return function hpkp(req, res, next) {
res.setHeader(headerKey, headerValue);
next();
};
};
return function hpkp (req, res, next) {
res.setHeader(headerKey, headerValue)
next()
}
}
function parseOptions(options) {
if (!options) { throw badArgumentsError; }
function parseOptions (options) {
if (!options) { throw badArgumentsError }
if (options.maxage && options.maxAge) { throw badArgumentsError; }
if (options.maxage && options.maxAge) { throw badArgumentsError }
var maxAge = options.maxAge || options.maxage;
var sha256s = options.sha256s;
var maxAge = options.maxAge
var sha256s = options.sha256s
if (!maxAge || maxAge <= 0) { throw badArgumentsError; }
if (!sha256s || sha256s.length < 2) { throw badArgumentsError; }
if (!maxAge || maxAge <= 0) { throw badArgumentsError }
if (!sha256s || sha256s.length < 2) { throw badArgumentsError }
var reportOnly;
if (options.reportOnly === undefined) {
reportOnly = Boolean(options.reportUri);
} else {
reportOnly = options.reportOnly;
}
if (options.reportOnly && !options.reportUri) { throw badArgumentsError }
if (reportOnly && !options.reportUri) { throw badArgumentsError; }
return {

@@ -39,26 +32,26 @@ maxAge: maxAge,

reportUri: options.reportUri,
reportOnly: reportOnly
};
reportOnly: options.reportOnly
}
}
function getHeaderKey(options) {
var header = 'Public-Key-Pins';
function getHeaderKey (options) {
var header = 'Public-Key-Pins'
if (options.reportOnly) {
header += '-Report-Only';
header += '-Report-Only'
}
return header;
return header
}
function getHeaderValue(options) {
function getHeaderValue (options) {
var result = options.sha256s.map(function (sha) {
return 'pin-sha256="' + sha + '"';
});
result.push('max-age=' + Math.round(options.maxAge / 1000));
return 'pin-sha256="' + sha + '"'
})
result.push('max-age=' + Math.round(options.maxAge / 1000))
if (options.includeSubdomains) {
result.push('includeSubdomains');
result.push('includeSubdomains')
}
if (options.reportUri) {
result.push('report-uri="' + options.reportUri + '"');
result.push('report-uri="' + options.reportUri + '"')
}
return result.join('; ');
return result.join('; ')
}

@@ -10,3 +10,3 @@ {

"description": "HTTP Public Key Pinning (HPKP) middleware",
"version": "0.3.0",
"version": "1.0.0",
"keywords": [

@@ -28,9 +28,17 @@ "helmet",

"scripts": {
"test": "mocha"
"test": "standard && mocha"
},
"devDependencies": {
"connect": "^3.3.4",
"mocha": "^2.1.0",
"supertest": "^0.15.0"
"connect": "^3.4.0",
"mocha": "^2.3.4",
"standard": "^5.4.1",
"supertest": "^1.1.0"
},
"standard": {
"global": [
"beforeEach",
"describe",
"it"
]
}
}

@@ -1,2 +0,5 @@

# HTTP Public Key Pinning (HPKP) middleware
HTTP Public Key Pinning (HPKP) middleware
=========================================
[![Build Status](https://travis-ci.org/helmetjs/hpkp.svg?branch=master)](https://travis-ci.org/helmetjs/hpkp)
[![js-standard-style](https://img.shields.io/badge/code%20style-standard-brightgreen.svg)](http://standardjs.com/)

@@ -8,8 +11,8 @@ Adds Public Key Pinning headers to Express/Connect applications. To learn more about HPKP, check out [the spec](https://tools.ietf.org/html/rfc7469), [the article on MDN](https://developer.mozilla.org/en-US/docs/Web/Security/Public_Key_Pinning), and [this tutorial](https://timtaubert.de/blog/2014/10/http-public-key-pinning-explained/).

```js
var express = require('express');
var hpkp = require('hpkp');
var express = require('express')
var hpkp = require('hpkp')
var app = express();
var app = express()
var ninetyDaysInMilliseconds = 7776000000;
var ninetyDaysInMilliseconds = 7776000000
app.use(hpkp({

@@ -20,5 +23,6 @@ maxAge: ninetyDaysInMilliseconds,

reportUri: 'http://example.com' // optional
}));
reportOnly: false // optional
}))
```
Specifying a `report-uri` changes the header from `Public-Key-Pins` to `Public-Key-Pins-Report-Only`. To reverse this, set another option: `reportOnly: false`. This behavior will change in the 1.0 release.
Setting `reportOnly` to `true` will change the header from `Public-Key-Pins` to `Public-Key-Pins-Report-Only`.

@@ -1,18 +0,16 @@

var hpkp = require('..');
var hpkp = require('..')
var connect = require('connect');
var request = require('supertest');
var assert = require('assert');
var connect = require('connect')
var request = require('supertest')
var assert = require('assert')
describe('hpkp', function () {
describe('with proper input', function () {
function test() {
var app = connect();
app.use(hpkp.apply(null, arguments));
function test () {
var app = connect()
app.use(hpkp.apply(null, arguments))
app.use(function (req, res) {
res.end('Hello world!');
});
return request(app).get('/');
res.end('Hello world!')
})
return request(app).get('/')
}

@@ -22,73 +20,82 @@

test({ maxAge: 10000, sha256s: ['abc123', 'xyz456'] })
.expect('Public-Key-Pins', 'pin-sha256="abc123"; pin-sha256="xyz456"; max-age=10', done);
});
.expect('Public-Key-Pins', 'pin-sha256="abc123"; pin-sha256="xyz456"; max-age=10', done)
})
it('allows lowercase "maxage"', function (done) {
test({ maxage: 10000, sha256s: ['abc123', 'xyz456'] })
.expect('Public-Key-Pins', 'pin-sha256="abc123"; pin-sha256="xyz456"; max-age=10', done);
});
it('can include subdomains', function (done) {
test({ maxage: 10000, sha256s: ['abc123', 'xyz456'], includeSubdomains: true })
.expect('Public-Key-Pins', 'pin-sha256="abc123"; pin-sha256="xyz456"; max-age=10; includeSubdomains', done);
});
test({ maxAge: 10000, sha256s: ['abc123', 'xyz456'], includeSubdomains: true })
.expect('Public-Key-Pins', 'pin-sha256="abc123"; pin-sha256="xyz456"; max-age=10; includeSubdomains', done)
})
it('changes the header when using a report URI', function (done) {
test({ maxage: 10000, sha256s: ['abc123', 'xyz456'], reportUri: 'http://example.com' })
.expect('Public-Key-Pins-Report-Only', 'pin-sha256="abc123"; pin-sha256="xyz456"; max-age=10; report-uri="http://example.com"', done);
});
it('can set a report-uri', function (done) {
test({
maxAge: 10000,
sha256s: ['abc123', 'xyz456'],
reportUri: 'http://example.com'
})
.expect('Public-Key-Pins', 'pin-sha256="abc123"; pin-sha256="xyz456"; max-age=10; report-uri="http://example.com"', done)
})
it('can disable Report-Only with a report URI', function (done) {
it('can enable Report-Only header', function (done) {
test({
maxage: 10000,
maxAge: 10000,
sha256s: ['abc123', 'xyz456'],
reportUri: 'http://example.com',
reportOnly: false
reportOnly: true
})
.expect('Public-Key-Pins', 'pin-sha256="abc123"; pin-sha256="xyz456"; max-age=10; report-uri="http://example.com"', done);
});
.expect('Public-Key-Pins-Report-Only', 'pin-sha256="abc123"; pin-sha256="xyz456"; max-age=10; report-uri="http://example.com"', done)
})
it('changes the header when using a report URI and includes subdomains', function (done) {
test({ maxage: 10000, sha256s: ['abc123', 'xyz456'], reportUri: 'http://example.com', includeSubdomains: true })
.expect('Public-Key-Pins-Report-Only', 'pin-sha256="abc123"; pin-sha256="xyz456"; max-age=10; includeSubdomains; report-uri="http://example.com"', done);
});
it('can use a report URI and include subdomains', function (done) {
test({
maxAge: 10000,
sha256s: ['abc123', 'xyz456'],
reportUri: 'http://example.com',
includeSubdomains: true
})
.expect('Public-Key-Pins', 'pin-sha256="abc123"; pin-sha256="xyz456"; max-age=10; includeSubdomains; report-uri="http://example.com"', done)
})
it('rounds down to the nearest second', function (done) {
test({ maxAge: 1234, sha256s: ['abc123', 'xyz456'] })
.expect('Public-Key-Pins', 'pin-sha256="abc123"; pin-sha256="xyz456"; max-age=1', done);
});
.expect('Public-Key-Pins', 'pin-sha256="abc123"; pin-sha256="xyz456"; max-age=1', done)
})
it('rounds up to the nearest second', function (done) {
test({ maxAge: 1567, sha256s: ['abc123', 'xyz456'] })
.expect('Public-Key-Pins', 'pin-sha256="abc123"; pin-sha256="xyz456"; max-age=2', done);
});
.expect('Public-Key-Pins', 'pin-sha256="abc123"; pin-sha256="xyz456"; max-age=2', done)
})
})
});
it('names its function and middleware', function () {
assert.equal(hpkp.name, 'hpkp');
assert.equal(hpkp.name, hpkp({ maxAge: 10000, sha256s: ['abc123', 'xyz456'] }).name);
});
assert.equal(hpkp.name, 'hpkp')
assert.equal(hpkp.name, hpkp({ maxAge: 10000, sha256s: ['abc123', 'xyz456'] }).name)
})
describe('with improper input', function () {
function callWith() {
var args = arguments;
function callWith () {
var args = arguments
return function () {
return hpkp.apply(this, args);
};
return hpkp.apply(this, args)
}
}
it('fails if called with no arguments', function () {
assert.throws(callWith());
});
assert.throws(callWith())
})
it('fails if called with an empty object', function () {
assert.throws(callWith({}));
});
assert.throws(callWith({}))
})
it('fails if called without a max-age', function () {
assert.throws(callWith({ sha256s: ['abc123', 'xyz456'] }));
});
assert.throws(callWith({ sha256s: ['abc123', 'xyz456'] }))
})
it('fails if called with a lowercase "maxage" option', function () {
assert.throws(callWith({
maxage: 10000,
sha256s: ['abc123', 'xyz456']
}))
})
it('fails if called with fewer than 2 SHAs', function () {

@@ -102,28 +109,26 @@ [

].forEach(function (value) {
assert.throws(callWith({ maxAge: 10000, sha256s: value }));
});
});
assert.throws(callWith({ maxAge: 10000, sha256s: value }))
})
})
it('fails if called with a zero maxAge', function () {
assert.throws(callWith({ maxAge: 0, sha256s: ['abc123', 'xyz456'] }));
});
assert.throws(callWith({ maxAge: 0, sha256s: ['abc123', 'xyz456'] }))
})
it('fails if called with a negative maxAge', function () {
assert.throws(callWith({ maxAge: -1000, sha256s: ['abc123', 'xyz456'] }));
});
assert.throws(callWith({ maxAge: -1000, sha256s: ['abc123', 'xyz456'] }))
})
it('fails if called with both types of maxAge argument', function () {
assert.throws(callWith({ maxAge: 1000, maxage: 1000, sha256s: ['abc123', 'xyz456'] }));
});
assert.throws(callWith({ maxAge: 1000, maxage: 1000, sha256s: ['abc123', 'xyz456'] }))
})
it('fails if called with reportOnly: true but no reportUri', function () {
assert.throws(callWith({
maxage: 10000,
maxAge: 10000,
sha256s: ['abc123', 'xyz456'],
reportOnly: true
}));
});
});
});
}))
})
})
})

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

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

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc