def get_open_vuln_by_type(finding_id: str, context) -> Dict[str, Union[int, List[str]]]: """Get open vulnerabilities group by type.""" vulnerabilities = finding_dal.get_vulnerabilities(finding_id) finding: Dict[str, Union[int, List[str]]] = { 'openVulnerabilities': 0, 'closedVulnerabilities': 0, 'portsVulns': [], 'linesVulns': [], 'inputsVulns': [] } vulns_types = ['ports', 'lines', 'inputs'] for vuln in vulnerabilities: current_state = get_last_approved_status(vuln) if current_state == 'open': finding['openVulnerabilities'] += 1 # type: ignore if vuln.get('vuln_type') in vulns_types: finding[vuln.get('vuln_type', '') + 'Vulns'].append( { # type: ignore 'where': vuln.get('where'), 'specific': vuln.get('specific') }) else: error_msg = 'Error: Vulnerability {vuln_id} of finding \ {finding_id} does not have the right type'\ .format(vuln_id=vuln.get('UUID'), finding_id=finding_id) rollbar.report_message(error_msg, 'error') elif current_state == 'closed': finding['closedVulnerabilities'] += 1 # type: ignore else: error_msg = 'Error: Vulnerability {vuln_id} of finding \ {finding_id} does not have the right state'\ .format(vuln_id=vuln.get('UUID'), finding_id=finding_id) util.cloudwatch_log(context, error_msg) return finding
def update_vulnerabilities_date(analyst: str, finding_id: str): """Update vulnerabilities date when a verification is required.""" vulnerabilities = cast(List[Dict[str, str]], finding_dal.get_vulnerabilities(finding_id)) for vuln in vulnerabilities: all_states = cast(List[Dict[str, str]], vuln.get('historic_state', [])) current_state: Dict[str, str] = all_states[len(all_states) - 1] tzn = pytz.timezone(settings.TIME_ZONE) # type: ignore last_date = datetime.strptime( str(current_state.get('date')).split(' ')[0], '%Y-%m-%d') last_date = cast(datetime, last_date.replace(tzinfo=tzn).date()) current_date = datetime.now(tz=tzn).date() if last_date != current_date: historic_state: List[Dict[str, str]] = [] current_time = datetime.now( tz=tzn).today().strftime('%Y-%m-%d %H:%M:%S') last_state = { 'date': current_time, 'state': current_state.get('state', ''), 'analyst': analyst } historic_state.append(last_state) vuln_dal.update_state(finding_id, vuln.get('UUID', ''), 'historic_state', historic_state, [vuln]) else: # A finding that change the same day should not be updated pass
def get_all_vulns_by_project( findings_released: List[Dict[str, FindingType]]) -> List[Dict[str, FindingType]]: """Get all vulnerabilities by project""" vulns: List[Dict[str, FindingType]] = [] for finding in findings_released: vulns += finding_dal.get_vulnerabilities(str(finding.get('finding_id', ''))) return vulns
def get_mean_remediate(findings: List[Dict[str, FindingType]]) -> Decimal: """Get mean time to remediate a vulnerability.""" total_vuln = 0 total_days = 0 tzn = pytz.timezone('America/Bogota') for finding in findings: if finding_domain.validate_finding(str(finding['finding_id'])): vulnerabilities = finding_dal.get_vulnerabilities( str(finding.get('finding_id', ''))) for vuln in vulnerabilities: open_vuln_date = get_open_vulnerability_date(vuln) closed_vuln_date = get_last_closing_date(vuln) if open_vuln_date: if closed_vuln_date: total_days += int( (closed_vuln_date - open_vuln_date).days) else: current_day = datetime.now(tz=tzn).date() total_days += int((current_day - open_vuln_date).days) total_vuln += 1 if total_vuln: mean_vulnerabilities = Decimal(round( total_days / float(total_vuln))).quantize(Decimal('0.1')) else: mean_vulnerabilities = Decimal(0).quantize(Decimal('0.1')) return mean_vulnerabilities
def get_last_closing_vuln(findings: List[Dict[str, FindingType]]) -> Decimal: """Get day since last vulnerability closing.""" closing_dates = [] for fin in findings: if finding_domain.validate_finding(str(fin['finding_id'])): vulnerabilities = finding_dal.get_vulnerabilities( str(fin.get('finding_id', ''))) closing_vuln_date = [ get_last_closing_date(vuln) for vuln in vulnerabilities if is_vulnerability_closed(vuln) ] if closing_vuln_date: closing_dates.append(max(closing_vuln_date)) else: # Vulnerability does not have closing date pass if closing_dates: current_date = max(closing_dates) tzn = pytz.timezone(settings.TIME_ZONE) # type: ignore last_closing = \ Decimal((datetime.now(tz=tzn).date() - current_date).days).quantize(Decimal('0.1')) else: last_closing = Decimal(0) return last_closing
def get_vulnerabilities_by_type( finding_id: str) -> Dict[str, List[FindingType]]: """Get vulnerabilities group by type.""" vulnerabilities = finding_dal.get_vulnerabilities(finding_id) vulnerabilities = [ vuln for vuln in vulnerabilities if cast(List[Dict[ str, str]], vuln['historic_state'])[-1].get('state') != 'DELETED' ] vulnerabilities_grouped = cast(List[Dict[str, FindingType]], group_vulnerabilities(vulnerabilities)) vulnerabilities_formatted = format_vulnerabilities(vulnerabilities_grouped) return vulnerabilities_formatted
def total_vulnerabilities(finding_id: str) -> Dict[str, int]: """Get total vulnerabilities in new format.""" finding = {'openVulnerabilities': 0, 'closedVulnerabilities': 0} if finding_domain.validate_finding(finding_id): vulnerabilities = finding_dal.get_vulnerabilities(finding_id) for vuln in vulnerabilities: current_state = vuln_domain.get_last_approved_status(vuln) if current_state == 'open': finding['openVulnerabilities'] += 1 elif current_state == 'closed': finding['closedVulnerabilities'] += 1 else: # Vulnerability does not have a valid state pass return finding
def generate_complete_report(request): user_data = util.get_jwt_content(request) projects = user_domain.get_projects(user_data['user_email']) book = load_workbook('/usr/src/app/app/techdoc/templates/COMPLETE.xlsx') sheet = book.active project_col = 1 finding_col = 2 vuln_where_col = 3 vuln_specific_col = 4 treatment_col = 5 treatment_mgr_col = 6 row_offset = 2 row_index = row_offset for project in projects: findings = project_domain.get_released_findings( project, 'finding_id, finding, treatment') for finding in findings: vulns = finding_dal.get_vulnerabilities(finding['finding_id']) for vuln in vulns: sheet.cell(row_index, vuln_where_col, vuln['where']) sheet.cell(row_index, vuln_specific_col, vuln['specific']) sheet.cell(row_index, project_col, project.upper()) sheet.cell(row_index, finding_col, '{name!s} (#{id!s})'.format( name=finding['finding'].encode('utf-8'), id=finding['finding_id'])) sheet.cell(row_index, treatment_col, finding['treatment']) sheet.cell(row_index, treatment_mgr_col, vuln.get('treatment_manager', 'Unassigned')) row_index += 1 username = user_data['user_email'].split('@')[0].encode('utf8', 'ignore') filename = 'complete_report.xlsx' filepath = '/tmp/{username}-{filename}'.format(filename=filename, username=username) book.save(filepath) with open(filepath, 'rb') as document: response = HttpResponse(document.read()) response['Content-Type'] = 'application/vnd.openxmlformats\ -officedocument.spreadsheetml.sheet' response['Content-Disposition'] = 'inline;filename={filename}'.format( filename=filename) return response
def calculate_vulnerabilities(act_finding: Dict[str, str]) -> int: vulns = finding_dal.get_vulnerabilities(act_finding['finding_id']) all_tracking = finding_domain.get_tracking_vulnerabilities(vulns) delta_total = 0 if len(all_tracking) > 1: if (datetime.strptime(str(all_tracking[-1]['date']), "%Y-%m-%d")) \ > (datetime.now() - timedelta(days=8)): delta_open = abs(all_tracking[-1]['open'] - all_tracking[-2]['open']) delta_closed = abs(all_tracking[-1]['closed'] - all_tracking[-2]['closed']) delta_total = delta_open - delta_closed elif len(all_tracking) == 1 and \ (datetime.strptime(str(all_tracking[-1]['date']), "%Y-%m-%d")) > \ (datetime.now() - timedelta(days=8)): delta_open = all_tracking[-1]['open'] delta_closed = all_tracking[-1]['closed'] delta_total = delta_open - delta_closed return delta_total
def update_last_vuln_date(finding_id: str) -> bool: inc = 0 has_new_open_vulns = False vulnerabilities = finding_dal.get_vulnerabilities(finding_id) today_date = str(datetime.today().strftime('%Y-%m-%d %H:%M:%S')) while inc < len(vulnerabilities) and has_new_open_vulns is False: vuln_historics = cast(List[Dict[str, str]], vulnerabilities[inc].get('historic_state')) current_state = vuln_historics[len(vuln_historics) - 1].get( 'state', '') current_date = vuln_historics[len(vuln_historics) - 1].get('date', '') if current_state == 'open' and current_date.split(' ')[0] == today_date.split(' ')[0] and \ ('approval_status' not in vuln_historics[-1] or vuln_historics[-1].get('approval_status') == 'APPROVED'): description: Dict[str, FindingType] = { 'lastVulnerability': today_date } finding_dal.update(finding_id, description) has_new_open_vulns = True else: inc += 1 success = has_new_open_vulns return success
def generate_all_vulns_xlsx(user_email: str) -> str: projects = project_dal.get_all() book = Workbook() sheet = book.active sheet.append(COLUMNS_FINS + COLUMNS_VULNS) row_index = 2 for project in projects: if project not in TEST_PROJECTS: findings = project_dal.get_released_findings(project) else: findings = [] for finding in findings: vulns = finding_dal.get_vulnerabilities(finding['finding_id']) finding_row = _mask_finding(finding) for vuln in vulns: vuln_row = _format_vuln(vuln, finding_row) fill_sheet(sheet, finding_row, vuln_row, row_index) row_index += 1 username = user_email.split('@')[0].encode('utf8', 'ignore') filepath = '/tmp/{username}-all_vulns.xlsx'.format( username=username) # type: ignore book.save(filepath) return filepath
def get_vulnerabilities(finding_id: str) -> List[Dict[str, FindingType]]: return finding_dal.get_vulnerabilities(finding_id)