conviso-ast 3.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.
Files changed (128) hide show
  1. conviso_ast-3.0.0.data/scripts/flow_bash_completer.sh +21 -0
  2. conviso_ast-3.0.0.data/scripts/flow_fish_completer.fish +1 -0
  3. conviso_ast-3.0.0.data/scripts/flow_zsh_completer.sh +32 -0
  4. conviso_ast-3.0.0.dist-info/METADATA +37 -0
  5. conviso_ast-3.0.0.dist-info/RECORD +128 -0
  6. conviso_ast-3.0.0.dist-info/WHEEL +5 -0
  7. conviso_ast-3.0.0.dist-info/entry_points.txt +3 -0
  8. conviso_ast-3.0.0.dist-info/top_level.txt +1 -0
  9. convisoappsec/__init__.py +0 -0
  10. convisoappsec/common/__init__.py +5 -0
  11. convisoappsec/common/box.py +251 -0
  12. convisoappsec/common/cleaner.py +78 -0
  13. convisoappsec/common/docker.py +399 -0
  14. convisoappsec/common/exceptions.py +8 -0
  15. convisoappsec/common/git_data_parser.py +76 -0
  16. convisoappsec/common/graphql/__init__.py +0 -0
  17. convisoappsec/common/graphql/error_handlers.py +75 -0
  18. convisoappsec/common/graphql/errors.py +16 -0
  19. convisoappsec/common/graphql/low_client.py +51 -0
  20. convisoappsec/common/retry_handler.py +40 -0
  21. convisoappsec/common/strings.py +8 -0
  22. convisoappsec/flow/__init__.py +3 -0
  23. convisoappsec/flow/api.py +104 -0
  24. convisoappsec/flow/cleaner.py +118 -0
  25. convisoappsec/flow/graphql_api/__init__.py +0 -0
  26. convisoappsec/flow/graphql_api/beta/__init__.py +0 -0
  27. convisoappsec/flow/graphql_api/beta/client.py +18 -0
  28. convisoappsec/flow/graphql_api/beta/models/__init__.py +0 -0
  29. convisoappsec/flow/graphql_api/beta/models/issues/__init__.py +0 -0
  30. convisoappsec/flow/graphql_api/beta/models/issues/container.py +72 -0
  31. convisoappsec/flow/graphql_api/beta/models/issues/iac.py +6 -0
  32. convisoappsec/flow/graphql_api/beta/models/issues/normalize.py +13 -0
  33. convisoappsec/flow/graphql_api/beta/models/issues/sast.py +53 -0
  34. convisoappsec/flow/graphql_api/beta/models/issues/sca.py +78 -0
  35. convisoappsec/flow/graphql_api/beta/resources_api.py +142 -0
  36. convisoappsec/flow/graphql_api/beta/schemas/__init__.py +0 -0
  37. convisoappsec/flow/graphql_api/beta/schemas/mutations/__init__.py +61 -0
  38. convisoappsec/flow/graphql_api/beta/schemas/resolvers/__init__.py +0 -0
  39. convisoappsec/flow/graphql_api/v1/__init__.py +0 -0
  40. convisoappsec/flow/graphql_api/v1/client.py +46 -0
  41. convisoappsec/flow/graphql_api/v1/models/__init__.py +0 -0
  42. convisoappsec/flow/graphql_api/v1/models/asset.py +14 -0
  43. convisoappsec/flow/graphql_api/v1/models/issues.py +16 -0
  44. convisoappsec/flow/graphql_api/v1/models/project.py +35 -0
  45. convisoappsec/flow/graphql_api/v1/resources_api.py +489 -0
  46. convisoappsec/flow/graphql_api/v1/schemas/__init__.py +0 -0
  47. convisoappsec/flow/graphql_api/v1/schemas/mutations/__init__.py +212 -0
  48. convisoappsec/flow/graphql_api/v1/schemas/resolvers/__init__.py +180 -0
  49. convisoappsec/flow/source_code_scanner/__init__.py +9 -0
  50. convisoappsec/flow/source_code_scanner/exceptions.py +2 -0
  51. convisoappsec/flow/source_code_scanner/scc.py +68 -0
  52. convisoappsec/flow/source_code_scanner/source_code_scanner.py +177 -0
  53. convisoappsec/flow/util/__init__.py +7 -0
  54. convisoappsec/flow/util/ci_provider.py +99 -0
  55. convisoappsec/flow/util/metrics.py +16 -0
  56. convisoappsec/flow/util/source_code_compressor.py +22 -0
  57. convisoappsec/flow/version_control_system_adapter.py +528 -0
  58. convisoappsec/flow/version_searchers/__init__.py +9 -0
  59. convisoappsec/flow/version_searchers/sorted_by_versioning_style.py +85 -0
  60. convisoappsec/flow/version_searchers/timebased_version_seacher.py +39 -0
  61. convisoappsec/flow/version_searchers/version_searcher_result.py +33 -0
  62. convisoappsec/flow/versioning_style/__init__.py +0 -0
  63. convisoappsec/flow/versioning_style/semantic_versioning.py +44 -0
  64. convisoappsec/flowcli/__init__.py +3 -0
  65. convisoappsec/flowcli/__main__.py +4 -0
  66. convisoappsec/flowcli/assets/__init__.py +4 -0
  67. convisoappsec/flowcli/assets/create.py +88 -0
  68. convisoappsec/flowcli/assets/entrypoint.py +20 -0
  69. convisoappsec/flowcli/assets/ls.py +63 -0
  70. convisoappsec/flowcli/ast/__init__.py +3 -0
  71. convisoappsec/flowcli/ast/entrypoint.py +427 -0
  72. convisoappsec/flowcli/common.py +175 -0
  73. convisoappsec/flowcli/companies/__init__.py +0 -0
  74. convisoappsec/flowcli/companies/ls.py +25 -0
  75. convisoappsec/flowcli/container/__init__.py +3 -0
  76. convisoappsec/flowcli/container/entrypoint.py +17 -0
  77. convisoappsec/flowcli/container/run.py +306 -0
  78. convisoappsec/flowcli/context.py +49 -0
  79. convisoappsec/flowcli/deploy/__init__.py +0 -0
  80. convisoappsec/flowcli/deploy/create/__init__.py +4 -0
  81. convisoappsec/flowcli/deploy/create/context.py +12 -0
  82. convisoappsec/flowcli/deploy/create/entrypoint.py +31 -0
  83. convisoappsec/flowcli/deploy/create/with_/__init__.py +3 -0
  84. convisoappsec/flowcli/deploy/create/with_/entrypoint.py +20 -0
  85. convisoappsec/flowcli/deploy/create/with_/tag_tracker/__init__.py +4 -0
  86. convisoappsec/flowcli/deploy/create/with_/tag_tracker/context.py +11 -0
  87. convisoappsec/flowcli/deploy/create/with_/tag_tracker/entrypoint.py +30 -0
  88. convisoappsec/flowcli/deploy/create/with_/tag_tracker/sort_by/__init__.py +4 -0
  89. convisoappsec/flowcli/deploy/create/with_/tag_tracker/sort_by/entrypoint.py +21 -0
  90. convisoappsec/flowcli/deploy/create/with_/tag_tracker/sort_by/time_.py +84 -0
  91. convisoappsec/flowcli/deploy/create/with_/tag_tracker/sort_by/versioning_style.py +115 -0
  92. convisoappsec/flowcli/deploy/create/with_/values.py +133 -0
  93. convisoappsec/flowcli/entrypoint.py +103 -0
  94. convisoappsec/flowcli/environment_checker.py +45 -0
  95. convisoappsec/flowcli/findings/__init__.py +4 -0
  96. convisoappsec/flowcli/findings/create/__init__.py +4 -0
  97. convisoappsec/flowcli/findings/create/entrypoint.py +18 -0
  98. convisoappsec/flowcli/findings/create/with_/__init__.py +3 -0
  99. convisoappsec/flowcli/findings/create/with_/entrypoint.py +19 -0
  100. convisoappsec/flowcli/findings/create/with_/version_tracker.py +93 -0
  101. convisoappsec/flowcli/findings/entrypoint.py +19 -0
  102. convisoappsec/flowcli/findings/import_sarif/__init__.py +4 -0
  103. convisoappsec/flowcli/findings/import_sarif/entrypoint.py +430 -0
  104. convisoappsec/flowcli/help_option.py +18 -0
  105. convisoappsec/flowcli/iac/__init__.py +3 -0
  106. convisoappsec/flowcli/iac/entrypoint.py +17 -0
  107. convisoappsec/flowcli/iac/run.py +328 -0
  108. convisoappsec/flowcli/requirements_verifier.py +132 -0
  109. convisoappsec/flowcli/sast/__init__.py +3 -0
  110. convisoappsec/flowcli/sast/entrypoint.py +17 -0
  111. convisoappsec/flowcli/sast/run.py +485 -0
  112. convisoappsec/flowcli/sbom/__init__.py +3 -0
  113. convisoappsec/flowcli/sbom/entrypoint.py +17 -0
  114. convisoappsec/flowcli/sbom/generate.py +235 -0
  115. convisoappsec/flowcli/sca/__init__.py +3 -0
  116. convisoappsec/flowcli/sca/entrypoint.py +17 -0
  117. convisoappsec/flowcli/sca/run.py +479 -0
  118. convisoappsec/flowcli/vulnerability/__init__.py +3 -0
  119. convisoappsec/flowcli/vulnerability/assert_security_rules.py +201 -0
  120. convisoappsec/flowcli/vulnerability/container_vulnerability_manager.py +175 -0
  121. convisoappsec/flowcli/vulnerability/entrypoint.py +18 -0
  122. convisoappsec/flowcli/vulnerability/rules_schema.json +53 -0
  123. convisoappsec/flowcli/vulnerability/run.py +487 -0
  124. convisoappsec/logger.py +29 -0
  125. convisoappsec/sast/__init__.py +0 -0
  126. convisoappsec/sast/decision.py +45 -0
  127. convisoappsec/sast/sastbox.py +296 -0
  128. convisoappsec/version.py +1 -0
