Package com.denimgroup.threadfix.service.merge

Source Code of com.denimgroup.threadfix.service.merge.VulnerabilityParser

////////////////////////////////////////////////////////////////////////
//
//     Copyright (c) 2009-2014 Denim Group, Ltd.
//
//     The contents of this file are subject to the Mozilla Public License
//     Version 2.0 (the "License"); you may not use this file except in
//     compliance with the License. You may obtain a copy of the License at
//     http://www.mozilla.org/MPL/
//
//     Software distributed under the License is distributed on an "AS IS"
//     basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
//     License for the specific language governing rights and limitations
//     under the License.
//
//     The Original Code is ThreadFix.
//
//     The Initial Developer of the Original Code is Denim Group, Ltd.
//     Portions created by Denim Group, Ltd. are Copyright (C)
//     Denim Group, Ltd. All Rights Reserved.
//
//     Contributor(s): Denim Group, Ltd.
//
////////////////////////////////////////////////////////////////////////
package com.denimgroup.threadfix.service.merge;

import com.denimgroup.threadfix.data.entities.Finding;
import com.denimgroup.threadfix.data.entities.GenericSeverity;
import com.denimgroup.threadfix.data.entities.GenericVulnerability;
import com.denimgroup.threadfix.data.entities.Vulnerability;
import com.denimgroup.threadfix.logging.SanitizedLogger;

import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Calendar;

public class VulnerabilityParser {
 
  private final static SanitizedLogger log = new SanitizedLogger(VulnerabilityParser.class);

  private VulnerabilityParser(){}
 
  /**
   * Find the hashed vulnerability ID(s) and put them into a vulnerability
   * object.
   *
   * THIS METHOD REQUIRES THE CHANNEL VULN AND EITHER PARAMETER OR PATH TO
   * ALREADY BE SET
   *
   * @return resulting Vulnerability
   */
  public static Vulnerability parse(Finding finding) {
   
    if (finding == null) {
      log.warn("Unable to parse a vulnerability due to a null Finding.");
      return null;
    }

    if (finding.getChannelVulnerability() == null) {
      log.warn("The finding did not have a ChannelVulnerability so no vulnerability could be parsed.");
      return null;
    }

    Vulnerability returnVulnerability = null;
   
    String locationVariableHash, locationHash, variableHash;
    GenericVulnerability genericVulnerability = finding.getChannelVulnerability().getGenericVulnerability();

    if (genericVulnerability == null
        || genericVulnerability.getName() == null
        || genericVulnerability.getName().trim().equals("")) {

            log.warn("No generic vulnerability was found for the Channel Vulnerability with code "
                    + finding.getChannelVulnerability().getCode());
      return null;
    }

    Vulnerability vulnerability = new Vulnerability();
    vulnerability.openVulnerability(Calendar.getInstance());
    vulnerability.setGenericVulnerability(genericVulnerability);
    vulnerability.setSurfaceLocation(finding.getSurfaceLocation());
   
    // TODO calculate some sort of threshold here and figure out whether or not we want to keep
    // the calculated url path or not.
    vulnerability.setCalculatedUrlPath(finding.getCalculatedUrlPath());
   
    if (finding.getIsStatic()) {
      vulnerability.setCalculatedFilePath(finding.getCalculatedFilePath());
    }
     
    if (finding.isMarkedFalsePositive()) {
      log.info("Creating a false positive vulnerability from a finding marked false positive.");
      vulnerability.setIsFalsePositive(finding.isMarkedFalsePositive());
    }

    String vulnName = genericVulnerability.getName();

    if (finding.getChannelSeverity() != null) {
      vulnerability.setGenericSeverity(getGenericSeverity(finding));
    }

    String param = null;
    if (finding.getSurfaceLocation() != null) {
      param = finding.getSurfaceLocation().getParameter();
    }
   
    if (finding.getSurfaceLocation() != null
        && finding.getSurfaceLocation().getPath() != null
        && !finding.getSurfaceLocation().getPath().equals("")) {
      if (param != null) {
        // if we get here, all three variables are present. Hash all of
        // them.
        locationVariableHash = hashFindingInfo(vulnName, finding
            .getSurfaceLocation().getPath(), param);
        locationHash = hashFindingInfo(vulnName, finding
            .getSurfaceLocation().getPath(), null);
        variableHash = hashFindingInfo(vulnName, null, param);
        vulnerability.setLocationVariableHash(locationVariableHash);
        vulnerability.setLocationHash(locationHash);
        vulnerability.setVariableHash(variableHash);
        returnVulnerability = vulnerability;
      } else {
        // if we get here, we just have location and CWE.
        locationHash = hashFindingInfo(vulnName, finding
            .getSurfaceLocation().getPath(), null);
        vulnerability.setLocationHash(locationHash);
        returnVulnerability = vulnerability;
      }
    } else if (param != null) {
      // if we get here, we have variable and CWE
      variableHash = hashFindingInfo(vulnName, null, param);
      vulnerability.setVariableHash(variableHash);
      returnVulnerability = vulnerability;
    } else {
      log.warn("The finding had neither path nor parameter and no vulnerability could be parsed.");
    }
   
    if (returnVulnerability != null) {
      vulnerability.setFindings(new ArrayList<Finding>());
      vulnerability.getFindings().add(finding);
      finding.setFirstFindingForVuln(true);
      finding.setVulnerability(vulnerability);
    }
   
    return returnVulnerability;
  }
 
 
  /**
   * Hashes whatever three strings are given to it.
   *
   * @param type
   *            The generic, CWE type of vulnerability.
   * @param url
   *            The URL location of the vulnerability.
   * @param param
   *            The vulnerable parameter (optional)
   * @return The three strings concatenated, downcased, trimmed, and hashed.
   */
  private static String hashFindingInfo(String type, String url, String param) {
    StringBuffer toHash = new StringBuffer();

    if (type != null) {
      toHash = toHash.append(type.toLowerCase().trim());
    }

    if (url != null) {
      if (url.indexOf('/') == 0 || url.indexOf('\\') == 0) {
        toHash = toHash.append(url.substring(1).toLowerCase().trim());
      } else {
        toHash = toHash.append(url.toLowerCase().trim());
      }
    }

    if (param != null) {
      toHash = toHash.append(param.toLowerCase().trim());
    }

    try {
      MessageDigest messageDigest = MessageDigest.getInstance("MD5");
      messageDigest.update(toHash.toString().getBytes(), 0,
          toHash.length());
      return new BigInteger(1, messageDigest.digest()).toString(16);
    } catch (NoSuchAlgorithmException e) {
      e.printStackTrace();
      return null;
    }
  }
 
