regscale-cli 6.20.9.1__py3-none-any.whl → 6.21.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.

Files changed (56) hide show
  1. regscale/_version.py +1 -1
  2. regscale/core/app/application.py +12 -5
  3. regscale/core/app/internal/set_permissions.py +58 -27
  4. regscale/integrations/commercial/defender.py +9 -0
  5. regscale/integrations/commercial/nessus/scanner.py +2 -0
  6. regscale/integrations/commercial/sonarcloud.py +35 -36
  7. regscale/integrations/commercial/synqly/ticketing.py +51 -0
  8. regscale/integrations/commercial/wizv2/async_client.py +325 -0
  9. regscale/integrations/commercial/wizv2/constants.py +756 -0
  10. regscale/integrations/commercial/wizv2/scanner.py +1301 -89
  11. regscale/integrations/commercial/wizv2/utils.py +280 -36
  12. regscale/integrations/commercial/wizv2/variables.py +2 -10
  13. regscale/integrations/integration_override.py +15 -6
  14. regscale/integrations/scanner_integration.py +221 -37
  15. regscale/integrations/variables.py +1 -0
  16. regscale/models/integration_models/amazon_models/inspector_scan.py +32 -57
  17. regscale/models/integration_models/aqua.py +92 -78
  18. regscale/models/integration_models/cisa_kev_data.json +47 -4
  19. regscale/models/integration_models/defenderimport.py +64 -59
  20. regscale/models/integration_models/ecr_models/ecr.py +100 -147
  21. regscale/models/integration_models/flat_file_importer/__init__.py +52 -38
  22. regscale/models/integration_models/ibm.py +29 -47
  23. regscale/models/integration_models/nexpose.py +156 -68
  24. regscale/models/integration_models/prisma.py +46 -66
  25. regscale/models/integration_models/qualys.py +99 -93
  26. regscale/models/integration_models/snyk.py +229 -158
  27. regscale/models/integration_models/synqly_models/capabilities.json +1 -1
  28. regscale/models/integration_models/veracode.py +15 -20
  29. regscale/models/integration_models/xray.py +276 -82
  30. regscale/models/regscale_models/__init__.py +13 -0
  31. regscale/models/regscale_models/classification.py +23 -0
  32. regscale/models/regscale_models/control_implementation.py +14 -12
  33. regscale/models/regscale_models/cryptography.py +56 -0
  34. regscale/models/regscale_models/deviation.py +4 -4
  35. regscale/models/regscale_models/group.py +3 -2
  36. regscale/models/regscale_models/interconnection.py +1 -1
  37. regscale/models/regscale_models/issue.py +140 -41
  38. regscale/models/regscale_models/milestone.py +40 -0
  39. regscale/models/regscale_models/property.py +0 -1
  40. regscale/models/regscale_models/rbac.py +22 -0
  41. regscale/models/regscale_models/regscale_model.py +29 -18
  42. regscale/models/regscale_models/team.py +55 -0
  43. {regscale_cli-6.20.9.1.dist-info → regscale_cli-6.21.0.0.dist-info}/METADATA +1 -1
  44. {regscale_cli-6.20.9.1.dist-info → regscale_cli-6.21.0.0.dist-info}/RECORD +56 -49
  45. tests/fixtures/test_fixture.py +58 -2
  46. tests/regscale/core/test_app.py +5 -3
  47. tests/regscale/integrations/test_integration_mapping.py +522 -40
  48. tests/regscale/integrations/test_issue_due_date.py +1 -1
  49. tests/regscale/integrations/test_property_and_milestone_creation.py +684 -0
  50. tests/regscale/integrations/test_update_finding_dates.py +336 -0
  51. tests/regscale/models/test_asset.py +406 -50
  52. tests/regscale/models/test_report.py +105 -29
  53. {regscale_cli-6.20.9.1.dist-info → regscale_cli-6.21.0.0.dist-info}/LICENSE +0 -0
  54. {regscale_cli-6.20.9.1.dist-info → regscale_cli-6.21.0.0.dist-info}/WHEEL +0 -0
  55. {regscale_cli-6.20.9.1.dist-info → regscale_cli-6.21.0.0.dist-info}/entry_points.txt +0 -0
  56. {regscale_cli-6.20.9.1.dist-info → regscale_cli-6.21.0.0.dist-info}/top_level.txt +0 -0
