Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save bobrich/3001f30f1c1eb045c7ce to your computer and use it in GitHub Desktop.
Save bobrich/3001f30f1c1eb045c7ce to your computer and use it in GitHub Desktop.
diff --git a/threadfix-entities/src/main/java/com/denimgroup/threadfix/data/entities/Finding.java b/threadfix-entities/src/main/java/com/denimgroup/threadfix/data/entities/Finding.java
index ec52241..ec0b47d 100644
--- a/threadfix-entities/src/main/java/com/denimgroup/threadfix/data/entities/Finding.java
+++ b/threadfix-entities/src/main/java/com/denimgroup/threadfix/data/entities/Finding.java
@@ -40,6 +40,12 @@ public class Finding extends AuditableEntity implements FindingLike {
private static final long serialVersionUID = 5978786078427181952L;
public static final int LONG_DESCRIPTION_LENGTH = 2047;
+ public static final int ATTACK_STRING_LENGTH = 65535;
+ public static final int ATTACK_REQUEST_LENGTH = 65535;
+ public static final int ATTACK_RESPONSE_LENGTH = 1048575;
+ public static final int SCANNER_DETAIL_LENGTH = 65535;
+ public static final int SCANNER_RECOMMENDATION_LENGTH = 65535;
+ public static final int RAW_FINDING_LENGTH = 1048575;
public static final int NATIVE_ID_LENGTH = 50;
public static final int SOURCE_FILE_LOCATION_LENGTH = 128;
@@ -47,15 +53,42 @@ public class Finding extends AuditableEntity implements FindingLike {
private Scan scan;
- @Size(max = LONG_DESCRIPTION_LENGTH, message = "{errors.maxlength} " + LONG_DESCRIPTION_LENGTH + ".")
+ @Size(max = LONG_DESCRIPTION_LENGTH, message = "{errors.maxlength} "
+ + LONG_DESCRIPTION_LENGTH + ".")
private String longDescription;
+ @Size(max = ATTACK_STRING_LENGTH, message = "{errors.maxlength} "
+ + ATTACK_STRING_LENGTH + ".")
+ private String attackString;
+
+ @Size(max = ATTACK_REQUEST_LENGTH, message = "{errors.maxlength} "
+ + ATTACK_REQUEST_LENGTH + ".")
+ private String attackRequest;
+
+ @Size(max = ATTACK_RESPONSE_LENGTH, message = "{errors.maxlength} "
+ + ATTACK_RESPONSE_LENGTH + ".")
+ private String attackResponse;
+
+ @Size(max = SCANNER_DETAIL_LENGTH, message = "{errors.maxlength} "
+ + SCANNER_DETAIL_LENGTH + ".")
+ private String scannerDetail;
+
+ @Size(max = SCANNER_RECOMMENDATION_LENGTH, message = "{errors.maxlength} "
+ + SCANNER_RECOMMENDATION_LENGTH + ".")
+ private String scannerRecommendation;
+
+ @Size(max = RAW_FINDING_LENGTH, message = "{errors.maxlength} "
+ + RAW_FINDING_LENGTH + ".")
+ private String rawFinding;
+
private ChannelVulnerability channelVulnerability;
- @Size(max = NATIVE_ID_LENGTH, message = "{errors.maxlength} " + NATIVE_ID_LENGTH + ".")
+ @Size(max = NATIVE_ID_LENGTH, message = "{errors.maxlength} "
+ + NATIVE_ID_LENGTH + ".")
private String nativeId;
- @Size(max = NATIVE_ID_LENGTH, message = "{errors.maxlength} " + NATIVE_ID_LENGTH + ".")
+ @Size(max = NATIVE_ID_LENGTH, message = "{errors.maxlength} "
+ + NATIVE_ID_LENGTH + ".")
private String displayId;
private ChannelSeverity channelSeverity;
@@ -65,7 +98,8 @@ public class Finding extends AuditableEntity implements FindingLike {
private int numberMergedResults = 1;
private Integer entryPointLineNumber = -1;
- @Size(max = SOURCE_FILE_LOCATION_LENGTH, message = "{errors.maxlength} " + SOURCE_FILE_LOCATION_LENGTH + ".")
+ @Size(max = SOURCE_FILE_LOCATION_LENGTH, message = "{errors.maxlength} "
+ + SOURCE_FILE_LOCATION_LENGTH + ".")
private String sourceFileLocation;
private boolean isStatic;
private boolean isFirstFindingForVuln;
@@ -161,7 +195,8 @@ public class Finding extends AuditableEntity implements FindingLike {
return staticPathInformation;
}
- public void setStaticPathInformation(StaticPathInformation staticPathInformation) {
+ public void setStaticPathInformation(
+ StaticPathInformation staticPathInformation) {
this.staticPathInformation = staticPathInformation;
}
@@ -191,7 +226,8 @@ public class Finding extends AuditableEntity implements FindingLike {
return scanRepeatFindingMaps;
}
- public void setScanRepeatFindingMaps(List<ScanRepeatFindingMap> scanRepeatFindingMaps) {
+ public void setScanRepeatFindingMaps(
+ List<ScanRepeatFindingMap> scanRepeatFindingMaps) {
this.scanRepeatFindingMaps = scanRepeatFindingMaps;
}
@@ -266,6 +302,60 @@ public class Finding extends AuditableEntity implements FindingLike {
return longDescription;
}
+ public String getAttackString() {
+ return attackString;
+ }
+
+ @Column(length = ATTACK_STRING_LENGTH)
+ public void setAttackString(String attackString) {
+ this.attackString = attackString;
+ }
+
+ public String getAttackRequest() {
+ return attackRequest;
+ }
+
+ @Column(length = ATTACK_REQUEST_LENGTH)
+ public void setAttackRequest(String attackRequest) {
+ this.attackRequest = attackRequest;
+ }
+
+ public String getAttackResponse() {
+ return attackResponse;
+ }
+
+ @Column(length = ATTACK_RESPONSE_LENGTH)
+ public void setAttackResponse(String attackResponse) {
+ this.attackResponse = attackResponse;
+ }
+
+ public String getScannerDetail() {
+ return scannerDetail;
+ }
+
+ @Column(length = SCANNER_DETAIL_LENGTH)
+ public void setScannerDetail(String scannerDetail) {
+ this.scannerDetail = scannerDetail;
+ }
+
+ public String getScannerRecommendation() {
+ return scannerRecommendation;
+ }
+
+ @Column(length = SCANNER_RECOMMENDATION_LENGTH)
+ public void setScannerRecommendation(String scannerRecommendation) {
+ this.scannerRecommendation = scannerRecommendation;
+ }
+
+ public String getRawFinding() {
+ return rawFinding;
+ }
+
+ @Column(length = RAW_FINDING_LENGTH)
+ public void setRawFinding(String rawFinding) {
+ this.rawFinding = rawFinding;
+ }
+
@Column(nullable = false)
public boolean isFirstFindingForVuln() {
return isFirstFindingForVuln;
@@ -324,4 +414,5 @@ public class Finding extends AuditableEntity implements FindingLike {
}
+
}
diff --git a/threadfix-entities/src/main/java/com/denimgroup/threadfix/data/entities/Vulnerability.java b/threadfix-entities/src/main/java/com/denimgroup/threadfix/data/entities/Vulnerability.java
index 11464c3..810a939 100644
--- a/threadfix-entities/src/main/java/com/denimgroup/threadfix/data/entities/Vulnerability.java
+++ b/threadfix-entities/src/main/java/com/denimgroup/threadfix/data/entities/Vulnerability.java
@@ -371,6 +371,7 @@ public class Vulnerability extends BaseEntity {
@Transient
public void closeVulnerability(Scan scan, Calendar closeTime) {
+ /*
active = false;
if (closeTime == null) {
this.closeTime = Calendar.getInstance();
@@ -382,6 +383,7 @@ public class Vulnerability extends BaseEntity {
if (scan != null) {
new ScanCloseVulnerabilityMap(this, scan);
}
+ */
}
@Transient
diff --git a/threadfix-importers/src/main/java/com/denimgroup/threadfix/importer/impl/AbstractChannelImporter.java b/threadfix-importers/src/main/java/com/denimgroup/threadfix/importer/impl/AbstractChannelImporter.java
index f19c00e..05a702a 100644
--- a/threadfix-importers/src/main/java/com/denimgroup/threadfix/importer/impl/AbstractChannelImporter.java
+++ b/threadfix-importers/src/main/java/com/denimgroup/threadfix/importer/impl/AbstractChannelImporter.java
@@ -80,7 +80,7 @@ public abstract class AbstractChannelImporter extends SpringBeanAutowiringSuppor
protected static final String FILE_CHECK_COMPLETED = "File check completed.";
protected enum FindingKey {
- VULN_CODE, PATH, PARAMETER, SEVERITY_CODE, NATIVE_ID, CVE, CWE
+ VULN_CODE, PATH, PARAMETER, SEVERITY_CODE, NATIVE_ID, CVE, CWE, VALUE, REQUEST, RESPONSE, DETAIL, RECOMMENDATION, RAWFINDING
}
// A stream pointing to the scan's contents. Set with either setFile or
@@ -267,7 +267,13 @@ public abstract class AbstractChannelImporter extends SpringBeanAutowiringSuppor
findingMap.get(FindingKey.PARAMETER),
findingMap.get(FindingKey.VULN_CODE),
findingMap.get(FindingKey.SEVERITY_CODE),
- findingMap.get(FindingKey.CWE));
+ findingMap.get(FindingKey.CWE),
+ findingMap.containsKey(FindingKey.VALUE) ? findingMap.get(FindingKey.VALUE) : null,
+ findingMap.containsKey(FindingKey.REQUEST) ? findingMap.get(FindingKey.REQUEST) : null,
+ findingMap.containsKey(FindingKey.RESPONSE) ? findingMap.get(FindingKey.RESPONSE) : null,
+ findingMap.containsKey(FindingKey.DETAIL) ? findingMap.get(FindingKey.DETAIL) : null,
+ findingMap.containsKey(FindingKey.RECOMMENDATION) ? findingMap.get(FindingKey.RECOMMENDATION) : null,
+ findingMap.containsKey(FindingKey.RAWFINDING) ? findingMap.get(FindingKey.RAWFINDING) : null);
}
/**
@@ -289,6 +295,33 @@ public abstract class AbstractChannelImporter extends SpringBeanAutowiringSuppor
@Nullable
protected Finding constructFinding(String url, String parameter,
String channelVulnerabilityCode, String channelSeverityCode, String cweCode) {
+ return constructFinding(url, parameter, channelVulnerabilityCode, channelSeverityCode, cweCode, null, null, null, null, null, null);
+ }
+
+ @Nullable
+ protected Finding constructFinding(String url, String parameter,
+ String channelVulnerabilityCode, String channelSeverityCode, String cweCode, String parameterValue, String request, String response) {
+ return constructFinding(url, parameter, channelVulnerabilityCode, channelSeverityCode, cweCode, parameterValue, request, response, null, null, null);
+ }
+
+ /**
+ *
+ * This method can be used to construct a finding out of the
+ * important common information that findings have.
+ * @param url
+ * @param parameter
+ * @param channelVulnerabilityCode
+ * @param channelSeverityCode
+ * @param cweCode
+ * @param parameterValue
+ * @param request
+ * @param response
+ * @return
+ */
+ protected Finding constructFinding(String url, String parameter,
+ String channelVulnerabilityCode, String channelSeverityCode, String cweCode, String parameterValue,
+ String request, String response, String detail, String recommendation, String rawFinding) {
+
if (channelVulnerabilityCode == null || channelVulnerabilityCode.isEmpty()) {
return null;
}
@@ -335,6 +368,30 @@ public abstract class AbstractChannelImporter extends SpringBeanAutowiringSuppor
finding.setSurfaceLocation(location);
+ if (parameterValue != null && parameterValue.length() > Finding.ATTACK_STRING_LENGTH)
+ parameterValue = parameterValue.substring(0,Finding.ATTACK_STRING_LENGTH-20) + "\n\n[truncated]\n";
+ finding.setAttackString(parameterValue);
+
+ if (request != null && request.length() > Finding.ATTACK_REQUEST_LENGTH)
+ request = request.substring(0,Finding.ATTACK_REQUEST_LENGTH-20) + "\n\n[truncated]\n";
+ finding.setAttackRequest(request);
+
+ if (response != null && response.length() > Finding.ATTACK_RESPONSE_LENGTH)
+ response = response.substring(0,Finding.ATTACK_RESPONSE_LENGTH-20) + "\n\n[truncated]\n";
+ finding.setAttackResponse(response);
+
+ if (detail != null && detail.length() > Finding.SCANNER_DETAIL_LENGTH)
+ detail = detail.substring(0,Finding.SCANNER_DETAIL_LENGTH-20) + "\n\n[truncated]\n";
+ finding.setScannerDetail(detail);
+
+ if (recommendation != null && recommendation.length() > Finding.SCANNER_RECOMMENDATION_LENGTH)
+ recommendation = recommendation.substring(0,Finding.SCANNER_RECOMMENDATION_LENGTH-20) + "\n\n[truncated]\n";
+ finding.setScannerRecommendation(recommendation);
+
+ if (rawFinding != null && rawFinding.length() > Finding.RAW_FINDING_LENGTH)
+ rawFinding = rawFinding.substring(0,Finding.RAW_FINDING_LENGTH-20) + "\n\n[truncated]\n";
+ finding.setRawFinding(rawFinding);
+
ChannelVulnerability channelVulnerability = getChannelVulnerability(channelVulnerabilityCode);
if (channelVulnerability == null) {
@@ -646,9 +703,9 @@ public abstract class AbstractChannelImporter extends SpringBeanAutowiringSuppor
int result = scan.getImportTime().compareTo(testDate);
if (result == 0) {
return ScanImportStatus.DUPLICATE_ERROR;
- } else if (result > 0) {
- return ScanImportStatus.OLD_SCAN_ERROR;
- }
+ } //else if (result > 0) {
+ // return ScanImportStatus.OLD_SCAN_ERROR;
+ //}
}
}
}
diff --git a/threadfix-importers/src/main/java/com/denimgroup/threadfix/importer/impl/upload/ArachniChannelImporter.java b/threadfix-importers/src/main/java/com/denimgroup/threadfix/importer/impl/upload/ArachniChannelImporter.java
index 20f247f..7161ced 100644
--- a/threadfix-importers/src/main/java/com/denimgroup/threadfix/importer/impl/upload/ArachniChannelImporter.java
+++ b/threadfix-importers/src/main/java/com/denimgroup/threadfix/importer/impl/upload/ArachniChannelImporter.java
@@ -23,20 +23,21 @@
////////////////////////////////////////////////////////////////////////
package com.denimgroup.threadfix.importer.impl.upload;
+import java.util.EnumMap;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+
+import com.denimgroup.threadfix.data.ScanCheckResultBean;
+import com.denimgroup.threadfix.data.ScanImportStatus;
import com.denimgroup.threadfix.data.entities.Finding;
import com.denimgroup.threadfix.data.entities.Scan;
import com.denimgroup.threadfix.data.entities.ScannerType;
import com.denimgroup.threadfix.importer.impl.AbstractChannelImporter;
-import com.denimgroup.threadfix.data.ScanCheckResultBean;
-import com.denimgroup.threadfix.data.ScanImportStatus;
import com.denimgroup.threadfix.importer.util.DateUtils;
import com.denimgroup.threadfix.importer.util.HandlerWithBuilder;
-import org.xml.sax.Attributes;
-import org.xml.sax.SAXException;
-
-import java.util.EnumMap;
-import java.util.HashMap;
-import java.util.Map;
/**
*
@@ -47,12 +48,20 @@ class ArachniChannelImporter extends AbstractChannelImporter {
private static Map<String, FindingKey> tagMap = new HashMap<>();
static {
tagMap.put("name", FindingKey.VULN_CODE);
- tagMap.put("code", FindingKey.SEVERITY_CODE);
+ tagMap.put("severity", FindingKey.SEVERITY_CODE);
tagMap.put("variable", FindingKey.PARAMETER);
tagMap.put("var", FindingKey.PARAMETER);
tagMap.put("url", FindingKey.PATH);
+ tagMap.put("injected", FindingKey.VALUE);
+ tagMap.put("request", FindingKey.REQUEST);
+ tagMap.put("html", FindingKey.RESPONSE);
+ tagMap.put("description", FindingKey.DETAIL);
+ tagMap.put("remedy_guidance", FindingKey.RECOMMENDATION);
+ tagMap.put("rawfinding", FindingKey.RAWFINDING);
}
+ private StringBuffer currentRawFinding = new StringBuffer();
+
// Since the severity mappings are static and not included in the XML output,
// these have been reverse engineered from the code
private static Map<String, String> severityMap = new HashMap<>();
@@ -135,6 +144,7 @@ class ArachniChannelImporter extends AbstractChannelImporter {
private boolean getDate = false;
private boolean inFinding = false;
+ private boolean inRequest = false; //for accumulating request headers
private FindingKey itemKey = null;
@@ -162,6 +172,19 @@ class ArachniChannelImporter extends AbstractChannelImporter {
inFinding = true;
} else if (inFinding && tagMap.containsKey(qName)) {
itemKey = tagMap.get(qName);
+ if ("request".equals(qName)){
+ inRequest=true;
+ }
+ } else if (inRequest && "field".equals(qName)){
+ String header = atts.getValue("name") + ": " + atts.getValue("value") + "\n";
+ if (! findingMap.containsKey(FindingKey.REQUEST)){
+ findingMap.put(FindingKey.REQUEST,header);
+ } else {
+ findingMap.put(FindingKey.REQUEST, findingMap.get(FindingKey.REQUEST) + header);
+ }
+ }
+ if (inFinding){
+ currentRawFinding.append(makeTag(name, qName, atts));
}
}
@@ -176,20 +199,41 @@ class ArachniChannelImporter extends AbstractChannelImporter {
"Cross-Site Scripting in HTML &quot;script&quot; tag.");
}
+ //left in place for old versions of Arachni
+ if (! findingMap.containsKey(FindingKey.SEVERITY_CODE) || findingMap.get(FindingKey.SEVERITY_CODE) == null)
findingMap.put(FindingKey.SEVERITY_CODE, severityMap.get(findingMap.get(FindingKey.VULN_CODE)));
+ currentRawFinding.append("</").append(qName).append(">");
+ findingMap.put(FindingKey.RAWFINDING,currentRawFinding.toString());
Finding finding = constructFinding(findingMap);
add(finding);
findingMap = null;
inFinding = false;
+ currentRawFinding.setLength(0);
+
} else if (inFinding && itemKey != null) {
String currentItem = getBuilderText();
+ if (currentItem != null && "RESPONSE".equals(itemKey.toString())){
+ //these are base64 encoded in the xml
+ try {
+ currentItem = new String(javax.xml.bind.DatatypeConverter.parseBase64Binary(currentItem));
+ } catch (Exception ignored){
+ //if it can't be decoded just pass as-is
+ }
+ }
+
+ if ("request".equals(qName)){
+ inRequest=false;
+ }
+
if (currentItem != null && findingMap.get(itemKey) == null) {
findingMap.put(itemKey, currentItem);
}
itemKey = null;
+
+ currentRawFinding.append("</").append(qName).append(">");
}
if (getDate) {
@@ -206,6 +250,9 @@ class ArachniChannelImporter extends AbstractChannelImporter {
if (getDate || itemKey != null) {
addTextToBuilder(ch, start, length);
}
+ if (inFinding){
+ currentRawFinding.append(ch, start, length);
+ }
}
}
diff --git a/threadfix-importers/src/main/java/com/denimgroup/threadfix/importer/impl/upload/BurpSuiteChannelImporter.java b/threadfix-importers/src/main/java/com/denimgroup/threadfix/importer/impl/upload/BurpSuiteChannelImporter.java
index 7f0bb20..bbc4b15 100644
--- a/threadfix-importers/src/main/java/com/denimgroup/threadfix/importer/impl/upload/BurpSuiteChannelImporter.java
+++ b/threadfix-importers/src/main/java/com/denimgroup/threadfix/importer/impl/upload/BurpSuiteChannelImporter.java
@@ -23,24 +23,27 @@
////////////////////////////////////////////////////////////////////////
package com.denimgroup.threadfix.importer.impl.upload;
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.util.HashMap;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.DefaultHandler;
+
+import com.denimgroup.threadfix.data.ScanCheckResultBean;
+import com.denimgroup.threadfix.data.ScanImportStatus;
import com.denimgroup.threadfix.data.entities.Finding;
import com.denimgroup.threadfix.data.entities.Scan;
import com.denimgroup.threadfix.data.entities.ScannerType;
import com.denimgroup.threadfix.importer.impl.AbstractChannelImporter;
-import com.denimgroup.threadfix.data.ScanCheckResultBean;
-import com.denimgroup.threadfix.data.ScanImportStatus;
import com.denimgroup.threadfix.importer.util.DateUtils;
import com.denimgroup.threadfix.importer.util.HandlerWithBuilder;
import com.denimgroup.threadfix.importer.util.RegexUtils;
-import org.xml.sax.Attributes;
-import org.xml.sax.SAXException;
-import org.xml.sax.helpers.DefaultHandler;
-
-import java.io.BufferedReader;
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.util.HashMap;
/**
*
@@ -53,6 +56,7 @@ class BurpSuiteChannelImporter extends AbstractChannelImporter {
private static final String REST_URL_PARAM = "REST URL parameter";
private static final String MANUAL_INSERTION_POINT = "manual insertion point";
private static final HashMap<String, String> SEVERITY_MAP = new HashMap<>();
+ private static Pattern pattern = Pattern.compile("The payload <b>(.*)</b> was submitted");
static {
SEVERITY_MAP.put("deformation", "Information");
SEVERITY_MAP.put("eddium", "Medium");
@@ -68,7 +72,7 @@ class BurpSuiteChannelImporter extends AbstractChannelImporter {
@Override
public Scan parseInput() {
- cleanInputStream();
+ //cleanInputStream();
return parseSAXInput(new BurpSuiteSAXParser());
}
@@ -109,7 +113,20 @@ class BurpSuiteChannelImporter extends AbstractChannelImporter {
private boolean getHostText = false;
private boolean getBackupParameter = false;
private boolean getSerialNumber = false;
-
+ private boolean getParamValueText = false;
+ private boolean getRequestText = false;
+ private boolean getResponseText = false;
+ private boolean getScannerDetail = false;
+ private boolean getScannerRecommendation = false;
+ private boolean getRawFinding = false;
+ private boolean isBase64Encoded = false;
+
+ private String currentScannerDetail = null;
+ private String currentScannerRecommendation = null;
+ private StringBuffer currentRawFinding = new StringBuffer();
+ private String currentParameterValue = null;
+ private String currentRequest = null;
+ private String currentResponse = null;
private String currentChannelVulnCode = null;
private String currentUrlText = null;
private String currentParameter = null;
@@ -141,18 +158,44 @@ class BurpSuiteChannelImporter extends AbstractChannelImporter {
{
if ("type".equals(qName)) {
getChannelVulnText = true;
+ getBuilderText(); //resets the stringbuffer
} else if ("location".equals(qName)) {
getUrlText = true;
+ getBuilderText(); //resets the stringbuffer
} else if ("serialNumber".equals(qName)) {
getSerialNumber = true;
+ getBuilderText(); //resets the stringbuffer
} else if ("host".equals(qName)) {
getHostText = true;
+ getBuilderText(); //resets the stringbuffer
} else if ("severity".equals(qName)) {
getSeverityText = true;
+ getBuilderText(); //resets the stringbuffer
} else if ("issues".equals(qName)) {
date = DateUtils.getCalendarFromString("EEE MMM dd kk:mm:ss zzz yyyy", atts.getValue("exportTime"));
+ getBuilderText(); //resets the stringbuffer
} else if ("request".equals(qName)) {
getBackupParameter = true;
+ getRequestText = true;
+ isBase64Encoded = "true".equals(atts.getValue("base64")) ? true : false;
+ getBuilderText(); //resets the stringbuffer
+ } else if ("response".equals(qName)) {
+ getResponseText = true;
+ isBase64Encoded = "true".equals(atts.getValue("base64")) ? true : false;
+ getBuilderText(); //resets the stringbuffer
+ } else if ("issueDetail".equals(qName)) {
+ getParamValueText = true;
+ getScannerDetail = true;
+ getBuilderText(); //resets the stringbuffer
+ } else if ("remediationDetail".equals(qName)) {
+ getScannerRecommendation = true;
+ getBuilderText(); //resets the stringbuffer
+ } else if ("issue".equals(qName)){
+ getRawFinding = true;
+ getBuilderText(); //resets the stringbuffer
+ }
+ if (getRawFinding){
+ currentRawFinding.append(makeTag(name, qName , atts));
}
}
@@ -179,6 +222,36 @@ class BurpSuiteChannelImporter extends AbstractChannelImporter {
} else if (getSerialNumber) {
currentSerialNumber = getBuilderText();
getSerialNumber = false;
+ } else if (getParamValueText) {
+ currentParameterValue = getBuilderText();
+ currentScannerDetail = currentParameterValue;
+ Matcher m = pattern.matcher(currentParameterValue);
+ if (m.find()){
+ currentParameterValue = m.group(1);
+ } else {
+ currentParameterValue = "";
+ }
+ getParamValueText = false;
+ } else if (getRequestText) {
+ currentRequest = getBuilderText();
+ if (currentRequest != null)
+ try {
+ if (isBase64Encoded)
+ currentRequest = new String(javax.xml.bind.DatatypeConverter.parseBase64Binary(currentRequest));
+ }catch(Exception ignored){
+ //sometimes the content throws an exception when decoding. If so, just leave as-is
+ }
+ getRequestText = false;
+ } else if (getResponseText) {
+ currentResponse = getBuilderText();
+ if (currentResponse != null)
+ try{
+ if (isBase64Encoded)
+ currentResponse = new String(javax.xml.bind.DatatypeConverter.parseBase64Binary(currentResponse));
+ }catch(Exception ignored){
+ //sometimes the content throws an exception when decoding. If so, just leave as-is
+ }
+ getResponseText = false;
} else if (getSeverityText) {
currentSeverityCode = getBuilderText();
getSeverityText = false;
@@ -194,6 +267,13 @@ class BurpSuiteChannelImporter extends AbstractChannelImporter {
}
getBackupParameter = false;
+ } else if (getScannerRecommendation){
+ currentScannerRecommendation = getBuilderText();
+ getScannerRecommendation = false;
+ }
+ //if we're inside an <issue/>
+ if (getRawFinding){
+ currentRawFinding.append("</" + qName + ">\n");
}
if ("issue".equals(qName)) {
@@ -210,11 +290,11 @@ class BurpSuiteChannelImporter extends AbstractChannelImporter {
currentParameter = "";
}
- if (SEVERITY_MAP.get(currentSeverityCode.toLowerCase()) != null) {
+ if (currentSeverityCode != null && SEVERITY_MAP.containsKey(currentSeverityCode.toLowerCase()) && SEVERITY_MAP.get(currentSeverityCode.toLowerCase()) != null) {
currentSeverityCode = SEVERITY_MAP.get(currentSeverityCode.toLowerCase());
}
Finding finding = constructFinding(currentHostText + currentUrlText, currentParameter,
- currentChannelVulnCode, currentSeverityCode);
+ currentChannelVulnCode, currentSeverityCode, null, currentParameterValue, currentRequest, currentResponse, currentScannerDetail, currentScannerRecommendation, currentRawFinding.toString());
add(finding);
@@ -224,15 +304,28 @@ class BurpSuiteChannelImporter extends AbstractChannelImporter {
currentUrlText = null;
currentSerialNumber = null;
currentBackupParameter = null;
+ currentParameterValue = null;
+ currentRequest = null;
+ currentResponse = null;
+ currentScannerDetail = null;
+ currentScannerRecommendation = null;
+
+ getRawFinding = false;
+ currentRawFinding.setLength(0);
}
}
public void characters (char ch[], int start, int length)
{
if (getChannelVulnText || getHostText || getUrlText || getParamText ||
- getSeverityText || getBackupParameter || getSerialNumber) {
+ getSeverityText || getBackupParameter || getSerialNumber ||
+ getParamValueText || getRequestText || getResponseText ||
+ getScannerDetail || getScannerRecommendation ) {
addTextToBuilder(ch,start,length);
}
+ if (getRawFinding){
+ currentRawFinding.append(ch, start, length);
+ }
}
}
diff --git a/threadfix-importers/src/main/java/com/denimgroup/threadfix/importer/impl/upload/NTOSpiderChannelImporter.java b/threadfix-importers/src/main/java/com/denimgroup/threadfix/importer/impl/upload/NTOSpiderChannelImporter.java
index 1f89618..aad33be 100644
--- a/threadfix-importers/src/main/java/com/denimgroup/threadfix/importer/impl/upload/NTOSpiderChannelImporter.java
+++ b/threadfix-importers/src/main/java/com/denimgroup/threadfix/importer/impl/upload/NTOSpiderChannelImporter.java
@@ -50,8 +50,16 @@ class NTOSpiderChannelImporter extends AbstractChannelImporter {
tagMap.put("attackscore", FindingKey.SEVERITY_CODE);
tagMap.put("parametername", FindingKey.PARAMETER);
tagMap.put("normalizedurl", FindingKey.PATH);
+ tagMap.put("attackvalue", FindingKey.VALUE);
+ tagMap.put("request", FindingKey.REQUEST);
+ tagMap.put("response", FindingKey.RESPONSE);
+ tagMap.put("description", FindingKey.DETAIL);
+ tagMap.put("recommendation", FindingKey.RECOMMENDATION);
+ tagMap.put("rawfinding", FindingKey.RAWFINDING); //there is no element rawfinding, this is just a placeholder
}
+ private StringBuilder currentRawFinding = new StringBuilder();
+
private static final String VULN_TAG = "vuln", SCAN_DATE = "scandate",
DATE_PATTERN = "yyyy-MM-dd kk:mm:ss", N_A = "n/a", VULN_LIST = "vulnlist",
VULN_SUMMARY = "VulnSummary";
@@ -97,10 +105,16 @@ class NTOSpiderChannelImporter extends AbstractChannelImporter {
} else if (inFinding && tagMap.containsKey(qName.toLowerCase())) {
itemKey = tagMap.get(qName.toLowerCase());
}
+ if (inFinding){
+ currentRawFinding.append(makeTag(name, qName, atts));
+ }
}
public void endElement (String uri, String name, String qName)
{
+ if (inFinding)
+ currentRawFinding.append("</").append(qName).append(">");
+
if (VULN_TAG.equalsIgnoreCase(qName)) {
if (findingMap.get(FindingKey.PARAMETER) != null &&
@@ -108,17 +122,28 @@ class NTOSpiderChannelImporter extends AbstractChannelImporter {
findingMap.remove(FindingKey.PARAMETER);
}
+ findingMap.put(FindingKey.RAWFINDING, currentRawFinding.toString());
Finding finding = constructFinding(findingMap);
add(finding);
findingMap = null;
inFinding = false;
+ currentRawFinding.setLength(0);
} else if (inFinding && itemKey != null) {
String currentItem = getBuilderText();
- if (currentItem != null && findingMap.get(itemKey) == null) {
+ if (currentItem != null &&
+ ("REQUEST".equals(itemKey.toString()) || "RESPONSE".equals(itemKey.toString()))){
+ //these are base64 encoded in the xml
+ currentItem = new String(javax.xml.bind.DatatypeConverter.parseBase64Binary(currentItem));
+ }
+
+ //NTO vulnerabilities have multiple attack details per vulnerability, with an extra attackvalue sent at the beginning
+ //because of this we allow them to be overwritten in the findingMap to grab the last instance
+ if (currentItem != null ){ // && findingMap.get(itemKey) == null) {
findingMap.put(itemKey, currentItem);
}
itemKey = null;
+
} else if (getDate) {
String tempDateString = getBuilderText();
@@ -127,12 +152,16 @@ class NTOSpiderChannelImporter extends AbstractChannelImporter {
}
getDate = false;
}
+
}
public void characters (char ch[], int start, int length) {
if (getDate || itemKey != null) {
addTextToBuilder(ch, start, length);
}
+ if (inFinding){
+ currentRawFinding.append(ch, start, length);
+ }
}
}
diff --git a/threadfix-importers/src/main/java/com/denimgroup/threadfix/importer/impl/upload/NetsparkerChannelImporter.java b/threadfix-importers/src/main/java/com/denimgroup/threadfix/importer/impl/upload/NetsparkerChannelImporter.java
index 1efddf7..5891a88 100644
--- a/threadfix-importers/src/main/java/com/denimgroup/threadfix/importer/impl/upload/NetsparkerChannelImporter.java
+++ b/threadfix-importers/src/main/java/com/denimgroup/threadfix/importer/impl/upload/NetsparkerChannelImporter.java
@@ -32,6 +32,7 @@ import com.denimgroup.threadfix.data.entities.ScannerType;
import com.denimgroup.threadfix.importer.impl.AbstractChannelImporter;
import com.denimgroup.threadfix.importer.util.DateUtils;
import com.denimgroup.threadfix.importer.util.HandlerWithBuilder;
+
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
@@ -65,11 +66,19 @@ class NetsparkerChannelImporter extends AbstractChannelImporter {
private Boolean getUrlText = false;
private Boolean getParamText = false;
private Boolean getSeverityText = false;
+ private Boolean getParamValueText = false;
+ private Boolean getRequestText = false;
+ private Boolean getResponseText = false;
+ private boolean inFinding = false;
+ private StringBuffer currentRawFinding = new StringBuffer();
private String currentChannelVulnCode = null;
private String currentUrlText = null;
private String currentParameter = null;
private String currentSeverityCode = null;
+ private String currentParameterValue = null;
+ private String currentRequest = null;
+ private String currentResponse = null;
private String host = null;
@@ -96,10 +105,23 @@ class NetsparkerChannelImporter extends AbstractChannelImporter {
getParamText = true;
} else if ("severity".equals(qName)) {
getSeverityText = true;
+ } else if("vulnerableparametervalue".equals(qName)){
+ getParamValueText = true;
+ } else if("rawrequest".equals(qName)){
+ getRequestText = true;
+ } else if("rawresponse".equals(qName)){
+ getResponseText = true;
} else if ("netsparker".equals(qName)) {
// date = getCalendarFromString("MM/dd/yyyy hh:mm:ss a", atts.getValue("generated"));
date = getCalendar(atts.getValue("generated"));
+ } else if ("vulnerability".equals(qName)){
+ inFinding = true;
+ }
+ // in a finding, build the tag
+ if (inFinding){
+ currentRawFinding.append(makeTag(name, qName , atts));
}
+
}
public void endElement (String uri, String name, String qName)
@@ -116,14 +138,28 @@ class NetsparkerChannelImporter extends AbstractChannelImporter {
} else if (getParamText) {
currentParameter = getBuilderText();
getParamText = false;
+ } else if (getParamValueText) {
+ currentParameterValue = getBuilderText();
+ getParamValueText = false;
+ } else if (getRequestText) {
+ currentRequest = getBuilderText();
+ getRequestText = false;
+ } else if (getResponseText) {
+ currentResponse = getBuilderText();
+ getResponseText = false;
} else if (getSeverityText) {
currentSeverityCode = getBuilderText();
getSeverityText = false;
}
+ if (inFinding){
+ currentRawFinding.append("</").append(qName).append(">");
+ }
if ("vulnerability".equals(qName)) {
+
+
Finding finding = constructFinding(currentUrlText, currentParameter,
- currentChannelVulnCode, currentSeverityCode);
+ currentChannelVulnCode, currentSeverityCode, null, currentParameterValue, currentRequest, currentResponse, null, null, currentRawFinding.toString());
// The old XML format didn't include severities. As severities are required
// for vulnerabilities to show on the application page, let's assign medium
@@ -139,14 +175,21 @@ class NetsparkerChannelImporter extends AbstractChannelImporter {
currentSeverityCode = null;
currentParameter = null;
currentUrlText = null;
+ currentParameterValue = null;
+ currentRequest = null;
+ currentResponse = null;
+ inFinding = false;
+ currentRawFinding.setLength(0);
}
}
public void characters (char ch[], int start, int length)
{
- if (getChannelVulnText || getUrlText || getParamText || getSeverityText) {
+ if (getChannelVulnText || getUrlText || getParamText || getSeverityText || getParamValueText || getRequestText || getResponseText) {
addTextToBuilder(ch, start, length);
}
+ if (inFinding)
+ currentRawFinding.append(ch,start,length);
}
}
diff --git a/threadfix-importers/src/main/java/com/denimgroup/threadfix/importer/util/HandlerWithBuilder.java b/threadfix-importers/src/main/java/com/denimgroup/threadfix/importer/util/HandlerWithBuilder.java
index f0bddfe..ce2d5ba 100644
--- a/threadfix-importers/src/main/java/com/denimgroup/threadfix/importer/util/HandlerWithBuilder.java
+++ b/threadfix-importers/src/main/java/com/denimgroup/threadfix/importer/util/HandlerWithBuilder.java
@@ -23,6 +23,9 @@
////////////////////////////////////////////////////////////////////////
package com.denimgroup.threadfix.importer.util;
+import javax.xml.stream.events.StartDocument;
+
+import org.xml.sax.Attributes;
import org.xml.sax.helpers.DefaultHandler;
public abstract class HandlerWithBuilder extends DefaultHandler {
@@ -37,4 +40,30 @@ public abstract class HandlerWithBuilder extends DefaultHandler {
builder.setLength(0);
return toReturn;
}
+
+ //used for synthesizing raw XML from SAX startElement events
+ protected String makeTag(String name, String qName, Attributes attrs){
+
+ StringBuffer tag = new StringBuffer();
+ tag.append("<");
+ if (name != null && name.length()>0){
+ tag.append(name);
+ } else {
+ tag.append(qName);
+ }
+
+ for (int i = 0; i < attrs.getLength(); i++){
+ tag.append(" ");
+ tag.append(attrs.getQName(i));
+ tag.append("=\"");
+ //this will probably need entity encoding
+ tag.append(attrs.getValue(i));
+ tag.append("\"");
+ }
+
+ tag.append(">");
+ return tag.toString();
+ }
+
+
}
diff --git a/threadfix-main/src/main/java/com/denimgroup/threadfix/service/report/ReportsServiceImpl.java b/threadfix-main/src/main/java/com/denimgroup/threadfix/service/report/ReportsServiceImpl.java
index 59965cb..062ddcd 100644
--- a/threadfix-main/src/main/java/com/denimgroup/threadfix/service/report/ReportsServiceImpl.java
+++ b/threadfix-main/src/main/java/com/denimgroup/threadfix/service/report/ReportsServiceImpl.java
@@ -716,6 +716,11 @@ public class ReportsServiceImpl implements ReportsService {
if (vuln == null || (!vuln.isActive() && !vuln.getIsFalsePositive())) {
continue;
}
+ Finding finding = null;
+ if ( vuln.getFindings() != null && vuln.getFindings().size() > 0){
+ finding = vuln.getFindings().get(0);
+ }
+
String openedDate = formatter.format(vuln.getOpenTime().getTime());
// Orders of positions: CWE ID, CWE Name, Path, Parameter, Severity, Open Date, Defect ID
rowParamsList.add(Arrays.asList(vuln.getGenericVulnerability().getId().toString(),
@@ -724,7 +729,12 @@ public class ReportsServiceImpl implements ReportsService {
vuln.getSurfaceLocation().getParameter(),
vuln.getGenericSeverity().getName(),
openedDate,
- (vuln.getDefect() == null) ? "" : vuln.getDefect().getId().toString()));
+ (vuln.getDefect() == null) ? "" : vuln.getDefect().getId().toString(),
+ (finding == null) ? "" : finding.getAttackString(),
+ (finding == null) ? "" : finding.getChannelVulnerability().getChannelType().getName(),
+ (finding == null) ? "" : finding.getNativeId()
+ )
+ );
}
}
return rowParamsList;
diff --git a/threadfix-main/src/main/resources/threadfix-backup.script b/threadfix-main/src/main/resources/threadfix-backup.script
index b91044e..f99628c 100644
--- a/threadfix-main/src/main/resources/threadfix-backup.script
+++ b/threadfix-main/src/main/resources/threadfix-backup.script
@@ -29,7 +29,7 @@ CREATE MEMORY TABLE DEPENDENCY(ID INTEGER GENERATED BY DEFAULT AS IDENTITY(START
CREATE MEMORY TABLE DOCUMENT(ID INTEGER GENERATED BY DEFAULT AS IDENTITY(START WITH 1) NOT NULL PRIMARY KEY,ACTIVE BOOLEAN NOT NULL,CREATEDDATE TIMESTAMP NOT NULL,MODIFIEDDATE TIMESTAMP NOT NULL,CONTENTTYPE VARCHAR(255),FILE LONGVARBINARY,NAME VARCHAR(50) NOT NULL,TYPE VARCHAR(10),APPLICATIONID INTEGER,VULNERABILITYID INTEGER,CONSTRAINT FK3737353BC96E039C FOREIGN KEY(APPLICATIONID) REFERENCES APPLICATION(ID))
CREATE MEMORY TABLE EMPTYSCAN(ID INTEGER GENERATED BY DEFAULT AS IDENTITY(START WITH 1) NOT NULL PRIMARY KEY,ALREADYPROCESSED BOOLEAN NOT NULL,DATEUPLOADED TIMESTAMP,FILENAME VARCHAR(100) NOT NULL,APPLICATIONCHANNELID INTEGER,CONSTRAINT FK22CE714AD1ED50A0 FOREIGN KEY(APPLICATIONCHANNELID) REFERENCES APPLICATIONCHANNEL(ID))
CREATE MEMORY TABLE EXCEPTIONLOG(ID INTEGER GENERATED BY DEFAULT AS IDENTITY(START WITH 1) NOT NULL PRIMARY KEY,UUID VARCHAR(36),EXCEPTIONSTACKTRACE LONGVARCHAR,EXCEPTIONTOSTRING LONGVARCHAR,MESSAGE VARCHAR(256),TIME TIMESTAMP,TYPE VARCHAR(256))
-CREATE MEMORY TABLE FINDING(ID INTEGER GENERATED BY DEFAULT AS IDENTITY(START WITH 1) NOT NULL PRIMARY KEY,ACTIVE BOOLEAN NOT NULL,CREATEDDATE TIMESTAMP NOT NULL,MODIFIEDDATE TIMESTAMP NOT NULL,DISPLAYID VARCHAR(50),FIRSTFINDINGFORVULN BOOLEAN NOT NULL,ISSTATIC BOOLEAN NOT NULL,LONGDESCRIPTION VARCHAR(2047),MARKEDFALSEPOSITIVE BOOLEAN,NATIVEID VARCHAR(50),NUMBERMERGEDRESULTS INTEGER,SOURCEFILELOCATION VARCHAR(128),CHANNELSEVERITYID INTEGER,CHANNELVULNERABILITYID INTEGER,DEPENDENCYID INTEGER,SCANID INTEGER,SURFACELOCATIONID INTEGER,USERID INTEGER,VULNERABILITYID INTEGER,CONSTRAINT FK305E33699240CF0 FOREIGN KEY(DEPENDENCYID) REFERENCES DEPENDENCY(ID),CONSTRAINT FK305E33694BC6129C FOREIGN KEY(CHANNELSEVERITYID) REFERENCES CHANNELSEVERITY(ID),CONSTRAINT FK305E3369E2A500AC FOREIGN KEY(CHANNELVULNERABILITYID) REFERENCES CHANNELVULNERABILITY(ID))
+CREATE MEMORY TABLE FINDING(ID INTEGER GENERATED BY DEFAULT AS IDENTITY(START WITH 1) NOT NULL PRIMARY KEY,ACTIVE BOOLEAN NOT NULL,CREATEDDATE TIMESTAMP NOT NULL,MODIFIEDDATE TIMESTAMP NOT NULL,DISPLAYID VARCHAR(50),FIRSTFINDINGFORVULN BOOLEAN NOT NULL,ISSTATIC BOOLEAN NOT NULL,LONGDESCRIPTION VARCHAR(2047),MARKEDFALSEPOSITIVE BOOLEAN,NATIVEID VARCHAR(50),NUMBERMERGEDRESULTS INTEGER,SOURCEFILELOCATION VARCHAR(128),CHANNELSEVERITYID INTEGER,CHANNELVULNERABILITYID INTEGER,DEPENDENCYID INTEGER,SCANID INTEGER,SURFACELOCATIONID INTEGER,USERID INTEGER,VULNERABILITYID INTEGER,ATTACKVALUE VARCHAR(65535),ATTACKREQUEST VARCHAR(65535),ATTACKRESPONSE VARCHAR(1048575),FINDINGDETAIL VARCHAR(65535),FINDINGRECOMMENDATION VARCHAR(65535),RAWFINDING VARCHAR(1048575), CONSTRAINT FK305E33699240CF0 FOREIGN KEY(DEPENDENCYID) REFERENCES DEPENDENCY(ID),CONSTRAINT FK305E33694BC6129C FOREIGN KEY(CHANNELSEVERITYID) REFERENCES CHANNELSEVERITY(ID),CONSTRAINT FK305E3369E2A500AC FOREIGN KEY(CHANNELVULNERABILITYID) REFERENCES CHANNELVULNERABILITY(ID))
CREATE MEMORY TABLE GENERICSEVERITY(ID INTEGER GENERATED BY DEFAULT AS IDENTITY(START WITH 1) NOT NULL PRIMARY KEY,INTVALUE INTEGER NOT NULL,NAME VARCHAR(50) NOT NULL)
CREATE MEMORY TABLE GENERICVULNERABILITY(ID INTEGER GENERATED BY DEFAULT AS IDENTITY(START WITH 1) NOT NULL PRIMARY KEY,NAME VARCHAR(256) NOT NULL)
CREATE MEMORY TABLE JOBSTATUS(ID INTEGER GENERATED BY DEFAULT AS IDENTITY(START WITH 1) NOT NULL PRIMARY KEY,ENDDATE TIMESTAMP,HASSTARTEDPROCESSING BOOLEAN NOT NULL,MODIFIEDDATE TIMESTAMP NOT NULL,OPEN BOOLEAN NOT NULL,SCANDATE TIMESTAMP,STARTDATE TIMESTAMP NOT NULL,STATUS VARCHAR(128),TYPE VARCHAR(128),URLPATH VARCHAR(128),URLTEXT VARCHAR(128),APPLICATIONCHANNELID INTEGER,CONSTRAINT FKBABFF5EFD1ED50A0 FOREIGN KEY(APPLICATIONCHANNELID) REFERENCES APPLICATIONCHANNEL(ID))
@@ -253,10 +253,10 @@ INSERT INTO CHANNELSEVERITY VALUES(72,'2','2',2,15)
INSERT INTO CHANNELSEVERITY VALUES(73,'3','3',3,15)
INSERT INTO CHANNELSEVERITY VALUES(74,'4','4',4,15)
INSERT INTO CHANNELSEVERITY VALUES(75,'5','5',5,15)
-INSERT INTO CHANNELSEVERITY VALUES(76,'INFORMATIONAL','INFORMATIONAL',1,2)
-INSERT INTO CHANNELSEVERITY VALUES(77,'LOW','LOW',2,2)
-INSERT INTO CHANNELSEVERITY VALUES(78,'MEDIUM','MEDIUM',3,2)
-INSERT INTO CHANNELSEVERITY VALUES(79,'HIGH','HIGH',4,2)
+INSERT INTO CHANNELSEVERITY VALUES(76,'Informational','Informational',1,2)
+INSERT INTO CHANNELSEVERITY VALUES(77,'Low','Low',2,2)
+INSERT INTO CHANNELSEVERITY VALUES(78,'Medium','Medium',3,2)
+INSERT INTO CHANNELSEVERITY VALUES(79,'High','High',4,2)
INSERT INTO CHANNELSEVERITY VALUES(80,'1','1',1,13)
INSERT INTO CHANNELSEVERITY VALUES(81,'2','2',2,13)
INSERT INTO CHANNELSEVERITY VALUES(82,'3','3',3,13)
@@ -10362,6 +10362,89 @@ INSERT INTO CHANNELVULNERABILITY VALUES(10061,'URL rewriting (Session IDs expose
INSERT INTO CHANNELVULNERABILITY VALUES(10062,'Unrestricted File Upload','Unrestricted File Upload',14)
INSERT INTO CHANNELVULNERABILITY VALUES(10063,'Unvalidated URL Redirect','Unvalidated URL Redirect',14)
INSERT INTO CHANNELVULNERABILITY VALUES(10064,'Web Service Parameter Fuzzing','Web Service Parameter Fuzzing',14)
+INSERT INTO CHANNELVULNERABILITY VALUES(10071,'AutoLogin','AutoLogin',2)
+INSERT INTO CHANNELVULNERABILITY VALUES(10072,'AutoThrottle','AutoThrottle',2)
+INSERT INTO CHANNELVULNERABILITY VALUES(10073,'Backdoors','Backdoors',2)
+INSERT INTO CHANNELVULNERABILITY VALUES(10074,'Backup file','Backup file',2)
+INSERT INTO CHANNELVULNERABILITY VALUES(10075,'Backup files','Backup files',2)
+INSERT INTO CHANNELVULNERABILITY VALUES(10076,'Beep notify','Beep notify',2)
+INSERT INTO CHANNELVULNERABILITY VALUES(10077,'CAPTCHA','CAPTCHA',2)
+INSERT INTO CHANNELVULNERABILITY VALUES(10078,'CAPTCHA protected form','CAPTCHA protected form',2)
+INSERT INTO CHANNELVULNERABILITY VALUES(10079,'Code injection','Code injection',2)
+INSERT INTO CHANNELVULNERABILITY VALUES(10080,'Common directories','Common directories',2)
+INSERT INTO CHANNELVULNERABILITY VALUES(10081,'Common directory','Common directory',2)
+INSERT INTO CHANNELVULNERABILITY VALUES(10082,'Common files','Common files',2)
+INSERT INTO CHANNELVULNERABILITY VALUES(10083,'Common sensitive file','Common sensitive file',2)
+INSERT INTO CHANNELVULNERABILITY VALUES(10084,'Content-types','Content-types',2)
+INSERT INTO CHANNELVULNERABILITY VALUES(10085,'Cookie collector','Cookie collector',2)
+INSERT INTO CHANNELVULNERABILITY VALUES(10086,'Credit card number disclosure','Credit card number disclosure',2)
+INSERT INTO CHANNELVULNERABILITY VALUES(10087,'Cross-Site Request Forgery','Cross-Site Request Forgery',2)
+INSERT INTO CHANNELVULNERABILITY VALUES(10088,'Cross-Site Scripting in event tag of HTML element','Cross-Site Scripting in event tag of HTML element',2)
+INSERT INTO CHANNELVULNERABILITY VALUES(10089,'Cross-Site Scripting in HTML \','Cross-Site Scripting in HTML \',2)
+INSERT INTO CHANNELVULNERABILITY VALUES(10090,'CSRF','CSRF',2)
+INSERT INTO CHANNELVULNERABILITY VALUES(10091,'CVS/SVN user disclosure','CVS/SVN user disclosure',2)
+INSERT INTO CHANNELVULNERABILITY VALUES(10092,'CVS/SVN users','CVS/SVN users',2)
+INSERT INTO CHANNELVULNERABILITY VALUES(10093,'Directory listing','Directory listing',2)
+INSERT INTO CHANNELVULNERABILITY VALUES(10094,'Discovery module response anomalies','Discovery module response anomalies',2)
+INSERT INTO CHANNELVULNERABILITY VALUES(10095,'E-mail address','E-mail address',2)
+INSERT INTO CHANNELVULNERABILITY VALUES(10096,'E-mail address disclosure','E-mail address disclosure',2)
+INSERT INTO CHANNELVULNERABILITY VALUES(10097,'E-mail notify','E-mail notify',2)
+INSERT INTO CHANNELVULNERABILITY VALUES(10098,'Exposed localstart.asp page','Exposed localstart.asp page',2)
+INSERT INTO CHANNELVULNERABILITY VALUES(10099,'File Inclusion','File Inclusion',2)
+INSERT INTO CHANNELVULNERABILITY VALUES(10100,'Form dictionary attacker','Form dictionary attacker',2)
+INSERT INTO CHANNELVULNERABILITY VALUES(10101,'Form-based File Upload','Form-based File Upload',2)
+INSERT INTO CHANNELVULNERABILITY VALUES(10102,'Health map','Health map',2)
+INSERT INTO CHANNELVULNERABILITY VALUES(10103,'HTML object','HTML object',2)
+INSERT INTO CHANNELVULNERABILITY VALUES(10104,'HTML objects','HTML objects',2)
+INSERT INTO CHANNELVULNERABILITY VALUES(10105,'HTTP dictionary attacker','HTTP dictionary attacker',2)
+INSERT INTO CHANNELVULNERABILITY VALUES(10106,'HTTP PUT','HTTP PUT',2)
+INSERT INTO CHANNELVULNERABILITY VALUES(10107,'HTTP TRACE','HTTP TRACE',2)
+INSERT INTO CHANNELVULNERABILITY VALUES(10108,'HttpOnly cookie','HttpOnly cookie',2)
+INSERT INTO CHANNELVULNERABILITY VALUES(10109,'HttpOnly cookies','HttpOnly cookies',2)
+INSERT INTO CHANNELVULNERABILITY VALUES(10110,'Insecure cookie','Insecure cookie',2)
+INSERT INTO CHANNELVULNERABILITY VALUES(10111,'Insecure cookies','Insecure cookies',2)
+INSERT INTO CHANNELVULNERABILITY VALUES(10112,'Interesting response','Interesting response',2)
+INSERT INTO CHANNELVULNERABILITY VALUES(10113,'Interesting responses','Interesting responses',2)
+INSERT INTO CHANNELVULNERABILITY VALUES(10114,'LDAP Injection','LDAP Injection',2)
+INSERT INTO CHANNELVULNERABILITY VALUES(10115,'LDAPInjection','LDAPInjection',2)
+INSERT INTO CHANNELVULNERABILITY VALUES(10116,'libnotify','libnotify',2)
+INSERT INTO CHANNELVULNERABILITY VALUES(10117,'localstart.asp','localstart.asp',2)
+INSERT INTO CHANNELVULNERABILITY VALUES(10118,'Misconfiguration in LIMIT directive of .htaccess file','Misconfiguration in LIMIT directive of .htaccess file',2)
+INSERT INTO CHANNELVULNERABILITY VALUES(10119,'Mixed Resource','Mixed Resource',2)
+INSERT INTO CHANNELVULNERABILITY VALUES(10120,'Operating system command injection','Operating system command injection',2)
+INSERT INTO CHANNELVULNERABILITY VALUES(10121,'OS command injection','OS command injection',2)
+INSERT INTO CHANNELVULNERABILITY VALUES(10122,'Password field with auto-complete','Password field with auto-complete',2)
+INSERT INTO CHANNELVULNERABILITY VALUES(10123,'Path Traversal','Path Traversal',2)
+INSERT INTO CHANNELVULNERABILITY VALUES(10124,'Private IP address disclosure','Private IP address disclosure',2)
+INSERT INTO CHANNELVULNERABILITY VALUES(10125,'Private IP address finder','Private IP address finder',2)
+INSERT INTO CHANNELVULNERABILITY VALUES(10126,'Profiler','Profiler',2)
+INSERT INTO CHANNELVULNERABILITY VALUES(10127,'Proxy','Proxy',2)
+INSERT INTO CHANNELVULNERABILITY VALUES(10128,'Publicly writable directory','Publicly writable directory',2)
+INSERT INTO CHANNELVULNERABILITY VALUES(10129,'Remote File Inclusion','Remote File Inclusion',2)
+INSERT INTO CHANNELVULNERABILITY VALUES(10130,'ReScan','ReScan',2)
+INSERT INTO CHANNELVULNERABILITY VALUES(10131,'Resolver','Resolver',2)
+INSERT INTO CHANNELVULNERABILITY VALUES(10132,'Response Splitting','Response Splitting',2)
+INSERT INTO CHANNELVULNERABILITY VALUES(10133,'Session fixation','Session fixation',2)
+INSERT INTO CHANNELVULNERABILITY VALUES(10134,'Source code disclosure','Source code disclosure',2)
+INSERT INTO CHANNELVULNERABILITY VALUES(10135,'SQL Injection','SQL Injection',2)
+INSERT INTO CHANNELVULNERABILITY VALUES(10136,'SSN','SSN',2)
+INSERT INTO CHANNELVULNERABILITY VALUES(10137,'Timing attack anomalies','Timing attack anomalies',2)
+INSERT INTO CHANNELVULNERABILITY VALUES(10138,'Trainer','Trainer',2)
+INSERT INTO CHANNELVULNERABILITY VALUES(10139,'Uncommon headers','Uncommon headers',2)
+INSERT INTO CHANNELVULNERABILITY VALUES(10140,'Unencrypted password form','Unencrypted password form',2)
+INSERT INTO CHANNELVULNERABILITY VALUES(10141,'Unencrypted password forms','Unencrypted password forms',2)
+INSERT INTO CHANNELVULNERABILITY VALUES(10142,'Unvalidated redirect','Unvalidated redirect',2)
+INSERT INTO CHANNELVULNERABILITY VALUES(10143,'Vector feed','Vector feed',2)
+INSERT INTO CHANNELVULNERABILITY VALUES(10144,'WAF Detector','WAF Detector',2)
+INSERT INTO CHANNELVULNERABILITY VALUES(10145,'WebDAV','WebDAV',2)
+INSERT INTO CHANNELVULNERABILITY VALUES(10146,'X-Forwarded-For Access Restriction Bypass','X-Forwarded-For Access Restriction Bypass',2)
+INSERT INTO CHANNELVULNERABILITY VALUES(10147,'XPath Injection','XPath Injection',2)
+INSERT INTO CHANNELVULNERABILITY VALUES(10148,'XSS','XSS',2)
+INSERT INTO CHANNELVULNERABILITY VALUES(10149,'XSS in HTML \','XSS in HTML \',2)
+INSERT INTO CHANNELVULNERABILITY VALUES(10150,'XSS in HTML element event attribute','XSS in HTML element event attribute',2)
+INSERT INTO CHANNELVULNERABILITY VALUES(10151,'XSS in HTML tag','XSS in HTML tag',2)
+INSERT INTO CHANNELVULNERABILITY VALUES(10152,'XSS in path','XSS in path',2)
+INSERT INTO CHANNELVULNERABILITY VALUES(10153,'XST','XST',2)
INSERT INTO DEFAULTCONFIGURATION VALUES(1,1,TRUE)
INSERT INTO DEFECTTRACKERTYPE VALUES(1,'com.denimgroup.threadfix.service.defects.BugzillaDefectTracker','Bugzilla',NULL)
INSERT INTO DEFECTTRACKERTYPE VALUES(2,'com.denimgroup.threadfix.service.defects.JiraDefectTracker','Jira',NULL)
@@ -21519,6 +21602,18 @@ INSERT INTO VULNERABILITYMAP VALUES(9732,TRUE,10061,384)
INSERT INTO VULNERABILITYMAP VALUES(9733,TRUE,10062,434)
INSERT INTO VULNERABILITYMAP VALUES(9734,TRUE,10063,601)
INSERT INTO VULNERABILITYMAP VALUES(9735,TRUE,10064,74)
+INSERT INTO VULNERABILITYMAP VALUES(9736,TRUE,10111,614)
+INSERT INTO VULNERABILITYMAP VALUES(9737,TRUE,10110,614)
+INSERT INTO VULNERABILITYMAP VALUES(9738,TRUE,10070,650)
+INSERT INTO VULNERABILITYMAP VALUES(9739,TRUE,9507,650)
+INSERT INTO VULNERABILITYMAP VALUES(9740,TRUE,10125,200)
+INSERT INTO VULNERABILITYMAP VALUES(9741,TRUE,10124,200)
+INSERT INTO VULNERABILITYMAP VALUES(9742,TRUE,10122,525)
+INSERT INTO VULNERABILITYMAP VALUES(9743,TRUE,10083,200)
+INSERT INTO VULNERABILITYMAP VALUES(9744,TRUE,9513,200)
+INSERT INTO VULNERABILITYMAP VALUES(9745,TRUE,10141,311)
+INSERT INTO VULNERABILITYMAP VALUES(9746,TRUE,10140,311)
+INSERT INTO VULNERABILITYMAP VALUES(9747,TRUE,9528,311)
INSERT INTO WAFRULEDIRECTIVE VALUES(1,'alert',1)
INSERT INTO WAFRULEDIRECTIVE VALUES(2,'log',1)
INSERT INTO WAFRULEDIRECTIVE VALUES(3,'pass',1)
diff --git a/threadfix-main/src/main/webapp/WEB-INF/views/applications/detailHeader.jsp b/threadfix-main/src/main/webapp/WEB-INF/views/applications/detailHeader.jsp
index 007c9b8..92d6223 100644
--- a/threadfix-main/src/main/webapp/WEB-INF/views/applications/detailHeader.jsp
+++ b/threadfix-main/src/main/webapp/WEB-INF/views/applications/detailHeader.jsp
@@ -1,7 +1,9 @@
+<%@ include file="/common/taglibs.jsp"%>
<spring:url value="/organizations/{orgId}" var="orgUrl">
<spring:param name="orgId" value="${ application.organization.id }"/>
</spring:url>
+
<ul class="breadcrumb">
<li><a id="applicationsIndexLink" href="<spring:url value="/organizations"/>">Applications Index</a> <span class="divider">/</span></li>
<li><a id="teamLink" href="${ fn:escapeXml(orgUrl) }">Team: <c:out value="${ application.organization.name }"/></a> <span class="divider">/</span></li>
diff --git a/threadfix-main/src/main/webapp/WEB-INF/views/scans/findingDetail.jsp b/threadfix-main/src/main/webapp/WEB-INF/views/scans/findingDetail.jsp
index 1cffa13..fe91439 100644
--- a/threadfix-main/src/main/webapp/WEB-INF/views/scans/findingDetail.jsp
+++ b/threadfix-main/src/main/webapp/WEB-INF/views/scans/findingDetail.jsp
@@ -85,6 +85,31 @@
<c:if test="${ empty finding.displayId }"><c:out value="${ finding.nativeId }" /></c:if>
</td>
</tr>
+ <tr>
+ <td class="bold" >Attack String</td>
+ <td class="inputValue"><c:out value="${ finding.attackString }"/></td>
+ </tr>
+ <tr class="odd">
+ <td class="bold" valign=top>Scanner Detail</td>
+ <td class="inputValue" style="word-wrap: break-word;"><style>li {list-style: square}</style>${ finding.scannerDetail }</td>
+ </tr>
+ <tr>
+ <td class="bold" valign=top>Scanner Recommendation</td>
+ <td class="inputValue" style="word-wrap: break-word;"><style>li {list-style: square}</style>${ finding.scannerRecommendation }</td>
+ </tr>
+ <tr>
+ <td class="bold" valign=top>Attack Request</td>
+ <td class="inputValue" style="word-wrap: break-word;"><PRE><c:out value="${ finding.attackRequest }"/></PRE></td>
+ </tr>
+ <tr>
+ <td class="bold" valign=top>Attack Response</td>
+ <td class="inputValue" style="word-wrap: break-word;"><PRE><c:out value="${ finding.attackResponse }"/></PRE></td>
+ </tr>
+ <tr>
+ <td class="bold" valign=top>Raw Finding</td>
+ <td class="inputValue" style="word-wrap: break-word;"><PRE><c:out value="${ finding.rawFinding }"/></PRE></td>
+ </tr>
+
</c:if>
<c:if test="${ not empty finding.dependency }">
<tr>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment