regscale-cli 6.21.0.0__py3-none-any.whl → 6.21.2.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.
- regscale/_version.py +1 -1
- regscale/core/app/application.py +7 -0
- regscale/integrations/commercial/__init__.py +9 -10
- regscale/integrations/commercial/amazon/common.py +79 -2
- regscale/integrations/commercial/aws/cli.py +183 -9
- regscale/integrations/commercial/aws/scanner.py +544 -9
- regscale/integrations/commercial/cpe.py +18 -1
- regscale/integrations/commercial/import_all/import_all_cmd.py +2 -2
- regscale/integrations/commercial/microsoft_defender/__init__.py +0 -0
- regscale/integrations/commercial/{defender.py → microsoft_defender/defender.py} +38 -612
- regscale/integrations/commercial/microsoft_defender/defender_api.py +286 -0
- regscale/integrations/commercial/microsoft_defender/defender_constants.py +80 -0
- regscale/integrations/commercial/microsoft_defender/defender_scanner.py +168 -0
- regscale/integrations/commercial/qualys/__init__.py +24 -86
- regscale/integrations/commercial/qualys/containers.py +2 -0
- regscale/integrations/commercial/qualys/scanner.py +7 -2
- regscale/integrations/commercial/sonarcloud.py +110 -71
- regscale/integrations/commercial/tenablev2/jsonl_scanner.py +2 -1
- regscale/integrations/commercial/wizv2/async_client.py +10 -3
- regscale/integrations/commercial/wizv2/click.py +105 -26
- regscale/integrations/commercial/wizv2/constants.py +249 -1
- regscale/integrations/commercial/wizv2/data_fetcher.py +401 -0
- regscale/integrations/commercial/wizv2/finding_processor.py +295 -0
- regscale/integrations/commercial/wizv2/issue.py +2 -2
- regscale/integrations/commercial/wizv2/parsers.py +3 -2
- regscale/integrations/commercial/wizv2/policy_compliance.py +3057 -0
- regscale/integrations/commercial/wizv2/policy_compliance_helpers.py +564 -0
- regscale/integrations/commercial/wizv2/scanner.py +19 -25
- regscale/integrations/commercial/wizv2/utils.py +258 -85
- regscale/integrations/commercial/wizv2/variables.py +4 -3
- regscale/integrations/compliance_integration.py +1607 -0
- regscale/integrations/public/fedramp/fedramp_five.py +93 -8
- regscale/integrations/public/fedramp/markdown_parser.py +7 -1
- regscale/integrations/scanner_integration.py +57 -6
- regscale/models/__init__.py +1 -1
- regscale/models/app_models/__init__.py +1 -0
- regscale/models/integration_models/cisa_kev_data.json +103 -4
- regscale/models/integration_models/synqly_models/capabilities.json +1 -1
- regscale/{integrations/commercial/wizv2/models.py → models/integration_models/wizv2.py} +4 -12
- regscale/models/regscale_models/file.py +4 -0
- regscale/models/regscale_models/issue.py +151 -8
- regscale/models/regscale_models/regscale_model.py +4 -2
- regscale/models/regscale_models/security_plan.py +1 -1
- regscale/utils/graphql_client.py +3 -1
- {regscale_cli-6.21.0.0.dist-info → regscale_cli-6.21.2.0.dist-info}/METADATA +9 -9
- {regscale_cli-6.21.0.0.dist-info → regscale_cli-6.21.2.0.dist-info}/RECORD +52 -44
- tests/regscale/core/test_version_regscale.py +5 -3
- tests/regscale/integrations/test_wiz_policy_compliance_affected_controls.py +154 -0
- tests/regscale/test_authorization.py +0 -65
- tests/regscale/test_init.py +0 -96
- {regscale_cli-6.21.0.0.dist-info → regscale_cli-6.21.2.0.dist-info}/LICENSE +0 -0
- {regscale_cli-6.21.0.0.dist-info → regscale_cli-6.21.2.0.dist-info}/WHEEL +0 -0
- {regscale_cli-6.21.0.0.dist-info → regscale_cli-6.21.2.0.dist-info}/entry_points.txt +0 -0
- {regscale_cli-6.21.0.0.dist-info → regscale_cli-6.21.2.0.dist-info}/top_level.txt +0 -0
|
@@ -1063,7 +1063,7 @@ def _update_existing_control(
|
|
|
1063
1063
|
existing_control,
|
|
1064
1064
|
control_dict.get("status"),
|
|
1065
1065
|
new_statement if new_statement else control_dict.get("statement"),
|
|
1066
|
-
control_dict.get("
|
|
1066
|
+
control_dict.get("origination"),
|
|
1067
1067
|
primary_role if primary_role and isinstance(primary_role, dict) and primary_role.get("id") else None,
|
|
1068
1068
|
parent_id,
|
|
1069
1069
|
)
|
|
@@ -1087,14 +1087,93 @@ def _update_existing_control(
|
|
|
1087
1087
|
|
|
1088
1088
|
def add_roles_to_control_implementation(implementation: ControlImplementation, roles: List[Dict]):
|
|
1089
1089
|
"""
|
|
1090
|
-
|
|
1090
|
+
Updates roles for a control implementation by checking existing roles and adding/removing as appropriate.
|
|
1091
|
+
This prevents duplicate roles on successive imports.
|
|
1092
|
+
:param ControlImplementation implementation: The control implementation.
|
|
1093
|
+
:param List[Dict] roles: The list of roles to set.
|
|
1094
|
+
"""
|
|
1095
|
+
if not implementation or not implementation.id:
|
|
1096
|
+
logger.warning("Control implementation is missing or has no ID, cannot update roles")
|
|
1097
|
+
return
|
|
1098
|
+
|
|
1099
|
+
try:
|
|
1100
|
+
# Get existing roles for this control implementation
|
|
1101
|
+
from regscale.models.regscale_models.implementation_role import ImplementationRole
|
|
1102
|
+
|
|
1103
|
+
# Get existing roles
|
|
1104
|
+
existing_roles = ImplementationRole.get_all_by_parent(
|
|
1105
|
+
parent_id=implementation.id, parent_module=implementation._module_string
|
|
1106
|
+
)
|
|
1107
|
+
existing_role_ids = {role.roleId for role in existing_roles if role and role.roleId}
|
|
1108
|
+
|
|
1109
|
+
# Get target role IDs from the new roles list
|
|
1110
|
+
target_role_ids = {role.get("id") for role in roles if isinstance(role, dict) and role.get("id")}
|
|
1111
|
+
|
|
1112
|
+
# Find roles to add (in target but not in existing)
|
|
1113
|
+
roles_to_add = target_role_ids - existing_role_ids
|
|
1114
|
+
|
|
1115
|
+
# Find roles to remove (in existing but not in target)
|
|
1116
|
+
roles_to_remove = existing_role_ids - target_role_ids
|
|
1117
|
+
|
|
1118
|
+
# Add new roles
|
|
1119
|
+
for role_id in roles_to_add:
|
|
1120
|
+
try:
|
|
1121
|
+
implementation.add_role(role_id)
|
|
1122
|
+
logger.debug(f"Added role {role_id} to control implementation {implementation.id}")
|
|
1123
|
+
except Exception as e:
|
|
1124
|
+
logger.warning(f"Failed to add role {role_id} to control implementation {implementation.id}: {e}")
|
|
1125
|
+
|
|
1126
|
+
# Remove roles that are no longer needed
|
|
1127
|
+
_remove_roles_from_control_implementation(implementation, roles_to_remove, existing_roles)
|
|
1128
|
+
|
|
1129
|
+
if roles_to_add or roles_to_remove:
|
|
1130
|
+
logger.info(
|
|
1131
|
+
f"Updated roles for control implementation {implementation.id}: added {len(roles_to_add)}, removed {len(roles_to_remove)}"
|
|
1132
|
+
)
|
|
1133
|
+
else:
|
|
1134
|
+
logger.debug(f"No role changes needed for control implementation {implementation.id}")
|
|
1135
|
+
|
|
1136
|
+
except Exception as e:
|
|
1137
|
+
logger.error(f"Error updating roles for control implementation {implementation.id}: {e}")
|
|
1138
|
+
# Fallback to old behavior if there's an error
|
|
1139
|
+
_fallback_add_roles_to_control_implementation(implementation, roles)
|
|
1140
|
+
|
|
1141
|
+
|
|
1142
|
+
def _remove_roles_from_control_implementation(
|
|
1143
|
+
implementation: ControlImplementation, roles_to_remove: set, existing_roles: List
|
|
1144
|
+
):
|
|
1145
|
+
"""
|
|
1146
|
+
Removes roles that are no longer needed from a control implementation.
|
|
1147
|
+
:param ControlImplementation implementation: The control implementation to remove roles from.
|
|
1148
|
+
:param set roles_to_remove: Set of role IDs that should be removed.
|
|
1149
|
+
:param List existing_roles: List of existing ImplementationRole objects.
|
|
1150
|
+
"""
|
|
1151
|
+
for role_id in roles_to_remove:
|
|
1152
|
+
try:
|
|
1153
|
+
# Find the ImplementationRole record to delete
|
|
1154
|
+
for existing_role in existing_roles:
|
|
1155
|
+
if existing_role.roleId == role_id:
|
|
1156
|
+
existing_role.delete()
|
|
1157
|
+
logger.debug(f"Removed role {role_id} from control implementation {implementation.id}")
|
|
1158
|
+
break
|
|
1159
|
+
except Exception as e:
|
|
1160
|
+
logger.warning(f"Failed to remove role {role_id} from control implementation {implementation.id}: {e}")
|
|
1161
|
+
|
|
1162
|
+
|
|
1163
|
+
def _fallback_add_roles_to_control_implementation(implementation: ControlImplementation, roles: List[Dict]):
|
|
1164
|
+
"""
|
|
1165
|
+
Fallback method for adding roles to a control implementation when the main method fails.
|
|
1166
|
+
This uses the old behavior of simply adding roles without checking for duplicates.
|
|
1091
1167
|
:param ControlImplementation implementation: The control implementation.
|
|
1092
|
-
:param List[Dict] roles: The list of roles.
|
|
1168
|
+
:param List[Dict] roles: The list of roles to add.
|
|
1093
1169
|
"""
|
|
1094
|
-
if roles and len(roles) > 0
|
|
1170
|
+
if roles and len(roles) > 0:
|
|
1095
1171
|
for role in roles:
|
|
1096
1172
|
if isinstance(role, dict) and role.get("id"):
|
|
1097
|
-
|
|
1173
|
+
try:
|
|
1174
|
+
implementation.add_role(role.get("id"))
|
|
1175
|
+
except Exception as add_error:
|
|
1176
|
+
logger.warning(f"Failed to add role {role.get('id')}: {add_error}")
|
|
1098
1177
|
|
|
1099
1178
|
|
|
1100
1179
|
def get_primary_and_supporting_roles(roles: List, parent_id: int) -> Tuple[List, Dict]:
|
|
@@ -1446,7 +1525,9 @@ def handle_matching_objectives(
|
|
|
1446
1525
|
part_statement = f"{part.get('value', '')}" if not new_statement else new_statement
|
|
1447
1526
|
statements_used.append(part_statement)
|
|
1448
1527
|
|
|
1449
|
-
has_existing_obj = check_for_existing_objective(
|
|
1528
|
+
has_existing_obj = check_for_existing_objective(
|
|
1529
|
+
control_implementation, objective, status, part_statement, origination
|
|
1530
|
+
)
|
|
1450
1531
|
if has_existing_obj:
|
|
1451
1532
|
continue
|
|
1452
1533
|
duplicate = True if part_statement in statements_used else False
|
|
@@ -1467,6 +1548,7 @@ def check_for_existing_objective(
|
|
|
1467
1548
|
objective: ControlObjective,
|
|
1468
1549
|
status: Optional[str],
|
|
1469
1550
|
part_statement: str,
|
|
1551
|
+
origination: Optional[str] = None,
|
|
1470
1552
|
) -> bool:
|
|
1471
1553
|
"""
|
|
1472
1554
|
Check for existing implementation objectives.
|
|
@@ -1474,6 +1556,7 @@ def check_for_existing_objective(
|
|
|
1474
1556
|
:param ControlObjective objective: The control objective object.
|
|
1475
1557
|
:param Optional[str] status: The status of the implementation.
|
|
1476
1558
|
:param str part_statement: The part statement.
|
|
1559
|
+
:param Optional[str] origination: The origination of the implementation.
|
|
1477
1560
|
:return: True if an existing implementation objective is found, False otherwise.
|
|
1478
1561
|
:rtype: bool
|
|
1479
1562
|
"""
|
|
@@ -1495,6 +1578,8 @@ def check_for_existing_objective(
|
|
|
1495
1578
|
status = status.value
|
|
1496
1579
|
existing_obj.status = status_map.get(status, status)
|
|
1497
1580
|
existing_obj.statement = part_statement
|
|
1581
|
+
if origination is not None:
|
|
1582
|
+
existing_obj.responsibility = origination
|
|
1498
1583
|
existing_obj.parentObjectiveId = objective.id
|
|
1499
1584
|
existing_obj.save()
|
|
1500
1585
|
return True
|
|
@@ -1755,7 +1840,7 @@ def update_existing_control(
|
|
|
1755
1840
|
if not control.stepsToImplement and steps_to_implement:
|
|
1756
1841
|
control.stepsToImplement = steps_to_implement
|
|
1757
1842
|
control.implementation = state_text
|
|
1758
|
-
control.responsibility = responsibility
|
|
1843
|
+
control.responsibility = map_responsibility(responsibility)
|
|
1759
1844
|
control.systemRoleId = primary_role.get("id") if primary_role and isinstance(primary_role, dict) else None
|
|
1760
1845
|
# Clean statement
|
|
1761
1846
|
# So, exclusion
|
|
@@ -1764,7 +1849,7 @@ def update_existing_control(
|
|
|
1764
1849
|
|
|
1765
1850
|
# Convert the model to a dict and back to a model to workaround these odd 400 errors.
|
|
1766
1851
|
try:
|
|
1767
|
-
|
|
1852
|
+
control.save()
|
|
1768
1853
|
except Exception as e:
|
|
1769
1854
|
logger.warning(f"Error updating control: {control.id} - {e}")
|
|
1770
1855
|
|
|
@@ -7,6 +7,7 @@ import re
|
|
|
7
7
|
import logging
|
|
8
8
|
import zipfile # Assuming you need this for other file handling
|
|
9
9
|
import pypandoc
|
|
10
|
+
import re
|
|
10
11
|
from collections import defaultdict
|
|
11
12
|
from typing import Dict, TextIO, Optional, Tuple
|
|
12
13
|
from regscale.models import ProfileMapping
|
|
@@ -108,7 +109,12 @@ class MDDocParser:
|
|
|
108
109
|
"""
|
|
109
110
|
# Extract control ID and clean it
|
|
110
111
|
html_free_line = self.clean_html_and_newlines(line)
|
|
111
|
-
|
|
112
|
+
# Use regex to find "what" case-insensitively and split
|
|
113
|
+
pattern = re.compile(r"what", re.IGNORECASE)
|
|
114
|
+
if pattern.search(html_free_line):
|
|
115
|
+
clean_line = pattern.split(html_free_line)[0].strip()
|
|
116
|
+
else:
|
|
117
|
+
clean_line = html_free_line
|
|
112
118
|
if not clean_line:
|
|
113
119
|
return None
|
|
114
120
|
clean_control_id_from_line = clean_line.strip()
|
|
@@ -286,6 +286,8 @@ class IntegrationAsset:
|
|
|
286
286
|
|
|
287
287
|
source_data: Optional[Dict[str, Any]] = None
|
|
288
288
|
url: Optional[str] = None
|
|
289
|
+
software_function: Optional[str] = None
|
|
290
|
+
baseline_configuration: Optional[str] = None
|
|
289
291
|
ports_and_protocols: List[Dict[str, Any]] = dataclasses.field(default_factory=list)
|
|
290
292
|
software_inventory: List[Dict[str, Any]] = dataclasses.field(default_factory=list)
|
|
291
293
|
|
|
@@ -423,6 +425,9 @@ class IntegrationFinding:
|
|
|
423
425
|
planned_milestone_changes: Optional[str] = None
|
|
424
426
|
adjusted_risk_rating: Optional[str] = None
|
|
425
427
|
risk_adjustment: str = "No"
|
|
428
|
+
|
|
429
|
+
# Compliance fields
|
|
430
|
+
assessment_id: Optional[int] = None
|
|
426
431
|
operational_requirements: Optional[str] = None
|
|
427
432
|
deviation_rationale: Optional[str] = None
|
|
428
433
|
is_cwe: bool = False
|
|
@@ -456,7 +461,7 @@ class IntegrationFinding:
|
|
|
456
461
|
source_rule_id: Optional[str] = None
|
|
457
462
|
vulnerability_type: Optional[str] = None
|
|
458
463
|
|
|
459
|
-
#
|
|
464
|
+
# CoalFire POAM
|
|
460
465
|
basis_for_adjustment: Optional[str] = None
|
|
461
466
|
poam_id: Optional[str] = None
|
|
462
467
|
|
|
@@ -569,6 +574,11 @@ class ScannerIntegration(ABC):
|
|
|
569
574
|
|
|
570
575
|
:param int plan_id: The ID of the security plan
|
|
571
576
|
:param int tenant_id: The ID of the tenant, defaults to 1
|
|
577
|
+
|
|
578
|
+
Configuration options available via kwargs:
|
|
579
|
+
- suppress_asset_not_found_errors (bool): When True, suppresses "Asset not found" error messages
|
|
580
|
+
that are commonly logged when assets referenced in findings don't exist in RegScale.
|
|
581
|
+
This can help reduce log noise in environments with many missing assets.
|
|
572
582
|
"""
|
|
573
583
|
|
|
574
584
|
stig_mapper = None
|
|
@@ -624,13 +634,18 @@ class ScannerIntegration(ABC):
|
|
|
624
634
|
close_outdated_findings = True
|
|
625
635
|
closed_count = 0
|
|
626
636
|
|
|
637
|
+
# Error suppression options
|
|
638
|
+
suppress_asset_not_found_errors = False
|
|
639
|
+
|
|
627
640
|
def __init__(self, plan_id: int, tenant_id: int = 1, is_component: bool = False, **kwargs):
|
|
628
641
|
"""
|
|
629
642
|
Initialize the ScannerIntegration.
|
|
630
643
|
|
|
631
644
|
:param int plan_id: The ID of the security plan
|
|
632
645
|
:param int tenant_id: The ID of the tenant, defaults to 1
|
|
646
|
+
:param bool is_component: Whether this is a component integration
|
|
633
647
|
:param kwargs: Additional keyword arguments
|
|
648
|
+
- suppress_asset_not_found_errors (bool): If True, suppress "Asset not found" error messages
|
|
634
649
|
"""
|
|
635
650
|
self.app = Application()
|
|
636
651
|
self.alerted_assets: Set[str] = set()
|
|
@@ -639,6 +654,9 @@ class ScannerIntegration(ABC):
|
|
|
639
654
|
self.plan_id: int = plan_id
|
|
640
655
|
self.tenant_id: int = tenant_id
|
|
641
656
|
self.is_component: bool = is_component
|
|
657
|
+
|
|
658
|
+
# Set configuration options from kwargs
|
|
659
|
+
self.suppress_asset_not_found_errors = kwargs.get("suppress_asset_not_found_errors", False)
|
|
642
660
|
if self.is_component:
|
|
643
661
|
self.component = regscale_models.Component.get_object(self.plan_id)
|
|
644
662
|
self.parent_module: str = regscale_models.Component.get_module_string()
|
|
@@ -1135,6 +1153,8 @@ class ScannerIntegration(ABC):
|
|
|
1135
1153
|
bAuthenticatedScan=asset.is_authenticated_scan,
|
|
1136
1154
|
systemAdministratorId=asset.system_administrator_id,
|
|
1137
1155
|
scanningTool=asset.scanning_tool,
|
|
1156
|
+
softwareFunction=asset.software_function,
|
|
1157
|
+
baselineConfiguration=asset.baseline_configuration,
|
|
1138
1158
|
)
|
|
1139
1159
|
if self.asset_identifier_field:
|
|
1140
1160
|
setattr(new_asset, self.asset_identifier_field, asset.identifier)
|
|
@@ -1612,6 +1632,23 @@ class ScannerIntegration(ABC):
|
|
|
1612
1632
|
issue.securityPlanId = self.plan_id if not self.is_component else None
|
|
1613
1633
|
issue.identification = finding.identification
|
|
1614
1634
|
issue.dateFirstDetected = finding.first_seen
|
|
1635
|
+
# Ensure a due date is always set using configured policy defaults (e.g., FedRAMP)
|
|
1636
|
+
if not finding.due_date:
|
|
1637
|
+
try:
|
|
1638
|
+
base_created = finding.date_created or issue.dateCreated
|
|
1639
|
+
finding.due_date = issue_due_date(
|
|
1640
|
+
severity=finding.severity,
|
|
1641
|
+
created_date=base_created,
|
|
1642
|
+
title=self.title,
|
|
1643
|
+
)
|
|
1644
|
+
except Exception:
|
|
1645
|
+
# Final fallback to a Low severity default if anything goes wrong
|
|
1646
|
+
base_created = finding.date_created or issue.dateCreated
|
|
1647
|
+
finding.due_date = issue_due_date(
|
|
1648
|
+
severity=regscale_models.IssueSeverity.Low,
|
|
1649
|
+
created_date=base_created,
|
|
1650
|
+
title=self.title,
|
|
1651
|
+
)
|
|
1615
1652
|
issue.dueDate = finding.due_date
|
|
1616
1653
|
issue.description = description
|
|
1617
1654
|
issue.sourceReport = finding.source_report or self.title
|
|
@@ -1622,15 +1659,21 @@ class ScannerIntegration(ABC):
|
|
|
1622
1659
|
issue.integrationFindingId = self.get_finding_identifier(finding)
|
|
1623
1660
|
issue.poamComments = finding.poam_comments
|
|
1624
1661
|
issue.cve = finding.cve
|
|
1662
|
+
issue.assessmentId = finding.assessment_id
|
|
1625
1663
|
control_id = self.get_control_implementation_id_for_cci(finding.cci_ref) if finding.cci_ref else None
|
|
1626
1664
|
issue.controlId = control_id # TODO REMOVE
|
|
1627
1665
|
# Add the control implementation ids and the cci ref if it exists
|
|
1628
1666
|
# Get control implementation ID for CCI if it exists
|
|
1629
1667
|
# Only add CCI control ID if it exists
|
|
1630
1668
|
cci_control_ids = [control_id] if control_id is not None else []
|
|
1631
|
-
|
|
1669
|
+
# Ensure failed control labels (e.g., AC-4(21)) are present in affectedControls
|
|
1670
|
+
if finding.affected_controls:
|
|
1671
|
+
issue.affectedControls = finding.affected_controls
|
|
1672
|
+
elif finding.control_labels:
|
|
1673
|
+
issue.affectedControls = ", ".join(sorted({cl for cl in finding.control_labels if cl}))
|
|
1632
1674
|
|
|
1633
1675
|
issue.controlImplementationIds = list(set(finding._control_implementation_ids + cci_control_ids)) # noqa
|
|
1676
|
+
# Always ensure isPoam reflects current settings, even when updating existing issues
|
|
1634
1677
|
issue.isPoam = is_poam
|
|
1635
1678
|
issue.basisForAdjustment = (
|
|
1636
1679
|
finding.basis_for_adjustment if finding.basis_for_adjustment else f"{self.title} import"
|
|
@@ -1647,6 +1690,8 @@ class ScannerIntegration(ABC):
|
|
|
1647
1690
|
issue.operationalRequirement = finding.operational_requirements
|
|
1648
1691
|
issue.deviationRationale = finding.deviation_rationale
|
|
1649
1692
|
issue.dateLastUpdated = get_current_datetime()
|
|
1693
|
+
## set affected controls if they exist
|
|
1694
|
+
issue.affectedControls = finding.affected_controls
|
|
1650
1695
|
|
|
1651
1696
|
if finding.cve:
|
|
1652
1697
|
issue = self.lookup_kev_and_update_issue(cve=finding.cve, issue=issue, cisa_kevs=self._kev_data)
|
|
@@ -2053,7 +2098,8 @@ class ScannerIntegration(ABC):
|
|
|
2053
2098
|
asset = self.asset_map_by_identifier.get(identifier)
|
|
2054
2099
|
if not asset and identifier not in self.alerted_assets:
|
|
2055
2100
|
self.alerted_assets.add(identifier)
|
|
2056
|
-
|
|
2101
|
+
if not getattr(self, "suppress_asset_not_found_errors", False):
|
|
2102
|
+
self.log_error("1. Asset not found for identifier %s", identifier)
|
|
2057
2103
|
return asset
|
|
2058
2104
|
|
|
2059
2105
|
def get_issue_by_integration_finding_id(self, integration_finding_id: str) -> Optional[regscale_models.Issue]:
|
|
@@ -2078,7 +2124,8 @@ class ScannerIntegration(ABC):
|
|
|
2078
2124
|
"""
|
|
2079
2125
|
logger.debug("Processing checklist %s", finding.external_id)
|
|
2080
2126
|
if not (asset := self.get_asset_by_identifier(finding.asset_identifier)):
|
|
2081
|
-
|
|
2127
|
+
if not getattr(self, "suppress_asset_not_found_errors", False):
|
|
2128
|
+
logger.error("2. Asset not found for identifier %s", finding.asset_identifier)
|
|
2082
2129
|
return 0
|
|
2083
2130
|
|
|
2084
2131
|
tool = regscale_models.ChecklistTool.STIGs
|
|
@@ -2305,7 +2352,8 @@ class ScannerIntegration(ABC):
|
|
|
2305
2352
|
# Process checklist if applicable
|
|
2306
2353
|
if self.type == ScannerIntegrationType.CHECKLIST:
|
|
2307
2354
|
if not (asset := self.get_asset_by_identifier(finding.asset_identifier)):
|
|
2308
|
-
|
|
2355
|
+
if not getattr(self, "suppress_asset_not_found_errors", False):
|
|
2356
|
+
logger.error("2. Asset not found for identifier %s", finding.asset_identifier)
|
|
2309
2357
|
return
|
|
2310
2358
|
|
|
2311
2359
|
tool = regscale_models.ChecklistTool.STIGs
|
|
@@ -2443,7 +2491,10 @@ class ScannerIntegration(ABC):
|
|
|
2443
2491
|
return None
|
|
2444
2492
|
|
|
2445
2493
|
if not asset:
|
|
2446
|
-
|
|
2494
|
+
if not getattr(self, "suppress_asset_not_found_errors", False):
|
|
2495
|
+
logger.warning(
|
|
2496
|
+
"VulnerabilityMapping Error: Asset not found for identifier %s", finding.asset_identifier
|
|
2497
|
+
)
|
|
2447
2498
|
return None
|
|
2448
2499
|
|
|
2449
2500
|
vulnerability = self.create_vulnerability_from_finding(finding, asset, scan_history)
|
regscale/models/__init__.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env python3
|
|
2
2
|
# -*- coding: utf-8 -*-
|
|
3
3
|
"""standard python imports"""
|
|
4
|
-
from regscale.models.app_models.click import regscale_id, regscale_module, regscale_ssp_id
|
|
4
|
+
from regscale.models.app_models.click import regscale_id, regscale_module, regscale_ssp_id, ssp_or_component_id
|
|
5
5
|
from .app_models import *
|
|
6
6
|
from .integration_models import *
|
|
7
7
|
from .regscale_models import *
|
|
@@ -1,9 +1,108 @@
|
|
|
1
1
|
{
|
|
2
2
|
"title": "CISA Catalog of Known Exploited Vulnerabilities",
|
|
3
|
-
"catalogVersion": "2025.08.
|
|
4
|
-
"dateReleased": "2025-08-
|
|
5
|
-
"count":
|
|
3
|
+
"catalogVersion": "2025.08.21",
|
|
4
|
+
"dateReleased": "2025-08-21T17:02:19.8046Z",
|
|
5
|
+
"count": 1401,
|
|
6
6
|
"vulnerabilities": [
|
|
7
|
+
{
|
|
8
|
+
"cveID": "CVE-2025-43300",
|
|
9
|
+
"vendorProject": "Apple",
|
|
10
|
+
"product": "iOS, iPadOS, and macOS",
|
|
11
|
+
"vulnerabilityName": "Apple iOS, iPadOS, and macOS Out-of-Bounds Write Vulnerability",
|
|
12
|
+
"dateAdded": "2025-08-21",
|
|
13
|
+
"shortDescription": "Apple iOS, iPadOS, and macOS contain an out-of-bounds write vulnerability in the Image I\/O framework.",
|
|
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-09-11",
|
|
16
|
+
"knownRansomwareCampaignUse": "Unknown",
|
|
17
|
+
"notes": "https:\/\/support.apple.com\/en-us\/124925 ; https:\/\/support.apple.com\/en-us\/124926 ; https:\/\/support.apple.com\/en-us\/124927 ; https:\/\/support.apple.com\/en-us\/124928 ; https:\/\/support.apple.com\/en-us\/124929 ; https:\/\/nvd.nist.gov\/vuln\/detail\/CVE-2025-43300",
|
|
18
|
+
"cwes": [
|
|
19
|
+
"CWE-787"
|
|
20
|
+
]
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
"cveID": "CVE-2025-54948",
|
|
24
|
+
"vendorProject": "Trend Micro",
|
|
25
|
+
"product": "Apex One",
|
|
26
|
+
"vulnerabilityName": "Trend Micro Apex One OS Command Injection Vulnerability",
|
|
27
|
+
"dateAdded": "2025-08-18",
|
|
28
|
+
"shortDescription": "Trend Micro Apex One Management Console (on-premise) contains an OS command injection vulnerability that could allow a pre-authenticated remote attacker to upload malicious code and execute commands on affected installations.",
|
|
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-09-08",
|
|
31
|
+
"knownRansomwareCampaignUse": "Unknown",
|
|
32
|
+
"notes": "https:\/\/success.trendmicro.com\/en-US\/solution\/KA-0020652 ; N\/A ; https:\/\/nvd.nist.gov\/vuln\/detail\/CVE-2025-54948",
|
|
33
|
+
"cwes": [
|
|
34
|
+
"CWE-78"
|
|
35
|
+
]
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
"cveID": "CVE-2025-8876",
|
|
39
|
+
"vendorProject": "N-able",
|
|
40
|
+
"product": "N-Central",
|
|
41
|
+
"vulnerabilityName": "N-able N-Central Command Injection Vulnerability",
|
|
42
|
+
"dateAdded": "2025-08-13",
|
|
43
|
+
"shortDescription": "N-able N-Central contains a command injection vulnerability via improper sanitization of user input.",
|
|
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-08-20",
|
|
46
|
+
"knownRansomwareCampaignUse": "Unknown",
|
|
47
|
+
"notes": "https:\/\/status.n-able.com\/2025\/08\/13\/announcing-the-ga-of-n-central-2025-3-1\/ ; https:\/\/nvd.nist.gov\/vuln\/detail\/CVE-2025-8876",
|
|
48
|
+
"cwes": []
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
"cveID": "CVE-2025-8875",
|
|
52
|
+
"vendorProject": "N-able",
|
|
53
|
+
"product": "N-Central",
|
|
54
|
+
"vulnerabilityName": "N-able N-Central Insecure Deserialization Vulnerability",
|
|
55
|
+
"dateAdded": "2025-08-13",
|
|
56
|
+
"shortDescription": "N-able N-Central contains an insecure deserialization vulnerability that could lead to command execution.",
|
|
57
|
+
"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.",
|
|
58
|
+
"dueDate": "2025-08-20",
|
|
59
|
+
"knownRansomwareCampaignUse": "Unknown",
|
|
60
|
+
"notes": "https:\/\/status.n-able.com\/2025\/08\/13\/announcing-the-ga-of-n-central-2025-3-1\/ ; https:\/\/nvd.nist.gov\/vuln\/detail\/CVE-2025-8875",
|
|
61
|
+
"cwes": []
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
"cveID": "CVE-2025-8088",
|
|
65
|
+
"vendorProject": "RARLAB",
|
|
66
|
+
"product": "WinRAR",
|
|
67
|
+
"vulnerabilityName": "RARLAB WinRAR Path Traversal Vulnerability",
|
|
68
|
+
"dateAdded": "2025-08-12",
|
|
69
|
+
"shortDescription": "RARLAB WinRAR contains a path traversal vulnerability affecting the Windows version of WinRAR. This vulnerability could allow an attacker to execute arbitrary code by crafting malicious archive files.",
|
|
70
|
+
"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.",
|
|
71
|
+
"dueDate": "2025-09-02",
|
|
72
|
+
"knownRansomwareCampaignUse": "Unknown",
|
|
73
|
+
"notes": "https:\/\/www.win-rar.com\/singlenewsview.html?&L=0&tx_ttnews%5Btt_news%5D=283&cHash=a64b4a8f662d3639dec8d65f47bc93c5 ; https:\/\/nvd.nist.gov\/vuln\/detail\/CVE-2025-8088",
|
|
74
|
+
"cwes": [
|
|
75
|
+
"CWE-35"
|
|
76
|
+
]
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
"cveID": "CVE-2007-0671",
|
|
80
|
+
"vendorProject": "Microsoft",
|
|
81
|
+
"product": "Office",
|
|
82
|
+
"vulnerabilityName": "Microsoft Office Excel Remote Code Execution Vulnerability",
|
|
83
|
+
"dateAdded": "2025-08-12",
|
|
84
|
+
"shortDescription": "Microsoft Office Excel contains a remote code execution vulnerability that can be exploited when a specially crafted Excel file is opened. This malicious file could be delivered as an email attachment or hosted on a malicious website. An attacker could leverage this vulnerability by creating a specially crafted Excel file, which, when opened, allowing an attacker to execute remote code on the affected system.",
|
|
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-09-02",
|
|
87
|
+
"knownRansomwareCampaignUse": "Unknown",
|
|
88
|
+
"notes": "https:\/\/learn.microsoft.com\/en-us\/security-updates\/securitybulletins\/2007\/ms07-015 ; https:\/\/nvd.nist.gov\/vuln\/detail\/CVE-2007-0671",
|
|
89
|
+
"cwes": []
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
"cveID": "CVE-2013-3893",
|
|
93
|
+
"vendorProject": "Microsoft",
|
|
94
|
+
"product": "Internet Explorer",
|
|
95
|
+
"vulnerabilityName": "Microsoft Internet Explorer Resource Management Errors Vulnerability",
|
|
96
|
+
"dateAdded": "2025-08-12",
|
|
97
|
+
"shortDescription": "Microsoft Internet Explorer contains a memory corruption vulnerability that allows for remote code execution. The impacted products could be end-of-life (EoL) and\/or end-of-service (EoS). Users should discontinue product utilization.",
|
|
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-09-02",
|
|
100
|
+
"knownRansomwareCampaignUse": "Unknown",
|
|
101
|
+
"notes": "https:\/\/learn.microsoft.com\/en-us\/security-updates\/securitybulletins\/2013\/ms13-080 ; https:\/\/nvd.nist.gov\/vuln\/detail\/CVE-2013-3893",
|
|
102
|
+
"cwes": [
|
|
103
|
+
"CWE-399"
|
|
104
|
+
]
|
|
105
|
+
},
|
|
7
106
|
{
|
|
8
107
|
"cveID": "CVE-2020-25078",
|
|
9
108
|
"vendorProject": "D-Link",
|
|
@@ -236,7 +335,7 @@
|
|
|
236
335
|
"shortDescription": "Citrix NetScaler ADC and Gateway contain an out-of-bounds read vulnerability due to insufficient input validation. This vulnerability can lead to memory overread when the NetScaler is configured as a Gateway (VPN virtual server, ICA Proxy, CVPN, RDP Proxy) OR AAA virtual server.",
|
|
237
336
|
"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.",
|
|
238
337
|
"dueDate": "2025-07-11",
|
|
239
|
-
"knownRansomwareCampaignUse": "
|
|
338
|
+
"knownRansomwareCampaignUse": "Known",
|
|
240
339
|
"notes": "https:\/\/support.citrix.com\/support-home\/kbsearch\/article?articleNumber=CTX693420 ; https:\/\/nvd.nist.gov\/vuln\/detail\/CVE-2025-5777",
|
|
241
340
|
"cwes": [
|
|
242
341
|
"CWE-125"
|