@@ -28,7 +28,7 @@ from regscale.integrations.commercial.durosuite.variables import DuroSuiteVariab
28
28
  from regscale.integrations.commercial.stig_mapper_integration.mapping_engine import StigMappingEngine as STIGMapper
29
29
  from regscale.integrations.public.cisa import pull_cisa_kev
30
30
  from regscale.integrations.variables import ScannerVariables
31
- from regscale.models import DateTimeEncoder, OpenIssueDict, regscale_models
31
+ from regscale.models import DateTimeEncoder, OpenIssueDict, Property, regscale_models
32
32
  from regscale.utils.threading import ThreadSafeDict, ThreadSafeList
33
33
 
34
34
  logger = logging.getLogger(__name__)
@@ -407,7 +407,7 @@ class IntegrationFinding:
407
407
  issue_type: str = "Risk"
408
408
  date_created: str = dataclasses.field(default_factory=get_current_datetime)
409
409
  date_last_updated: str = dataclasses.field(default_factory=get_current_datetime)
410
- due_date: str = dataclasses.field(default_factory=lambda: date_str(days_from_today(60)))
410
+ due_date: str = "" # dataclasses.field(default_factory=lambda: date_str(days_from_today(60)))
411
411
  external_id: str = ""
412
412
  gaps: str = ""
413
413
  observations: str = ""
@@ -463,6 +463,9 @@ class IntegrationFinding:
463
463
  # Additional fields from Wiz integration
464
464
  vpr_score: Optional[float] = None
465
465
 
466
+ # Extra data field for miscellaneous data
467
+ extra_data: Dict[str, Any] = dataclasses.field(default_factory=dict)
468
+
466
469
  def __post_init__(self):
467
470
  """Validate and adjust types after initialization."""
468
471
  # Set default date values if empty
@@ -1646,25 +1649,34 @@ class ScannerIntegration(ABC):
1646
1649
  issue.dateLastUpdated = get_current_datetime()
1647
1650
 
1648
1651
  if finding.cve:
1649
- issue = self.lookup_kev_and_upate_issue(cve=finding.cve, issue=issue, cisa_kevs=self._kev_data)
1652
+ issue = self.lookup_kev_and_update_issue(cve=finding.cve, issue=issue, cisa_kevs=self._kev_data)
1650
1653
 
1651
1654
  if existing_issue:
1652
- logger.debug("Saving existing issue %s with assetIdentifier: %s", issue.id, issue.assetIdentifier)
1655
+ logger.debug("Saving Old Issue: %s with assetIdentifier: %s", issue.id, issue.assetIdentifier)
1653
1656
  issue.save(bulk=True)
1657
+ logger.debug("Saved existing issue %s with assetIdentifier: %s", issue.id, issue.assetIdentifier)
1658
+
1654
1659
  else:
1655
1660
  issue = issue.create_or_update(
1656
1661
  bulk_update=True, defaults={"otherIdentifier": self._get_other_identifier(finding, is_poam)}
1657
1662
  )
1663
+ self.extra_data_to_properties(finding, issue.id)
1658
1664
 
1659
- self._handle_property_creation_for_issue(issue, finding)
1665
+ self._handle_property_and_milestone_creation(issue, finding, existing_issue)
1660
1666
  return issue
1661
1667
 
1662
- def _handle_property_creation_for_issue(self, issue: regscale_models.Issue, finding: IntegrationFinding) -> None:
1668
+ def _handle_property_and_milestone_creation(
1669
+ self,
1670
+ issue: regscale_models.Issue,
1671
+ finding: IntegrationFinding,
1672
+ existing_issue: Optional[regscale_models.Issue] = None,
1673
+ ) -> None:
1663
1674
  """
1664
1675
  Handles property creation for an issue based on the finding data
1665
1676
 
1666
1677
  :param regscale_models.Issue issue: The issue to handle properties for
1667
1678
  :param IntegrationFinding finding: The finding data
1679
+ :param bool new_issue: Whether this is a new issue
1668
1680
  :rtype: None
1669
1681
  """
