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

@middy/http-security-headers

Package Overview
Dependencies
Maintainers
3
Versions
173
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@middy/http-security-headers - npm Package Compare versions

Comparing version 5.0.0-alpha.1 to 5.0.0-alpha.2

508

index.js

@@ -1,288 +0,260 @@

import { normalizeHttpResponse } from '@middy/util'
import { normalizeHttpResponse } from '@middy/util';
// Code and Defaults heavily based off https://helmetjs.github.io/
const defaults = {
contentSecurityPolicy: {
// Fetch directives
// 'child-src': '', // fallback default-src
// 'connect-src': '', // fallback default-src
'default-src': "'none'",
// 'font-src':'', // fallback default-src
// 'frame-src':'', // fallback child-src > default-src
// 'img-src':'', // fallback default-src
// 'manifest-src':'', // fallback default-src
// 'media-src':'', // fallback default-src
// 'object-src':'', // fallback default-src
// 'prefetch-src':'', // fallback default-src
// 'script-src':'', // fallback default-src
// 'script-src-elem':'', // fallback script-src > default-src
// 'script-src-attr':'', // fallback script-src > default-src
// 'style-src':'', // fallback default-src
// 'style-src-elem':'', // fallback style-src > default-src
// 'style-src-attr':'', // fallback style-src > default-src
// 'worker-src':'', // fallback child-src > script-src > default-src
// Document directives
'base-uri': "'none'",
sandbox: '',
// Navigation directives
'form-action': "'none'",
'frame-ancestors': "'none'",
'navigate-to': "'none'",
// Reporting directives
'report-to': 'csp',
// Other directives
'require-trusted-types-for': "'script'",
'trusted-types': "'none'",
'upgrade-insecure-requests': ''
},
contentTypeOptions: {
action: 'nosniff'
},
crossOriginEmbedderPolicy: {
policy: 'require-corp'
},
crossOriginOpenerPolicy: {
policy: 'same-origin'
},
crossOriginResourcePolicy: {
policy: 'same-origin'
},
dnsPrefetchControl: {
allow: false
},
downloadOptions: {
action: 'noopen'
},
frameOptions: {
action: 'deny'
},
originAgentCluster: {},
permissionsPolicy: {
// Standard
accelerometer: '',
'ambient-light-sensor': '',
autoplay: '',
battery: '',
camera: '',
'cross-origin-isolated': '',
'display-capture': '',
'document-domain': '',
'encrypted-media': '',
'execution-while-not-rendered': '',
'execution-while-out-of-viewport': '',
fullscreen: '',
geolocation: '',
gyroscope: '',
'keyboard-map': '',
magnetometer: '',
microphone: '',
midi: '',
'navigation-override': '',
payment: '',
'picture-in-picture': '',
'publickey-credentials-get': '',
'screen-wake-lock': '',
'sync-xhr': '',
usb: '',
'web-share': '',
'xr-spatial-tracking': '',
// Proposed
'clipboard-read': '',
'clipboard-write': '',
gamepad: '',
'speaker-selection': '',
// Experimental
'conversion-measurement': '',
'focus-without-user-activation': '',
hid: '',
'idle-detection': '',
'interest-cohort': '',
serial: '',
'sync-script': '',
'trust-token-redemption': '',
'window-placement': '',
'vertical-scroll': ''
},
permittedCrossDomainPolicies: {
policy: 'none' // none, master-only, by-content-type, by-ftp-filename, all
},
poweredBy: {
server: ''
},
referrerPolicy: {
policy: 'no-referrer'
},
reportTo: {
maxAge: 365 * 24 * 60 * 60,
default: '',
includeSubdomains: true,
csp: '',
staple: '',
xss: ''
},
strictTransportSecurity: {
maxAge: 180 * 24 * 60 * 60,
includeSubDomains: true,
preload: true
},
xssProtection: {
reportTo: 'xss'
}
}
const helmet = {}
const helmetHtmlOnly = {}
contentSecurityPolicy: {
// Fetch directives
// 'child-src': '', // fallback default-src
// 'connect-src': '', // fallback default-src
'default-src': "'none'",
// 'font-src':'', // fallback default-src
// 'frame-src':'', // fallback child-src > default-src
// 'img-src':'', // fallback default-src
// 'manifest-src':'', // fallback default-src
// 'media-src':'', // fallback default-src
// 'object-src':'', // fallback default-src
// 'prefetch-src':'', // fallback default-src
// 'script-src':'', // fallback default-src
// 'script-src-elem':'', // fallback script-src > default-src
// 'script-src-attr':'', // fallback script-src > default-src
// 'style-src':'', // fallback default-src
// 'style-src-elem':'', // fallback style-src > default-src
// 'style-src-attr':'', // fallback style-src > default-src
// 'worker-src':'', // fallback child-src > script-src > default-src
// Document directives
'base-uri': "'none'",
sandbox: '',
// Navigation directives
'form-action': "'none'",
'frame-ancestors': "'none'",
'navigate-to': "'none'",
// Reporting directives
'report-to': 'csp',
// Other directives
'require-trusted-types-for': "'script'",
'trusted-types': "'none'",
'upgrade-insecure-requests': ''
},
contentTypeOptions: {
action: 'nosniff'
},
crossOriginEmbedderPolicy: {
policy: 'require-corp'
},
crossOriginOpenerPolicy: {
policy: 'same-origin'
},
crossOriginResourcePolicy: {
policy: 'same-origin'
},
dnsPrefetchControl: {
allow: false
},
downloadOptions: {
action: 'noopen'
},
frameOptions: {
action: 'deny'
},
originAgentCluster: {},
permissionsPolicy: {
// Standard
accelerometer: '',
'ambient-light-sensor': '',
autoplay: '',
battery: '',
camera: '',
'cross-origin-isolated': '',
'display-capture': '',
'document-domain': '',
'encrypted-media': '',
'execution-while-not-rendered': '',
'execution-while-out-of-viewport': '',
fullscreen: '',
geolocation: '',
gyroscope: '',
'keyboard-map': '',
magnetometer: '',
microphone: '',
midi: '',
'navigation-override': '',
payment: '',
'picture-in-picture': '',
'publickey-credentials-get': '',
'screen-wake-lock': '',
'sync-xhr': '',
usb: '',
'web-share': '',
'xr-spatial-tracking': '',
// Proposed
'clipboard-read': '',
'clipboard-write': '',
gamepad: '',
'speaker-selection': '',
// Experimental
'conversion-measurement': '',
'focus-without-user-activation': '',
hid: '',
'idle-detection': '',
'interest-cohort': '',
serial: '',
'sync-script': '',
'trust-token-redemption': '',
'window-placement': '',
'vertical-scroll': ''
},
permittedCrossDomainPolicies: {
policy: 'none' // none, master-only, by-content-type, by-ftp-filename, all
},
poweredBy: {
server: ''
},
referrerPolicy: {
policy: 'no-referrer'
},
reportTo: {
maxAge: 365 * 24 * 60 * 60,
default: '',
includeSubdomains: true,
csp: '',
staple: '',
xss: ''
},
strictTransportSecurity: {
maxAge: 180 * 24 * 60 * 60,
includeSubDomains: true,
preload: true
},
xssProtection: {
reportTo: 'xss'
}
};
const helmet = {};
const helmetHtmlOnly = {};
// *** https://github.com/helmetjs/helmet/tree/main/middlewares *** //
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy
helmetHtmlOnly.contentSecurityPolicy = (headers, config) => {
let header = Object.keys(config)
.map((policy) => (config[policy] ? `${policy} ${config[policy]}` : ''))
.filter((str) => str)
.join('; ')
if (config.sandbox === '') {
header += '; sandbox'
}
if (config['upgrade-insecure-requests'] === '') {
header += '; upgrade-insecure-requests'
}
headers['Content-Security-Policy'] = header
}
helmetHtmlOnly.contentSecurityPolicy = (headers, config)=>{
let header = Object.keys(config).map((policy)=>config[policy] ? `${policy} ${config[policy]}` : '').filter((str)=>str).join('; ');
if (config.sandbox === '') {
header += '; sandbox';
}
if (config['upgrade-insecure-requests'] === '') {
header += '; upgrade-insecure-requests';
}
headers['Content-Security-Policy'] = header;
};
// crossdomain - N/A - for Adobe products
helmetHtmlOnly.crossOriginEmbedderPolicy = (headers, config) => {
headers['Cross-Origin-Embedder-Policy'] = config.policy
}
helmetHtmlOnly.crossOriginOpenerPolicy = (headers, config) => {
headers['Cross-Origin-Opener-Policy'] = config.policy
}
helmetHtmlOnly.crossOriginResourcePolicy = (headers, config) => {
headers['Cross-Origin-Resource-Policy'] = config.policy
}
helmetHtmlOnly.crossOriginEmbedderPolicy = (headers, config)=>{
headers['Cross-Origin-Embedder-Policy'] = config.policy;
};
helmetHtmlOnly.crossOriginOpenerPolicy = (headers, config)=>{
headers['Cross-Origin-Opener-Policy'] = config.policy;
};
helmetHtmlOnly.crossOriginResourcePolicy = (headers, config)=>{
headers['Cross-Origin-Resource-Policy'] = config.policy;
};
// DEPRECATED: expectCt
// DEPRECATED: hpkp
// https://www.permissionspolicy.com/
helmetHtmlOnly.permissionsPolicy = (headers, config) => {
headers['Permissions-Policy'] = Object.keys(config)
.map(
(policy) =>
`${policy}=${config[policy] === '*' ? '*' : '(' + config[policy] + ')'}`
)
.join(', ')
}
helmet.originAgentCluster = (headers, config) => {
headers['Origin-Agent-Cluster'] = '?1'
}
helmetHtmlOnly.permissionsPolicy = (headers, config)=>{
headers['Permissions-Policy'] = Object.keys(config).map((policy)=>`${policy}=${config[policy] === '*' ? '*' : '(' + config[policy] + ')'}`).join(', ');
};
helmet.originAgentCluster = (headers, config)=>{
headers['Origin-Agent-Cluster'] = '?1';
};
// https://github.com/helmetjs/referrer-policy
helmet.referrerPolicy = (headers, config) => {
headers['Referrer-Policy'] = config.policy
}
helmetHtmlOnly.reportTo = (headers, config) => {
headers['Report-To'] = Object.keys(config)
.map((group) => {
const includeSubdomains =
group === 'default'
? `, "include_subdomains": ${config.includeSubdomains}`
: ''
return config[group] && group !== 'includeSubdomains'
? `{ "group": "default", "max_age": ${config.maxAge}, "endpoints": [ { "url": "${config[group]}" } ]${includeSubdomains} }`
: ''
})
.filter((str) => str)
.join(', ')
}
helmet.referrerPolicy = (headers, config)=>{
headers['Referrer-Policy'] = config.policy;
};
helmetHtmlOnly.reportTo = (headers, config)=>{
headers['Report-To'] = Object.keys(config).map((group)=>{
const includeSubdomains = group === 'default' ? `, "include_subdomains": ${config.includeSubdomains}` : '';
return config[group] && group !== 'includeSubdomains' ? `{ "group": "default", "max_age": ${config.maxAge}, "endpoints": [ { "url": "${config[group]}" } ]${includeSubdomains} }` : '';
}).filter((str)=>str).join(', ');
};
// https://github.com/helmetjs/hsts
helmet.strictTransportSecurity = (headers, config) => {
let header = 'max-age=' + Math.round(config.maxAge)
if (config.includeSubDomains) {
header += '; includeSubDomains'
}
if (config.preload) {
header += '; preload'
}
headers['Strict-Transport-Security'] = header
}
helmet.strictTransportSecurity = (headers, config)=>{
let header = 'max-age=' + Math.round(config.maxAge);
if (config.includeSubDomains) {
header += '; includeSubDomains';
}
if (config.preload) {
header += '; preload';
}
headers['Strict-Transport-Security'] = header;
};
// noCache - N/A - separate middleware
// X-* //
// https://github.com/helmetjs/dont-sniff-mimetype
helmet.contentTypeOptions = (headers, config) => {
headers['X-Content-Type-Options'] = config.action
}
helmet.contentTypeOptions = (headers, config)=>{
headers['X-Content-Type-Options'] = config.action;
};
// https://github.com/helmetjs/dns-Prefetch-control
helmet.dnsPrefetchControl = (headers, config) => {
headers['X-DNS-Prefetch-Control'] = config.allow ? 'on' : 'off'
}
helmet.dnsPrefetchControl = (headers, config)=>{
headers['X-DNS-Prefetch-Control'] = config.allow ? 'on' : 'off';
};
// https://github.com/helmetjs/ienoopen
helmet.downloadOptions = (headers, config) => {
headers['X-Download-Options'] = config.action
}
helmet.downloadOptions = (headers, config)=>{
headers['X-Download-Options'] = config.action;
};
// https://github.com/helmetjs/frameOptions
helmetHtmlOnly.frameOptions = (headers, config) => {
headers['X-Frame-Options'] = config.action.toUpperCase()
}
helmetHtmlOnly.frameOptions = (headers, config)=>{
headers['X-Frame-Options'] = config.action.toUpperCase();
};
// https://github.com/helmetjs/crossdomain
helmet.permittedCrossDomainPolicies = (headers, config) => {
headers['X-Permitted-Cross-Domain-Policies'] = config.policy
}
helmet.permittedCrossDomainPolicies = (headers, config)=>{
headers['X-Permitted-Cross-Domain-Policies'] = config.policy;
};
// https://github.com/helmetjs/hide-powered-by
helmet.poweredBy = (headers, config) => {
if (config.server) {
headers['X-Powered-By'] = config.server
} else {
delete headers.Server
delete headers['X-Powered-By']
}
}
helmet.poweredBy = (headers, config)=>{
if (config.server) {
headers['X-Powered-By'] = config.server;
} else {
delete headers.Server;
delete headers['X-Powered-By'];
}
};
// https://github.com/helmetjs/x-xss-protection
helmetHtmlOnly.xssProtection = (headers, config) => {
let header = '1; mode=block'
if (config.reportTo) {
header += '; report=' + config.reportTo
}
headers['X-XSS-Protection'] = header
}
helmetHtmlOnly.xssProtection = (headers, config)=>{
let header = '1; mode=block';
if (config.reportTo) {
header += '; report=' + config.reportTo;
}
headers['X-XSS-Protection'] = header;
};
const httpSecurityHeadersMiddleware = (opts = {})=>{
const options = {
...defaults,
...opts
};
const httpSecurityHeadersMiddlewareAfter = async (request)=>{
normalizeHttpResponse(request);
Object.keys(helmet).forEach((key)=>{
if (!options[key]) return;
const config = {
...defaults[key],
...options[key]
};
helmet[key](request.response.headers, config);
});
if (request.response.headers['Content-Type']?.includes('text/html')) {
Object.keys(helmetHtmlOnly).forEach((key)=>{
if (!options[key]) return;
const config = {
...defaults[key],
...options[key]
};
helmetHtmlOnly[key](request.response.headers, config);
});
}
};
const httpSecurityHeadersMiddlewareOnError = async (request)=>{
if (request.response === undefined) return;
await httpSecurityHeadersMiddlewareAfter(request);
};
return {
after: httpSecurityHeadersMiddlewareAfter,
onError: httpSecurityHeadersMiddlewareOnError
};
};
export default httpSecurityHeadersMiddleware;
const httpSecurityHeadersMiddleware = (opts = {}) => {
const options = { ...defaults, ...opts }
const httpSecurityHeadersMiddlewareAfter = async (request) => {
normalizeHttpResponse(request)
Object.keys(helmet).forEach((key) => {
if (!options[key]) return
const config = { ...defaults[key], ...options[key] }
helmet[key](request.response.headers, config)
})
if (request.response.headers['Content-Type']?.includes('text/html')) {
Object.keys(helmetHtmlOnly).forEach((key) => {
if (!options[key]) return
const config = { ...defaults[key], ...options[key] }
helmetHtmlOnly[key](request.response.headers, config)
})
}
}
const httpSecurityHeadersMiddlewareOnError = async (request) => {
if (request.response === undefined) return
await httpSecurityHeadersMiddlewareAfter(request)
}
return {
after: httpSecurityHeadersMiddlewareAfter,
onError: httpSecurityHeadersMiddlewareOnError
}
}
export default httpSecurityHeadersMiddleware
{
"name": "@middy/http-security-headers",
"version": "5.0.0-alpha.1",
"version": "5.0.0-alpha.2",
"description": "Applies best practice security headers to responses. It's a simplified port of HelmetJS",

@@ -67,7 +67,7 @@ "type": "module",

"dependencies": {
"@middy/util": "5.0.0-alpha.1"
"@middy/util": "5.0.0-alpha.2"
},
"devDependencies": {
"@middy/core": "5.0.0-alpha.1"
"@middy/core": "5.0.0-alpha.2"
}
}
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