is-website-vulnerable
Version:
finds publicly known security vulnerabilities in a website's frontend JavaScript libraries
134 lines (111 loc) • 3.43 kB
JavaScript
/* eslint-disable security/detect-object-injection */
/* eslint-disable indent */
const chalk = require('chalk')
const { trimUtmParams } = require('./Utils')
module.exports = class RenderConsole {
constructor(scanResults, showLibs) {
this.data = scanResults
this.showLibs = showLibs
}
print() {
const output = this.format()
console.log(output)
}
format() {
let output = ''
output += `
`
output += `Website: ${this.data.lhr.finalUrl}`
const vulnerabilitiesResults = this.data.lhr.audits['no-vulnerable-libraries']
let vulnerabilitiesCount = 0
if (this.showLibs) {
output += this.formatLibraries()
}
if (
vulnerabilitiesResults.details &&
vulnerabilitiesResults.details.items &&
vulnerabilitiesResults.details.items.length > 0
) {
if (this.showLibs) {
output += `
Vulnerabilities:`
}
vulnerabilitiesResults.details.items.forEach(vulnItem => {
vulnerabilitiesCount += vulnItem.vulnCount
const vulnInfo = this.formatVulnerability(vulnItem)
output += vulnInfo
})
} else {
output += `
○ No JavaScript libraries detected with publicly known security vulnerabilities`
}
output += `
[${chalk.bold.white(vulnerabilitiesCount)}] Total vulnerabilities
[${this.data.lhr.timing.total}ms] execution time
vulnerabilities powered by Snyk.io (https://snyk.io/vuln?type=npm)
`
return output
}
formatLibraries() {
let output = ''
if (!this.data.lhr) return output
const jsLibrariesResult = this.data.lhr.audits['js-libraries']
if (
jsLibrariesResult.details &&
jsLibrariesResult.details.items &&
jsLibrariesResult.details.items.length > 0
) {
output = `
Libraries:
`
jsLibrariesResult.details.items.forEach(jsLib => {
output += `
[*] ${jsLib.name} ${jsLib.version || '(version not available)'}`
})
output += `
`
} else {
output += `
○ No JavaScript libraries detected`
}
return output
}
formatVulnerability(vulnItem) {
if (!vulnItem || !vulnItem.detectedLib || !vulnItem.vulnCount || !vulnItem.highestSeverity) {
return ''
}
return `
⎡ ${chalk.red('✖')} ${vulnItem.detectedLib.text}
⎜ ${this.formatSeverityChart(vulnItem.highestSeverity)} ${chalk
.bgHex(this.formatSeverityColor(vulnItem.highestSeverity))
.bold(` ${vulnItem.vulnCount} `)} vulnerabilities
⎣ ${chalk.hex('#4b45a1')('▶')}︎ ${trimUtmParams(vulnItem.detectedLib.url)}`
}
formatSeverityColor(severity) {
const colorSeverityMap = {
Low: '#595775',
Medium: '#df8620',
High: '#b31a6b'
}
return colorSeverityMap[severity] || colorSeverityMap.Low
}
formatSeverityChart(severity) {
let severityText = ''
switch (severity) {
case 'Low':
severityText = `${chalk.hex(this.formatSeverityColor(severity)).bold('■')}■■`
break
case 'Medium':
severityText = `■${chalk.hex(this.formatSeverityColor(severity)).bold('■')}■`
break
case 'High':
severityText = `■■${chalk.hex(this.formatSeverityColor(severity)).bold('■')}`
break
default:
severityText = `${chalk.hex(this.formatSeverityColor(severity)).bold('■')}■■`
break
}
return severityText
}
}