1670
1682
  if poc := finding.point_of_contact:
@@ -1685,6 +1697,74 @@ class ScannerIntegration(ABC):
1685
1697
  ).create_or_update()
1686
1698
  logger.debug("Added CWE property %s to issue %s", finding.plugin_id, issue.id)
1687
1699
 
1700
+ if ScannerVariables.useMilestones:
1701
+ if (
1702
+ existing_issue
1703
+ and existing_issue.status == regscale_models.IssueStatus.Closed
1704
+ and issue.status == regscale_models.IssueStatus.Open
1705
+ ):
1706
+ regscale_models.Milestone(
1707
+ title=f"Issue reopened from {self.title} scan",
1708
+ milestoneDate=get_current_datetime(),
1709
+ responsiblePersonId=self.assessor_id,
1710
+ parentID=issue.id,
1711
+ parentModule="issues",
1712
+ ).create_or_update()
1713
+ logger.debug("Added milestone for issue %s from finding %s", issue.id, finding.external_id)
1714
+ elif (
1715
+ existing_issue
1716
+ and existing_issue.status == regscale_models.IssueStatus.Open
1717
+ and issue.status == regscale_models.IssueStatus.Closed
1718
+ ):
1719
+ regscale_models.Milestone(
1720
+ title=f"Issue closed from {self.title} scan",
1721
+ milestoneDate=issue.dateCompleted,
1722
+ responsiblePersonId=self.assessor_id,
1723
+ parentID=issue.id,
1724
+ parentModule="issues",
1725
+ ).create_or_update()
1726
+ logger.debug("Added milestone for issue %s from finding %s", issue.id, finding.external_id)
1727
+ elif not existing_issue:
1728
+ regscale_models.Milestone(
1729
+ title=f"Issue created from {self.title} scan",
1730
+ milestoneDate=self.scan_date,
1731
+ responsiblePersonId=self.assessor_id,
1732
+ parentID=issue.id,
1733
+ parentModule="issues",
1734
+ ).create_or_update()
1735
+ logger.debug("Created milestone for issue %s from finding %s", issue.id, finding.external_id)
1736
+ else:
1737
+ logger.debug("No milestone created for issue %s from finding %s", issue.id, finding.external_id)
1738
+
1739
+ @staticmethod
1740
+ def extra_data_to_properties(finding: IntegrationFinding, issue_id: int) -> None:
1741
+ """
1742
+ Adds extra data to properties for an issue in a separate thread
1743
+
1744
+ :param IntegrationFinding finding: The finding data
1745
+ :param int issue_id: The ID of the issue
1746
+ :rtype: None
1747
+ """
1748
+
1749
+ def _create_property():
1750
+ """Create the property in a separate thread"""
1751
+ if not finding.extra_data:
1752
+ return
1753
+ try:
1754
+ Property(
1755
+ key="source_file_path",
1756
+ value=finding.extra_data.get("source_file_path"),
1757
+ parentId=issue_id,
1758
+ parentModule="issues",
1759
+ ).create()
1760
+ except Exception as exc:
1761
+ # Log any errors that occur in the thread
1762
+ logger.error(f"Error creating property for issue {issue_id}: {exc}")
1763
+
1764
+ # Start the property creation in a separate thread
1765
+ thread = threading.Thread(target=_create_property, daemon=True)
1766
+ thread.start()
1767
+
1688
1768
  @staticmethod
