regscale-cli 6.26.0.0__py3-none-any.whl → 6.27.0.0__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.
- regscale/_version.py +1 -1
- regscale/core/app/application.py +1 -1
- regscale/core/app/internal/evidence.py +419 -2
- regscale/dev/code_gen.py +24 -20
- regscale/integrations/commercial/jira.py +367 -126
- regscale/integrations/commercial/qualys/__init__.py +7 -8
- regscale/integrations/commercial/qualys/scanner.py +8 -3
- regscale/integrations/commercial/synqly/assets.py +17 -0
- regscale/integrations/commercial/synqly/vulnerabilities.py +45 -28
- regscale/integrations/commercial/tenablev2/cis_parsers.py +453 -0
- regscale/integrations/commercial/tenablev2/cis_scanner.py +447 -0
- regscale/integrations/commercial/tenablev2/commands.py +142 -1
- regscale/integrations/commercial/tenablev2/scanner.py +0 -1
- regscale/integrations/commercial/tenablev2/stig_parsers.py +113 -57
- regscale/integrations/commercial/wizv2/WizDataMixin.py +1 -1
- regscale/integrations/commercial/wizv2/click.py +44 -59
- regscale/integrations/commercial/wizv2/compliance/__init__.py +15 -0
- regscale/integrations/commercial/wizv2/{policy_compliance_helpers.py → compliance/helpers.py} +78 -60
- regscale/integrations/commercial/wizv2/compliance_report.py +10 -9
- regscale/integrations/commercial/wizv2/core/__init__.py +133 -0
- regscale/integrations/commercial/wizv2/{async_client.py → core/client.py} +3 -3
- regscale/integrations/commercial/wizv2/{constants.py → core/constants.py} +1 -17
- regscale/integrations/commercial/wizv2/core/file_operations.py +237 -0
- regscale/integrations/commercial/wizv2/fetchers/__init__.py +11 -0
- regscale/integrations/commercial/wizv2/{data_fetcher.py → fetchers/policy_assessment.py} +5 -9
- regscale/integrations/commercial/wizv2/issue.py +1 -1
- regscale/integrations/commercial/wizv2/models/__init__.py +0 -0
- regscale/integrations/commercial/wizv2/parsers/__init__.py +34 -0
- regscale/integrations/commercial/wizv2/{parsers.py → parsers/main.py} +1 -1
- regscale/integrations/commercial/wizv2/processors/__init__.py +11 -0
- regscale/integrations/commercial/wizv2/{finding_processor.py → processors/finding.py} +1 -1
- regscale/integrations/commercial/wizv2/reports.py +1 -1
- regscale/integrations/commercial/wizv2/sbom.py +1 -1
- regscale/integrations/commercial/wizv2/scanner.py +40 -100
- regscale/integrations/commercial/wizv2/utils/__init__.py +48 -0
- regscale/integrations/commercial/wizv2/{utils.py → utils/main.py} +116 -61
- regscale/integrations/commercial/wizv2/variables.py +89 -3
- regscale/integrations/compliance_integration.py +0 -46
- regscale/integrations/control_matcher.py +22 -3
- regscale/integrations/due_date_handler.py +14 -8
- regscale/integrations/public/fedramp/docx_parser.py +10 -1
- regscale/integrations/public/fedramp/fedramp_cis_crm.py +393 -340
- regscale/integrations/public/fedramp/fedramp_five.py +1 -1
- regscale/integrations/scanner_integration.py +127 -57
- regscale/models/integration_models/cisa_kev_data.json +132 -9
- regscale/models/integration_models/qualys.py +3 -4
- regscale/models/integration_models/synqly_models/capabilities.json +1 -1
- regscale/models/integration_models/synqly_models/connectors/vulnerabilities.py +24 -7
- regscale/models/integration_models/synqly_models/synqly_model.py +8 -1
- regscale/models/regscale_models/control_implementation.py +1 -1
- regscale/models/regscale_models/issue.py +0 -1
- {regscale_cli-6.26.0.0.dist-info → regscale_cli-6.27.0.0.dist-info}/METADATA +1 -17
- {regscale_cli-6.26.0.0.dist-info → regscale_cli-6.27.0.0.dist-info}/RECORD +93 -60
- tests/regscale/integrations/commercial/test_jira.py +481 -91
- tests/regscale/integrations/commercial/test_wiz.py +96 -200
- tests/regscale/integrations/commercial/wizv2/__init__.py +1 -1
- tests/regscale/integrations/commercial/wizv2/compliance/__init__.py +1 -0
- tests/regscale/integrations/commercial/wizv2/compliance/test_helpers.py +903 -0
- tests/regscale/integrations/commercial/wizv2/core/__init__.py +1 -0
- tests/regscale/integrations/commercial/wizv2/core/test_auth.py +701 -0
- tests/regscale/integrations/commercial/wizv2/core/test_client.py +1037 -0
- tests/regscale/integrations/commercial/wizv2/core/test_file_operations.py +989 -0
- tests/regscale/integrations/commercial/wizv2/fetchers/__init__.py +1 -0
- tests/regscale/integrations/commercial/wizv2/fetchers/test_policy_assessment.py +805 -0
- tests/regscale/integrations/commercial/wizv2/parsers/__init__.py +1 -0
- tests/regscale/integrations/commercial/wizv2/parsers/test_main.py +1153 -0
- tests/regscale/integrations/commercial/wizv2/processors/__init__.py +1 -0
- tests/regscale/integrations/commercial/wizv2/processors/test_finding.py +671 -0
- tests/regscale/integrations/commercial/wizv2/test_WizDataMixin.py +537 -0
- tests/regscale/integrations/commercial/wizv2/test_click_comprehensive.py +851 -0
- tests/regscale/integrations/commercial/wizv2/test_compliance_report_comprehensive.py +910 -0
- tests/regscale/integrations/commercial/wizv2/test_file_cleanup.py +283 -0
- tests/regscale/integrations/commercial/wizv2/test_file_operations.py +260 -0
- tests/regscale/integrations/commercial/wizv2/test_issue.py +1 -1
- tests/regscale/integrations/commercial/wizv2/test_issue_comprehensive.py +1203 -0
- tests/regscale/integrations/commercial/wizv2/test_reports.py +497 -0
- tests/regscale/integrations/commercial/wizv2/test_sbom.py +643 -0
- tests/regscale/integrations/commercial/wizv2/test_scanner_comprehensive.py +805 -0
- tests/regscale/integrations/commercial/wizv2/test_wiz_click_client_id.py +1 -1
- tests/regscale/integrations/commercial/wizv2/test_wiz_compliance_report.py +72 -29
- tests/regscale/integrations/commercial/wizv2/test_wiz_findings_comprehensive.py +364 -0
- tests/regscale/integrations/commercial/wizv2/test_wiz_inventory_comprehensive.py +644 -0
- tests/regscale/integrations/commercial/wizv2/test_wizv2.py +946 -78
- tests/regscale/integrations/commercial/wizv2/test_wizv2_utils.py +97 -202
- tests/regscale/integrations/commercial/wizv2/utils/__init__.py +1 -0
- tests/regscale/integrations/commercial/wizv2/utils/test_main.py +1523 -0
- tests/regscale/integrations/public/test_fedramp.py +301 -0
- tests/regscale/integrations/test_control_matcher.py +83 -0
- regscale/integrations/commercial/wizv2/policy_compliance.py +0 -3543
- tests/regscale/integrations/commercial/wizv2/test_wiz_policy_compliance.py +0 -750
- /regscale/integrations/commercial/wizv2/{wiz_auth.py → core/auth.py} +0 -0
- {regscale_cli-6.26.0.0.dist-info → regscale_cli-6.27.0.0.dist-info}/LICENSE +0 -0
- {regscale_cli-6.26.0.0.dist-info → regscale_cli-6.27.0.0.dist-info}/WHEEL +0 -0
- {regscale_cli-6.26.0.0.dist-info → regscale_cli-6.27.0.0.dist-info}/entry_points.txt +0 -0
- {regscale_cli-6.26.0.0.dist-info → regscale_cli-6.27.0.0.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
|
-
|
|
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(
|
|
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
|
-
|
|
2990
|
-
|
|
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
|
-
|
|
2998
|
-
|
|
2999
|
-
|
|
3000
|
-
|
|
3001
|
-
|
|
3002
|
-
|
|
3003
|
-
|
|
3004
|
-
|
|
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]]) ->
|
|
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
|
-
:
|
|
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.
|
|
3346
|
+
logger.debug("Closed vulnerability %d", vuln.id)
|
|
3293
3347
|
|
|
3294
|
-
|
|
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(
|
|
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
|
-
|
|
3637
|
-
|
|
3638
|
-
logger.debug(f"
|
|
3639
|
-
|
|
3640
|
-
|
|
3641
|
-
|
|
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
|
-
|
|
3653
|
-
|
|
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
|
-
|
|
3657
|
-
|
|
3658
|
-
|
|
3659
|
-
|
|
3660
|
-
|
|
3661
|
-
|
|
3662
|
-
|
|
3663
|
-
|
|
3664
|
-
|
|
3665
|
-
|
|
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.
|
|
4
|
-
"dateReleased": "2025-10-
|
|
5
|
-
"count":
|
|
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": "
|
|
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": "
|
|
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": "
|
|
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;
|
|
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": "
|
|
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": "
|
|
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
|
|
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
|
|
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))
|
|
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
|