if (data.report) {
const report = data.report;
const cwe = data.cwe;
return {
decision: {
status: 'continue',
message: 'Creating Vulnerability',
},
request: {
body: buildRequestBody(report, cwe)
},
data: {}
};
}
else {
return {
decision: {
status: 'abort',
message: 'Missing HackerOne Report',
}
};
}
function buildRequestBody (report, cwe) {
const vuln = {
projectId: "685500711d6a44e61f90db4e",
title: "New Submission",
affected_asset_name: "AttackForge-TEST H1B",
priority: "Info",
likelihood_of_exploitation: 1,
description: "TBD",
attack_scenario: "TBD",
remediation_recommendation: "TBD",
steps_to_reproduce: "TBD",
tags: [
'HackerOne',
'H1'
],
is_visible: true,
custom_fields: []
};
if (cwe) {
if (cwe.ID) {
const name = cwe.ID;
Array.push(vuln.tags, 'CWE-' + cwe.ID);
}
if (cwe.Name) {
const name = cwe.Name;
vuln.title = name;
}
if (cwe.Description) {
let description = cwe.Description;
vuln.description = formatVulnInfo(description);
}
if (cwe.ExtendedDescription) {
let extendedDescription = cwe.ExtendedDescription;
vuln.description = vuln.description + ' ' + formatVulnInfo(extendedDescription);
}
if (cwe.BackgroundDetails) {
const backgroundDetails = cwe.BackgroundDetails;
vuln.attack_scenario = "";
if (Array.isArray(backgroundDetails)) {
for (let x = 0; x < backgroundDetails.length; x++) {
const attackScenario = backgroundDetails[x];
vuln.attack_scenario = vuln.attack_scenario + formatVulnInfo(attackScenario);
}
}
else {
vuln.attack_scenario = vuln.attack_scenario + formatVulnInfo(backgroundDetails);
}
}
if (cwe.PotentialMitigations) {
const potentialMitigations = cwe.PotentialMitigations;
vuln.remediation_recommendation = "";
if (Array.isArray(potentialMitigations)) {
for (let x = 0; x < potentialMitigations.length; x++) {
const mitigation = potentialMitigations[x];
if (mitigation.Description) {
vuln.remediation_recommendation = vuln.remediation_recommendation
+ formatVulnInfo(mitigation.Description);
}
}
}
else {
if (potentialMitigations.Description) {
vuln.remediation_recommendation = vuln.remediation_recommendation
+ formatVulnInfo(potentialMitigations.Description);
}
}
}
if (report.attributes?.title && report.attributes.vulnerability_information) {
vuln.steps_to_reproduce = '<p>'
+ report.attributes.title + '</p><p>'
+ formatVulnInfo(report.attributes.vulnerability_information)
+ '</p>';
}
}
else {
if (report.attributes?.title) {
vuln.title = report.attributes.title;
}
if (report.attributes?.vulnerability_information) {
vuln.description = formatVulnInfo(report.attributes.vulnerability_information);
}
}
if (report.id) {
Array.push(vuln.custom_fields, {
key: "hackerone_report_id",
value: report.id
});
if (report.relationships?.program?.data?.attributes?.handle) {
const handle = report.relationships.program.data.attributes.handle;
Array.push(vuln.custom_fields, {
key: "hackerone_report_url",
value: 'https://hackerone.com/bugs?report_id=' + report.id + '&subject=' + handle
});
}
}
if (report.relationships?.severity?.data?.attributes) {
const severity = report.relationships.severity.data.attributes;
if (severity.rating === 'critical') {
vuln.priority = 'Critical';
}
else if (severity.rating === 'high') {
vuln.priority = 'High';
}
else if (severity.rating === 'medium') {
vuln.priority = 'Medium';
}
else if (severity.rating === 'low') {
vuln.priority = 'Low';
}
if (severity.score && severity.cvss_vector_string) {
vuln.likelihood_of_exploitation = Number.parseInt(Math.ceil(severity.score));
Array.push(vuln.tags, 'CVSSv3.1 Base Score: ' + severity.score);
Array.push(vuln.tags, severity.cvss_vector_string);
}
}
return vuln;
};
function formatVulnInfo (value) {
if (String.startsWith(value, "\n\n")) {
value = String.substring(value, 2);
}
else if (String.startsWith(value, "\n")) {
value = String.substring(value, 1);
}
value = String.replaceAll(value, "\n\n", "<br/>");
value = String.replaceAll(value, "\n", "<br/>");
return value;
};