  public static void addToVuln(Vulnerability vuln, Finding finding) {
    vuln.getFindings().add(finding);

    // update the generic severity
        GenericSeverity higherGenericSeverity = getHigherSeverity(finding, vuln);
    vuln.setGenericSeverity(higherGenericSeverity);
        vuln.setOriginalGenericSeverity(higherGenericSeverity);

    finding.setVulnerability(vuln);
  }
 
  private static GenericSeverity getHigherSeverity(Finding finding, Vulnerability vuln) {
    GenericSeverity
      findingSeverity = getGenericSeverity(finding),
      vulnSeverity = vuln.getGenericSeverity(),
      returnSeverity = null;
   
    if (findingSeverity != null) {
      if (vulnSeverity == null) {
        returnSeverity = findingSeverity;
      } else if (vulnSeverity.getIntValue() != null &&
          findingSeverity.getIntValue() != null &&
          vulnSeverity.getIntValue() < findingSeverity.getIntValue()) {
        returnSeverity = findingSeverity;
      }
    }
   
    if (returnSeverity == null) {
      returnSeverity = vulnSeverity;
    }
   
    return returnSeverity;
  }
 
  private static GenericSeverity getGenericSeverity(Finding finding) {
    GenericSeverity severity = null;

        if (finding != null && finding.getChannelSeverity() == null) {
            log.warn("No Channel Severity found for " + finding.getChannelVulnerability().getName());
        }
    if (finding != null && finding.getChannelSeverity()!= null && finding.getChannelSeverity().getSeverityMap() != null)
      severity = finding.getChannelSeverity().getSeverityMap().getGenericSeverity();
 
    return severity;
  }
 
}
TOP

Related Classes of com.denimgroup.threadfix.service.merge.VulnerabilityParser

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.