1689
1769
  def get_consolidated_asset_identifier(
1690
1770
  finding: IntegrationFinding,
@@ -1731,7 +1811,7 @@ class ScannerIntegration(ABC):
1731
1811
  return None
1732
1812
 
1733
1813
  @staticmethod
1734
- def lookup_kev_and_upate_issue(
1814
+ def lookup_kev_and_update_issue(
1735
1815
  cve: str, issue: regscale_models.Issue, cisa_kevs: Optional[ThreadSafeDict[str, Any]] = None
1736
1816
  ) -> regscale_models.Issue:
1737
1817
  """
@@ -1759,7 +1839,14 @@ class ScannerIntegration(ABC):
1759
1839
  None,
1760
1840
  )
1761
1841
  if kev_data:
1762
- issue.dueDate = convert_datetime_to_regscale_string(datetime.strptime(kev_data["dueDate"], "%Y-%m-%d"))
1842
+ # If kev due date is before the issue date created, add the difference to the date created
1843
+ calculated_due_date = ScannerIntegration._calculate_kev_due_date(kev_data, issue.dateCreated)
1844
+ if calculated_due_date:
1845
+ issue.dueDate = calculated_due_date
1846
+ else:
1847
+ issue.dueDate = convert_datetime_to_regscale_string(
1848
+ datetime.strptime(kev_data["dueDate"], "%Y-%m-%d")
1849
+ )
1763
1850
  issue.kevList = "Yes"
1764
1851
 
1765
1852
  return issue
@@ -2523,6 +2610,17 @@ class ScannerIntegration(ABC):
2523
2610
  issue.dateLastUpdated = get_current_datetime()
2524
2611
  issue.save()
2525
2612
 
2613
+ if ScannerVariables.useMilestones:
2614
+ regscale_models.Milestone(
2615
+ title=f"Issue closed from {self.title} scan",
2616
+ milestoneDate=issue.dateCompleted,
2617
+ responsiblePersonId=self.assessor_id,
2618
+ completed=True,
2619
+ parentID=issue.id,
2620
+ parentModule="issues",
2621
+ ).create_or_update()
2622
+ logger.debug("Created milestone for issue %s from %s tool", issue.id, self.title)
2623
+
2526
2624
  with count_lock:
2527
2625
  self.closed_count += 1
2528
2626
  if issue.controlImplementationIds:
@@ -2600,6 +2698,9 @@ class ScannerIntegration(ABC):
2600
2698
  """
2601
2699
  # Do not close issues from other tools
2602
2700
  if issue.sourceReport != self.title:
2701
+ logger.debug(
2702
+ "Skipping issue %d from different source: %s (expected: %s)", issue.id, issue.sourceReport, self.title
2703
+ )
2603
2704
  return False
2604
2705
 
2605
2706
  # If the issue has a vulnerability ID, check if it's still current for any asset
@@ -2611,14 +2712,19 @@ class ScannerIntegration(ABC):
2611
2712
 
2612
2713
  # Check if the issue's vulnerability is still current for any asset
2613
2714
  # If it is, we shouldn't close the issue
2614
- if any(
2615
- mapping.assetId in current_vulnerabilities
2616
- and issue.vulnerabilityId in current_vulnerabilities[mapping.assetId]
2617
- for mapping in vuln_mappings
2618
- ):
2619
- return False
2715
+ for mapping in vuln_mappings:
2716
+ if mapping.assetId in current_vulnerabilities:
2717
+ if issue.vulnerabilityId in current_vulnerabilities[mapping.assetId]:
2718
+ logger.debug(
2719
+ "Issue %d has current vulnerability %d for asset %d",
2720
+ issue.id,
2721
+ issue.vulnerabilityId,
2722
+ mapping.assetId,
2723
+ )
2724
+ return False
2620
2725
 
2621
2726
  # If we've checked all conditions and found no current vulnerabilities, we should close it
2727
+ logger.debug("Issue %d has no current vulnerabilities, marking for closure", issue.id)
2622
2728
  return True
2623
2729
 
2624
2730
  @staticmethod
@@ -2901,6 +3007,65 @@ class ScannerIntegration(ABC):
2901
3007
  finding.first_seen = self.scan_date
2902
3008
  return existing_vuln
2903
3009
 
3010
+ def _update_first_seen_date(
3011
+ self, finding: IntegrationFinding, existing_vuln: Optional[regscale_models.VulnerabilityMapping]
3012
+ ) -> None:
3013
+ """
3014
+ Update the first_seen date based on existing vulnerability mapping or scan date.
3015
+
3016
+ :param IntegrationFinding finding: The integration finding
3017
+ :param Optional[regscale_models.VulnerabilityMapping] existing_vuln: The existing vulnerability mapping
3018
+ :return: None
3019
+ :rtype: None
3020
+ """
3021
+ if existing_vuln and existing_vuln.firstSeen:
3022
+ finding.first_seen = existing_vuln.firstSeen
3023
+ elif not finding.first_seen:
3024
+ finding.first_seen = self.scan_date
3025
+
3026
+ def _update_date_created(self, finding: IntegrationFinding, issue: Optional[regscale_models.Issue]) -> None:
3027
+ """
3028
+ Update the date_created based on issue or scan date.
3029
+
3030
+ :param IntegrationFinding finding: The integration finding
3031
+ :param Optional[regscale_models.Issue] issue: The existing issue
3032
+ :return: None
3033
+ :rtype: None
3034
+ """
3035
+ if issue and issue.dateFirstDetected:
3036
+ finding.date_created = issue.dateFirstDetected
3037
+ elif not finding.date_created:
3038
+ finding.date_created = self.scan_date
3039
+
3040
+ def _update_due_date(self, finding: IntegrationFinding) -> None:
3041
+ """
3042
+ Update the due_date based on severity and configuration.
3043
+
3044
+ :param IntegrationFinding finding: The integration finding
3045
+ :return: None
3046
+ :rtype: None
3047
+ """
3048
+ finding.due_date = issue_due_date(
3049
+ severity=finding.severity,
3050
+ created_date=finding.date_created or self.scan_date,
3051
+ title=self.title,
3052
+ config=self.app.config,
3053
+ )
3054
+
3055
+ def _update_last_seen_date(self, finding: IntegrationFinding) -> None:
3056
+ """
3057
+ Update the last_seen date if scan date is after first_seen.
3058
+
3059
+ :param IntegrationFinding finding: The integration finding
3060
+ :return: None
3061
+ :rtype: None
3062
+ """
3063
+ scan_date = date_obj(self.scan_date)
3064
+ first_seen = date_obj(finding.first_seen)
3065
+
3066
+ if scan_date and first_seen and scan_date >= first_seen:
3067
+ finding.last_seen = self.scan_date
3068
+
2904
3069
  def update_finding_dates(
2905
3070
  self,
2906
3071
  finding: IntegrationFinding,
@@ -2916,28 +3081,17 @@ class ScannerIntegration(ABC):
2916
3081
  :return: The updated integration finding
2917
3082
  :rtype: IntegrationFinding
2918
3083
  """
2919
- if not finding.due_date:
2920
- if not existing_vuln:
2921
- finding.first_seen = self.scan_date
2922
- finding.date_created = self.scan_date
2923
- # From @mlongworth:
2924
- # It also appears that the suspense date (due date for remediation) is set based upon the import date rather
2925
- # than the scan date. This calculation needs to be based upon scan date e.g. scan date of 2/5/2024 severity
2926
- # High, should set the due date for remediation in the POA&M to 4/5/2024.
2927
- finding.due_date = issue_due_date(
2928
- severity=finding.severity,
2929
- created_date=finding.date_created or self.scan_date,
2930
- title=self.title,
2931
- config=self.app.config,
2932
- )
2933
- else:
2934
- finding.first_seen = existing_vuln.firstSeen if existing_vuln else finding.first_seen
2935
- if issue:
2936
- finding.date_created = issue.dateFirstDetected or finding.date_created
2937
- scan_date = date_obj(self.scan_date)
2938
- first_seen = date_obj(finding.first_seen)
2939
- if scan_date and first_seen and scan_date >= first_seen:
2940
- finding.last_seen = self.scan_date
3084
+ if finding.due_date:
3085
+ # If due_date is already set, only update last_seen if needed
3086
+ self._update_last_seen_date(finding)
3087
+ return finding
3088
+
3089
+ # Update dates for new findings
3090
+ self._update_first_seen_date(finding, existing_vuln)
3091
+ self._update_date_created(finding, issue)
3092
+ self._update_due_date(finding)
3093
+ self._update_last_seen_date(finding)
3094
+
2941
3095
  return finding
2942
3096
 
2943
3097
  def update_scan(self, scan_history: regscale_models.ScanHistory) -> None:
@@ -2991,7 +3145,9 @@ class ScannerIntegration(ABC):
2991
3145
  :rtype: None
2992
3146
  """
2993
3147
  # Method is deprecated - using update_control_implementation_status_after_close instead
2994
- pass
3148
+ logger.warning(
3149
+ "update_control_implementation_status is deprecated - using update_control_implementation_status_after_close instead"
3150
+ )
2995
3151
 
2996
3152
  def update_regscale_checklists(self, findings: List[IntegrationFinding]) -> int:
2997
3153
  """
@@ -3074,3 +3230,31 @@ class ScannerIntegration(ABC):
3074
3230
  impact=finding.impact,
3075
3231
  recommendationForMitigation=finding.recommendation_for_mitigation,
3076
3232
  ).create()
3233
+
3234
+ @staticmethod
3235
+ def _calculate_kev_due_date(kev_data: dict, issue_date_created: str) -> Optional[str]:
3236
+ """
3237
+ Calculate the due date for a KEV issue based on the difference between
3238
+ KEV due date and date added, then add that difference to the issue creation date.
3239
+
3240
+ :param dict kev_data: KEV data containing dueDate and dateAdded
3241
+ :param str issue_date_created: The issue creation date string
3242
+ :return: Calculated due date as a RegScale formatted string or None
3243
+ :rtype: Optional[str]
3244
+ """
3245
+ from datetime import datetime
3246
+
3247
+ from regscale.core.app.utils.app_utils import convert_datetime_to_regscale_string
3248
+
3249
+ if datetime.strptime(kev_data["dueDate"], "%Y-%m-%d") < datetime.strptime(
3250
+ issue_date_created, "%Y-%m-%d %H:%M:%S"
3251
+ ):
3252
+ # diff kev due date and kev dateAdded
3253
+ diff = datetime.strptime(kev_data["dueDate"], "%Y-%m-%d") - datetime.strptime(
3254
+ kev_data["dateAdded"], "%Y-%m-%d"
3255
+ )
3256
+ # add diff to issue.dateCreated
3257
+ return convert_datetime_to_regscale_string(
3258
+ datetime.strptime(issue_date_created, "%Y-%m-%d %H:%M:%S") + diff
3259
+ )
3260
+ return None
@@ -26,3 +26,4 @@ class ScannerVariables(metaclass=RsVariablesMeta):
26
26
  maxRetries: RsVariableType(int, "3", default=3, required=False) # type: ignore
27
27
  timeout: RsVariableType(int, "60", default=60, required=False) # type: ignore
28
28
  complianceCreation: RsVariableType(str, "Assessment|Issue|POAM", default="Assessment", required=False) # type: ignore # noqa: F722,F821
29
+ useMilestones: RsVariableType(bool, "true|false", default=False, required=False) # type: ignore # noqa: F722,F722,F821
@@ -3,18 +3,17 @@ AWS Inspector Scan information
3
3
  """
4
4
 
5
5
  import re
6
- from typing import List, Optional, Tuple
7
-
8
6
  from pathlib import Path
7
+ from typing import List, Optional, Tuple
9
8
 
10
9
  from regscale.core.app.application import Application
11
10
  from regscale.core.app.logz import create_logger
12
- from regscale.core.app.utils.app_utils import get_current_datetime, is_valid_fqdn
11
+ from regscale.core.app.utils.app_utils import is_valid_fqdn
12
+ from regscale.integrations.scanner_integration import IntegrationAsset, IntegrationFinding
13
13
  from regscale.models import ImportValidater
14
14
  from regscale.models.integration_models.amazon_models.inspector import InspectorRecord
15
15
  from regscale.models.integration_models.flat_file_importer import FlatFileImporter
16
- from regscale.models.regscale_models.asset import Asset
17
- from regscale.models.regscale_models.vulnerability import Vulnerability
16
+ from regscale.models.regscale_models import Asset, AssetStatus, IssueStatus, Vulnerability
18
17
 
19
18
 
20
19
  class InspectorScan(FlatFileImporter):
@@ -101,26 +100,17 @@ class InspectorScan(FlatFileImporter):
101
100
  # Container Image, Virtual Machine (VM), etc.
102
101
  asset_type = self.amazon_type_map().get(dat.resource_type, "Other")
103
102
 
104
- return Asset(
105
- **{
106
- "id": 0,
107
- "name": hostname,
108
- "awsIdentifier": hostname,
109
- "ipAddress": "",
110
- "isPublic": True,
111
- "status": "Active (On Network)",
112
- "assetCategory": "Hardware",
113
- "bLatestScan": True,
114
- "bAuthenticatedScan": True,
115
- "scanningTool": self.name,
116
- "assetOwnerId": self.config["userId"],
117
- "assetType": asset_type,
118
- "fqdn": hostname if is_valid_fqdn(hostname) else None,
119
- "operatingSystem": Asset.find_os(distro),
120
- "systemAdministratorId": self.config["userId"],
121
- "parentId": self.attributes.parent_id,
122
- "parentModule": self.attributes.parent_module,
123
- }
103
+ return IntegrationAsset(
104
+ identifier=hostname,
105
+ name=hostname,
106
+ ip_address="0.0.0.0",
107
+ cpu=0,
108
+ ram=0,
109
+ status=AssetStatus.Active.value,
110
+ asset_type=asset_type,
111
+ asset_category="Software",
112
+ operating_system=Asset.find_os(distro),
113
+ fqdn=hostname if is_valid_fqdn(hostname) else None,
124
114
  )
125
115
 
126
116
  def create_vuln(self, dat: Optional[InspectorRecord] = None, **kwargs) -> Optional[Vulnerability]:
@@ -132,44 +122,29 @@ class InspectorScan(FlatFileImporter):
132
122
  :rtype: Optional[Vulnerability]
133
123
  """
134
124
  hostname = dat.resource_id
135
- distro = dat.platform
136
125
  cve: str = dat.vulnerability_id
137
126
  description: str = dat.description
138
127
  title = dat.title if dat.title else dat.description
139
128
  aws_severity = dat.severity
140
129
  severity = self.severity_mapper(aws_severity)
141
- config = self.attributes.app.config
142
- asset_match = [asset for asset in self.data["assets"] if asset.name == hostname]
143
- asset = asset_match[0] if asset_match else None
144
- if dat and asset_match:
145
- return Vulnerability(
146
- id=0,
147
- scanId=0, # set later
148
- parentId=asset.id,
149
- parentModule="assets",
150
- ipAddress="0.0.0.0", # No ip address available
151
- lastSeen=dat.last_seen,
152
- firstSeen=dat.first_seen,
153
- daysOpen=None,
154
- dns=hostname,
155
- mitigated=None,
156
- operatingSystem=(Asset.find_os(distro) if Asset.find_os(distro) else None),
157
- severity=severity,
158
- plugInName=dat.title,
159
- plugInId=self.convert_cve_string_to_int(dat.vulnerability_id),
160
- cve=cve,
161
- vprScore=None,
162
- tenantsId=0,
163
- title=f"{description} on asset {asset.name}",
130
+ if dat:
131
+ return IntegrationFinding(
132
+ title=title,
164
133
  description=description,
165
- plugInText=title,
166
- createdById=config["userId"],
167
- lastUpdatedById=config["userId"],
168
- dateCreated=get_current_datetime(),
169
- extra_data={
170
- "solution": dat.remediation,
171
- "proof": dat.finding_arn,
172
- },
134
+ severity=self.determine_severity(severity),
135
+ status=IssueStatus.Open.value,
136
+ ip_address="0.0.0.0",
137
+ plugin_text=title,
138
+ plugin_name=dat.title,
139
+ plugin_id=self.convert_cve_string_to_int(dat.vulnerability_id),
140
+ asset_identifier=hostname,
141
+ remediation=dat.remediation,
142
+ cve=cve,
143
+ first_seen=dat.first_seen,
144
+ last_seen=dat.last_seen,
145
+ scan_date=self.scan_date,
146
+ category="Software",
147
+ control_labels=[],
173
148
  )
174
149
  return None
175
150