regscale-cli 6.22.0.1__py3-none-any.whl → 6.23.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 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.22.0.1" # fallback version
36
+ return "6.23.0.0" # fallback version
37
37
 
38
38
 
39
39
  __version__ = get_version_from_pyproject()
regscale/core/app/api.py CHANGED
@@ -44,7 +44,10 @@ class Api:
44
44
  from regscale.integrations.variables import ScannerVariables
45
45
 
46
46
  if isinstance(timeout, str):
47
- timeout = int(timeout)
47
+ try:
48
+ timeout = int(timeout)
49
+ except ValueError:
50
+ timeout = ScannerVariables.timeout
48
51
 
49
52
  self.verify = True
50
53
  self.timeout = timeout
@@ -602,7 +602,7 @@ def save_to_csv(file: Path, data: Any, output_log: bool, transpose: bool = True)
602
602
  data = pd.DataFrame(data)
603
603
  data.to_csv(file)
604
604
  if output_log:
605
- logger.info("Data successfully saved to: %s", file.name)
605
+ logger.info("Data successfully saved to: %s", file.absolute())
606
606
 
607
607
 
608
608
  def save_to_excel(file: Path, data: Any, output_log: bool, transpose: bool = True) -> None:
@@ -623,7 +623,7 @@ def save_to_excel(file: Path, data: Any, output_log: bool, transpose: bool = Tru
623
623
 
624
624
  d_frame.to_excel(file)
625
625
  if output_log:
626
- logger.info("Data successfully saved to: %s", file.name)
626
+ logger.info("Data successfully saved to: %s", file.absolute())
627
627
 
628
628
 
629
629
  def save_to_json(file: Path, data: Any, output_log: bool) -> None:
@@ -642,7 +642,7 @@ def save_to_json(file: Path, data: Any, output_log: bool) -> None:
642
642
  with open(file, "w", encoding="utf-8") as outfile:
643
643
  outfile.write(str(data))
644
644
  if output_log:
645
- logger.info("Data successfully saved to %s", file.name)
645
+ logger.info("Data successfully saved to %s", file.absolute())
646
646
 
647
647
 
648
648
  def save_data_to(file: Path, data: Any, output_log: bool = True, transpose_data: bool = True) -> None:
regscale/dev/code_gen.py CHANGED
@@ -179,7 +179,7 @@ def _build_op_kwargs_and_docstring(
179
179
  name="scan_date",
180
180
  type="string",
181
181
  description="The date of the scan to sync vulnerabilities into RegScale.",
182
- default="Critical",
182
+ default=None,
183
183
  ),
184
184
  "all_scans": Param(
185
185
  name="all_scans",
@@ -319,6 +319,18 @@ def qualys():
319
319
  show_mapping(group=qualys, import_name="qualys", file_type="csv")
320
320
 
321
321
 
322
+ @click.group(
323
+ cls=LazyGroup,
324
+ lazy_subcommands={
325
+ "import": "regscale.integrations.commercial.sarif.sarif_converter.import_sarif",
326
+ },
327
+ name="sarif",
328
+ )
329
+ def sarif():
330
+ """Convert SARIF files to OCSF format via API."""
331
+ pass
332
+
333
+
322
334
  @click.group(
323
335
  cls=LazyGroup,
324
336
  lazy_subcommands={
File without changes
@@ -0,0 +1,432 @@
1
+ """
2
+ Module to import and convert SARIF files to OCSF format using an API converter, and creating Vulnerability,
3
+ VulnerabilityMapping, and ScanHistory objects in RegScale.
4
+ """
5
+
6
+ import datetime
7
+ import json
8
+ import os
9
+ from logging import getLogger
10
+ from typing import Any, Dict, Optional, Union
11
+
12
+ import requests
13
+ from pathlib import Path
14
+ from requests.exceptions import RequestException
15
+ from rich.progress import Progress
16
+ from synqly.engine.resources.ocsf.resources.v_1_3_0.resources.vulnerabilityfinding import Vulnerability as OcsfVuln
17
+ from synqly.engine.resources.ocsf.resources.v_1_5_0.resources.applicationsecurityposturefinding import (
18
+ ApplicationSecurityPostureFinding,
19
+ )
20
+
21
+ from regscale.core.app.application import Application
22
+ from regscale.core.app.utils.app_utils import (
23
+ create_progress_object,
24
+ check_file_path,
25
+ check_license,
26
+ error_and_exit,
27
+ save_data_to,
28
+ get_current_datetime,
29
+ )
30
+ from regscale.models import Asset, IssueStatus, Issue, ScanHistory, SecurityPlan, Vulnerability, VulnerabilityMapping
31
+ from regscale.validation.record import validate_regscale_object
32
+
33
+ logger = getLogger("regscale")
34
+
35
+
36
+ class SarifImporter:
37
+ """
38
+ Class to handle importing and converting SARIF files to OCSF format using an API converter. It then creates
39
+ Vulnerability, VulnerabilityMapping, ScanHistory objects in RegScale.
40
+
41
+ :param Path file_path: Path to the SARIF file or directory of files
42
+ :param int asset_id: The RegScale Asset ID to import the findings to
43
+ :param Union[datetime.datetime, str, None] scan_date: The scan date of the file (defaults to current date if None)
44
+ :rtype: None
45
+ """
46
+
47
+ def __init__(self, file_path: Path, asset_id: int, scan_date: Union[datetime.datetime, str, None] = None) -> None:
48
+ self.file_path: Path = file_path
49
+ self.app: Application = check_license()
50
+ if not scan_date:
51
+ scan_date = get_current_datetime()
52
+ if isinstance(scan_date, datetime.datetime):
53
+ scan_date = scan_date.strftime("%Y-%m-%d")
54
+ self.scan_date: str = scan_date
55
+ self.token: Optional[str] = os.getenv("synqlyAccessToken") or self.app.config.get("synqlyAccessToken")
56
+ if not self.token:
57
+ error_and_exit("synqlyAccessToken environment variable or init.yaml value is required")
58
+ if not validate_regscale_object(asset_id, Asset.get_module_string()):
59
+ error_and_exit(f"Asset ID {asset_id} does not exist in RegScale.")
60
+ self.asset: Asset = Asset.get_object(asset_id)
61
+ self.parent_id = asset_id
62
+ self.parent_module = Asset.get_module_slug()
63
+ self.scan_history: Optional[ScanHistory] = None
64
+ self.progress: Progress = create_progress_object()
65
+ self.process_sarif_files()
66
+
67
+ @staticmethod
68
+ def load_sarif_file(file_path: Path) -> Dict[str, Any]:
69
+ """
70
+ Load and parse a SARIF file from disk
71
+
72
+ :param Path file_path: Path to the SARIF file
73
+ :return: Parsed SARIF data as dictionary
74
+ :rtype: Dict[str, Any]
75
+ :raises: SystemExit if file cannot be loaded or parsed
76
+ """
77
+ try:
78
+ with open(file_path, "r", encoding="utf-8") as file: # type: ignore
79
+ sarif_data = json.load(file)
80
+
81
+ # Basic validation that it's a SARIF file
82
+ if not isinstance(sarif_data, dict) or "$schema" not in sarif_data:
83
+ logger.warning("File may not be a valid SARIF file (missing $schema)")
84
+ elif "sarif" not in sarif_data.get("$schema", "").lower():
85
+ logger.warning("File may not be a valid SARIF file (schema doesn't contain 'sarif')")
86
+
87
+ logger.debug("Successfully loaded SARIF file with %d runs", len(sarif_data.get("runs", [])))
88
+ return sarif_data
89
+
90
+ except FileNotFoundError:
91
+ error_and_exit(f"SARIF file not found: {file_path}")
92
+ except json.JSONDecodeError as e:
93
+ error_and_exit(f"Failed to parse SARIF file as JSON: {e}")
94
+ except Exception as e:
95
+ error_and_exit(f"Failed to load SARIF file: {e}")
96
+
97
+ def convert_sarif_to_ocsf(self, sarif_data: Dict[str, Any]) -> Optional[Any]:
98
+ """
99
+ Convert SARIF data to OCSF format using Synqly API
100
+
101
+ :param Dict[str, Any] sarif_data: The SARIF data to convert
102
+ :raises: SystemExit if API call fails
103
+ :return: Converted data from Synqly API
104
+ :rtype: Optional[Any]
105
+ """
106
+ api_url = "https://api.synqly.com/v1/mappings/apply"
107
+
108
+ headers = {"content-type": "application/json", "authorization": f"Bearer {self.token}"}
109
+
110
+ payload = {"mappings": ["synqly-default.sarif:1.5.0.0"], "data": sarif_data}
111
+
112
+ try:
113
+ logger.debug("Making API request to convert the data: %s", api_url)
114
+ response = requests.post(api_url, headers=headers, json=payload, timeout=60) # 60 second timeout
115
+
116
+ if response.status_code != 200:
117
+ logger.error("API request failed with status %d: %s", response.status_code, response.text)
118
+
119
+ converted_data = response.json()
120
+ logger.debug("Successfully converted SARIF data using API.")
121
+ logger.debug("Response status: %d, Content length: %d bytes", response.status_code, len(response.content))
122
+
123
+ # get the results from the nested dictionary
124
+ if mapping := converted_data.get("result", {}).get("mapping", {}):
125
+ return mapping
126
+ logger.error("Failed to convert SARIF data using API.")
127
+
128
+ except RequestException as e:
129
+ if hasattr(e, "response") and e.response is not None:
130
+ try:
131
+ error_detail = e.response.json()
132
+ error_and_exit(f"API error ({e.response.status_code}): {error_detail}")
133
+ except json.JSONDecodeError:
134
+ error_and_exit(f"API error ({e.response.status_code}): {e.response.text}")
135
+ else:
136
+ error_and_exit(f"Failed to connect to API: {e}")
137
+ except json.JSONDecodeError:
138
+ error_and_exit("Failed to parse API response as JSON")
139
+ except Exception as e:
140
+ error_and_exit(f"Unexpected error during SARIF conversion: {e}")
141
+
142
+ def _process_single_sarif_file(
143
+ self,
144
+ sarif_file: Path,
145
+ output_directory: Path,
146
+ ) -> Dict[str, Any]:
147
+ """
148
+ Process a single SARIF file and return result information
149
+
150
+ :param Path sarif_file: Path to the SARIF file to process
151
+ :param Path output_directory: Output directory for converted files
152
+ :return: Processing result information
153
+ :rtype: Dict[str, Any]
154
+ """
155
+ try:
156
+ sarif_data = self.load_sarif_file(sarif_file)
157
+ logger.debug(f"Converting {sarif_file} data to OCSF data via API...")
158
+
159
+ if "runs" in sarif_data and isinstance(sarif_data["runs"], list) and len(sarif_data["runs"]) > 0:
160
+ # Process each run separately and collect results
161
+ converted_data = [self.convert_sarif_to_ocsf(run) for run in sarif_data["runs"]]
162
+ else:
163
+ # Process the entire SARIF data as a single unit
164
+ converted_data = self.convert_sarif_to_ocsf(sarif_data)
165
+
166
+ # Save converted data
167
+ output_file = output_directory / f"{sarif_file.stem}-converted.json"
168
+ logger.debug("Saving converted data to: %s", output_file)
169
+
170
+ save_data_to(
171
+ file=output_file,
172
+ data=converted_data, # Only log save details in single file mode
173
+ )
174
+
175
+ created_count, updated_count = self._map_sarif_to_integration_findings(converted_data)
176
+
177
+ return {
178
+ "file": sarif_file.absolute(),
179
+ "output": output_file.absolute(),
180
+ "status": "success",
181
+ "error": None,
182
+ "created": created_count,
183
+ "updated": updated_count,
184
+ }
185
+
186
+ except Exception as e:
187
+ return {"file": sarif_file.absolute(), "output": None, "status": "failed", "error": str(e)}
188
+
189
+ def process_sarif_files(
190
+ self,
191
+ ) -> None:
192
+ """
193
+ Unified function to process SARIF files (single or multiple) and convert them using an API converter
194
+
195
+ :rtype: None
196
+ """
197
+ if self.file_path.is_file():
198
+ sarif_files = [self.file_path]
199
+ else:
200
+ sarif_files = list(self.file_path.glob("*.sarif"))
201
+
202
+ # Ensure output directory exists
203
+ output_directory = self.file_path.parent / "converted"
204
+ check_file_path(output_directory)
205
+
206
+ # Initialize processing statistics
207
+ successful_conversions = 0
208
+ failed_conversions = 0
209
+ processed_files = []
210
+
211
+ if total_files := len(sarif_files):
212
+ self.create_scan_history()
213
+ else:
214
+ error_and_exit(f"No SARIF files found in directory: {self.file_path}")
215
+ if batch_mode := total_files > 1:
216
+ logger.info("Found %d SARIF files to convert", total_files)
217
+
218
+ # Process each SARIF file
219
+ for idx, sarif_file in enumerate(sarif_files, 1):
220
+ # Log progress for batch mode
221
+ if batch_mode:
222
+ logger.info("Processing file %d/%d: %s", idx, total_files, sarif_file.name)
223
+ else:
224
+ logger.info("Loading SARIF file: %s", sarif_file)
225
+
226
+ # Process single file
227
+ result = self._process_single_sarif_file(sarif_file, output_directory)
228
+ processed_files.append(result)
229
+
230
+ successful_conversions, failed_conversions = self._log_result_summary(
231
+ result=result,
232
+ successful_conversions=successful_conversions,
233
+ failed_conversions=failed_conversions,
234
+ batch_mode=batch_mode,
235
+ )
236
+
237
+ self.scan_history.save()
238
+ if batch_mode:
239
+ logger.info(
240
+ "Batch conversion completed: %d successful, %d failed", successful_conversions, failed_conversions
241
+ )
242
+ logger.info("Converted files saved to: %s", output_directory.absolute())
243
+ else:
244
+ if successful_conversions == 1:
245
+ logger.info(
246
+ "Conversion completed successfully. Converted file saved to: %s", output_directory.absolute()
247
+ )
248
+ else:
249
+ error_and_exit("SARIF file conversion failed.")
250
+
251
+ def create_scan_history(self) -> None:
252
+ """
253
+ Create a ScanHistory record for the SARIF import
254
+
255
+ :rtype: None
256
+ """
257
+ if getattr(self.asset, "parentModule") == SecurityPlan.get_module_string():
258
+ parent_id = self.asset.parentId
259
+ parent_module: str = SecurityPlan.get_module_string()
260
+ else:
261
+ parent_id = self.asset.id
262
+ parent_module = self.asset.parentModule
263
+ self.scan_history = ScanHistory(
264
+ parentId=parent_id,
265
+ parentModule=parent_module,
266
+ scanningTool="Sarif Scanner",
267
+ scanDate=self.scan_date,
268
+ tenantsId=Asset.get_tenant_id(),
269
+ vLow=0,
270
+ vMedium=0,
271
+ vHigh=0,
272
+ vCritical=0,
273
+ ).create()
274
+
275
+ @staticmethod
276
+ def _log_result_summary(
277
+ result: Dict[str, Any],
278
+ successful_conversions: int,
279
+ failed_conversions: int,
280
+ batch_mode: bool,
281
+ ) -> tuple[int, int]:
282
+ """
283
+ Log the result of a single SARIF file conversion and update statistics
284
+
285
+ :param Dict[str, Any] result: The result of the conversion
286
+ :param int successful_conversions: The number of successful conversions
287
+ :param int failed_conversions: The number of failed conversions
288
+ :param bool batch_mode: Whether running in batch mode (multiple files)
289
+ :return: Updated counts of successful and failed conversions
290
+ :rtype: tuple[int, int]
291
+ """
292
+ if result["status"] == "success":
293
+ successful_conversions += 1
294
+ logger.debug("Successfully converted: %s -> %s", result["file"], result["output"])
295
+ logger.info(
296
+ "Successfully converted: %s -> %s, %s created vulnerabilities and %s updated vulnerabilities",
297
+ result["file"],
298
+ result["output"],
299
+ result["created"],
300
+ result["updated"],
301
+ )
302
+ else:
303
+ failed_conversions += 1
304
+ if batch_mode:
305
+ logger.error("Failed to convert %s: %s", result["file"], result["error"])
306
+ else:
307
+ error_and_exit(f"Failed to convert SARIF file: {result['error']}")
308
+ return successful_conversions, failed_conversions
309
+
310
+ def _map_sarif_to_integration_findings(
311
+ self,
312
+ converted_data: list[dict[str, Any]],
313
+ ) -> tuple[int, int]:
314
+ """
315
+ Map converted SARIF data to a list of IntegrationFinding objects
316
+
317
+ :param Any converted_data: The converted SARIF data from the API
318
+ :return: Number of created and updated vulnerabilities
319
+ :rtype: tuple[int, int]
320
+ """
321
+ create_vuln_count = 0
322
+ updated_vuln_count = 0
323
+ # Convert the nested dictionary to a list of ApplicationSecurityPostureFinding objects for easier parsing
324
+ with self.progress as progress:
325
+ task = progress.add_task("Mapping Sarif data to RegScale vulnerabilities...", total=len(converted_data))
326
+ vulneribility_task = progress.add_task("Creating vulnerabilities and mappings...", total=0)
327
+ for result in converted_data:
328
+ name = self._parse_name(result)
329
+ findings = ApplicationSecurityPostureFinding(**result).vulnerabilities
330
+ progress.update(vulneribility_task, total=len(findings))
331
+ for finding in findings:
332
+ created, vuln = Vulnerability(
333
+ title=finding.title,
334
+ severity=Issue.assign_severity(finding.severity), # type: ignore
335
+ description=self._build_description(finding),
336
+ status=IssueStatus.Open,
337
+ firstSeen=self.scan_date,
338
+ lastSeen=self.scan_date,
339
+ plugInName=name,
340
+ plugInId=self._parse_plugin_id(finding),
341
+ parentId=self.parent_id,
342
+ parentModule=self.parent_module,
343
+ ).create_or_update_with_status()
344
+ self.update_scan_history_count(vuln.severity)
345
+ if created:
346
+ create_vuln_count += 1
347
+ else:
348
+ updated_vuln_count += 1
349
+ # Map vulnerability to asset
350
+ VulnerabilityMapping(
351
+ assetId=self.asset.id,
352
+ vulnerabilityId=vuln.id,
353
+ scanId=self.scan_history.id,
354
+ securityPlanId=self.asset.parentId if self.asset.parentModule == "securityplans" else None,
355
+ status=vuln.status,
356
+ firstSeen=vuln.firstSeen,
357
+ lastSeen=vuln.lastSeen,
358
+ dateCreated=self.scan_date,
359
+ ).create_or_update()
360
+ progress.update(vulneribility_task, advance=1)
361
+ progress.update(task, advance=1)
362
+ return create_vuln_count, updated_vuln_count
363
+
364
+ @staticmethod
365
+ def _parse_name(result: Dict[str, Any]) -> str:
366
+ """
367
+ Parse the name and version from the result metadata
368
+
369
+ :param Dict[str, Any] result: The result to parse the name and version from
370
+ :return: The name and version string
371
+ :rtype: str
372
+ """
373
+ if metadata := result["metadata"]:
374
+ name = metadata.get("product", {}).get("name", "Static Scanner")
375
+ version = metadata.get("version")
376
+ else:
377
+ name = "Static Scanner"
378
+ version = None
379
+ name = f"{name} {version}" if version else name
380
+ return name
381
+
382
+ @staticmethod
383
+ def _parse_plugin_id(finding: OcsfVuln) -> str:
384
+ """
385
+ Parse the plugin ID from the finding
386
+
387
+ :param ocsf_vuln finding: The finding to parse the plugin ID from
388
+ :return: The plugin ID string
389
+ :rtype: str
390
+ """
391
+ if cwe := getattr(finding, "cwe"):
392
+ return cwe.uid
393
+ elif cve := getattr(finding, "cve"):
394
+ return cve.uid
395
+ return finding.title
396
+
397
+ def update_scan_history_count(self, severity: str) -> None:
398
+ """
399
+ Update the scan history count for a given severity
400
+
401
+ :param str severity: The severity of the vulnerability
402
+ :rtype: None
403
+ """
404
+ if "Low" in severity:
405
+ self.scan_history.vLow += 1
406
+ elif "Moderate" in severity:
407
+ self.scan_history.vMedium += 1
408
+ elif "High" in severity:
409
+ self.scan_history.vHigh += 1
410
+ elif "Critical" in severity:
411
+ self.scan_history.vCritical += 1
412
+ else:
413
+ self.scan_history.vInfo += 1
414
+
415
+ @staticmethod
416
+ def _build_description(finding: OcsfVuln) -> str:
417
+ """
418
+ Build a detailed description for a vulnerability finding
419
+
420
+ :param ocsf_vuln finding: The finding to build the description for
421
+ :return: Detailed description string
422
+ :rtype: str
423
+ """
424
+ description = f"{finding.desc}\n"
425
+ for affected_code in getattr(finding, "affected_code", []):
426
+
427
+ for key, value in affected_code.dict().items():
428
+ if isinstance(value, dict):
429
+ for sub_key, sub_value in value.items():
430
+ description += f"file {sub_key}: {sub_value}\n"
431
+ description += f"{key}: {value}\n"
432
+ return description
@@ -0,0 +1,67 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ """SARIF Converter integration for RegScale CLI"""
4
+
5
+ import datetime
6
+ import logging
7
+ from typing import Optional
8
+
9
+ import click
10
+ from pathlib import Path
11
+
12
+ from regscale.core.app.utils.app_utils import (
13
+ get_current_datetime,
14
+ )
15
+
16
+ logger = logging.getLogger("regscale")
17
+
18
+
19
+ @click.group()
20
+ def sarif():
21
+ """Convert SARIF files to OCSF data using an API converter."""
22
+
23
+
24
+ @sarif.command(name="import")
25
+ @click.option(
26
+ "--file_path",
27
+ "-f",
28
+ type=click.Path(exists=True, file_okay=True, dir_okay=True, path_type=Path),
29
+ help="Path to the SARIF file or a directory of files to convert",
30
+ prompt="Enter the path",
31
+ required=True,
32
+ )
33
+ @click.option(
34
+ "--asset_id",
35
+ "-id",
36
+ type=click.INT,
37
+ help="The RegScale Asset ID # to import the findings to.",
38
+ prompt="RegScale Asset ID",
39
+ required=True,
40
+ )
41
+ @click.option(
42
+ "--scan_date",
43
+ "-sd",
44
+ type=click.DateTime(formats=["%Y-%m-%d"]),
45
+ help="The scan date of the file.",
46
+ required=False,
47
+ default=get_current_datetime(),
48
+ )
49
+ def import_sarif(file_path: Path, asset_id: int, scan_date: Optional[datetime.datetime] = None) -> None:
50
+ """Convert a SARIF file(s) to OCSF format using an API converter."""
51
+ process_sarif_files(file_path, asset_id, scan_date)
52
+
53
+
54
+ def process_sarif_files(file_path: Path, asset_id: int, scan_date: Optional[datetime.datetime]) -> None:
55
+ """
56
+ Process SARIF files for import.
57
+
58
+ :param Path file_path: Path to the SARIF file or directory of files
59
+ :param int asset_id: The RegScale Asset ID to import the findings to
60
+ :param Optional[datetime.datetime] scan_date: The scan date of the file
61
+ :return: None
62
+ """
63
+ from regscale.integrations.commercial.sarif.sairf_importer import SarifImporter
64
+
65
+ if not scan_date:
66
+ scan_date = get_current_datetime()
67
+ SarifImporter(file_path, asset_id, scan_date=scan_date)
@@ -1,9 +1,39 @@
1
1
  {
2
2
  "title": "CISA Catalog of Known Exploited Vulnerabilities",
3
- "catalogVersion": "2025.09.02",
4
- "dateReleased": "2025-09-02T14:00:03.8096Z",
5
- "count": 1408,
3
+ "catalogVersion": "2025.09.03",
4
+ "dateReleased": "2025-09-03T17:00:44.122Z",
5
+ "count": 1410,
6
6
  "vulnerabilities": [
7
+ {
8
+ "cveID": "CVE-2023-50224",
9
+ "vendorProject": "TP-Link",
10
+ "product": "TL-WR841N",
11
+ "vulnerabilityName": "TP-Link TL-WR841N Authentication Bypass by Spoofing Vulnerability",
12
+ "dateAdded": "2025-09-03",
13
+ "shortDescription": "TP-Link TL-WR841N contains an authentication bypass by spoofing vulnerability within the httpd service, which listens on TCP port 80 by default, leading to the disclose of stored credentials. The impacted products could be end-of-life (EoL) and\/or end-of-service (EoS). Users should discontinue product utilization.",
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-24",
16
+ "knownRansomwareCampaignUse": "Unknown",
17
+ "notes": "https:\/\/www.tp-link.com\/us\/support\/faq\/4308\/ ; https:\/\/nvd.nist.gov\/vuln\/detail\/CVE-2023-50224",
18
+ "cwes": [
19
+ "CWE-290"
20
+ ]
21
+ },
22
+ {
23
+ "cveID": "CVE-2025-9377",
24
+ "vendorProject": "TP-Link",
25
+ "product": "Multiple Routers",
26
+ "vulnerabilityName": "TP-Link Archer C7(EU) and TL-WR841N\/ND(MS) OS Command Injection Vulnerability",
27
+ "dateAdded": "2025-09-03",
28
+ "shortDescription": "TP-Link Archer C7(EU) and TL-WR841N\/ND(MS) contain an OS command injection vulnerability that exists in the Parental Control page. The impacted products could be end-of-life (EoL) and\/or end-of-service (EoS). Users should discontinue product utilization.",
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-24",
31
+ "knownRansomwareCampaignUse": "Unknown",
32
+ "notes": "https:\/\/www.tp-link.com\/us\/support\/faq\/4308\/ ; https:\/\/nvd.nist.gov\/vuln\/detail\/CVE-2025-9377",
33
+ "cwes": [
34
+ "CWE-78"
35
+ ]
36
+ },
7
37
  {
8
38
  "cveID": "CVE-2020-24363",
9
39
  "vendorProject": "TP-Link",
@@ -32,10 +32,9 @@ from regscale.core.app.utils.app_utils import (
32
32
  from regscale.core.app.utils.parser_utils import safe_datetime_str
33
33
  from regscale.integrations.scanner_integration import ScannerIntegration
34
34
  from regscale.models import IssueStatus, Metadata, regscale_models
35
- from regscale.models.app_models.mapping import Mapping
36
35
  from regscale.models.regscale_models import Asset, File, IssueSeverity, Vulnerability
37
36
 
38
- logger = logging.getLogger(__name__)
37
+ logger = logging.getLogger("regscale")
39
38
 
40
39
  DT_FORMAT = "%Y-%m-%d"
41
40
 
@@ -85,7 +85,7 @@ class Vulnerabilities(SynqlyModel):
85
85
  if scan_date := date_obj(scan_date):
86
86
  vuln_filter.append(f"finding.last_seen_time[gte]{scan_date.isoformat()}")
87
87
  else:
88
- raise ValueError(f"Invalid scan date: {scan_date}")
88
+ vuln_filter.append(f"finding.last_seen_time[gte]{get_last_pull_epoch(regscale_ssp_id)}")
89
89
  else:
90
90
  vuln_filter.append(f"finding.last_seen_time[gte]{get_last_pull_epoch(regscale_ssp_id)}")
91
91
  return vuln_filter
@@ -5,7 +5,7 @@ from typing import Any, Union, TYPE_CHECKING, Optional
5
5
 
6
6
  if TYPE_CHECKING:
7
7
  from regscale.models.integration_models.synqly_models.connectors import Edr, Ticketing, Vulnerabilities
8
- from synqly.engine.resources.ocsf.resources.v_1_1_0.resources.securityfinding import ResourceDetails, Vulnerability
8
+ from synqly.engine.resources.ocsf.resources.v_1_3_0.resources.securityfinding import ResourceDetails, Vulnerability
9
9
 
10
10
  from synqly import engine
11
11
  from synqly.engine import CreateTicketRequest
@@ -160,7 +160,7 @@ class Mapper:
160
160
  :return: A dictionary of the parsed data
161
161
  :rtype: dict
162
162
  """
163
- from synqly.engine.resources.ocsf.resources.v_1_1_0.resources.securityfinding import Remediation
163
+ from synqly.engine.resources.ocsf.resources.v_1_3_0.resources.securityfinding import Remediation
164
164
 
165
165
  finding_data = {
166
166
  "cve": None,
@@ -526,6 +526,7 @@ class Issue(RegScaleModel):
526
526
  "low": IssueSeverity.Low.value,
527
527
  "moderate": IssueSeverity.Moderate.value,
528
528
  "high": IssueSeverity.High.value,
529
+ "critical": IssueSeverity.Critical.value,
529
530
  }
530
531
  severity = IssueSeverity.NotAssigned.value
531
532
  # see if the value is an int or float
@@ -542,8 +543,10 @@ class Issue(RegScaleModel):
542
543
  severity = severity_levels["low"]
543
544
  elif value.lower() in ["medium", "moderate", "major"]:
544
545
  severity = severity_levels["moderate"]
545
- elif value.lower() in ["high", "critical", "highest", "critical", "blocker"]:
546
+ elif value.lower() in ["high", "highest", "blocker"]:
546
547
  severity = severity_levels["high"]
548
+ elif value.lower() in ["critical"]:
549
+ severity = severity_levels["critical"]
547
550
  elif value in list(severity_levels.values()):
548
551
  severity = value
549
552
  return severity
@@ -67,8 +67,8 @@ class Vulnerability(RegScaleModel):
67
67
  lastSeen: Optional[str] = None
68
68
  firstSeen: Optional[str] = None
69
69
  daysOpen: Optional[int] = None
70
- dns: Optional[str] = None
71
- ipAddress: Optional[str] = None
70
+ dns: Optional[str] = ""
71
+ ipAddress: Optional[str] = ""
72
72
  mitigated: Optional[bool] = None
73
73
  operatingSystem: Optional[str] = None
74
74
  port: Optional[Union[str, int]] = None
@@ -83,7 +83,7 @@ class Vulnerability(RegScaleModel):
83
83
  cvsSv3BaseScore: Optional[Union[float, int]] = None
84
84
  description: Optional[str] = None
85
85
  plugInText: Optional[str] = None
86
- tenantsId: int = Field(default=0)
86
+ tenantsId: int = Field(default_factory=RegScaleModel.get_tenant_id)
87
87
  isPublic: bool = Field(default=False)
88
88
  dateClosed: Optional[str] = None
89
89
  status: Optional[Union[str, IssueStatus]] = Field(default_factory=lambda: IssueStatus.Open)
regscale/regscale.py CHANGED
@@ -172,6 +172,7 @@ okta = import_command_with_timing(COMMERCIAL, "okta")
172
172
  prisma = import_command_with_timing(COMMERCIAL, "prisma")
173
173
  qualys = import_command_with_timing(COMMERCIAL, "qualys")
174
174
  salesforce = import_command_with_timing(COMMERCIAL, "salesforce")
175
+ sarif = import_command_with_timing(COMMERCIAL, "sarif")
175
176
  sap = import_command_with_timing("regscale.integrations.commercial.sap.click", "sap")
176
177
  sysdig = import_command_with_timing("regscale.integrations.commercial.sap.sysdig.click", "sysdig")
177
178
  servicenow = import_command_with_timing(COMMERCIAL, "servicenow")
@@ -756,8 +757,8 @@ cli.add_command(catalog) # add Catalog Management Feature
756
757
  cli.add_command(compare) # add Comparison support
757
758
  cli.add_command(control_editor) # add Control Editor Feature
758
759
  cli.add_command(evidence) # add Evidence Feature
759
- cli.add_command(migrations) # add data migration support
760
760
  cli.add_command(issues) # add POAM(Issues) Editor Feature
761
+ cli.add_command(migrations) # add data migration support
761
762
  cli.add_command(model) # add POAM(Issues) Editor Feature
762
763
  cli.add_command(set_permissions) # add builk editor for record permissions
763
764
 
@@ -791,15 +792,16 @@ cli.add_command(prisma) # add Prisma support
791
792
  cli.add_command(qualys) # add Qualys Functionality
792
793
  cli.add_command(salesforce) # add Salesforce support
793
794
  cli.add_command(sap) # add SAP Concur support
795
+ cli.add_command(sarif) # add SARIF Converter support
794
796
  cli.add_command(servicenow) # add ServiceNow support
795
797
  cli.add_command(sicura) # add Sicura Integration
796
798
  cli.add_command(snyk) # add Snyk support
797
- cli.add_command(veracode) # add Veracode Integration
798
799
  cli.add_command(sonarcloud) # add SonarCloud Integration
799
800
  cli.add_command(stig) # add STIGv2 support
800
801
  cli.add_command(stig_mapper) # add STIG Mapper support
801
802
  cli.add_command(tenable) # add Tenable & TenableV2 support
802
803
  cli.add_command(trivy) # add Trivy support
804
+ cli.add_command(veracode) # add Veracode Integration
803
805
  cli.add_command(wiz) # add Wiz support
804
806
  cli.add_command(xray) # add JFrog Xray support
805
807
 
@@ -808,12 +810,12 @@ cli.add_command(xray) # add JFrog Xray support
808
810
  ############################################################
809
811
  cli.add_command(alienvault) # add Alienvault OTX integration
810
812
  cli.add_command(cisa) # add CISA support
813
+ cli.add_command(criticality_updater) # add Criticality Updater support
811
814
  cli.add_command(csam) # add CSAM support
812
815
  cli.add_command(emass) # add eMASS support
813
816
  cli.add_command(fedramp) # add FedRAMP support
814
817
  cli.add_command(nist) # add Nist_Catalog support
815
818
  cli.add_command(oscal) # add OSCAL support
816
- cli.add_command(criticality_updater) # add Criticality Updater support
817
819
 
818
820
  # start function for the CLI
819
821
  if __name__ == "__main__":
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: regscale-cli
3
- Version: 6.22.0.1
3
+ Version: 6.23.0.0
4
4
  Summary: Command Line Interface (CLI) for bulk processing/loading data into RegScale
5
5
  Home-page: https://github.com/RegScale/regscale-cli
6
6
  Author: Travis Howerton
@@ -68,7 +68,7 @@ Requires-Dist: setuptools
68
68
  Requires-Dist: simple-salesforce
69
69
  Requires-Dist: smart-open ~=7.0
70
70
  Requires-Dist: static
71
- Requires-Dist: synqly
71
+ Requires-Dist: synqly >=0.4.56
72
72
  Requires-Dist: tools
73
73
  Requires-Dist: typing-extensions ~=4.12.2
74
74
  Requires-Dist: wheel
@@ -150,7 +150,7 @@ Requires-Dist: setuptools >=69.0.0 ; extra == 'airflow'
150
150
  Requires-Dist: simple-salesforce ; extra == 'airflow'
151
151
  Requires-Dist: smart-open ~=7.0 ; extra == 'airflow'
152
152
  Requires-Dist: static ; extra == 'airflow'
153
- Requires-Dist: synqly ; extra == 'airflow'
153
+ Requires-Dist: synqly >=0.4.56 ; extra == 'airflow'
154
154
  Requires-Dist: tools ; extra == 'airflow'
155
155
  Requires-Dist: typing-extensions ~=4.12.2 ; extra == 'airflow'
156
156
  Requires-Dist: wheel ; extra == 'airflow'
@@ -235,7 +235,7 @@ Requires-Dist: setuptools >=69.0.0 ; extra == 'airflow-azure'
235
235
  Requires-Dist: simple-salesforce ; extra == 'airflow-azure'
236
236
  Requires-Dist: smart-open ~=7.0 ; extra == 'airflow-azure'
237
237
  Requires-Dist: static ; extra == 'airflow-azure'
238
- Requires-Dist: synqly ; extra == 'airflow-azure'
238
+ Requires-Dist: synqly >=0.4.56 ; extra == 'airflow-azure'
239
239
  Requires-Dist: tools ; extra == 'airflow-azure'
240
240
  Requires-Dist: typing-extensions ~=4.12.2 ; extra == 'airflow-azure'
241
241
  Requires-Dist: wheel ; extra == 'airflow-azure'
@@ -320,7 +320,7 @@ Requires-Dist: setuptools >=69.0.0 ; extra == 'airflow-sqlserver'
320
320
  Requires-Dist: simple-salesforce ; extra == 'airflow-sqlserver'
321
321
  Requires-Dist: smart-open ~=7.0 ; extra == 'airflow-sqlserver'
322
322
  Requires-Dist: static ; extra == 'airflow-sqlserver'
323
- Requires-Dist: synqly ; extra == 'airflow-sqlserver'
323
+ Requires-Dist: synqly >=0.4.56 ; extra == 'airflow-sqlserver'
324
324
  Requires-Dist: tools ; extra == 'airflow-sqlserver'
325
325
  Requires-Dist: typing-extensions ~=4.12.2 ; extra == 'airflow-sqlserver'
326
326
  Requires-Dist: wheel ; extra == 'airflow-sqlserver'
@@ -410,7 +410,7 @@ Requires-Dist: setuptools >=69.0.0 ; extra == 'all'
410
410
  Requires-Dist: simple-salesforce ; extra == 'all'
411
411
  Requires-Dist: smart-open ~=7.0 ; extra == 'all'
412
412
  Requires-Dist: static ; extra == 'all'
413
- Requires-Dist: synqly ; extra == 'all'
413
+ Requires-Dist: synqly >=0.4.56 ; extra == 'all'
414
414
  Requires-Dist: tools ; extra == 'all'
415
415
  Requires-Dist: typing-extensions ~=4.12.2 ; extra == 'all'
416
416
  Requires-Dist: werkzeug >=2.3.8 ; extra == 'all'
@@ -472,7 +472,7 @@ Requires-Dist: setuptools ; extra == 'ansible'
472
472
  Requires-Dist: simple-salesforce ; extra == 'ansible'
473
473
  Requires-Dist: smart-open ~=7.0 ; extra == 'ansible'
474
474
  Requires-Dist: static ; extra == 'ansible'
475
- Requires-Dist: synqly ; extra == 'ansible'
475
+ Requires-Dist: synqly >=0.4.56 ; extra == 'ansible'
476
476
  Requires-Dist: tools ; extra == 'ansible'
477
477
  Requires-Dist: typing-extensions ~=4.12.2 ; extra == 'ansible'
478
478
  Requires-Dist: wheel ; extra == 'ansible'
@@ -555,7 +555,7 @@ Requires-Dist: sphinx ; extra == 'dev'
555
555
  Requires-Dist: sphinx-autodoc-typehints ; extra == 'dev'
556
556
  Requires-Dist: sphinx-click ; extra == 'dev'
557
557
  Requires-Dist: static ; extra == 'dev'
558
- Requires-Dist: synqly ; extra == 'dev'
558
+ Requires-Dist: synqly >=0.4.56 ; extra == 'dev'
559
559
  Requires-Dist: tools ; extra == 'dev'
560
560
  Requires-Dist: types-python-dateutil ; extra == 'dev'
561
561
  Requires-Dist: types-pyyaml ; extra == 'dev'
@@ -624,7 +624,7 @@ Requires-Dist: setuptools ; extra == 'server'
624
624
  Requires-Dist: simple-salesforce ; extra == 'server'
625
625
  Requires-Dist: smart-open ~=7.0 ; extra == 'server'
626
626
  Requires-Dist: static ; extra == 'server'
627
- Requires-Dist: synqly ; extra == 'server'
627
+ Requires-Dist: synqly >=0.4.56 ; extra == 'server'
628
628
  Requires-Dist: tools ; extra == 'server'
629
629
  Requires-Dist: typing-extensions ~=4.12.2 ; extra == 'server'
630
630
  Requires-Dist: werkzeug >=2.3.8 ; extra == 'server'
@@ -1,6 +1,6 @@
1
1
  regscale/__init__.py,sha256=ZygAIkX6Nbjag1czWdQa-yP-GM1mBE_9ss21Xh__JFc,34
2
- regscale/_version.py,sha256=EYNOOd0vp241KuX2hAA7xgSlflkwJKr4PsBZ38WsRdA,1198
3
- regscale/regscale.py,sha256=B5XR-4v7dNChlXmLD-GIw7UEyB0aJw-25jROkUGgnaA,31006
2
+ regscale/_version.py,sha256=WCBjfKcCkvP_rge5Txea03DdGp8t8G4D7ysVpze60LM,1198
3
+ regscale/regscale.py,sha256=Lfjztf_bYITfITh830v1ENkrj5ZBDbNinygsUxGdh7o,31116
4
4
  regscale/airflow/__init__.py,sha256=yMwN0Bz4JbM0nl5qY_hPegxo_O2ilhTOL9PY5Njhn-s,270
5
5
  regscale/airflow/click_dags.py,sha256=H3SUR5jkvInNMv1gu-VG-Ja_H-kH145CpQYNalWNAbE,4520
6
6
  regscale/airflow/click_mixins.py,sha256=BTwKWsEu6KVtlrzFbXpD_RuEpMzc-CSnCCySUzqzCgQ,3571
@@ -35,7 +35,7 @@ regscale/core/decorators.py,sha256=YuX9VCbCJh76qlc_6ungu0nD4VT1VsV2spXH_bsDTfY,8
35
35
  regscale/core/lazy_group.py,sha256=S2-nA5tzm47A929NOTqGkzrzKuZQDlq2OAPbNnG1W1Q,2046
36
36
  regscale/core/login.py,sha256=-8vy1HVAtv1iARnZh6uzYtwmx8VFYPwLYR0QAf1ttCk,2714
37
37
  regscale/core/app/__init__.py,sha256=nGcCN1vWBAnZzoccIlt0jwWQdegCOrBWOB7LPhQkQSs,96
38
- regscale/core/app/api.py,sha256=CSyUCV6haBAQ9IyE1FViJcAfTcoS5GJRaULwnRoAV9U,23499
38
+ regscale/core/app/api.py,sha256=vDcdvXLz9hEu6R-U-f9z7zZ-aXmmhCjiUKlhzm5M6zA,23602
39
39
  regscale/core/app/application.py,sha256=qGi5aLixOGhUq_ioGqx9vSbZBKXWxtqNaaQ_pQX9kXM,32020
40
40
  regscale/core/app/logz.py,sha256=8AdBKmquv45JGi5fCMc38JqQg6-FpUONGmqfd5EGwrI,2583
41
41
  regscale/core/app/internal/__init__.py,sha256=rod4nmE7rrYDdbuYF4mCWz49TK_2r-v4tWy1UHW63r0,4808
@@ -57,7 +57,7 @@ regscale/core/app/internal/workflow.py,sha256=SpgYk1QyzdilVLOK1fFzaKhdLspumaugf5
57
57
  regscale/core/app/utils/XMLIR.py,sha256=M_RrCsbjznihatkucCKw6dPgHTPQczXyqIdUXWhuCLI,8328
58
58
  regscale/core/app/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
59
59
  regscale/core/app/utils/api_handler.py,sha256=T1meKw6Yi3ZAgRbQ1xuKDVh9Q9B8mbMqqN_LrSwIlAM,11765
60
- regscale/core/app/utils/app_utils.py,sha256=xb-hZtotBu6vJrlTZtfn8YVGWVXqGMlImTBoYwbCOJE,37116
60
+ regscale/core/app/utils/app_utils.py,sha256=c7V61VYaHaz_4o4YNmpQl0gZ3bHlbRwfpj-fUBVcb_s,37134
61
61
  regscale/core/app/utils/file_utils.py,sha256=x7cqYPxJ-PgSb2lX_K6zhdqyGQjOCmr04lnqdBQV3hI,9269
62
62
  regscale/core/app/utils/parser_utils.py,sha256=aBEgcFwbJMD-ARf3wzf-tyWwR6NHvzEcdYcPMm8hGqo,2533
63
63
  regscale/core/app/utils/pickle_file_handler.py,sha256=iMdv4N8z00TB5LyPdxIcLKNRpDQVWQ8ZQWAqCKpqmF0,1695
@@ -100,7 +100,7 @@ regscale/core/utils/urls.py,sha256=ZcU9OJqDmVQXgu6BrLESIp2KMkkUuzTZZ_wHsZMzfA4,6
100
100
  regscale/dev/__init__.py,sha256=wVP59B1iurp36ul8pD_CjmunJLHOdKWWodz1r5loNvw,190
101
101
  regscale/dev/analysis.py,sha256=9s6pfTGK6FBqV-karQQnCc_GYHloETmFyvsvVJ5jBm8,15603
102
102
  regscale/dev/cli.py,sha256=VT9QHhfJX10KdJlSL9zBx-D__0H7qqS8G1GPwOb59Xs,8783
103
- regscale/dev/code_gen.py,sha256=Y3LPB7NO-bNM3lP_8andZ4iFKFXvEv-kBhEmUKGU9eE,22544
103
+ regscale/dev/code_gen.py,sha256=wh9398z_CoEN7ndBf31N5xrXZx1FKoZK34w77WWfY9Y,22538
104
104
  regscale/dev/dirs.py,sha256=wmEKM4UZjMXDiNi6a17JchhyfQNvJg6ACQmqT_Xt6V0,2044
105
105
  regscale/dev/docs.py,sha256=Ngtd2Z0vYXYQXUIAqhL02f-_fUuIpmTPa5YIO3wAOHY,14678
106
106
  regscale/dev/monitoring.py,sha256=h0pewRSXF8bLEtQ9dB3D0XqGTM4HtjaCiUUH3ijEllM,835
@@ -116,7 +116,7 @@ regscale/integrations/integration_override.py,sha256=HjYBCuvNpU3t3FptaqYAkdexLFO
116
116
  regscale/integrations/jsonl_scanner_integration.py,sha256=l8nq_T3rE1XX-6HxrNHm3xzxCNWbIjxQvGMdtZWs7KQ,57003
117
117
  regscale/integrations/scanner_integration.py,sha256=fMdA4SrpzJJiTTTPtKCjq5HjeoM1QrIhHNp7wVj1BuI,161584
118
118
  regscale/integrations/variables.py,sha256=MfQ34WuYVN5437A9sZ2ssHRkA3gFhMHfk1DVasceGmY,2336
119
- regscale/integrations/commercial/__init__.py,sha256=LZj1qV5f7RdHIOfedDVELV62ADe5gyNccWayHMF1aVc,14026
119
+ regscale/integrations/commercial/__init__.py,sha256=lbwZX0BKAe5euU5d_MV4MaAhCvd5actLiCklk9LHUAA,14276
120
120
  regscale/integrations/commercial/ad.py,sha256=YXSmK8vRf6yi2GnREGa5GrE6GelhFrLj44SY8AO1pK0,15509
121
121
  regscale/integrations/commercial/burp.py,sha256=3BLNKLfwL1x7jfhd8MJD6hdHEpj58pOEtrtCkn2hcWA,3344
122
122
  regscale/integrations/commercial/cpe.py,sha256=vUHKGdq0UlR38pZWqqHLLTdDfooLtE9zIiFHdoFcUr0,5735
@@ -201,6 +201,9 @@ regscale/integrations/commercial/sap/sysdig/sysdig_scanner.py,sha256=3Xy6vSznlb5
201
201
  regscale/integrations/commercial/sap/tenable/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
202
202
  regscale/integrations/commercial/sap/tenable/click.py,sha256=vCdRe6d5ey6mywtL8GY21n5ecqWTdYLLDceEOy8QrLg,1425
203
203
  regscale/integrations/commercial/sap/tenable/scanner.py,sha256=eeXXe2b-zoth80pVcasO7Cy-3NhW_4PcDhin1G8hj0o,9363
204
+ regscale/integrations/commercial/sarif/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
205
+ regscale/integrations/commercial/sarif/sairf_importer.py,sha256=gCuDsybT0jbhCtQLJW0L88hLxUpWIgatVERU4D6_9Xc,17886
206
+ regscale/integrations/commercial/sarif/sarif_converter.py,sha256=VwUBfw6FYXIVGqLsqoipPEYbF7GJSOZ6kkCyXQDlNhM,1900
204
207
  regscale/integrations/commercial/sicura/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
205
208
  regscale/integrations/commercial/sicura/api.py,sha256=4FDM3ATk8bysdGaBtcfsexlZoTHUf-ckA60eGrK-KDk,32151
206
209
  regscale/integrations/commercial/sicura/commands.py,sha256=-54gqCpmGECC1ph5Wpr8cwYhBscsQy1V_24-xQ0sFyw,1874
@@ -319,7 +322,7 @@ regscale/models/integration_models/azure_alerts.py,sha256=2etrpvcxa7jVQrc98bJlVG
319
322
  regscale/models/integration_models/base64.py,sha256=sxV6O5qY1_TstJENX5jBPsSdQwmA83-NNhgJFunXiZE,570
320
323
  regscale/models/integration_models/burp.py,sha256=FBEBkH3U0Q8vq71FFoWnvgLRF5Hkr9GYmQFmNNHFrVk,16932
321
324
  regscale/models/integration_models/burp_models.py,sha256=UytDTAcCaxyu-knFkm_mEUH6UmWK3OTXKSC9Sc6OjVs,3669
322
- regscale/models/integration_models/cisa_kev_data.json,sha256=DneAkMd5PiDNtl0wfyc2vlAyiVxxWNfGohIV1BS_IJE,1262064
325
+ regscale/models/integration_models/cisa_kev_data.json,sha256=UVI0CQadIoComCdjuIs5wUsNCZ6ARdpQv1_7W439Qn8,1264242
323
326
  regscale/models/integration_models/defender_data.py,sha256=jsAcjKxiGmumGerj7xSWkFd6r__YpuKDnYX5o7xHDiE,2844
324
327
  regscale/models/integration_models/defenderimport.py,sha256=Ze4kgwns-IYPyO7sBjEzW8PXWlxwU-DAo2fIyRcTC3k,6242
325
328
  regscale/models/integration_models/drf.py,sha256=Aq7AdLa_CH97NrnR-CxaFI22JjVN9uCxVN7Z-BBUaNU,18896
@@ -346,13 +349,13 @@ regscale/models/integration_models/axonius_models/connectors/assets.py,sha256=6m
346
349
  regscale/models/integration_models/ecr_models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
347
350
  regscale/models/integration_models/ecr_models/data.py,sha256=l28DCidXar1JygYBQZL9MYenQA9N-Cx3Skf51IOjZcw,1017
348
351
  regscale/models/integration_models/ecr_models/ecr.py,sha256=oAkQ-SDS3Mjrn291dh9qF5LaRYGFJnmuNY28UyrzIfg,7293
349
- regscale/models/integration_models/flat_file_importer/__init__.py,sha256=IoM8SPjccK0X4reUjc2jH5bA8iDeVwwO4OENSRveCpk,40648
352
+ regscale/models/integration_models/flat_file_importer/__init__.py,sha256=HYO7mrqnBaXKyo7dBNGnVqYY7m_1OjTadJKfg4f_ae4,40595
350
353
  regscale/models/integration_models/sbom/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
351
354
  regscale/models/integration_models/sbom/cyclone_dx.py,sha256=0pFR0BWBrF5c8_cC_8mj2MXvNOMHOdHbBYXvTVfFAh8,4058
352
355
  regscale/models/integration_models/synqly_models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
353
356
  regscale/models/integration_models/synqly_models/capabilities.json,sha256=mjnI5C29qmT7rr1wkdebvo0-5w10msVtLYvl3bODvUY,394787
354
357
  regscale/models/integration_models/synqly_models/connector_types.py,sha256=8nxptkTexpskySnmL0obNAff_iu_fx6tJ7i1-4hJvao,461
355
- regscale/models/integration_models/synqly_models/ocsf_mapper.py,sha256=e2kTOhWSNRnzbgMchMx-7c21pCgSv2DqWnxvajKEKJM,16960
358
+ regscale/models/integration_models/synqly_models/ocsf_mapper.py,sha256=ftObPhGg9CamnwRZ5z6qi8pW2Gu4JYy8apEo33o7q00,16960
356
359
  regscale/models/integration_models/synqly_models/param.py,sha256=Xt5Zm6lC_VkLj7LF2qXo72TJZHysqttsp5ai0NCf1po,2643
357
360
  regscale/models/integration_models/synqly_models/synqly_model.py,sha256=9wgR0mNTuteMarnMj3iAIj8Ki9-8rc-pIWZpku4hH_k,34701
358
361
  regscale/models/integration_models/synqly_models/tenants.py,sha256=kewIZw-iv18bNXJGG3ghwuFJ4CK5iXQhn_x2-xvV0iM,1078
@@ -360,7 +363,7 @@ regscale/models/integration_models/synqly_models/connectors/__init__.py,sha256=J
360
363
  regscale/models/integration_models/synqly_models/connectors/assets.py,sha256=HHNIAVh5pRuJe8sStqhFEc6VnX2wT0FcY5178nbQgkQ,3705
361
364
  regscale/models/integration_models/synqly_models/connectors/edr.py,sha256=kio3uoEYubCHretpDOJqxdwmzid1IzbVYz0BF64zeL0,5547
362
365
  regscale/models/integration_models/synqly_models/connectors/ticketing.py,sha256=yRBuCkRAVfa_C91r3WqJ9gxrQsoD0qV9cY48YXpJl70,25358
363
- regscale/models/integration_models/synqly_models/connectors/vulnerabilities.py,sha256=kwKvmEIsxkLDOYoDOiqdtyapBZ5fHYQcrQjDpFJQvWc,7143
366
+ regscale/models/integration_models/synqly_models/connectors/vulnerabilities.py,sha256=NzsaaBuuL8mCxOgUGhA7eqvrc398l_3cJSJgv0WVF4s,7180
364
367
  regscale/models/integration_models/tenable_models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
365
368
  regscale/models/integration_models/tenable_models/integration.py,sha256=lplL8zmjTFuhLreW-4y7G1fiCOBgzNAaATq800jgTQc,10271
366
369
  regscale/models/integration_models/tenable_models/models.py,sha256=dmG7btkN4YkDWwnfW5Ldc3tWEAGjPiaRgJjrqMOkPEU,15846
@@ -409,7 +412,7 @@ regscale/models/regscale_models/incident.py,sha256=jsS4MfigzjwFphvdIrBk62GfvbceQ
409
412
  regscale/models/regscale_models/inheritance.py,sha256=n8CtDQZ8WPQ-AwC0kq5D0nMwK1_njfB-rUN5PdjiMOs,1314
410
413
  regscale/models/regscale_models/inherited_control.py,sha256=RuQJgVyZgfoIrUG_vvwQYHECb3wsFjDH-zPj-bIFBNU,2007
411
414
  regscale/models/regscale_models/interconnection.py,sha256=8Q9CGeHEX9TXQrim_NIAj9KuM4MwaUTpBLs_LKaXAlw,1256
412
- regscale/models/regscale_models/issue.py,sha256=h88GRUD1YtC0-bVHXm3p9owDt1F0bJD48tzm03HkrOg,59248
415
+ regscale/models/regscale_models/issue.py,sha256=pPrCTDy9y9ZTYMtOCl9J2U12NrWn09XhFjF1A5cUgdw,59381
413
416
  regscale/models/regscale_models/leveraged_authorization.py,sha256=OUrL8JQV3r7T3ldHlL6Y_ZLv6KuQIC-3eZW5wZ7XFUk,4192
414
417
  regscale/models/regscale_models/line_of_inquiry.py,sha256=Uu0lQEhif0W6yTSkJo27GyQGmExSngJvyqGBTr4Q8Fg,1713
415
418
  regscale/models/regscale_models/link.py,sha256=lAY4Ig3Menm1EqfcAbVJ7jsCsRO5tWtJIf-9-G9FXT8,6593
@@ -457,7 +460,7 @@ regscale/models/regscale_models/team.py,sha256=MfJvSg6E77FF5dkIlGJs-2XnHMZLMYS3e
457
460
  regscale/models/regscale_models/threat.py,sha256=4TNZcRnTgmlDwBsYu5Pbh9GRd8ZWAtqqr0Xph3uPNAA,7255
458
461
  regscale/models/regscale_models/user.py,sha256=wiU2qKwp3aYtmaHEmTtv8BbMEgFb913dHgc2VnmsAkg,7186
459
462
  regscale/models/regscale_models/user_group.py,sha256=vzlXHvPNsgJd38H0R3osi46Oj19QO5oPx0qXntQBKWI,1891
460
- regscale/models/regscale_models/vulnerability.py,sha256=CyR1hkt07Inn8U7Ac-DTntgJXeKM3RluldKy1RWTYIA,11050
463
+ regscale/models/regscale_models/vulnerability.py,sha256=OxHGwq2REY5CCilis-TRgvVGYUyJs_BWNgP0bKOtyN0,11080
461
464
  regscale/models/regscale_models/vulnerability_mapping.py,sha256=k14azHU7VwryHfXaJdvAMWXs3AqHDr7rnj602bscWQM,6260
462
465
  regscale/models/regscale_models/workflow.py,sha256=uMNVVAn5qR8wxjMP5PHbcvMmvPRe1gn1oclVUpbv52s,1873
463
466
  regscale/models/regscale_models/workflow_action.py,sha256=zMHrvUkTQJlkCj6Xx6wadozBwsVPpObj5GD81LI2VZc,925
@@ -533,9 +536,9 @@ tests/regscale/models/test_regscale_model.py,sha256=ZsrEZkC4EtdIsoQuayn1xv2gEGcV
533
536
  tests/regscale/models/test_report.py,sha256=IqUq7C__a1_q_mLaz0PE9Lq6fHggBsB14-AzEYNBxLw,4666
534
537
  tests/regscale/models/test_tenable_integrations.py,sha256=y1qaW77H094VSGHjZdlvF66UCt-nPEib9Mv3cdwbM94,32435
535
538
  tests/regscale/models/test_user_model.py,sha256=e9olv28qBApgnvK6hFHOgXjUC-pkaV8aGDirEIWASL4,4427
536
- regscale_cli-6.22.0.1.dist-info/LICENSE,sha256=ytNhYQ9Rmhj_m-EX2pPq9Ld6tH5wrqqDYg-fCf46WDU,1076
537
- regscale_cli-6.22.0.1.dist-info/METADATA,sha256=B-6Lcj_QXC8gBaI1u44SeRtjqVo-e63cBXrlefK6Pfo,34955
538
- regscale_cli-6.22.0.1.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
539
- regscale_cli-6.22.0.1.dist-info/entry_points.txt,sha256=cLOaIP1eRv1yZ2u7BvpE3aB4x3kDrDwkpeisKOu33z8,269
540
- regscale_cli-6.22.0.1.dist-info/top_level.txt,sha256=Uv8VUCAdxRm70bgrD4YNEJUmDhBThad_1aaEFGwRByc,15
541
- regscale_cli-6.22.0.1.dist-info/RECORD,,
539
+ regscale_cli-6.23.0.0.dist-info/LICENSE,sha256=ytNhYQ9Rmhj_m-EX2pPq9Ld6tH5wrqqDYg-fCf46WDU,1076
540
+ regscale_cli-6.23.0.0.dist-info/METADATA,sha256=cjr3qeaYzjy47S7c4z4l7daXTpF92UldmmYpIJb83F8,35027
541
+ regscale_cli-6.23.0.0.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
542
+ regscale_cli-6.23.0.0.dist-info/entry_points.txt,sha256=cLOaIP1eRv1yZ2u7BvpE3aB4x3kDrDwkpeisKOu33z8,269
543
+ regscale_cli-6.23.0.0.dist-info/top_level.txt,sha256=Uv8VUCAdxRm70bgrD4YNEJUmDhBThad_1aaEFGwRByc,15
544
+ regscale_cli-6.23.0.0.dist-info/RECORD,,