regscale-cli 6.26.0.0__py3-none-any.whl → 6.27.0.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of regscale-cli might be problematic. Click here for more details.

Files changed (96) hide show
  1. regscale/_version.py +1 -1
  2. regscale/core/app/application.py +1 -1
  3. regscale/core/app/internal/evidence.py +419 -2
  4. regscale/dev/code_gen.py +24 -20
  5. regscale/integrations/commercial/__init__.py +0 -1
  6. regscale/integrations/commercial/jira.py +367 -126
  7. regscale/integrations/commercial/qualys/__init__.py +7 -8
  8. regscale/integrations/commercial/qualys/scanner.py +8 -3
  9. regscale/integrations/commercial/synqly/assets.py +17 -0
  10. regscale/integrations/commercial/synqly/vulnerabilities.py +45 -28
  11. regscale/integrations/commercial/tenablev2/cis_parsers.py +453 -0
  12. regscale/integrations/commercial/tenablev2/cis_scanner.py +447 -0
  13. regscale/integrations/commercial/tenablev2/commands.py +142 -1
  14. regscale/integrations/commercial/tenablev2/scanner.py +0 -1
  15. regscale/integrations/commercial/tenablev2/stig_parsers.py +113 -57
  16. regscale/integrations/commercial/wizv2/WizDataMixin.py +1 -1
  17. regscale/integrations/commercial/wizv2/click.py +44 -59
  18. regscale/integrations/commercial/wizv2/compliance/__init__.py +15 -0
  19. regscale/integrations/commercial/wizv2/{policy_compliance_helpers.py → compliance/helpers.py} +78 -60
  20. regscale/integrations/commercial/wizv2/compliance_report.py +10 -9
  21. regscale/integrations/commercial/wizv2/core/__init__.py +133 -0
  22. regscale/integrations/commercial/wizv2/{async_client.py → core/client.py} +3 -3
  23. regscale/integrations/commercial/wizv2/{constants.py → core/constants.py} +1 -17
  24. regscale/integrations/commercial/wizv2/core/file_operations.py +237 -0
  25. regscale/integrations/commercial/wizv2/fetchers/__init__.py +11 -0
  26. regscale/integrations/commercial/wizv2/{data_fetcher.py → fetchers/policy_assessment.py} +5 -9
  27. regscale/integrations/commercial/wizv2/issue.py +1 -1
  28. regscale/integrations/commercial/wizv2/models/__init__.py +0 -0
  29. regscale/integrations/commercial/wizv2/parsers/__init__.py +34 -0
  30. regscale/integrations/commercial/wizv2/{parsers.py → parsers/main.py} +1 -1
  31. regscale/integrations/commercial/wizv2/processors/__init__.py +11 -0
  32. regscale/integrations/commercial/wizv2/{finding_processor.py → processors/finding.py} +1 -1
  33. regscale/integrations/commercial/wizv2/reports.py +1 -1
  34. regscale/integrations/commercial/wizv2/sbom.py +1 -1
  35. regscale/integrations/commercial/wizv2/scanner.py +40 -100
  36. regscale/integrations/commercial/wizv2/utils/__init__.py +48 -0
  37. regscale/integrations/commercial/wizv2/{utils.py → utils/main.py} +116 -61
  38. regscale/integrations/commercial/wizv2/variables.py +89 -3
  39. regscale/integrations/compliance_integration.py +0 -46
  40. regscale/integrations/control_matcher.py +22 -3
  41. regscale/integrations/due_date_handler.py +14 -8
  42. regscale/integrations/public/fedramp/docx_parser.py +10 -1
  43. regscale/integrations/public/fedramp/fedramp_cis_crm.py +393 -340
  44. regscale/integrations/public/fedramp/fedramp_five.py +1 -1
  45. regscale/integrations/scanner_integration.py +127 -57
  46. regscale/models/integration_models/cisa_kev_data.json +132 -9
  47. regscale/models/integration_models/qualys.py +3 -4
  48. regscale/models/integration_models/synqly_models/capabilities.json +1 -1
  49. regscale/models/integration_models/synqly_models/connectors/vulnerabilities.py +24 -7
  50. regscale/models/integration_models/synqly_models/synqly_model.py +8 -1
  51. regscale/models/regscale_models/control_implementation.py +1 -1
  52. regscale/models/regscale_models/issue.py +0 -1
  53. {regscale_cli-6.26.0.0.dist-info → regscale_cli-6.27.0.1.dist-info}/METADATA +1 -17
  54. {regscale_cli-6.26.0.0.dist-info → regscale_cli-6.27.0.1.dist-info}/RECORD +94 -61
  55. tests/regscale/integrations/commercial/test_jira.py +481 -91
  56. tests/regscale/integrations/commercial/test_wiz.py +96 -200
  57. tests/regscale/integrations/commercial/wizv2/__init__.py +1 -1
  58. tests/regscale/integrations/commercial/wizv2/compliance/__init__.py +1 -0
  59. tests/regscale/integrations/commercial/wizv2/compliance/test_helpers.py +903 -0
  60. tests/regscale/integrations/commercial/wizv2/core/__init__.py +1 -0
  61. tests/regscale/integrations/commercial/wizv2/core/test_auth.py +701 -0
  62. tests/regscale/integrations/commercial/wizv2/core/test_client.py +1037 -0
  63. tests/regscale/integrations/commercial/wizv2/core/test_file_operations.py +989 -0
  64. tests/regscale/integrations/commercial/wizv2/fetchers/__init__.py +1 -0
  65. tests/regscale/integrations/commercial/wizv2/fetchers/test_policy_assessment.py +805 -0
  66. tests/regscale/integrations/commercial/wizv2/parsers/__init__.py +1 -0
  67. tests/regscale/integrations/commercial/wizv2/parsers/test_main.py +1153 -0
  68. tests/regscale/integrations/commercial/wizv2/processors/__init__.py +1 -0
  69. tests/regscale/integrations/commercial/wizv2/processors/test_finding.py +671 -0
  70. tests/regscale/integrations/commercial/wizv2/test_WizDataMixin.py +537 -0
  71. tests/regscale/integrations/commercial/wizv2/test_click_comprehensive.py +851 -0
  72. tests/regscale/integrations/commercial/wizv2/test_compliance_report_comprehensive.py +910 -0
  73. tests/regscale/integrations/commercial/wizv2/test_file_cleanup.py +283 -0
  74. tests/regscale/integrations/commercial/wizv2/test_file_operations.py +260 -0
  75. tests/regscale/integrations/commercial/wizv2/test_issue.py +1 -1
  76. tests/regscale/integrations/commercial/wizv2/test_issue_comprehensive.py +1203 -0
  77. tests/regscale/integrations/commercial/wizv2/test_reports.py +497 -0
  78. tests/regscale/integrations/commercial/wizv2/test_sbom.py +643 -0
  79. tests/regscale/integrations/commercial/wizv2/test_scanner_comprehensive.py +805 -0
  80. tests/regscale/integrations/commercial/wizv2/test_wiz_click_client_id.py +1 -1
  81. tests/regscale/integrations/commercial/wizv2/test_wiz_compliance_report.py +72 -29
  82. tests/regscale/integrations/commercial/wizv2/test_wiz_findings_comprehensive.py +364 -0
  83. tests/regscale/integrations/commercial/wizv2/test_wiz_inventory_comprehensive.py +644 -0
  84. tests/regscale/integrations/commercial/wizv2/test_wizv2.py +946 -78
  85. tests/regscale/integrations/commercial/wizv2/test_wizv2_utils.py +97 -202
  86. tests/regscale/integrations/commercial/wizv2/utils/__init__.py +1 -0
  87. tests/regscale/integrations/commercial/wizv2/utils/test_main.py +1523 -0
  88. tests/regscale/integrations/public/test_fedramp.py +301 -0
  89. tests/regscale/integrations/test_control_matcher.py +83 -0
  90. regscale/integrations/commercial/wizv2/policy_compliance.py +0 -3543
  91. tests/regscale/integrations/commercial/wizv2/test_wiz_policy_compliance.py +0 -750
  92. /regscale/integrations/commercial/wizv2/{wiz_auth.py → core/auth.py} +0 -0
  93. {regscale_cli-6.26.0.0.dist-info → regscale_cli-6.27.0.1.dist-info}/LICENSE +0 -0
  94. {regscale_cli-6.26.0.0.dist-info → regscale_cli-6.27.0.1.dist-info}/WHEEL +0 -0
  95. {regscale_cli-6.26.0.0.dist-info → regscale_cli-6.27.0.1.dist-info}/entry_points.txt +0 -0
  96. {regscale_cli-6.26.0.0.dist-info → regscale_cli-6.27.0.1.dist-info}/top_level.txt +0 -0
