secureCodeBox/secureCodeBox

View on GitHub
scanners/wpscan/parser/parser.js

Summary

Maintainability
C
7 hrs
Test Coverage
A
100%
// SPDX-FileCopyrightText: the secureCodeBox authors
//
// SPDX-License-Identifier: Apache-2.0

/**
 * Convert the WPScan file / json into secureCodeBox Findings
 */
async function parse(scanResults) {
  if (typeof (scanResults) === "string") // empty file
    return [];

  const wpscanVersion = scanResults.banner.version;
  const wpscanRequestsDone = scanResults.requests_done;

  const targetUrl = scanResults.target_url;
  const targetIp = scanResults.target_ip;
  // convert unix timestamp to ISO date string, multiply by 1000 because JS uses milliseconds
  const identified_at = new Date(scanResults.stop_time * 1000).toISOString();

  // Add a general INFORMATIONAL summary finding
const summaryFinding = {
  name: "WordPress Service",
  description: "WordPress Service Information",
  identified_at: identified_at,
  category: "WordPress Service",
  location: targetUrl,
  osi_layer: "APPLICATION",
  severity: "INFORMATIONAL",
  references: null,
  confidence: scanResults.version?.confidence,
  attributes: {
    hostname: targetUrl,
    ip_addresses: [targetIp],
    wpscan_version: wpscanVersion,
    wpscan_requests: wpscanRequestsDone,
    wp_version: scanResults.version?.number,
    wp_release_date: scanResults.version?.release_date,
    wp_release_status: scanResults.version?.status,
    wp_interesting_entries: scanResults.version?.interesting_entries,
    wp_found_by: scanResults.version?.found_by,
    wp_confirmed_by: scanResults.version?.confirmed_by,
    wp_vulnerabilities: scanResults.version?.vulnerabilities,
  },
};

// Add all interesting findings as INFORMATIONAL
const interestingFindings = scanResults.interesting_findings.map(interestingFinding => {
  // Create a flattened array of references with their types
  const references = Object.entries(interestingFinding.references)
    .flatMap(([key, elements]) =>
      elements.map(element => ({
        type: key.toUpperCase(),
        value: element,
      }))
    );

 // Return the interesting findings object for the current entry
  return {
    name: `WordPress finding '${interestingFinding.type}'`,
    description: interestingFinding.to_s,
    category: `WordPress ${interestingFinding.type}`,
    location: interestingFinding.url,
    osi_layer: "APPLICATION",
    severity: "INFORMATIONAL",
    confidence: interestingFinding.confidence,
    references: references.length > 0 ? references : null,
    attributes: {
      hostname: targetUrl,
      wp_interesting_entries: interestingFinding.interesting_entries,
      wp_found_by: interestingFinding.found_by,
      wp_confirmed_by: interestingFinding.confirmed_by,
    },
  };
});

// Add plugin vulnerabilities as HIGH
const pluginVulnerabilities = Object.values(scanResults.plugins).flatMap(plugin =>
  plugin.vulnerabilities.map(vulnerability => {
    // Create a flattened array of references with their types
    const references = Object.entries(vulnerability.references)
      .flatMap(([key, elements]) =>
        elements.map(element => ({
          type: key.toUpperCase(),
          value: element,
        }))
      );
    // Return the plugin vulnerabilities object for the current plugin and vulnerability
    return {
      name: `WordPress finding: vulnerability in '${plugin['slug']}'`,
      description: vulnerability['title'],
      category: "WordPress Plugin",
      location: plugin['location'],
      osi_layer: "APPLICATION",
      severity: "HIGH",
      references: references.length > 0 ? references : null,
      attributes: {
        hostname: targetUrl,
        confidence: plugin['confidence'],
        wp_interesting_entries: plugin['interesting_entries'],
        wp_found_by: plugin['found_by'],
        wp_confirmed_by: plugin['confirmed_by'],
      },
    };
  })
);

// Combine all findings and return
return [summaryFinding, ...interestingFindings, ...pluginVulnerabilities];
}
module.exports.parse = parse;