-
Notifications
You must be signed in to change notification settings - Fork 323
/
Copy pathhsts-header-missing-analyzer.js
49 lines (40 loc) · 1.44 KB
/
hsts-header-missing-analyzer.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
'use strict'
const { HSTS_HEADER_MISSING } = require('../vulnerabilities')
const { MissingHeaderAnalyzer } = require('./missing-header-analyzer')
const HSTS_HEADER_NAME = 'Strict-Transport-Security'
const HEADER_VALID_PREFIX = 'max-age'
class HstsHeaderMissingAnalyzer extends MissingHeaderAnalyzer {
constructor () {
super(HSTS_HEADER_MISSING, HSTS_HEADER_NAME)
}
_isVulnerableFromRequestAndResponse (req, res) {
const headerValues = this._getHeaderValues(res, HSTS_HEADER_NAME)
return this._isHttpsProtocol(req) && (
headerValues.length === 0 ||
headerValues.some(headerValue => !this._isHeaderValid(headerValue))
)
}
_isHeaderValid (headerValue) {
if (!headerValue) {
return false
}
headerValue = headerValue.trim()
if (!headerValue.startsWith(HEADER_VALID_PREFIX)) {
return false
}
const semicolonIndex = headerValue.indexOf(';')
let timestampString
if (semicolonIndex > -1) {
timestampString = headerValue.substring(HEADER_VALID_PREFIX.length + 1, semicolonIndex)
} else {
timestampString = headerValue.substring(HEADER_VALID_PREFIX.length + 1)
}
const timestamp = parseInt(timestampString)
// eslint-disable-next-line eqeqeq
return timestamp == timestampString && timestamp > 0
}
_isHttpsProtocol (req) {
return req.protocol === 'https' || req.headers['x-forwarded-proto'] === 'https'
}
}
module.exports = new HstsHeaderMissingAnalyzer()