Files
shields/services/security-headers/security-headers.service.js

92 lines
2.0 KiB
JavaScript

import Joi from 'joi'
import { optionalUrl } from '../validators.js'
import { BaseService, NotFound } from '../index.js'
const queryParamSchema = Joi.object({
url: optionalUrl.required(),
ignoreRedirects: Joi.equal(''),
}).required()
const documentation = `
The [Security Headers](https://securityheaders.com/)
provide an easy mechanism to analyze HTTP response headers and
give information on how to deploy missing headers.
The scan result will be hidden from the public result list and follow redirects will be on too.
`
export default class SecurityHeaders extends BaseService {
static category = 'monitoring'
static route = {
base: '',
pattern: 'security-headers',
queryParamSchema,
}
static examples = [
{
title: 'Security Headers',
namedParams: {},
queryParams: { url: 'https://shields.io' },
staticPreview: this.render({
grade: 'A+',
}),
documentation,
},
{
title: "Security Headers (Don't follow redirects)",
namedParams: {},
queryParams: { url: 'https://www.shields.io', ignoreRedirects: null },
staticPreview: this.render({
grade: 'R',
}),
documentation,
},
]
static defaultBadgeData = {
label: 'security headers',
}
static render({ grade }) {
const colorMap = {
'A+': 'brightgreen',
A: 'green',
B: 'yellow',
C: 'yellow',
D: 'orange',
E: 'orange',
F: 'red',
R: 'blue',
}
return {
message: grade,
color: colorMap[grade],
}
}
async handle(namedParams, { url, ignoreRedirects }) {
const { res } = await this._request({
url: 'https://securityheaders.com',
options: {
method: 'HEAD',
searchParams: {
q: url,
hide: 'on',
followRedirects: ignoreRedirects !== undefined ? null : 'on',
},
},
})
const grade = res.headers['x-grade']
if (!grade) {
throw new NotFound({ prettyMessage: 'not available' })
}
return this.constructor.render({ grade })
}
}