Security and Compliance Assessor.
Analyzes security vulnerabilities, compliance readiness (GDPR, SOC2, HIPAA),
and overall security posture of technology stacks.
from typing import Dict, List, Any, Optional
from datetime import datetime, timedelta
"""Assess security and compliance readiness of technology stacks."""
# Compliance standards mapping
'GDPR': ['data_privacy', 'consent_management', 'data_portability', 'right_to_deletion', 'audit_logging'],
'SOC2': ['access_controls', 'encryption_at_rest', 'encryption_in_transit', 'audit_logging', 'backup_recovery'],
'HIPAA': ['phi_protection', 'encryption_at_rest', 'encryption_in_transit', 'access_controls', 'audit_logging'],
'PCI_DSS': ['payment_data_encryption', 'access_controls', 'network_security', 'vulnerability_management']
def __init__(self, security_data: Dict[str, Any]):
Initialize security assessor with security data.
security_data: Dictionary containing vulnerability and compliance data
self.technology = security_data.get('technology', 'Unknown')
self.vulnerabilities = security_data.get('vulnerabilities', {})
self.security_features = security_data.get('security_features', {})
self.compliance_requirements = security_data.get('compliance_requirements', [])
def calculate_security_score(self) -> Dict[str, Any]:
Calculate overall security score (0-100).
Dictionary with security score components
vuln_score = self._score_vulnerabilities()
patch_score = self._score_patch_responsiveness()
features_score = self._score_security_features()
track_record_score = self._score_track_record()
'vulnerability_score': 0.30,
'patch_responsiveness': 0.25,
'security_features': 0.30,
vuln_score * weights['vulnerability_score'] +
patch_score * weights['patch_responsiveness'] +
features_score * weights['security_features'] +
track_record_score * weights['track_record']
'overall_security_score': overall,
'vulnerability_score': vuln_score,
'patch_responsiveness': patch_score,
'security_features_score': features_score,
'track_record_score': track_record_score,
'security_grade': self._calculate_grade(overall)
def _score_vulnerabilities(self) -> float:
Score based on vulnerability count and severity.
Vulnerability score (0-100, higher is better)
# Get vulnerability counts by severity (last 12 months)
critical = self.vulnerabilities.get('critical_last_12m', 0)
high = self.vulnerabilities.get('high_last_12m', 0)
medium = self.vulnerabilities.get('medium_last_12m', 0)
low = self.vulnerabilities.get('low_last_12m', 0)
# Calculate weighted vulnerability count
weighted_vulns = (critical * 4) + (high * 2) + (medium * 1) + (low * 0.5)
# Score based on weighted count (fewer is better)
elif weighted_vulns <= 5:
elif weighted_vulns <= 10:
elif weighted_vulns <= 20:
elif weighted_vulns <= 30:
elif weighted_vulns <= 50:
score = max(0, 50 - (weighted_vulns - 50) / 2)
# Penalty for critical vulnerabilities
score = max(0, score - (critical * 10))
return max(0.0, min(100.0, score))
def _score_patch_responsiveness(self) -> float:
Score based on patch response time.
Patch responsiveness score (0-100)
# Average days to patch critical vulnerabilities
critical_patch_days = self.vulnerabilities.get('avg_critical_patch_days', 30)
high_patch_days = self.vulnerabilities.get('avg_high_patch_days', 60)
# Score critical patch time (most important)
if critical_patch_days <= 7:
elif critical_patch_days <= 14:
elif critical_patch_days <= 30:
elif critical_patch_days <= 60:
# Score high severity patch time
if high_patch_days <= 14:
elif high_patch_days <= 30:
elif high_patch_days <= 60:
elif high_patch_days <= 90:
# Has active security team
has_security_team = self.vulnerabilities.get('has_security_team', False)
team_score = 20 if has_security_team else 0
total_score = critical_score + high_score + team_score
return min(100.0, total_score)
def _score_security_features(self) -> float:
Score based on built-in security features.
Security features score (0-100)
# Essential features (10 points each)
for feature in essential_features:
if self.security_features.get(feature, False):
# Advanced features (5 points each)
'sql_injection_protection',
for feature in advanced_features:
if self.security_features.get(feature, False):
def _score_track_record(self) -> float:
Score based on historical security track record.
Track record score (0-100)
score = 50.0 # Start at neutral
# Years since major security incident
years_since_major = self.vulnerabilities.get('years_since_major_incident', 5)
if years_since_major >= 3:
elif years_since_major >= 1:
# Security certifications
has_certifications = self.vulnerabilities.get('has_security_certifications', False)
has_bug_bounty = self.vulnerabilities.get('has_bug_bounty_program', False)
security_audits = self.vulnerabilities.get('security_audits_per_year', 0)
score += min(20, security_audits * 10)
return min(100.0, max(0.0, score))
def _calculate_grade(self, score: float) -> str:
Convert score to letter grade.
score: Security score (0-100)
def assess_compliance(self, standards: List[str] = None) -> Dict[str, Dict[str, Any]]:
Assess compliance readiness for specified standards.
standards: List of compliance standards to assess (defaults to all required)
Dictionary of compliance assessments by standard
standards = self.compliance_requirements
for standard in standards:
if standard not in self.COMPLIANCE_STANDARDS:
'status': 'Unknown standard'
readiness = self._assess_standard_readiness(standard)
results[standard] = readiness
def _assess_standard_readiness(self, standard: str) -> Dict[str, Any]:
Assess readiness for a specific compliance standard.
standard: Compliance standard name
required_features = self.COMPLIANCE_STANDARDS[standard]
total_count = len(required_features)
for feature in required_features:
if self.security_features.get(feature, False):
missing_features.append(feature)
# Calculate readiness percentage
readiness_pct = (met_count / total_count * 100) if total_count > 0 else 0
# Determine readiness level
readiness_level = "Ready"
status = "Compliant - meets all requirements"
elif readiness_pct >= 70:
readiness_level = "Mostly Ready"
status = "Minor gaps - additional configuration needed"
elif readiness_pct >= 50:
readiness_level = "Partial"
status = "Significant work required"
readiness_level = "Not Ready"
status = "Major gaps - extensive implementation needed"
'readiness_level': readiness_level,
'readiness_percentage': readiness_pct,
'features_met': met_count,
'features_required': total_count,
'missing_features': missing_features,
'recommendation': self._generate_compliance_recommendation(readiness_level, missing_features)
def _generate_compliance_recommendation(self, readiness_level: str, missing_features: List[str]) -> str:
Generate compliance recommendation.
readiness_level: Current readiness level
missing_features: List of missing features
if readiness_level == "Ready":
return "Proceed with compliance audit and certification"
elif readiness_level == "Mostly Ready":
return f"Implement missing features: {', '.join(missing_features[:3])}"
elif readiness_level == "Partial":
return f"Significant implementation needed. Start with: {', '.join(missing_features[:3])}"
return "Not recommended without major security enhancements"
def identify_vulnerabilities(self) -> Dict[str, Any]:
Identify and categorize vulnerabilities.
Categorized vulnerability report
# Current vulnerabilities
'critical': self.vulnerabilities.get('critical_last_12m', 0),
'high': self.vulnerabilities.get('high_last_12m', 0),
'medium': self.vulnerabilities.get('medium_last_12m', 0),
'low': self.vulnerabilities.get('low_last_12m', 0)
# Historical vulnerabilities (last 3 years)
'critical': self.vulnerabilities.get('critical_last_3y', 0),
'high': self.vulnerabilities.get('high_last_3y', 0),
'medium': self.vulnerabilities.get('medium_last_3y', 0),
'low': self.vulnerabilities.get('low_last_3y', 0)
# Common vulnerability types
common_types = self.vulnerabilities.get('common_vulnerability_types', [
'current_vulnerabilities': current,
'total_current': sum(current.values()),
'historical_vulnerabilities': historical,
'total_historical': sum(historical.values()),
'common_types': common_types,
'severity_distribution': self._calculate_severity_distribution(current),
'trend': self._analyze_vulnerability_trend(current, historical)
def _calculate_severity_distribution(self, vulnerabilities: Dict[str, int]) -> Dict[str, str]:
Calculate percentage distribution of vulnerability severities.
vulnerabilities: Vulnerability counts by severity
total = sum(vulnerabilities.values())
return {k: "0%" for k in vulnerabilities.keys()}
severity: f"{(count / total * 100):.1f}%"
for severity, count in vulnerabilities.items()
def _analyze_vulnerability_trend(self, current: Dict[str, int], historical: Dict[str, int]) -> str:
Analyze vulnerability trend.
current: Current vulnerabilities
historical: Historical vulnerabilities
current_total = sum(current.values())
historical_avg = sum(historical.values()) / 3 # 3-year average
if current_total < historical_avg * 0.7:
return "Improving - fewer vulnerabilities than historical average"
elif current_total < historical_avg * 1.2:
return "Stable - consistent with historical average"
return "Concerning - more vulnerabilities than historical average"
def generate_security_report(self) -> Dict[str, Any]:
Generate comprehensive security assessment report.
Complete security analysis
security_score = self.calculate_security_score()
compliance = self.assess_compliance()
vulnerabilities = self.identify_vulnerabilities()
# Generate recommendations
recommendations = self._generate_security_recommendations(
'technology': self.technology,
'security_score': security_score,
'compliance_assessment': compliance,
'vulnerability_analysis': vulnerabilities,
'recommendations': recommendations,
'overall_risk_level': self._determine_risk_level(security_score['overall_security_score'])
def _generate_security_recommendations(
security_score: Dict[str, Any],
compliance: Dict[str, Dict[str, Any]],
vulnerabilities: Dict[str, Any]
Generate security recommendations.
security_score: Security score data
compliance: Compliance assessment
vulnerabilities: Vulnerability analysis
# Security score recommendations
if security_score['overall_security_score'] < 70:
recommendations.append("Improve overall security posture - score below acceptable threshold")
# Vulnerability recommendations
current_critical = vulnerabilities['current_vulnerabilities']['critical']
recommendations.append(f"Address {current_critical} critical vulnerabilities immediately")
if security_score['patch_responsiveness'] < 60:
recommendations.append("Improve vulnerability patch response time")
if security_score['security_features_score'] < 70:
recommendations.append("Implement additional security features (MFA, audit logging, RBAC)")
# Compliance recommendations
for standard, assessment in compliance.items():
if assessment['readiness_level'] == "Not Ready":
recommendations.append(f"{standard}: {assessment['recommendation']}")
recommendations.append("Security posture is strong - continue monitoring and maintenance")
def _determine_risk_level(self, security_score: float) -> str:
Determine overall risk level.
security_score: Overall security score
return "Low Risk - Strong security posture"
elif security_score >= 70:
return "Medium Risk - Acceptable with monitoring"
elif security_score >= 55:
return "High Risk - Security improvements needed"
return "Critical Risk - Not recommended for production use"