//////////////////////////////////////////////////////////////////////// // // Copyright (c) 2009-2013 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.data.entities; import java.util.Calendar; import java.util.List; import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; import javax.persistence.OneToMany; import javax.persistence.Table; import javax.persistence.Temporal; import javax.persistence.TemporalType; import javax.persistence.Transient; import javax.validation.constraints.Size; import org.codehaus.jackson.annotate.JsonIgnore; @Entity @Table(name = "Vulnerability") public class Vulnerability extends BaseEntity { private static final long serialVersionUID = 8339606486988417904L; private Application application; private Defect defect; private GenericVulnerability genericVulnerability; private GenericSeverity genericSeverity; private SurfaceLocation surfaceLocation; @Size(max = 128, message = "{errors.maxlength} 128.") private String variableHash; @Size(max = 128, message = "{errors.maxlength} 128.") private String locationVariableHash; @Size(max = 128, message = "{errors.maxlength} 128.") private String locationHash; private boolean active = true; private boolean isFalsePositive = false; private Calendar wafRuleGeneratedTime; private Calendar defectSubmittedTime; private Calendar defectClosedTime; private Calendar openTime; private Calendar closeTime; private boolean foundByScanner = true; private boolean expired = false; private List<Audit> audits; private List<Finding> findings; private List<WafRule> wafRules; private List<VulnerabilityComment> comments; private List<ScanCloseVulnerabilityMap> scanCloseVulnerabilityMaps; private List<ScanReopenVulnerabilityMap> scanReopenVulnerabilityMaps; private Finding originalFinding = null; @ManyToOne @JoinColumn(name = "applicationId") @JsonIgnore public Application getApplication() { return application; } public void setApplication(Application application) { this.application = application; } @OneToMany(mappedBy = "vulnerability", cascade = CascadeType.ALL) @JsonIgnore public List<ScanCloseVulnerabilityMap> getScanCloseVulnerabilityMaps() { return scanCloseVulnerabilityMaps; } public void setScanCloseVulnerabilityMaps(List<ScanCloseVulnerabilityMap> scanCloseVulnerabilityMaps) { this.scanCloseVulnerabilityMaps = scanCloseVulnerabilityMaps; } @OneToMany(mappedBy = "vulnerability", cascade = CascadeType.ALL) @JsonIgnore public List<ScanReopenVulnerabilityMap> getScanReopenVulnerabilityMaps() { return scanReopenVulnerabilityMaps; } public void setScanReopenVulnerabilityMaps(List<ScanReopenVulnerabilityMap> scanReopenVulnerabilityMaps) { this.scanReopenVulnerabilityMaps = scanReopenVulnerabilityMaps; } @ManyToOne @JoinColumn(name = "defectId") @JsonIgnore public Defect getDefect() { return defect; } public void setDefect(Defect defect) { this.defect = defect; } @ManyToOne @JoinColumn(name = "genericVulnerabilityId") public GenericVulnerability getGenericVulnerability() { return genericVulnerability; } public void setGenericVulnerability(GenericVulnerability genericVulnerability) { this.genericVulnerability = genericVulnerability; } @ManyToOne @JoinColumn(name = "genericSeverityId") public GenericSeverity getGenericSeverity() { return genericSeverity; } public void setGenericSeverity(GenericSeverity genericSeverity) { this.genericSeverity = genericSeverity; } @Column(length = 128, nullable = true) @JsonIgnore public String getVariableHash() { return variableHash; } public void setVariableHash(String variableHash) { this.variableHash = variableHash; } @Column(length = 128, nullable = true) @JsonIgnore public String getLocationVariableHash() { return locationVariableHash; } public void setLocationVariableHash(String locationVariableHash) { this.locationVariableHash = locationVariableHash; } @Column(length = 128, nullable = true) @JsonIgnore public String getLocationHash() { return locationHash; } public void setLocationHash(String locationHash) { this.locationHash = locationHash; } @Column(nullable = false) public boolean isActive() { return active; } public void setActive(boolean isActive) { this.active = isActive; } @Column(nullable = false) public boolean getIsFalsePositive() { return isFalsePositive; } public void setIsFalsePositive(boolean isFalsePositive) { this.isFalsePositive = isFalsePositive; } @Temporal(TemporalType.TIMESTAMP) @JsonIgnore public Calendar getWafRuleGeneratedTime() { return wafRuleGeneratedTime; } public void setWafRuleGeneratedTime(Calendar wafRuleGeneratedTime) { this.wafRuleGeneratedTime = wafRuleGeneratedTime; } @Temporal(TemporalType.TIMESTAMP) @JsonIgnore public Calendar getDefectSubmittedTime() { return defectSubmittedTime; } public void setDefectSubmittedTime(Calendar defectSubmittedTime) { this.defectSubmittedTime = defectSubmittedTime; } @Temporal(TemporalType.TIMESTAMP) @JsonIgnore public Calendar getDefectClosedTime() { return defectClosedTime; } public void setDefectClosedTime(Calendar defectClosedTime) { this.defectClosedTime = defectClosedTime; } // this should just point to the surface location that the vulnerability was created with. @ManyToOne @JoinColumn(name = "surfaceLocationId") public SurfaceLocation getSurfaceLocation() { return surfaceLocation; } public void setSurfaceLocation(SurfaceLocation surfaceLocation) { this.surfaceLocation = surfaceLocation; } @Temporal(TemporalType.TIMESTAMP) public Calendar getOpenTime() { return openTime; } public void setOpenTime(Calendar openTime) { this.openTime = openTime; } @Temporal(TemporalType.TIMESTAMP) public Calendar getCloseTime() { return closeTime; } public void setCloseTime(Calendar closeTime) { this.closeTime = closeTime; } @Column(nullable = false) @JsonIgnore public boolean isExpired() { return expired; } public void setExpired(boolean isExpired) { this.expired = isExpired; } /** * This indicates whether the user has closed the vulnerability. * @return */ @Column(nullable = false) @JsonIgnore public boolean isFoundByScanner() { return foundByScanner; } public void setFoundByScanner(boolean isFoundByScanner) { this.foundByScanner = isFoundByScanner; } @OneToMany(mappedBy = "vulnerability") @JsonIgnore public List<Audit> getAudits() { return audits; } public void setAudits(List<Audit> audits) { this.audits = audits; } @OneToMany(mappedBy = "vulnerability") @JsonIgnore public List<Finding> getFindings() { return findings; } public void setFindings(List<Finding> findings) { this.findings = findings; } @OneToMany(mappedBy = "vulnerability") @JsonIgnore public List<VulnerabilityComment> getVulnerabilityComments() { return comments; } public void setVulnerabilityComments(List<VulnerabilityComment> comments) { this.comments = comments; } @OneToMany(mappedBy = "vulnerability", cascade = CascadeType.ALL) @JsonIgnore public List<WafRule> getWafRules() { return wafRules; } public void setWafRules(List<WafRule> wafRules) { this.wafRules = wafRules; } @Transient public void closeVulnerability(Scan scan, Calendar closeTime) { active = false; if (closeTime == null) this.closeTime = Calendar.getInstance(); else this.closeTime = closeTime; // This constructor maps the objects for us if (scan != null) { new ScanCloseVulnerabilityMap(this, scan); } } @Transient @JsonIgnore public void openVulnerability(Calendar openTime) { active = true; if (openTime == null) this.openTime = Calendar.getInstance(); else this.openTime = openTime; } @Transient @JsonIgnore public void reopenVulnerability(Scan scan, Calendar openTime) { active = true; if (openTime == null) this.openTime = Calendar.getInstance(); else this.openTime = openTime; // This constructor maps the objects for us if (scan != null) { new ScanReopenVulnerabilityMap(this, scan); } } @Transient @JsonIgnore public int getNoOfSecurityEvents() { int numEvents = 0; for (WafRule wafRule : wafRules) numEvents += wafRule.getSecurityEvents().size(); return numEvents; } @Transient @JsonIgnore public String getIsOpen() { return isActive() ? "OPEN" : "CLOSED"; } /** * This method is for reporting to help ensure that we aren't counting vulns more than once. */ @Transient @JsonIgnore public Finding getOriginalFinding() { if (originalFinding == null && getFindings() != null) { for (Finding finding : getFindings()) { if (finding == null) continue; if (finding.isFirstFindingForVuln()) { originalFinding = finding; break; } } } return originalFinding; } }