@@ -2257,7 +2257,7 @@ def create_ports_and_protocols(ports_and_protocols: List[PortsAndProtocolData],
2257
2257
  startPort=port.start_port,
2258
2258
  endPort=port.end_port,
2259
2259
  protocol=port.protocol,
2260
- purpose=port.purpose,
2260
+ purpose=port.purpose or "N/A",
2261
2261
  usedBy=port.used_by,
2262
2262
  parentId=ssp_id,
2263
2263
  parentModule="securityplans",
@@ -713,6 +713,9 @@ class ScannerIntegration(ABC):
713
713
  self._no_ccis: bool = False
714
714
  self.cci_to_control_map_lock: threading.Lock = threading.Lock()
715
715
 
716
+ # Lock for thread-safe scan history count updates
717
+ self.scan_history_lock: threading.RLock = threading.RLock()
718
+
716
719
  self.assessment_map: ThreadSafeDict[int, regscale_models.Assessment] = ThreadSafeDict()
717
720
  self.assessor_id: str = self.get_assessor_id()
718
721
  self.asset_progress: Progress = create_progress_object()
@@ -2654,17 +2657,45 @@ class ScannerIntegration(ABC):
2654
2657
 
2655
2658
  def get_asset_by_identifier(self, identifier: str) -> Optional[regscale_models.Asset]:
2656
2659
  """
2657
- Gets an asset by its identifier
2660
+ Gets an asset by its identifier with fallback lookups.
2661
+
2662
+ REG-17044: Enhanced to support multiple identifier fields (qualysId, IP, FQDN)
2663
+ to improve asset matching and reduce "asset not found" errors.
2658
2664
 
2659
2665
  :param str identifier: The identifier of the asset
2660
2666
  :return: The asset
2661
2667
  :rtype: Optional[regscale_models.Asset]
2662
2668
  """
2663
- asset = self.asset_map_by_identifier.get(identifier)
2669
+ # Try primary identifier field first
2670
+ if asset := self.asset_map_by_identifier.get(identifier):
2671
+ return asset
2672
+
2673
+ # Fallback: Try common identifier fields
2674
+ # This helps when asset_identifier_field doesn't match or assets use different identifiers
2675
+ if not asset and identifier:
2676
+ for cached_asset in self.asset_map_by_identifier.values():
2677
+ # Try IP address lookup
2678
+ if getattr(cached_asset, "ipAddress", None) == identifier:
2679
+ logger.debug(f"Found asset {cached_asset.id} by IP address fallback: {identifier}")
2680
+ return cached_asset
2681
+ # Try FQDN lookup
2682
+ if getattr(cached_asset, "fqdn", None) == identifier:
2683
+ logger.debug(f"Found asset {cached_asset.id} by FQDN fallback: {identifier}")
2684
+ return cached_asset
2685
+ # Try DNS lookup
2686
+ if getattr(cached_asset, "dns", None) == identifier:
2687
+ logger.debug(f"Found asset {cached_asset.id} by DNS fallback: {identifier}")
2688
+ return cached_asset
2689
+
2690
+ # Log error if still not found
2664
2691
  if not asset and identifier not in self.alerted_assets:
2665
2692
  self.alerted_assets.add(identifier)
2666
2693
  if not getattr(self, "suppress_asset_not_found_errors", False):
2667
- self.log_error("1. Asset not found for identifier %s", identifier)
2694
+ self.log_error(
2695
+ "Asset not found for identifier '%s' (tried %s, ipAddress, fqdn, dns)",
2696
+ identifier,
2697
+ self.asset_identifier_field,
2698
+ )
2668
2699
  return asset
2669
2700
 
2670
2701
  def get_issue_by_integration_finding_id(self, integration_finding_id: str) -> Optional[regscale_models.Issue]:
@@ -2862,7 +2893,7 @@ class ScannerIntegration(ABC):
2862
2893
  def _finalize_finding_processing(
2863
2894
  self, scan_history: regscale_models.ScanHistory, current_vulnerabilities: Dict[int, Set[int]]
2864
2895
  ) -> None:
2865
- """Finalize the finding processing by saving scan history and closing outdated issues."""
2896
+ """Finalize the finding processing by saving scan history and closing outdated vulnerabilities and issues."""
2866
2897
  logger.info(
2867
2898
  f"Saving scan history with final counts - Low: {scan_history.vLow}, Medium: {scan_history.vMedium}, High: {scan_history.vHigh}, Critical: {scan_history.vCritical}, Info: {scan_history.vInfo}"
2868
2899
  )
@@ -2881,6 +2912,7 @@ class ScannerIntegration(ABC):
2881
2912
 
2882
2913
  self._results["scan_history"] = scan_history
2883
2914
  self.update_result_counts("issues", regscale_models.Issue.bulk_save(progress_context=self.finding_progress))
2915
+ self.close_outdated_vulnerabilities(current_vulnerabilities)
2884
2916
  self.close_outdated_issues(current_vulnerabilities)
2885
2917
  self._perform_batch_operations(self.finding_progress)
2886
2918
 
@@ -2986,24 +3018,25 @@ class ScannerIntegration(ABC):
2986
3018
  self._process_checklist_finding(finding)
2987
3019
 
2988
3020
  # Process vulnerability if applicable
2989
- if finding.status != regscale_models.IssueStatus.Closed or ScannerVariables.ingestClosedIssues:
2990
- vulnerability_created = self._process_vulnerability_finding(finding, scan_history, current_vulnerabilities)
3021
+ # IMPORTANT: Always track vulnerabilities regardless of status to enable proper issue closure logic
3022
+ # This ensures that current_vulnerabilities dict accurately reflects the scan state
3023
+ vulnerability_created = self._process_vulnerability_finding(finding, scan_history, current_vulnerabilities)
2991
3024
 
3025
+ # Only create/update issues for non-closed findings (unless ingestClosedIssues is enabled)
3026
+ if finding.status != regscale_models.IssueStatus.Closed or ScannerVariables.ingestClosedIssues:
2992
3027
  self.handle_failing_finding(
2993
3028
  issue_title=finding.issue_title or finding.title,
2994
3029
  finding=finding,
2995
3030
  )
2996
3031
 
2997
- # Update scan history severity counts only if vulnerability was successfully created
2998
- if vulnerability_created:
2999
- logger.debug(
3000
- f"Updating severity count for successfully created vulnerability with severity: {finding.severity}"
3001
- )
3002
- self.set_severity_count_for_scan(finding.severity, scan_history)
3003
- else:
3004
- logger.debug(
3005
- f"Skipping severity count update for finding {finding.external_id} - no vulnerability created"
3006
- )
3032
+ # Update scan history severity counts only if vulnerability was successfully created
3033
+ if vulnerability_created:
3034
+ logger.debug(
3035
+ f"Updating severity count for successfully created vulnerability with severity: {finding.severity}"
3036
+ )
3037
+ self.set_severity_count_for_scan(finding.severity, scan_history, self.scan_history_lock)
3038
+ else:
3039
+ logger.debug(f"Skipping severity count update for finding {finding.external_id} - no vulnerability created")
3007
3040
 
3008
3041
  def _process_checklist_finding(self, finding: IntegrationFinding) -> None:
3009
3042
  """Process a checklist finding."""
@@ -3260,13 +3293,34 @@ class ScannerIntegration(ABC):
3260
3293
  vuln_list.append(vuln)
3261
3294
  return vuln_list
3262
3295
 
3263
- def close_outdated_vulnerabilities(self, current_vulnerabilities: Dict[int, Set[int]]) -> None:
3296
+ def close_outdated_vulnerabilities(self, current_vulnerabilities: Dict[int, Set[int]]) -> int:
3264
3297
  """
3265
3298
  Closes vulnerabilities that are not in the current set of vulnerability IDs for each asset.
3266
3299
 
3267
3300
  :param Dict[int, Set[int]] current_vulnerabilities: Dictionary of asset IDs to lists of current vulnerability IDs
3268
- :rtype: None
3301
+ :return: Number of vulnerabilities closed
3302
+ :rtype: int
3269
3303
  """
3304
+ if not self.close_outdated_findings:
3305
+ logger.info("Skipping closing outdated vulnerabilities.")
3306
+ return 0
3307
+
3308
+ # Check global preventAutoClose setting
3309
+ from regscale.core.app.application import Application
3310
+
3311
+ app = Application()
3312
+ if app.config.get("preventAutoClose", False):
3313
+ logger.info("Skipping closing outdated vulnerabilities due to global preventAutoClose setting.")
3314
+ return 0
3315
+
3316
+ # REG-17044: Add defensive logging to track vulnerability closure state
3317
+ logger.debug(f"Vulnerability Closure Analysis for {self.title}:")
3318
+ logger.debug(f" - Assets with current vulnerabilities: {len(current_vulnerabilities)}")
3319
+ total_current_vulns = sum(len(vuln_set) for vuln_set in current_vulnerabilities.values())
3320
+ logger.debug(f" - Total current vulnerabilities tracked: {total_current_vulns}")
3321
+ if total_current_vulns == 0:
3322
+ logger.warning("No current vulnerabilities tracked - this may close all vulnerabilities!")
3323
+
3270
3324
  # Get all current vulnerability IDs
3271
3325
  current_vuln_ids = {vuln_id for vuln_ids in current_vulnerabilities.values() for vuln_id in vuln_ids}
3272
3326
 
@@ -3289,9 +3343,14 @@ class ScannerIntegration(ABC):
3289
3343
  vuln.dateClosed = get_current_datetime()
3290
3344
  vuln.save()
3291
3345
  closed_count += 1
3292
- logger.info("Closed vulnerability %d", vuln.id)
3346
+ logger.debug("Closed vulnerability %d", vuln.id)
3293
3347
 
3294
- logger.info("Closed %d outdated vulnerabilities.", closed_count)
3348
+ (
3349
+ logger.info("Closed %d outdated vulnerabilities.", closed_count)
3350
+ if closed_count > 0
3351
+ else logger.info("No outdated vulnerabilities to close.")
3352
+ )
3353
+ return closed_count
3295
3354
 
3296
3355
  @classmethod
3297
3356
  def close_mappings_list(cls, vuln: regscale_models.Vulnerability) -> None:
@@ -3341,6 +3400,13 @@ class ScannerIntegration(ABC):
3341
3400
  logger.info("Skipping closing outdated issues due to global preventAutoClose setting.")
3342
3401
  return 0
3343
3402
 
3403
+ # REG-17044: Add defensive logging to track issue closure state
3404
+ logger.debug(f"Issue Closure Analysis for {self.title}:")
3405
+ total_current_vulns = sum(len(vuln_set) for vuln_set in current_vulnerabilities.values())
3406
+ logger.debug(f" - Total current vulnerabilities to check against: {total_current_vulns}")
3407
+ if total_current_vulns == 0:
3408
+ logger.warning("No current vulnerabilities tracked - this may close all issues!")
3409
+
3344
3410
  closed_count = 0
3345
3411
  affected_control_ids = set()
3346
3412
  count_lock = threading.Lock()
@@ -3621,51 +3687,55 @@ class ScannerIntegration(ABC):
3621
3687
  return True
3622
3688
 
3623
3689
  @staticmethod
3624
- def set_severity_count_for_scan(severity: str, scan_history: regscale_models.ScanHistory) -> None:
3690
+ def set_severity_count_for_scan(
3691
+ severity: str, scan_history: regscale_models.ScanHistory, lock: Optional[threading.RLock] = None
3692
+ ) -> None:
3625
3693
  """
3626
- Increments the count of the severity
3694
+ Increments the count of the severity in a thread-safe manner.
3695
+
3696
+ NOTE: This method does NOT save the scan_history object. The caller is responsible
3697
+ for saving the scan_history after all increments are complete to avoid race conditions
3698
+ and excessive database writes in multi-threaded environments.
3699
+
3627
3700
  :param str severity: Severity of the vulnerability
3628
3701
  :param regscale_models.ScanHistory scan_history: Scan history object
3702
+ :param Optional[threading.RLock] lock: Thread lock for synchronization (recommended in multi-threaded context)
3629
3703
  :rtype: None
3630
3704
  """
3631
- logger.debug(f"Setting severity count for scan {scan_history.id}: severity='{severity}'")
3632
- logger.debug(
3633
- f"Current counts - Low: {scan_history.vLow}, Medium: {scan_history.vMedium}, High: {scan_history.vHigh}, Critical: {scan_history.vCritical}, Info: {scan_history.vInfo}"
3634
- )
3635
3705
 
3636
- if severity == regscale_models.IssueSeverity.Low.value:
3637
- scan_history.vLow += 1
3638
- logger.debug(f"Incremented vLow count to {scan_history.vLow}")
3639
- elif severity == regscale_models.IssueSeverity.Moderate.value:
3640
- scan_history.vMedium += 1
3641
- logger.debug(f"Incremented vMedium count to {scan_history.vMedium}")
3642
- elif severity == regscale_models.IssueSeverity.High.value:
3643
- scan_history.vHigh += 1
3644
- logger.debug(f"Incremented vHigh count to {scan_history.vHigh}")
3645
- elif severity == regscale_models.IssueSeverity.Critical.value:
3646
- scan_history.vCritical += 1
3647
- logger.debug(f"Incremented vCritical count to {scan_history.vCritical}")
3648
- else:
3649
- scan_history.vInfo += 1
3650
- logger.debug(f"Incremented vInfo count to {scan_history.vInfo}")
3706
+ def _increment_severity():
3707
+ """Internal method to perform the actual increment."""
3708
+ logger.debug(f"Setting severity count for scan {scan_history.id}: severity='{severity}'")
3709
+ logger.debug(
3710
+ f"Current counts - Low: {scan_history.vLow}, Medium: {scan_history.vMedium}, High: {scan_history.vHigh}, Critical: {scan_history.vCritical}, Info: {scan_history.vInfo}"
3711
+ )
3651
3712
 
3652
- logger.debug(
3653
- f"Final counts - Low: {scan_history.vLow}, Medium: {scan_history.vMedium}, High: {scan_history.vHigh}, Critical: {scan_history.vCritical}, Info: {scan_history.vInfo}"
3654
- )
3713
+ if severity.lower() == regscale_models.IssueSeverity.Low.value.lower():
3714
+ scan_history.vLow += 1
3715
+ logger.debug(f"Incremented vLow count to {scan_history.vLow}")
3716
+ elif severity.lower() == regscale_models.IssueSeverity.Moderate.value.lower():
3717
+ scan_history.vMedium += 1
3718
+ logger.debug(f"Incremented vMedium count to {scan_history.vMedium}")
3719
+ elif severity.lower() == regscale_models.IssueSeverity.High.value.lower():
3720
+ scan_history.vHigh += 1
3721
+ logger.debug(f"Incremented vHigh count to {scan_history.vHigh}")
3722
+ elif severity.lower() == regscale_models.IssueSeverity.Critical.value.lower():
3723
+ scan_history.vCritical += 1
3724
+ logger.debug(f"Incremented vCritical count to {scan_history.vCritical}")
3725
+ else:
3726
+ scan_history.vInfo += 1
3727
+ logger.debug(f"Incremented vInfo count to {scan_history.vInfo}")
3655
3728
 
3656
- # Save the scan history immediately to persist the count changes
3657
- try:
3658
- scan_history.save()
3659
- logger.debug(f"Successfully saved scan history {scan_history.id} with updated counts")
3660
- except Exception as e:
3661
- logger.error(f"Error saving scan history {scan_history.id} after updating counts: {e}")
3662
- # Try to save again with a fresh fetch
3663
- try:
3664
- scan_history.fetch()
3665
- scan_history.save()
3666
- logger.debug(f"Successfully saved scan history {scan_history.id} after retry")
3667
- except Exception as e2:
3668
- logger.error(f"Failed to save scan history {scan_history.id} after retry: {e2}")
3729
+ logger.debug(
3730
+ f"Updated counts - Low: {scan_history.vLow}, Medium: {scan_history.vMedium}, High: {scan_history.vHigh}, Critical: {scan_history.vCritical}, Info: {scan_history.vInfo}"
3731
+ )
3732
+
3733
+ # Use lock if provided for thread-safe increments
3734
+ if lock:
3735
+ with lock:
3736
+ _increment_severity()
3737
+ else:
3738
+ _increment_severity()
3669
3739
 
3670
3740
  @classmethod
3671
3741
  def cci_assessment(cls, plan_id: int) -> None:
@@ -1,9 +1,132 @@
1
1
  {
2
2
  "title": "CISA Catalog of Known Exploited Vulnerabilities",
3
- "catalogVersion": "2025.10.02",
4
- "dateReleased": "2025-10-02T14:59:13.7696Z",
5
- "count": 1427,
3
+ "catalogVersion": "2025.10.09",
4
+ "dateReleased": "2025-10-09T16:52:28.6547Z",
5
+ "count": 1436,
6
6
  "vulnerabilities": [
7
+ {
8
+ "cveID": "CVE-2021-43798",
9
+ "vendorProject": "Grafana Labs",
10
+ "product": "Grafana",
11
+ "vulnerabilityName": "Grafana Path Traversal Vulnerability",
12
+ "dateAdded": "2025-10-09",
13
+ "shortDescription": "Grafana contains a path traversal vulnerability that could allow access to local files.",
14
+ "requiredAction": "Apply mitigations per vendor instructions, follow applicable BOD 22-01 guidance for cloud services, or discontinue use of the product if mitigations are unavailable.",
15
+ "dueDate": "2025-10-30",
16
+ "knownRansomwareCampaignUse": "Unknown",
17
+ "notes": "https:\/\/grafana.com\/blog\/2021\/12\/07\/grafana-8.3.1-8.2.7-8.1.8-and-8.0.7-released-with-high-severity-security-fix\/ ; https:\/\/nvd.nist.gov\/vuln\/detail\/CVE-2021-43798",
18
+ "cwes": [
19
+ "CWE-22"
20
+ ]
21
+ },
22
+ {
23
+ "cveID": "CVE-2025-27915",
24
+ "vendorProject": "Synacor",
25
+ "product": "Zimbra Collaboration Suite (ZCS)",
26
+ "vulnerabilityName": "Synacor Zimbra Collaboration Suite (ZCS) Cross-site Scripting Vulnerability",
27
+ "dateAdded": "2025-10-07",
28
+ "shortDescription": "Synacor Zimbra Collaboration Suite (ZCS) contains a cross-site scripting vulnerability that exists in the Classic Web Client due to insufficient sanitization of HTML content in ICS files. When a user views an e-mail message containing a malicious ICS entry, its embedded JavaScript executes via an ontoggle event inside a tag. This allows an attacker to run arbitrary JavaScript within the victim's session, potentially leading to unauthorized actions such as setting e-mail filters to redirect messages to an attacker-controlled address. As a result, an attacker can perform unauthorized actions on the victim's account, including e-mail redirection and data exfiltration.",
29
+ "requiredAction": "Apply mitigations per vendor instructions, follow applicable BOD 22-01 guidance for cloud services, or discontinue use of the product if mitigations are unavailable.",
30
+ "dueDate": "2025-10-28",
31
+ "knownRansomwareCampaignUse": "Unknown",
32
+ "notes": "https:\/\/wiki.zimbra.com\/wiki\/Security_Center ; https:\/\/nvd.nist.gov\/vuln\/detail\/CVE-2025-27915",
33
+ "cwes": [
34
+ "CWE-79"
35
+ ]
36
+ },
37
+ {
38
+ "cveID": "CVE-2021-22555",
39
+ "vendorProject": "Linux",
40
+ "product": "Kernel",
41
+ "vulnerabilityName": "Linux Kernel Heap Out-of-Bounds Write Vulnerability",
42
+ "dateAdded": "2025-10-06",
43
+ "shortDescription": "Linux Kernel contains a heap out-of-bounds write vulnerability that could allow an attacker to gain privileges or cause a DoS (via heap memory corruption) through user name space.",
44
+ "requiredAction": "Apply mitigations per vendor instructions, follow applicable BOD 22-01 guidance for cloud services, or discontinue use of the product if mitigations are unavailable.",
45
+ "dueDate": "2025-10-27",
46
+ "knownRansomwareCampaignUse": "Unknown",
47
+ "notes": "https:\/\/git.kernel.org\/pub\/scm\/linux\/kernel\/git\/torvalds\/linux.git\/commit\/net\/netfilter\/x_tables.c?id=9fa492cdc160cd27ce1046cb36f47d3b2b1efa21 ; https:\/\/git.kernel.org\/pub\/scm\/linux\/kernel\/git\/torvalds\/linux.git\/commit\/net\/netfilter\/x_tables.c?id=b29c457a6511435960115c0f548c4360d5f4801d ; https:\/\/security.netapp.com\/advisory\/ntap-20210805-0010\/ ; https:\/\/github.com\/google\/security-research\/security\/advisories\/GHSA-xxx5-8mvq-3528 ; https:\/\/nvd.nist.gov\/vuln\/detail\/CVE-2021-22555",
48
+ "cwes": [
49
+ "CWE-787"
50
+ ]
51
+ },
52
+ {
53
+ "cveID": "CVE-2010-3962",
54
+ "vendorProject": "Microsoft",
55
+ "product": "Internet Explorer",
56
+ "vulnerabilityName": "Microsoft Internet Explorer Uninitialized Memory Corruption Vulnerability",
57
+ "dateAdded": "2025-10-06",
58
+ "shortDescription": "Microsoft Internet Explorer contains an uninitialized memory corruption vulnerability that could allow for remote code execution. The impacted product could be end-of-life (EoL) and\/or end-of-service (EoS). Users should discontinue product utilization.",
59
+ "requiredAction": "Apply mitigations per vendor instructions, follow applicable BOD 22-01 guidance for cloud services, or discontinue use of the product if mitigations are unavailable.",
60
+ "dueDate": "2025-10-27",
61
+ "knownRansomwareCampaignUse": "Unknown",
62
+ "notes": "https:\/\/learn.microsoft.com\/en-us\/security-updates\/SecurityAdvisories\/2010\/2458511?redirectedfrom=MSDN ; https:\/\/nvd.nist.gov\/vuln\/detail\/CVE-2010-3962",
63
+ "cwes": []
64
+ },
65
+ {
66
+ "cveID": "CVE-2021-43226",
67
+ "vendorProject": "Microsoft",
68
+ "product": "Windows",
69
+ "vulnerabilityName": "Microsoft Windows Privilege Escalation Vulnerability",
70
+ "dateAdded": "2025-10-06",
71
+ "shortDescription": "Microsoft Windows Common Log File System Driver contains a privilege escalation vulnerability that could allow a local, privileged attacker to bypass certain security mechanisms.",
72
+ "requiredAction": "Apply mitigations per vendor instructions, follow applicable BOD 22-01 guidance for cloud services, or discontinue use of the product if mitigations are unavailable.",
73
+ "dueDate": "2025-10-27",
74
+ "knownRansomwareCampaignUse": "Unknown",
75
+ "notes": "https:\/\/msrc.microsoft.com\/update-guide\/vulnerability\/CVE-2021-43226 ; https:\/\/nvd.nist.gov\/vuln\/detail\/CVE-2021-43226",
76
+ "cwes": []
77
+ },
78
+ {
79
+ "cveID": "CVE-2013-3918",
80
+ "vendorProject": "Microsoft",
81
+ "product": "Windows",
82
+ "vulnerabilityName": "Microsoft Windows Out-of-Bounds Write Vulnerability",
83
+ "dateAdded": "2025-10-06",
84
+ "shortDescription": "Microsoft Windows contains an out-of-bounds write vulnerability in the InformationCardSigninHelper Class ActiveX control, icardie.dll. An attacker could exploit the vulnerability by constructing a specially crafted webpage. When a user views the webpage, the vulnerability could allow remote code execution. An attacker who successfully exploited this vulnerability could gain the same user rights as the current user. The impacted product could be end-of-life (EoL) and\/or end-of-service (EoS). Users should discontinue product utilization.",
85
+ "requiredAction": "Apply mitigations per vendor instructions, follow applicable BOD 22-01 guidance for cloud services, or discontinue use of the product if mitigations are unavailable.",
86
+ "dueDate": "2025-10-27",
87
+ "knownRansomwareCampaignUse": "Unknown",
88
+ "notes": "https:\/\/docs.microsoft.com\/en-us\/security-updates\/securitybulletins\/2013\/ms13-090 ; https:\/\/nvd.nist.gov\/vuln\/detail\/CVE-2013-3918",
89
+ "cwes": []
90
+ },
91
+ {
92
+ "cveID": "CVE-2011-3402",
93
+ "vendorProject": "Microsoft",
94
+ "product": "Windows",
95
+ "vulnerabilityName": "Microsoft Windows Remote Code Execution Vulnerability",
96
+ "dateAdded": "2025-10-06",
97
+ "shortDescription": "Microsoft Windows Kernel contains an unspecified vulnerability in the TrueType font parsing engine in win32k.sys in the kernel-mode drivers that allows remote attackers to execute arbitrary code via crafted font data in a Word document or web page.",
98
+ "requiredAction": "Apply mitigations per vendor instructions, follow applicable BOD 22-01 guidance for cloud services, or discontinue use of the product if mitigations are unavailable.",
99
+ "dueDate": "2025-10-27",
100
+ "knownRansomwareCampaignUse": "Unknown",
101
+ "notes": "https:\/\/docs.microsoft.com\/en-us\/security-updates\/securitybulletins\/2011\/ms11-087 ; https:\/\/nvd.nist.gov\/vuln\/detail\/CVE-2011-3402",
102
+ "cwes": []
103
+ },
104
+ {
105
+ "cveID": "CVE-2010-3765",
106
+ "vendorProject": "Mozilla",
107
+ "product": "Multiple Products",
108
+ "vulnerabilityName": "Mozilla Multiple Products Remote Code Execution Vulnerability",
109
+ "dateAdded": "2025-10-06",
110
+ "shortDescription": "Mozilla Firefox, SeaMonkey, and Thunderbird contain an unspecified vulnerability when JavaScript is enabled. This allows remote attackers to execute arbitrary code via vectors related to nsCSSFrameConstructor::ContentAppended, the appendChild method, incorrect index tracking, and the creation of multiple frames, which triggers memory corruption.",
111
+ "requiredAction": "Apply mitigations per vendor instructions, follow applicable BOD 22-01 guidance for cloud services, or discontinue use of the product if mitigations are unavailable.",
112
+ "dueDate": "2025-10-27",
113
+ "knownRansomwareCampaignUse": "Unknown",
114
+ "notes": "https:\/\/www.mozilla.org\/en-US\/security\/advisories\/mfsa2010-73 ; https:\/\/nvd.nist.gov\/vuln\/detail\/CVE-2010-3765",
115
+ "cwes": []
116
+ },
117
+ {
118
+ "cveID": "CVE-2025-61882",
119
+ "vendorProject": "Oracle",
120
+ "product": "E-Business Suite",
121
+ "vulnerabilityName": "Oracle E-Business Suite Unspecified Vulnerability",
122
+ "dateAdded": "2025-10-06",
123
+ "shortDescription": "Oracle E-Business Suite contains an unspecified vulnerability in the BI Publisher Integration component. The vulnerability allows unauthenticated attacker with network access via HTTP to compromise Oracle Concurrent Processing. Successful attacks can result in takeover of Oracle Concurrent Processing.",
124
+ "requiredAction": "Apply mitigations per vendor instructions, follow applicable BOD 22-01 guidance for cloud services, or discontinue use of the product if mitigations are unavailable.",
125
+ "dueDate": "2025-10-27",
126
+ "knownRansomwareCampaignUse": "Known",
127
+ "notes": "https:\/\/www.oracle.com\/security-alerts\/alert-cve-2025-61882.html ; https:\/\/nvd.nist.gov\/vuln\/detail\/CVE-2025-61882",
128
+ "cwes": []
129
+ },
7
130
  {
8
131
  "cveID": "CVE-2014-6278",
9
132
  "vendorProject": "GNU",
@@ -117,7 +240,7 @@
117
240
  "shortDescription": "Fortra GoAnywhere MFT contains a deserialization of untrusted data vulnerability allows an actor with a validly forged license response signature to deserialize an arbitrary actor-controlled object, possibly leading to command injection.",
118
241
  "requiredAction": "Apply mitigations per vendor instructions, follow applicable BOD 22-01 guidance for cloud services, or discontinue use of the product if mitigations are unavailable.",
119
242
  "dueDate": "2025-10-20",
120
- "knownRansomwareCampaignUse": "Unknown",
243
+ "knownRansomwareCampaignUse": "Known",
121
244
  "notes": "https:\/\/www.fortra.com\/security\/advisories\/product-security\/fi-2025-012 ; https:\/\/nvd.nist.gov\/vuln\/detail\/CVE-2025-10035",
122
245
  "cwes": [
123
246
  "CWE-502",
@@ -5205,7 +5328,7 @@
5205
5328
  "shortDescription": "Microsoft Windows Internet Shortcut Files contains an unspecified vulnerability that allows for a security feature bypass.",
5206
5329
  "requiredAction": "Apply mitigations per vendor instructions or discontinue use of the product if mitigations are unavailable.",
5207
5330
  "dueDate": "2024-03-05",
5208
- "knownRansomwareCampaignUse": "Unknown",
5331
+ "knownRansomwareCampaignUse": "Known",
5209
5332
  "notes": "https:\/\/msrc.microsoft.com\/update-guide\/en-US\/vulnerability\/CVE-2024-21412; https:\/\/nvd.nist.gov\/vuln\/detail\/CVE-2024-21412",
5210
5333
  "cwes": [
5211
5334
  "CWE-693"
@@ -5295,8 +5418,8 @@
5295
5418
  "shortDescription": "Ivanti Connect Secure (ICS, formerly known as Pulse Connect Secure), Ivanti Policy Secure, and Ivanti Neurons contain a server-side request forgery (SSRF) vulnerability in the SAML component that allows an attacker to access certain restricted resources without authentication.",
5296
5419
  "requiredAction": "Apply mitigations per vendor instructions or discontinue use of the product if mitigations are unavailable.",
5297
5420
  "dueDate": "2024-02-02",
5298
- "knownRansomwareCampaignUse": "Unknown",
5299
- "notes": "https:\/\/forums.ivanti.com\/s\/article\/KB-CVE-2023-46805-Authentication-Bypass-CVE-2024-21887-Command-Injection-for-Ivanti-Connect-Secure-and-Ivanti-Policy-Secure-Gateways?language=en_US; https:\/\/nvd.nist.gov\/vuln\/detail\/CVE-2024-21893",
5421
+ "knownRansomwareCampaignUse": "Known",
5422
+ "notes": "https:\/\/forums.ivanti.com\/s\/article\/KB-CVE-2023-46805-Authentication-Bypass-CVE-2024-21887-Command-Injection-for-Ivanti-Connect-Secure-and-Ivanti-Policy-Secure-Gateways?language=en_US ; https:\/\/nvd.nist.gov\/vuln\/detail\/CVE-2024-21893",
5300
5423
  "cwes": [
5301
5424
  "CWE-918"
5302
5425
  ]
@@ -5445,7 +5568,7 @@
5445
5568
  "shortDescription": "Ivanti Connect Secure (ICS, formerly known as Pulse Connect Secure) and Ivanti Policy Secure gateways contain an authentication bypass vulnerability in the web component that allows an attacker to access restricted resources by bypassing control checks. This vulnerability can be leveraged in conjunction with CVE-2024-21887, a command injection vulnerability.",
5446
5569
  "requiredAction": "Apply mitigations per vendor instructions or discontinue use of the product if mitigations are unavailable.",
5447
5570
  "dueDate": "2024-01-22",
5448
- "knownRansomwareCampaignUse": "Unknown",
5571
+ "knownRansomwareCampaignUse": "Known",
5449
5572
  "notes": "Please apply mitigations per vendor instructions. For more information, please see: https:\/\/forums.ivanti.com\/s\/article\/KB-CVE-2023-46805-Authentication-Bypass-CVE-2024-21887-Command-Injection-for-Ivanti-Connect-Secure-and-Ivanti-Policy-Secure-Gateways?language=en_US ; https:\/\/nvd.nist.gov\/vuln\/detail\/CVE-2023-46805",
5450
5573
  "cwes": [
5451
5574
  "CWE-287"
@@ -5460,7 +5583,7 @@
5460
5583
  "shortDescription": "Ivanti Connect Secure (ICS, formerly known as Pulse Connect Secure) and Ivanti Policy Secure contain a command injection vulnerability in the web components of these products, which can allow an authenticated administrator to send crafted requests to execute code on affected appliances. This vulnerability can be leveraged in conjunction with CVE-2023-46805, an authenticated bypass issue.",
5461
5584
  "requiredAction": "Apply mitigations per vendor instructions or discontinue use of the product if mitigations are unavailable.",
5462
5585
  "dueDate": "2024-01-22",
5463
- "knownRansomwareCampaignUse": "Unknown",
5586
+ "knownRansomwareCampaignUse": "Known",
5464
5587
  "notes": "Please apply mitigations per vendor instructions. For more information, please see: https:\/\/forums.ivanti.com\/s\/article\/KB-CVE-2023-46805-Authentication-Bypass-CVE-2024-21887-Command-Injection-for-Ivanti-Connect-Secure-and-Ivanti-Policy-Secure-Gateways?language=en_US ; https:\/\/nvd.nist.gov\/vuln\/detail\/CVE-2024-21887",
5465
5588
  "cwes": [
5466
5589
  "CWE-77"
@@ -7,9 +7,8 @@ import logging
7
7
 
8
8
  # pylint: disable=C0415
9
9
  import re
10
- from calendar import firstweekday
11
10
  from datetime import datetime
12
- from typing import Any, Iterator, List, Optional, TextIO, TypeVar, Union
11
+ from typing import Iterator, List, Optional, TextIO, TypeVar, Union
13
12
 
14
13
  from openpyxl.reader.excel import load_workbook
15
14
  from pandas import Timestamp
@@ -119,7 +118,7 @@ class Qualys(FlatFileImporter):
119
118
  return IntegrationAsset(
120
119
  name=self.mapping.get_value(dat, DNS),
121
120
  ip_address=self.mapping.get_value(dat, IP),
122
- status=AssetStatus.Active.value,
121
+ status=AssetStatus.Active,
123
122
  cpu=0,
124
123
  ram=0,
125
124
  asset_category="Hardware",
@@ -162,7 +161,7 @@ class Qualys(FlatFileImporter):
162
161
  description: str = self.mapping.get_value(dat, "Threat")
163
162
  title = self.mapping.get_value(dat, self.vuln_title)
164
163
  severity = self.mapping.get_value(dat, SEVERITY)
165
- regscale_severity = map_qualys_severity_to_regscale(int(severity))[1]
164
+ regscale_severity, _ = map_qualys_severity_to_regscale(int(severity))
166
165
  if dat:
167
166
  finding = IntegrationFinding(
168
167
  control_labels=[], # Add an empty list for control_labels