regscale-cli 6.25.0.0__py3-none-any.whl → 6.25.1.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 CHANGED
@@ -33,7 +33,7 @@ def get_version_from_pyproject() -> str:
33
33
  return match.group(1)
34
34
  except Exception:
35
35
  pass
36
- return "6.25.0.0" # fallback version
36
+ return "6.25.1.0" # fallback version
37
37
 
38
38
 
39
39
  __version__ = get_version_from_pyproject()
@@ -248,9 +248,9 @@ def sync_regscale_and_jira(
248
248
  jql_str = jql
249
249
  else:
250
250
  jql_str = (
251
- f"project = {jira_project} AND issueType = {jira_issue_type}"
251
+ f"project = '{jira_project}' AND issueType = '{jira_issue_type}'"
252
252
  if sync_tasks_only
253
- else f"project = {jira_project}"
253
+ else f"project = '{jira_project}'"
254
254
  )
255
255
  regscale_objects, regscale_attachments = get_regscale_data_and_attachments(
256
256
  parent_id=parent_id,
@@ -753,7 +753,7 @@ def sync_regscale_to_jira(
753
753
  """
754
754
  Sync issues or tasks from RegScale to Jira
755
755
 
756
- :param list[Union[Issue, Task]] regscale_issues: list of RegScale issues or tasks to sync to Jira
756
+ :param list[Union[Issue, Task]] regscale_objects: list of RegScale issues or tasks to sync to Jira
757
757
  :param JIRA jira_client: Jira client to use for issue creation in Jira
758
758
  :param str jira_project: Jira Project to create the issues in
759
759
  :param str jira_issue_type: Type of issue to create in Jira
@@ -829,7 +829,7 @@ def fetch_jira_objects(
829
829
  max_results = 100 # 100 is the max allowed by Jira
830
830
  jira_issues = []
831
831
  issue_response = jira_client.enhanced_search_issues(
832
- jql_str=jql_str or f"project = {jira_project}",
832
+ jql_str=jql_str or f"project = '{jira_project}'",
833
833
  maxResults=max_results,
834
834
  )
835
835
  jira_issues.extend(issue_response)
@@ -97,6 +97,23 @@ def sync_crowdstrike(regscale_ssp_id: int, filter: str, url: str) -> None:
97
97
  assets_crowdstrike.run_sync(regscale_ssp_id=regscale_ssp_id, filter=filter.split(";") if filter else [], url=url)
98
98
 
99
99
 
100
+ @assets.command(name="sync_ivanti_neurons")
101
+ @regscale_ssp_id()
102
+ @click.option(
103
+ "--filter",
104
+ help='STRING: Apply filters to the query. Can be a single filter "field[operator]value" or semicolon-separated filters "field1[op]value1;field2[op]value2"',
105
+ required=False,
106
+ type=str,
107
+ default=None,
108
+ )
109
+ def sync_ivanti_neurons(regscale_ssp_id: int, filter: str) -> None:
110
+ """Sync Assets from Ivanti Neurons to RegScale."""
111
+ from regscale.models.integration_models.synqly_models.connectors import Assets
112
+
113
+ assets_ivanti_neurons = Assets("ivanti_neurons")
114
+ assets_ivanti_neurons.run_sync(regscale_ssp_id=regscale_ssp_id, filter=filter.split(";") if filter else [])
115
+
116
+
100
117
  @assets.command(name="sync_nozomi_vantage")
101
118
  @regscale_ssp_id()
102
119
  @click.option(
@@ -1171,85 +1171,24 @@ fragment SecuritySubCategoryDetails on SecuritySubCategory {
1171
1171
  }
1172
1172
  """
1173
1173
  DATA_FINDING_QUERY = """
1174
- query DataFindingsGroupedByValueTable($groupBy: DataFindingsGroupedByValueField!, $after: String, $first: Int, $filterBy: DataFindingFilters, $orderBy: DataFindingsGroupedByValueOrder) {
1175
- dataFindingsGroupedByValue(
1176
- groupBy: $groupBy
1174
+ query DataFindingsTable($after: String, $first: Int, $filterBy: DataFindingFiltersV2, $orderBy: DataFindingOrder, $fetchTotalCount: Boolean = true) {
1175
+ dataFindingsV2(
1177
1176
  filterBy: $filterBy
1178
1177
  first: $first
1179
1178
  after: $after
1180
1179
  orderBy: $orderBy
1181
1180
  ) {
1182
1181
  nodes {
1183
- categories
1184
- location {
1185
- countryCode
1186
- state
1187
- }
1188
- regionCount
1189
- graphEntityCount
1190
- graphEntity {
1191
- id
1192
- name
1193
- type
1194
- properties
1195
- projects {
1196
- id
1197
- name
1198
- slug
1199
- isFolder
1200
- }
1201
- issues(filterBy: {status: [OPEN, IN_PROGRESS]}) {
1202
- criticalSeverityCount
1203
- highSeverityCount
1204
- mediumSeverityCount
1205
- lowSeverityCount
1206
- informationalSeverityCount
1207
- }
1208
- }
1209
- cloudAccount {
1210
- id
1211
- name
1212
- externalId
1213
- cloudProvider
1214
- }
1215
- dataClassifiers {
1216
- id
1217
- name
1218
- category
1219
- matcherType
1220
- severity
1221
- }
1222
- securitySubCategories {
1223
- id
1224
- title
1225
- externalId
1226
- description
1227
- category {
1228
- id
1229
- name
1230
- description
1231
- framework {
1232
- id
1233
- name
1234
- description
1235
- enabled
1236
- }
1237
- }
1238
- }
1239
- findingsCount
1240
- dataFindings(first: 5) {
1241
- nodes {
1242
- ...DataFindingDetails
1243
- }
1244
- }
1182
+ ...DataFindingDetails
1245
1183
  }
1246
1184
  pageInfo {
1247
1185
  hasNextPage
1248
1186
  endCursor
1249
1187
  }
1250
- totalCount
1188
+ totalCount @include(if: $fetchTotalCount)
1251
1189
  }
1252
1190
  }
1191
+
1253
1192
  fragment DataFindingDetails on DataFinding {
1254
1193
  id
1255
1194
  name
@@ -1257,10 +1196,10 @@ fragment DataFindingDetails on DataFinding {
1257
1196
  id
1258
1197
  name
1259
1198
  category
1199
+ isTenantSpecific
1260
1200
  securitySubCategories {
1261
1201
  id
1262
1202
  title
1263
- externalId
1264
1203
  description
1265
1204
  category {
1266
1205
  id
@@ -1286,8 +1225,12 @@ fragment DataFindingDetails on DataFinding {
1286
1225
  state
1287
1226
  }
1288
1227
  severity
1228
+ status
1289
1229
  totalMatchCount
1290
1230
  uniqueMatchCount
1231
+ maxUniqueMatchesReached
1232
+ uniqueLocationsCount
1233
+ isEntityPublic
1291
1234
  graphEntity {
1292
1235
  id
1293
1236
  name
@@ -1301,6 +1244,12 @@ fragment DataFindingDetails on DataFinding {
1301
1244
  }
1302
1245
  }
1303
1246
  externalSource
1247
+ details {
1248
+ applicationServices {
1249
+ id
1250
+ displayName
1251
+ }
1252
+ }
1304
1253
  }
1305
1254
  """
1306
1255
 
@@ -1387,14 +1336,14 @@ def get_wiz_vulnerability_queries(project_id: str, filter_by: Optional[dict] = N
1387
1336
  {
1388
1337
  "type": WizVulnerabilityType.DATA_FINDING,
1389
1338
  "query": DATA_FINDING_QUERY,
1390
- "topic_key": "dataFindingsGroupedByValue",
1339
+ "topic_key": "dataFindingsV2",
1391
1340
  "file_path": DATA_FINDINGS_FILE_PATH,
1392
- "asset_lookup": "resource",
1341
+ "asset_lookup": "graphEntity",
1393
1342
  "variables": {
1394
1343
  "first": 200,
1344
+ "fetchTotalCount": True,
1395
1345
  "filterBy": {"projectId": [project_id]},
1396
- "orderBy": {"field": "FINDING_COUNT", "direction": "DESC"},
1397
- "groupBy": "GRAPH_ENTITY",
1346
+ "orderBy": {"field": "TOTAL_MATCHES", "direction": "DESC"},
1398
1347
  },
1399
1348
  },
1400
1349
  {
@@ -7,13 +7,16 @@ from datetime import datetime
7
7
  from typing import Any, Dict, Optional
8
8
 
9
9
  from regscale.core.app.application import Application
10
- from regscale.core.utils.date import date_str, get_day_increment
10
+ from regscale.core.utils.date import get_day_increment
11
11
  from regscale.integrations.public.cisa import pull_cisa_kev
12
12
  from regscale.models import regscale_models
13
13
  from regscale.utils.threading import ThreadSafeDict
14
14
 
15
15
  logger = logging.getLogger("regscale")
16
16
 
17
+ # Date format constant for consistent datetime string formatting
18
+ DATETIME_FORMAT = "%Y-%m-%dT%H:%M:%S"
19
+
17
20
 
18
21
  class DueDateHandler:
19
22
  """
@@ -21,6 +24,19 @@ class DueDateHandler:
21
24
  1. Init.yaml timeline configurations per integration
22
25
  2. KEV (Known Exploited Vulnerabilities) dates from CISA
23
26
  3. Default severity-based timelines
27
+ 4. Configurable past due date validation (noPastDueDates setting)
28
+
29
+ Configuration Options:
30
+ - Global setting: issues.noPastDueDates (default: true)
31
+ - Per-integration: issues.{integration_name}.noPastDueDates
32
+
33
+ When noPastDueDates=true (default):
34
+ - Due dates calculated in the past are automatically adjusted to future dates
35
+ - Prevents API validation errors for past due dates
36
+
37
+ When noPastDueDates=false:
38
+ - Original due dates are preserved, even if they're in the past
39
+ - Useful for historical data or when past dates are intentionally required
24
40
  """
25
41
 
26
42
  def __init__(self, integration_name: str, config: Optional[Dict[str, Any]] = None):
@@ -45,6 +61,9 @@ class DueDateHandler:
45
61
  # Load integration-specific timelines from config
46
62
  self.integration_timelines = self._load_integration_timelines()
47
63
 
64
+ # Load noPastDueDates setting (defaults to True)
65
+ self.no_past_due_dates = self._load_no_past_due_dates_setting()
66
+
48
67
  def _load_integration_timelines(self) -> Dict[regscale_models.IssueSeverity, int]:
49
68
  """
50
69
  Load timeline configurations for this integration from init.yaml
@@ -75,6 +94,37 @@ class DueDateHandler:
75
94
 
76
95
  return timelines
77
96
 
97
+ def _load_no_past_due_dates_setting(self) -> bool:
98
+ """
99
+ Load noPastDueDates setting for this integration from init.yaml
100
+
101
+ Configuration hierarchy:
102
+ 1. Integration-specific setting: issues.{integration_name}.noPastDueDates
103
+ 2. Global setting: issues.noPastDueDates
104
+ 3. Default: True
105
+
106
+ :return: True if past due dates should be automatically adjusted to future dates
107
+ :rtype: bool
108
+ """
109
+ issues_config = self.config.get("issues", {})
110
+ integration_config = issues_config.get(self.integration_name, {})
111
+
112
+ # Check integration-specific setting first
113
+ if "noPastDueDates" in integration_config:
114
+ setting = integration_config["noPastDueDates"]
115
+ logger.debug(f"Using integration-specific noPastDueDates={setting} for {self.integration_name}")
116
+ return bool(setting)
117
+
118
+ # Fall back to global setting
119
+ if "noPastDueDates" in issues_config:
120
+ setting = issues_config["noPastDueDates"]
121
+ logger.debug(f"Using global noPastDueDates={setting} for {self.integration_name}")
122
+ return bool(setting)
123
+
124
+ # Default to True (prevent past due dates)
125
+ logger.debug(f"Using default noPastDueDates=True for {self.integration_name}")
126
+ return True
127
+
78
128
  def _get_kev_data(self) -> ThreadSafeDict:
79
129
  """
80
130
  Get KEV data from CISA, using cache if available
@@ -160,17 +210,26 @@ class DueDateHandler:
160
210
  kev_date = date_parse(kev_due_date).date()
161
211
  created_dt = date_parse(created_date).date()
162
212
 
163
- # If KEV due date is after creation date, use KEV date
213
+ # If KEV due date is after creation date, use KEV date but ensure it's not in the past
164
214
  # If KEV due date is before creation date, add the difference to creation date
165
215
  if kev_date >= created_dt:
166
- logger.debug(f"Using KEV due date {kev_due_date} for CVE {cve}")
167
- return kev_due_date
216
+ # Ensure KEV due date is not in the past
217
+ kev_due_validated = self._ensure_future_due_date(
218
+ kev_due_date, 30
219
+ ) # Use 30 days as fallback for KEV
220
+ logger.debug(f"Using KEV due date {kev_due_validated} for CVE {cve}")
221
+ return kev_due_validated
168
222
  else:
169
223
  # KEV date has passed, calculate new due date from creation
170
224
  days_diff = (created_dt - kev_date).days
171
225
  # Give at least 30 days from creation for critical KEV items
172
226
  adjusted_days = max(30, days_diff)
173
- due_date = date_str(get_day_increment(start=created_date, days=adjusted_days))
227
+ calculated_due_date_obj = get_day_increment(start=created_date, days=adjusted_days)
228
+ calculated_due_date = datetime.combine(calculated_due_date_obj, datetime.min.time()).strftime(
229
+ DATETIME_FORMAT
230
+ )
231
+ # Ensure the adjusted due date is not in the past
232
+ due_date = self._ensure_future_due_date(calculated_due_date, adjusted_days)
174
233
  logger.debug(f"KEV date passed, using adjusted due date {due_date} for CVE {cve}")
175
234
  return due_date
176
235
 
@@ -179,12 +238,64 @@ class DueDateHandler:
179
238
 
180
239
  # Fall back to severity-based timeline from integration config
181
240
  days = self.integration_timelines.get(severity, self.default_timelines[severity])
182
- due_date = date_str(get_day_increment(start=created_date, days=days))
241
+ calculated_due_date_obj = get_day_increment(start=created_date, days=days)
242
+ calculated_due_date = datetime.combine(calculated_due_date_obj, datetime.min.time()).strftime(DATETIME_FORMAT)
243
+
244
+ # Ensure due date is never in the past (allow yesterday for timezone differences)
245
+ due_date = self._ensure_future_due_date(calculated_due_date, days)
183
246
 
184
247
  logger.debug(f"Using {self.integration_name} timeline: {severity.name} = {days} days, due date = {due_date}")
185
248
 
186
249
  return due_date
187
250
 
251
+ def _ensure_future_due_date(self, calculated_due_date: str, original_days: int) -> str:
252
+ """
253
+ Ensure the due date is not in the past. If it is, set it to today + original timeline days.
254
+ Behavior is controlled by the noPastDueDates configuration setting.
255
+
256
+ :param str calculated_due_date: The originally calculated due date
257
+ :param int original_days: The original number of days for this severity
258
+ :return: A due date that respects the noPastDueDates setting
259
+ :rtype: str
260
+ """
261
+ # If noPastDueDates is disabled, return the original date without validation
262
+ if not self.no_past_due_dates:
263
+ logger.debug(
264
+ f"noPastDueDates=False for {self.integration_name}, returning original due date: {calculated_due_date}"
265
+ )
266
+ return calculated_due_date
267
+
268
+ from dateutil.parser import parse as date_parse
269
+ from datetime import date
270
+
271
+ try:
272
+ calculated_date = date_parse(calculated_due_date).date()
273
+ today = date.today()
274
+
275
+ if calculated_date >= today:
276
+ return calculated_due_date
277
+ else:
278
+ # Due date is in the past, calculate new due date from today
279
+ # Use minimum 1 day to ensure it's always in the future
280
+ safe_days = max(1, original_days)
281
+ new_due_date_obj = get_day_increment(start=today, days=safe_days)
282
+ new_due_date = datetime.combine(new_due_date_obj, datetime.min.time()).strftime(DATETIME_FORMAT)
283
+ logger.debug(
284
+ f"Due date {calculated_due_date} was in the past for {self.integration_name}. "
285
+ f"Adjusted to {new_due_date} ({safe_days} days from today)."
286
+ )
287
+ return new_due_date
288
+
289
+ except Exception as e:
290
+ logger.warning(f"Failed to validate due date {calculated_due_date}: {e}")
291
+ # If we can't parse the date, return a safe fallback only if noPastDueDates is enabled
292
+ if self.no_past_due_dates:
293
+ safe_days = max(1, original_days)
294
+ fallback_due_date_obj = get_day_increment(start=date.today(), days=safe_days)
295
+ return datetime.combine(fallback_due_date_obj, datetime.min.time()).strftime(DATETIME_FORMAT)
296
+ else:
297
+ return calculated_due_date
298
+
188
299
  def get_integration_config(self) -> Dict[str, Any]:
189
300
  """
190
301
  Get the full integration configuration from init.yaml
@@ -205,6 +316,7 @@ class DueDateHandler:
205
316
  return {
206
317
  "integration_name": self.integration_name,
207
318
  "use_kev": self._should_use_kev(),
319
+ "no_past_due_dates": self.no_past_due_dates,
208
320
  "timelines": {severity.name: days for severity, days in self.integration_timelines.items()},
209
321
  "config_source": "init.yaml",
210
322
  }
@@ -48,6 +48,31 @@ def get_thread_workers_max() -> int:
48
48
  return ScannerVariables.threadMaxWorkers
49
49
 
50
50
 
51
+ def _create_config_override(
52
+ config: Optional[Dict[str, Dict]],
53
+ integration_name: str,
54
+ critical: Optional[int],
55
+ high: Optional[int],
56
+ moderate: Optional[int],
57
+ low: Optional[int],
58
+ ) -> Dict[str, Dict]:
59
+ """Create a config override for legacy parameter support."""
60
+ override_config = config.copy() if config else {}
61
+ if "issues" not in override_config:
62
+ override_config["issues"] = {}
63
+ if integration_name not in override_config["issues"]:
64
+ override_config["issues"][integration_name] = {}
65
+
66
+ integration_config = override_config["issues"][integration_name]
67
+ severity_params = {"critical": critical, "high": high, "moderate": moderate, "low": low}
68
+
69
+ for param_name, param_value in severity_params.items():
70
+ if param_value is not None:
71
+ integration_config[param_name] = param_value
72
+
73
+ return override_config
74
+
75
+
51
76
  def issue_due_date(
52
77
  severity: regscale_models.IssueSeverity,
53
78
  created_date: str,
@@ -61,6 +86,9 @@ def issue_due_date(
61
86
  """
62
87
  Calculate the due date for an issue based on its severity and creation date.
63
88
 
89
+ DEPRECATED: This function is kept for backward compatibility. New code should use DueDateHandler directly.
90
+ This function now uses DueDateHandler internally to ensure consistent behavior and proper validation.
91
+
64
92
  :param regscale_models.IssueSeverity severity: The severity of the issue.
65
93
  :param str created_date: The creation date of the issue.
66
94
  :param Optional[int] critical: Days until due for high severity issues.
@@ -72,40 +100,19 @@ def issue_due_date(
72
100
  :return: The due date for the issue.
73
101
  :rtype: str
74
102
  """
75
- if critical is None:
76
- critical = ScannerVariables.issueDueDates.get("critical", 30)
77
- if high is None:
78
- high = ScannerVariables.issueDueDates.get("high", 60)
79
- if moderate is None:
80
- moderate = ScannerVariables.issueDueDates.get("moderate", 120)
81
- if low is None:
82
- low = ScannerVariables.issueDueDates.get("low", 364)
83
-
84
- if config is None:
85
- config = {}
86
-
87
- due_date_map = {
88
- regscale_models.IssueSeverity.Critical: critical,
89
- regscale_models.IssueSeverity.High: high,
90
- regscale_models.IssueSeverity.Moderate: moderate,
91
- regscale_models.IssueSeverity.Low: low,
92
- }
93
-
94
- if title and config:
95
- # if title in a config key, use that key
96
- issues_dict = config.get("issues", {})
97
- matching_key = next((key.lower() for key in issues_dict if title.lower() in key.lower()), None)
98
- if matching_key:
99
- title_config = issues_dict.get(matching_key, {})
100
- due_date_map = {
101
- regscale_models.IssueSeverity.Critical: title_config.get("critical", critical),
102
- regscale_models.IssueSeverity.High: title_config.get("high", high),
103
- regscale_models.IssueSeverity.Moderate: title_config.get("moderate", moderate),
104
- regscale_models.IssueSeverity.Low: title_config.get("low", low),
105
- }
106
-
107
- days = due_date_map.get(severity, low)
108
- return date_str(get_day_increment(start=created_date, days=days))
103
+ integration_name = title or "default"
104
+
105
+ # Check if individual parameters need config override
106
+ if any(param is not None for param in [critical, high, moderate, low]):
107
+ config = _create_config_override(config, integration_name, critical, high, moderate, low)
108
+
109
+ due_date_handler = DueDateHandler(integration_name, config=config)
110
+ return due_date_handler.calculate_due_date(
111
+ severity=severity,
112
+ created_date=created_date,
113
+ cve=None, # Legacy function doesn't have CVE parameter
114
+ title=title,
115
+ )
109
116
 
110
117
 
111
118
  class ManagedDefaultDict(Generic[K, V]):
@@ -2106,7 +2113,9 @@ class ScannerIntegration(ABC):
2106
2113
 
2107
2114
  def _set_issue_due_date(self, issue: regscale_models.Issue, finding: IntegrationFinding) -> None:
2108
2115
  """Set the due date for the issue using DueDateHandler."""
2116
+ # Always calculate or validate due date to ensure it's not in the past
2109
2117
  if not finding.due_date:
2118
+ # No due date set, calculate new one
2110
2119
  try:
2111
2120
  base_created = finding.date_created or issue.dateCreated
2112
2121
  finding.due_date = self.due_date_handler.calculate_due_date(
@@ -2125,6 +2134,12 @@ class ScannerIntegration(ABC):
2125
2134
  cve=finding.cve,
2126
2135
  title=finding.title or self.title,
2127
2136
  )
2137
+ else:
2138
+ # Due date already exists, but validate it's not in the past (if noPastDueDates is enabled)
2139
+ finding.due_date = self.due_date_handler._ensure_future_due_date(
2140
+ finding.due_date, self.due_date_handler.integration_timelines.get(finding.severity, 60)
2141
+ )
2142
+
2128
2143
  issue.dueDate = finding.due_date
2129
2144
 
2130
2145
  def _set_additional_issue_fields(
@@ -1,9 +1,54 @@
1
1
  {
2
2
  "title": "CISA Catalog of Known Exploited Vulnerabilities",
3
- "catalogVersion": "2025.09.11",
4
- "dateReleased": "2025-09-11T17:00:46.0046Z",
5
- "count": 1414,
3
+ "catalogVersion": "2025.09.25",
4
+ "dateReleased": "2025-09-25T16:17:38.0447Z",
5
+ "count": 1417,
6
6
  "vulnerabilities": [
7
+ {
8
+ "cveID": "CVE-2025-20362",
9
+ "vendorProject": "Cisco",
10
+ "product": "Secure Firewall Adaptive Security Appliance and Secure Firewall Threat Defense",
11
+ "vulnerabilityName": "Cisco Secure Firewall Adaptive Security (ASA) Appliance and Secure Firewall Threat Defense (FTD) Missing Authorization Vulnerability",
12
+ "dateAdded": "2025-09-25",
13
+ "shortDescription": "Cisco Secure Firewall Adaptive Security (ASA) Appliance and Secure Firewall Threat Defense (FTD) Software VPN Web Server contain a missing authorization vulnerability. This vulnerability could be chained with CVE-2025-20333.",
14
+ "requiredAction": "The KEV due date refers to the deadline by which FCEB agencies are expected to review and begin implementing the guidance outlined in Emergency Directive (ED) 25-03 (URL listed below in Notes). Agencies must follow the mitigation steps provided by CISA (URL listed below in Notes) and vendor\u2019s instructions (URL listed below in Notes). Adhere to the applicable BOD 22-01 guidance for cloud services or discontinue use of the product if mitigations are not available.",
15
+ "dueDate": "2025-09-26",
16
+ "knownRansomwareCampaignUse": "Unknown",
17
+ "notes": "CISA Mitigation Instructions: https:\/\/www.cisa.gov\/news-events\/directives\/ed-25-03-identify-and-mitigate-potential-compromise-cisco-devices ; https:\/\/www.cisa.gov\/news-events\/directives\/supplemental-direction-ed-25-03-core-dump-and-hunt-instructions ; https:\/\/www.cisa.gov\/eviction-strategies-tool\/create-from-template ; https:\/\/sec.cloudapps.cisco.com\/security\/center\/resources\/asa_ftd_continued_attacks ; https:\/\/sec.cloudapps.cisco.com\/security\/center\/private\/resources\/asa_ftd_continued_attacks#Details ; https:\/\/sec.cloudapps.cisco.com\/security\/center\/content\/CiscoSecurityAdvisory\/cisco-sa-asaftd-webvpn-YROOTUW ; https:\/\/nvd.nist.gov\/vuln\/detail\/CVE-2025-20362",
18
+ "cwes": [
19
+ "CWE-862"
20
+ ]
21
+ },
22
+ {
23
+ "cveID": "CVE-2025-20333",
24
+ "vendorProject": "Cisco",
25
+ "product": "Secure Firewall Adaptive Security Appliance and Secure Firewall Threat Defense",
26
+ "vulnerabilityName": "Cisco Secure Firewall Adaptive Security Appliance (ASA) and Secure Firewall Threat Defense (FTD) Buffer Overflow Vulnerability",
27
+ "dateAdded": "2025-09-25",
28
+ "shortDescription": "Cisco Secure Firewall Adaptive Security (ASA) Appliance and Secure Firewall Threat Defense (FTD) Software VPN Web Server contain a buffer overflow vulnerability that allows for remote code execution. This vulnerability could be chained with CVE-2025-20362.",
29
+ "requiredAction": "The KEV due date refers to the deadline by which FCEB agencies are expected to review and begin implementing the guidance outlined in Emergency Directive (ED) 25-03 (URL listed below in Notes). Agencies must follow the mitigation steps provided by CISA (URL listed below in Notes) and vendor\u2019s instructions (URL listed below in Notes). Adhere to the applicable BOD 22-01 guidance for cloud services or discontinue use of the product if mitigations are not available.",
30
+ "dueDate": "2025-09-26",
31
+ "knownRansomwareCampaignUse": "Unknown",
32
+ "notes": "CISA Mitigation Instructions: https:\/\/www.cisa.gov\/news-events\/directives\/ed-25-03-identify-and-mitigate-potential-compromise-cisco-devices ; https:\/\/www.cisa.gov\/news-events\/directives\/supplemental-direction-ed-25-03-core-dump-and-hunt-instructions ; https:\/\/www.cisa.gov\/eviction-strategies-tool\/create-from-template ; https:\/\/sec.cloudapps.cisco.com\/security\/center\/resources\/asa_ftd_continued_attacks ; https:\/\/sec.cloudapps.cisco.com\/security\/center\/private\/resources\/asa_ftd_continued_attacks#Details ; https:\/\/sec.cloudapps.cisco.com\/security\/center\/content\/CiscoSecurityAdvisory\/cisco-sa-asaftd-webvpn-z5xP8EUB ; https:\/\/nvd.nist.gov\/vuln\/detail\/CVE-2025-20333",
33
+ "cwes": [
34
+ "CWE-120"
35
+ ]
36
+ },
37
+ {
38
+ "cveID": "CVE-2025-10585",
39
+ "vendorProject": "Google",
40
+ "product": "Chromium V8",
41
+ "vulnerabilityName": "Google Chromium V8 Type Confusion Vulnerability",
42
+ "dateAdded": "2025-09-23",
43
+ "shortDescription": "Google Chromium contains a type confusion vulnerability in the V8 JavaScript and WebAssembly engine.",
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-14",
46
+ "knownRansomwareCampaignUse": "Unknown",
47
+ "notes": "https:\/\/chromereleases.googleblog.com\/2025\/09\/stable-channel-update-for-desktop_17.html ; https:\/\/nvd.nist.gov\/vuln\/detail\/CVE-2025-10585",
48
+ "cwes": [
49
+ "CWE-843"
50
+ ]
51
+ },
7
52
  {
8
53
  "cveID": "CVE-2025-5086",
9
54
  "vendorProject": "Dassault Syst\u00e8mes",