@@ -0,0 +1,175 @@
1
+ import click
2
+ import json
3
+ import hashlib
4
+ from convisoappsec.flowcli.context import pass_flow_context
5
+ from convisoappsec.common.graphql.errors import ResponseError
6
+
7
+ class ContainerVulnerabilityManager:
8
+ """
9
+ Manages the lifecycle of vulnerabilities detected in container/image scans, including closing and reopening.
10
+ """
11
+
12
+ def __init__(self):
13
+ pass
14
+
15
+ def close_vulnerability(self):
16
+ """
17
+ Close vulnerabilities on conviso platform when is not detected anymore.
18
+ """
19
+ result_file = "result.json"
20
+ hash_issues = []
21
+
22
+ log_func("Running automatic closure of vulnerabilities for image/container...")
23
+
24
+ try:
25
+ with open(result_file, 'r') as file:
26
+ data = json.load(file)
27
+ results = data.get('Results', [])
28
+
29
+ for result in results:
30
+ if 'Vulnerabilities' in result and isinstance(result['Vulnerabilities'], list):
31
+ for vulnerability in result['Vulnerabilities']:
32
+ title = vulnerability.get('Title', '')
33
+ description = vulnerability.get('Description', '')
34
+ severity = vulnerability.get('Severity', '')
35
+ cve = vulnerability.get('VulnerabilityID', '')
36
+ package_name = vulnerability.get('PkgName', '')
37
+
38
+ hash_value = generate_hash_issue(title, description, severity, cve, package_name)
39
+ hash_issues.append(hash_value)
40
+ except FileNotFoundError:
41
+ print(f"Error: The file '{result_file}' was not found.")
42
+ except json.JSONDecodeError:
43
+ print(f"Error: Could not decode JSON from '{result_file}'. Check file format.")
44
+ except Exception as e:
45
+ print(f"An unexpected error occurred: {e}")
46
+
47
+ issues_from_conviso = fetch_and_merge_conviso_issues()
48
+
49
+ if len(issues_from_conviso) == 0:
50
+ log_func("No vulnerabilities were found on the Conviso Platform!")
51
+ return None
52
+
53
+ issues_with_fix_accepted = [item for item in issues_from_conviso if item['status'] == 'FIX_ACCEPTED']
54
+ issues_without_fix_accepted = [item for item in issues_from_conviso if item['status'] != 'FIX_ACCEPTED']
55
+ set_of_hash_issues = set(hash_issues)
56
+
57
+ close_issues(issues_from_cp=issues_without_fix_accepted, issues_from_current_scan=set_of_hash_issues)
58
+ reopen_vulnerability(issues_with_fix_accepted=issues_with_fix_accepted, hash_issues=set_of_hash_issues)
59
+
60
+ return None
61
+
62
+ def generate_hash_issue(title, description, severity, cve, package_name):
63
+ """
64
+ Generates a SHA256 hash based on the provided vulnerability details.
65
+ """
66
+
67
+ concatenated_string = f"{title}{description}{severity}{cve}{package_name}"
68
+
69
+ return hashlib.sha256(concatenated_string.encode('utf-8')).hexdigest()
70
+
71
+ @pass_flow_context
72
+ def close_issues(flow_context, issues_from_cp, issues_from_current_scan):
73
+ """
74
+ method to close container issues on conviso platform
75
+
76
+ # issues_from_cp are issues already on conviso platform.
77
+ # issues_from_current_scan are issues identify on each time the ast command runs, these are always from a full code
78
+ base scan
79
+ """
80
+ conviso_api = flow_context.create_conviso_api_client_beta()
81
+ differences = [
82
+ {'id': item['id'], 'originalIssueIdFromTool': item['originalIssueIdFromTool']}
83
+ for item in issues_from_cp if item['originalIssueIdFromTool'] not in issues_from_current_scan
84
+ ]
85
+
86
+ if len(differences) == 0:
87
+ log_func("No vulnerabilities have been fixed yet...")
88
+ return
89
+
90
+ log_func("Container: Fixing {issues} vulnerabilities on the Conviso Platform...".format(issues=len(differences)))
91
+
92
+ for issue in differences:
93
+ issue_id = issue['id']
94
+ status = 'FIX_ACCEPTED'
95
+ reason = ("The vulnerability is no longer found in the specified image. Its status has been updated by "
96
+ "Conviso AST")
97
+
98
+ conviso_api.issues.update_issue_status(issue_id=issue_id, status=status, reason=reason)
99
+
100
+ @pass_flow_context
101
+ def reopen_vulnerability(flow_context, issues_with_fix_accepted, hash_issues):
102
+ """
103
+ Reopen vulnerabilities on conviso platform when is detected and already exists on conviso platform and
104
+ was fixed in other moment.
105
+ """
106
+ conviso_api = flow_context.create_conviso_api_client_beta()
107
+
108
+ issues_to_reopen = [
109
+ {'id': item['id'], 'originalIssueIdFromTool': item['originalIssueIdFromTool']}
110
+ for item in issues_with_fix_accepted if item['originalIssueIdFromTool'] in hash_issues
111
+ ]
112
+
113
+ if issues_to_reopen:
114
+ log_func("Container: Reopening {issues} vulnerability/vulnerabilities on conviso platform ...".format(
115
+ issues=len(issues_to_reopen))
116
+ )
117
+
118
+ for issue in issues_to_reopen:
119
+ issue_id = issue['id']
120
+ status = 'IDENTIFIED'
121
+ reason = 'Status has been updated from Fixed to Identified by Conviso AST'
122
+
123
+ conviso_api.issues.update_issue_status(issue_id=issue_id, status=status, reason=reason)
124
+
125
+ @pass_flow_context
126
+ @click.pass_context
127
+ def fetch_and_merge_conviso_issues(context, flow_context):
128
+ page = 1
129
+ conviso_api = flow_context.create_conviso_api_client_beta()
130
+ company_id = context.params['company_id']
131
+ asset_id = context.params['asset_id']
132
+ statuses = ['CREATED', 'IDENTIFIED', 'IN_PROGRESS', 'AWAITING_VALIDATION', 'FIX_ACCEPTED']
133
+ merged_issues = []
134
+
135
+ while True:
136
+ try:
137
+ issues_from_cp = conviso_api.issues.auto_close_vulnerabilities(
138
+ company_id, asset_id, statuses, page, vulnerability_type='CONTAINER_FINDING'
139
+ )
140
+ except ResponseError as error:
141
+ if 'Variable $company_id' in str(error):
142
+ log_func(f"Invalid company_id passed: {company_id}", fg='red')
143
+ else:
144
+ log_func(f"error: {error}", fg='red')
145
+
146
+ log_func(
147
+ "⚠️ Auto-close will not be performed at this time. "
148
+ "Please set it using --company-id and try again.",
149
+ fg='red'
150
+ )
151
+ return None
152
+
153
+ total_pages = issues_from_cp['metadata']['totalPages']
154
+ issues_collection = issues_from_cp['collection']
155
+
156
+ issues_collection = [
157
+ item for item in issues_collection
158
+ if item.get('scanSource') == 'conviso_scanner'
159
+ ]
160
+ container_issues = [
161
+ item for item in issues_collection
162
+ if item.get('type') == 'CONTAINER_FINDING'
163
+ ]
164
+
165
+ if container_issues:
166
+ merged_issues.extend(container_issues)
167
+
168
+ if page >= total_pages:
169
+ break
170
+ page += 1
171
+
172
+ return merged_issues
173
+
174
+ def log_func(msg, new_line=True, fg='white'):
175
+ click.echo(click.style(msg, bold=True, fg=fg), nl=new_line, err=True)
@@ -0,0 +1,18 @@
1
+ import click
2
+ from convisoappsec.flowcli import help_option
3
+ from .assert_security_rules import assert_security_rules
4
+ from .run import run
5
+
6
+
7
+ @click.group()
8
+ @help_option
9
+ def vulnerability():
10
+ pass
11
+
12
+
13
+ vulnerability.add_command(assert_security_rules)
14
+ vulnerability.add_command(run)
15
+
16
+ vulnerability.epilog = '''
17
+ Run flow vulnerability COMMAND --help for more information on a command.
18
+ '''
@@ -0,0 +1,53 @@
1
+ {
2
+ "definitions": {
3
+ "criticity": {
4
+ "type": "object",
5
+ "required": [
6
+ "maximum"
7
+ ],
8
+ "properties": {
9
+ "maximum": {
10
+ "type": "integer",
11
+ "minimum": 0
12
+ }
13
+ }
14
+ },
15
+ "severity": {
16
+ "type": "object",
17
+ "minProperties": 1,
18
+ "patternProperties": {
19
+ "^(critical|high|medium|low)$": {
20
+ "$ref": "#/definitions/criticity"
21
+ }
22
+ },
23
+ "additionalProperties": false
24
+ }
25
+ },
26
+ "type": "object",
27
+ "required": [
28
+ "rules"
29
+ ],
30
+ "properties": {
31
+ "rules": {
32
+ "type": "array",
33
+ "default": [],
34
+ "items": {
35
+ "type": "object",
36
+ "required": [
37
+ "from",
38
+ "severity"
39
+ ],
40
+ "properties": {
41
+ "from": {
42
+ "enum": [
43
+ "any"
44
+ ]
45
+ },
46
+ "severity": {
47
+ "$ref": "#/definitions/severity"
48
+ }
49
+ }
50
+ }
51
+ }
52
+ }
53
+ }