boman-cli 2.4.7__tar.gz → 2.4.8__tar.gz
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.
- {boman-cli-2.4.7 → boman_cli-2.4.8}/PKG-INFO +15 -5
- {boman-cli-2.4.7 → boman_cli-2.4.8}/README.md +8 -1
- {boman-cli-2.4.7 → boman_cli-2.4.8}/boman_cli.egg-info/PKG-INFO +15 -5
- {boman-cli-2.4.7 → boman_cli-2.4.8}/boman_cli.egg-info/entry_points.txt +0 -1
- {boman-cli-2.4.7 → boman_cli-2.4.8}/bomancli/Config.py +27 -2
- {boman-cli-2.4.7 → boman_cli-2.4.8}/bomancli/auth.py +19 -1
- {boman-cli-2.4.7 → boman_cli-2.4.8}/bomancli/main.py +225 -92
- {boman-cli-2.4.7 → boman_cli-2.4.8}/bomancli/templates/template_plan.yaml +139 -139
- {boman-cli-2.4.7 → boman_cli-2.4.8}/bomancli/utils.py +102 -0
- {boman-cli-2.4.7 → boman_cli-2.4.8}/bomancli/validation.py +31 -9
- {boman-cli-2.4.7 → boman_cli-2.4.8}/setup.cfg +3 -2
- {boman-cli-2.4.7 → boman_cli-2.4.8}/boman_cli.egg-info/SOURCES.txt +0 -0
- {boman-cli-2.4.7 → boman_cli-2.4.8}/boman_cli.egg-info/dependency_links.txt +0 -0
- {boman-cli-2.4.7 → boman_cli-2.4.8}/boman_cli.egg-info/requires.txt +3 -3
- {boman-cli-2.4.7 → boman_cli-2.4.8}/boman_cli.egg-info/top_level.txt +0 -0
- {boman-cli-2.4.7 → boman_cli-2.4.8}/bomancli/_init_.py +0 -0
- {boman-cli-2.4.7 → boman_cli-2.4.8}/bomancli/base_logger.py +0 -0
- {boman-cli-2.4.7 → boman_cli-2.4.8}/bomancli/loc_finder.py +0 -0
- {boman-cli-2.4.7 → boman_cli-2.4.8}/setup.py +0 -0
|
@@ -1,17 +1,22 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: boman-cli
|
|
3
|
-
Version: 2.4.
|
|
3
|
+
Version: 2.4.8
|
|
4
4
|
Summary: CLI tool of boman.ai
|
|
5
5
|
Home-page: https://boman.ai
|
|
6
6
|
Author: Sumeru Software Solutions Pvt. Ltd.
|
|
7
7
|
Author-email: support@boman.ai
|
|
8
8
|
License: BSD 2-clause
|
|
9
|
-
Platform: UNKNOWN
|
|
10
9
|
Classifier: Development Status :: 5 - Production/Stable
|
|
11
10
|
Classifier: Intended Audience :: Developers
|
|
12
11
|
Classifier: License :: OSI Approved :: BSD License
|
|
13
12
|
Classifier: Operating System :: OS Independent
|
|
14
13
|
Description-Content-Type: text/markdown
|
|
14
|
+
Requires-Dist: docker<=7.0.0
|
|
15
|
+
Requires-Dist: requests<=2.31.0
|
|
16
|
+
Requires-Dist: pyyaml
|
|
17
|
+
Requires-Dist: coloredlogs<=15.0.1
|
|
18
|
+
Requires-Dist: xmltodict<=0.13.0
|
|
19
|
+
Requires-Dist: pyfiglet<=1.0.2
|
|
15
20
|
|
|
16
21
|
# Introduction
|
|
17
22
|
Boman CLI is a Orchestration script written in python to run security scans on the local or CI/CD environment and upload the results to Boman.ai SaaS server.
|
|
@@ -95,11 +100,18 @@ Example: boman-cli -a run -zap_session_script ./session.js
|
|
|
95
100
|
|
|
96
101
|
### Release Note:
|
|
97
102
|
|
|
103
|
+
### 2.4.8
|
|
104
|
+
- **New:** Semgrep pro (API) integration. Navigate to **Integrations -> Semgrep pro/api** in the Boman SaaS to setup Semgrep pro.
|
|
105
|
+
|
|
106
|
+
- **New:** Reachability analysis for SCA enabled.
|
|
107
|
+
|
|
108
|
+
- **Feature Request:** when Failbuild is configured. Boman should not take false positive, Accepted Risk, Not applicable and Muted vulnerabilities into account.
|
|
109
|
+
|
|
98
110
|
### V2.4.7
|
|
99
111
|
- **BUG:** Failing build if token is not configured.
|
|
100
112
|
|
|
101
113
|
### V2.4.6
|
|
102
|
-
- **New:** Semgrep
|
|
114
|
+
- **New:** Semgrep CLI integration. Pass the semgrep token as -semgrep_token {value}.
|
|
103
115
|
|
|
104
116
|
### V2.4.5
|
|
105
117
|
- **New:** Snyk API integration. Navigate to **Integrations -> Snyk** in the Boman SaaS to setup Snyk.
|
|
@@ -165,5 +177,3 @@ Released on: 21 May 2024
|
|
|
165
177
|
|
|
166
178
|
|
|
167
179
|
|
|
168
|
-
|
|
169
|
-
|
|
@@ -80,11 +80,18 @@ Example: boman-cli -a run -zap_session_script ./session.js
|
|
|
80
80
|
|
|
81
81
|
### Release Note:
|
|
82
82
|
|
|
83
|
+
### 2.4.8
|
|
84
|
+
- **New:** Semgrep pro (API) integration. Navigate to **Integrations -> Semgrep pro/api** in the Boman SaaS to setup Semgrep pro.
|
|
85
|
+
|
|
86
|
+
- **New:** Reachability analysis for SCA enabled.
|
|
87
|
+
|
|
88
|
+
- **Feature Request:** when Failbuild is configured. Boman should not take false positive, Accepted Risk, Not applicable and Muted vulnerabilities into account.
|
|
89
|
+
|
|
83
90
|
### V2.4.7
|
|
84
91
|
- **BUG:** Failing build if token is not configured.
|
|
85
92
|
|
|
86
93
|
### V2.4.6
|
|
87
|
-
- **New:** Semgrep
|
|
94
|
+
- **New:** Semgrep CLI integration. Pass the semgrep token as -semgrep_token {value}.
|
|
88
95
|
|
|
89
96
|
### V2.4.5
|
|
90
97
|
- **New:** Snyk API integration. Navigate to **Integrations -> Snyk** in the Boman SaaS to setup Snyk.
|
|
@@ -1,17 +1,22 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: boman-cli
|
|
3
|
-
Version: 2.4.
|
|
3
|
+
Version: 2.4.8
|
|
4
4
|
Summary: CLI tool of boman.ai
|
|
5
5
|
Home-page: https://boman.ai
|
|
6
6
|
Author: Sumeru Software Solutions Pvt. Ltd.
|
|
7
7
|
Author-email: support@boman.ai
|
|
8
8
|
License: BSD 2-clause
|
|
9
|
-
Platform: UNKNOWN
|
|
10
9
|
Classifier: Development Status :: 5 - Production/Stable
|
|
11
10
|
Classifier: Intended Audience :: Developers
|
|
12
11
|
Classifier: License :: OSI Approved :: BSD License
|
|
13
12
|
Classifier: Operating System :: OS Independent
|
|
14
13
|
Description-Content-Type: text/markdown
|
|
14
|
+
Requires-Dist: docker<=7.0.0
|
|
15
|
+
Requires-Dist: requests<=2.31.0
|
|
16
|
+
Requires-Dist: pyyaml
|
|
17
|
+
Requires-Dist: coloredlogs<=15.0.1
|
|
18
|
+
Requires-Dist: xmltodict<=0.13.0
|
|
19
|
+
Requires-Dist: pyfiglet<=1.0.2
|
|
15
20
|
|
|
16
21
|
# Introduction
|
|
17
22
|
Boman CLI is a Orchestration script written in python to run security scans on the local or CI/CD environment and upload the results to Boman.ai SaaS server.
|
|
@@ -95,11 +100,18 @@ Example: boman-cli -a run -zap_session_script ./session.js
|
|
|
95
100
|
|
|
96
101
|
### Release Note:
|
|
97
102
|
|
|
103
|
+
### 2.4.8
|
|
104
|
+
- **New:** Semgrep pro (API) integration. Navigate to **Integrations -> Semgrep pro/api** in the Boman SaaS to setup Semgrep pro.
|
|
105
|
+
|
|
106
|
+
- **New:** Reachability analysis for SCA enabled.
|
|
107
|
+
|
|
108
|
+
- **Feature Request:** when Failbuild is configured. Boman should not take false positive, Accepted Risk, Not applicable and Muted vulnerabilities into account.
|
|
109
|
+
|
|
98
110
|
### V2.4.7
|
|
99
111
|
- **BUG:** Failing build if token is not configured.
|
|
100
112
|
|
|
101
113
|
### V2.4.6
|
|
102
|
-
- **New:** Semgrep
|
|
114
|
+
- **New:** Semgrep CLI integration. Pass the semgrep token as -semgrep_token {value}.
|
|
103
115
|
|
|
104
116
|
### V2.4.5
|
|
105
117
|
- **New:** Snyk API integration. Navigate to **Integrations -> Snyk** in the Boman SaaS to setup Snyk.
|
|
@@ -165,5 +177,3 @@ Released on: 21 May 2024
|
|
|
165
177
|
|
|
166
178
|
|
|
167
179
|
|
|
168
|
-
|
|
169
|
-
|
|
@@ -91,6 +91,7 @@ class Config:
|
|
|
91
91
|
secret_scan_status = None
|
|
92
92
|
secret_scan_upload_status = None
|
|
93
93
|
secret_scan_errors = None
|
|
94
|
+
secret_scan_lang = None
|
|
94
95
|
|
|
95
96
|
|
|
96
97
|
jenkins = None
|
|
@@ -120,7 +121,7 @@ class Config:
|
|
|
120
121
|
|
|
121
122
|
log_level = "INFO"
|
|
122
123
|
|
|
123
|
-
version = 'v2.4.
|
|
124
|
+
version = 'v2.4.8'
|
|
124
125
|
|
|
125
126
|
boman_config_file = 'boman.yaml'
|
|
126
127
|
|
|
@@ -165,6 +166,7 @@ class Config:
|
|
|
165
166
|
sbom_upload_status=None
|
|
166
167
|
sbom_scan_status=None
|
|
167
168
|
sbom_target=None
|
|
169
|
+
sbom_output_file=None
|
|
168
170
|
|
|
169
171
|
#IAC scanning
|
|
170
172
|
iac_scan_present=None
|
|
@@ -189,4 +191,27 @@ class Config:
|
|
|
189
191
|
iac_scan_configuration = None
|
|
190
192
|
semgrep_token = None
|
|
191
193
|
|
|
192
|
-
dast_adv_auth_enabled = None
|
|
194
|
+
dast_adv_auth_enabled = None
|
|
195
|
+
|
|
196
|
+
supported_languages_reachability =[
|
|
197
|
+
"js",
|
|
198
|
+
"python",
|
|
199
|
+
"php",
|
|
200
|
+
"java",
|
|
201
|
+
"ruby",
|
|
202
|
+
"c",
|
|
203
|
+
"c++"
|
|
204
|
+
]
|
|
205
|
+
|
|
206
|
+
reachability_present=None
|
|
207
|
+
reachability_build_dir=None
|
|
208
|
+
reachability_message=None
|
|
209
|
+
reachability_response=None
|
|
210
|
+
reachability_errors=None
|
|
211
|
+
reachability_upload_status=None
|
|
212
|
+
reachability_status=None
|
|
213
|
+
reachability_language=None
|
|
214
|
+
|
|
215
|
+
fail_build = False
|
|
216
|
+
polling_time = 60
|
|
217
|
+
polling_frequency = 10
|
|
@@ -164,7 +164,25 @@ def authorize():
|
|
|
164
164
|
Config.scan_name = json_response['data']['scan_name']
|
|
165
165
|
Config.con_scan_response = json_response['data']['cs']
|
|
166
166
|
Config.sbom_response = json_response['data']['sbom']
|
|
167
|
-
Config.iac_scan_response = json_response['data']['iac']
|
|
167
|
+
Config.iac_scan_response = json_response['data']['iac']
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
if 'reachability' in json_response['data'].keys():
|
|
171
|
+
Config.reachability_response = json_response['data']['reachability']
|
|
172
|
+
if 'code_language' in json_response.keys():
|
|
173
|
+
Config.reachability_language = json_response['code_language']
|
|
174
|
+
if Utils.reachability_support_check(Config.reachability_language):
|
|
175
|
+
Config.reachability_language = Utils.reachability_support_check(Config.reachability_language)
|
|
176
|
+
Config.reachability_present = True
|
|
177
|
+
Config.sbom_present = True
|
|
178
|
+
else:
|
|
179
|
+
Config.reachability_present = False
|
|
180
|
+
else:
|
|
181
|
+
Config.reachability_present = False
|
|
182
|
+
logging.warning("Reachability: Not Configured!!!! Message: Code language was not found on JSON Response")
|
|
183
|
+
else:
|
|
184
|
+
Config.reachability_present = False
|
|
185
|
+
logging.warning("Reachability: Not Configured!!!! Message: Tool configuration data was not found on JSON Response")
|
|
168
186
|
|
|
169
187
|
return 1
|
|
170
188
|
except:
|
|
@@ -36,7 +36,7 @@ parser = argparse.ArgumentParser(
|
|
|
36
36
|
description='''
|
|
37
37
|
#This is a CLI tool to communicate with Boman.ai SaaS server
|
|
38
38
|
''',
|
|
39
|
-
epilog='copyright (c) 2025
|
|
39
|
+
epilog='copyright (c) 2025 BOMAN.AI'
|
|
40
40
|
)
|
|
41
41
|
|
|
42
42
|
|
|
@@ -81,7 +81,10 @@ def runImage(data=None,type=None):
|
|
|
81
81
|
output_file= data['output_file']
|
|
82
82
|
will_generate_output = data['will_generate_output']
|
|
83
83
|
tool_id= data['tool_id']
|
|
84
|
-
|
|
84
|
+
if tool_name != "atom":
|
|
85
|
+
scan_details_id= data['scan_details_id']
|
|
86
|
+
else:
|
|
87
|
+
scan_details_id=0
|
|
85
88
|
conversion_required = data['conversion_required']
|
|
86
89
|
|
|
87
90
|
|
|
@@ -171,7 +174,7 @@ def runImage(data=None,type=None):
|
|
|
171
174
|
else:
|
|
172
175
|
try:
|
|
173
176
|
|
|
174
|
-
#
|
|
177
|
+
# logging.info('Semgrep token present')
|
|
175
178
|
|
|
176
179
|
if Config.jenkins == 'yes':
|
|
177
180
|
|
|
@@ -179,7 +182,7 @@ def runImage(data=None,type=None):
|
|
|
179
182
|
|
|
180
183
|
Config.build_dir = Config.sast_build_dir
|
|
181
184
|
container_output = docker.containers.run(docker_image, command_line, volumes={Config.sast_build_dir: {
|
|
182
|
-
'bind': data['bind']}}, user=userid,detach=detach,environment=env_var)
|
|
185
|
+
'bind': data['bind']}}, user=userid,detach=detach,environment=env_var, remove=True)
|
|
183
186
|
logging.info('SAST Docker: SUCCESS !!!. Message: %s Scan Completed',tool_name)
|
|
184
187
|
|
|
185
188
|
else:
|
|
@@ -327,7 +330,7 @@ def runImage(data=None,type=None):
|
|
|
327
330
|
try:
|
|
328
331
|
Config.build_dir = Config.sast_build_dir
|
|
329
332
|
container= docker.containers.run(docker_image, command_line, volumes={Config.sast_build_dir: {
|
|
330
|
-
'bind': data['bind'], 'mode': 'rw'}},user=userid,detach=detach)
|
|
333
|
+
'bind': data['bind'], 'mode': 'rw'}},user=userid,detach=detach, remove=True)
|
|
331
334
|
|
|
332
335
|
#print(output_file,toolname,tool_id,scan_details_id)
|
|
333
336
|
logging.info('[SUCCESS]: %s Scan Completed',tool_name)
|
|
@@ -355,7 +358,7 @@ def runImage(data=None,type=None):
|
|
|
355
358
|
Config.build_dir = Config.sast_build_dir
|
|
356
359
|
logging.info('DAST Docker: Command for running the scan %s',command_line)
|
|
357
360
|
container= docker.containers.run(docker_image, command_line, volumes={Config.sast_build_dir: {
|
|
358
|
-
'bind': data['bind'], 'mode': 'rw'}},user=userid,detach=detach)
|
|
361
|
+
'bind': data['bind'], 'mode': 'rw'}},user=userid,detach=detach, remove=True)
|
|
359
362
|
|
|
360
363
|
#print(output_file,toolname,tool_id,scan_details_id)
|
|
361
364
|
logging.info('DAST Docker: SUCCESS!!! Message: %s Scan Completed',tool_name)
|
|
@@ -404,14 +407,14 @@ def runImage(data=None,type=None):
|
|
|
404
407
|
Config.build_dir = Config.sca_build_dir
|
|
405
408
|
command_line = "% s" % command_line.format(target = './'+target)
|
|
406
409
|
container_output = docker.containers.run(docker_image, command_line, volumes={Config.sca_build_dir: {
|
|
407
|
-
'bind': data['bind']}}, user=uid)
|
|
410
|
+
'bind': data['bind']}}, user=uid, remove=True)
|
|
408
411
|
logging.info('SCA Docker: SUCCESS!!! Message: %s Scan Completed',tool_name)
|
|
409
412
|
else:
|
|
410
413
|
target = Utils.remove_leading_slash(Config.sca_target)
|
|
411
414
|
Config.build_dir = Config.sca_build_dir
|
|
412
415
|
command_line = "% s" % command_line.format(target ='/src/'+target)
|
|
413
416
|
container_output = docker.containers.run(docker_image, command_line, volumes={Config.sca_build_dir: {
|
|
414
|
-
'bind': data['bind']}}, user=uid)
|
|
417
|
+
'bind': data['bind']}}, user=uid, remove=True)
|
|
415
418
|
logging.info('SCA Docker: SUCCESS!!! Message: %s Scan Completed',tool_name)
|
|
416
419
|
else:
|
|
417
420
|
if Config.sca_ignore:
|
|
@@ -422,7 +425,7 @@ def runImage(data=None,type=None):
|
|
|
422
425
|
logging.info('SCA Docker: Command ==> %s',command_line)
|
|
423
426
|
Config.build_dir = Config.sca_build_dir
|
|
424
427
|
container_output = docker.containers.run(docker_image, command_line, volumes={Config.sca_build_dir: {
|
|
425
|
-
'bind': data['bind']}}, user=uid)
|
|
428
|
+
'bind': data['bind']}}, user=uid, remove=True)
|
|
426
429
|
logging.info('SCA Docker: SUCCESS!!! Message: %s Scan Completed',tool_name)
|
|
427
430
|
Config.sca_message ='SCA scan completed'
|
|
428
431
|
Config.sca_scan_status ='Completed'
|
|
@@ -474,7 +477,7 @@ def runImage(data=None,type=None):
|
|
|
474
477
|
logging.info(f"CS Docker: command ==> {command_line}")
|
|
475
478
|
Config.build_dir = Config.con_scan_build_dir
|
|
476
479
|
container_output = docker.containers.run(docker_image, command_line, volumes={Config.con_scan_build_dir: {
|
|
477
|
-
'bind': data['bind']}}, user=uid)
|
|
480
|
+
'bind': data['bind']}}, user=uid, remove=True)
|
|
478
481
|
logging.info('CS Docker: SUCCESS!!! Message: %s Scan Completed',tool_name)
|
|
479
482
|
Config.con_scan_message ='Container Scan completed'
|
|
480
483
|
Config.con_scan_status ='Completed'
|
|
@@ -507,14 +510,15 @@ def runImage(data=None,type=None):
|
|
|
507
510
|
Utils.logError(msg,str(e))
|
|
508
511
|
|
|
509
512
|
if type == 'sbom':
|
|
513
|
+
Config.sbom_output_file = output_file
|
|
510
514
|
Utils.checkImageAlreadyExsist(docker_image)
|
|
511
515
|
logging.info('Running %s',tool_name)
|
|
512
516
|
|
|
513
517
|
try:
|
|
514
|
-
Config.build_dir = Config.sbom_build_dir
|
|
518
|
+
Config.build_dir = Config.sbom_build_dir = os.getcwd()+'/'
|
|
515
519
|
command_line = "% s" % command_line.format(target = 'src/')
|
|
516
520
|
container_output = docker.containers.run(docker_image, command_line, volumes={Config.sbom_build_dir: {
|
|
517
|
-
'bind': data['bind']}}, user=uid)
|
|
521
|
+
'bind': data['bind']}}, user=uid, remove=True)
|
|
518
522
|
logging.info('SBOM Docker: SUCCESS!!! Message: %s Scan Completed',tool_name)
|
|
519
523
|
Config.sbom_message ='SBOM scan completed'
|
|
520
524
|
Config.sbom_scan_status ='Completed'
|
|
@@ -555,7 +559,7 @@ def runImage(data=None,type=None):
|
|
|
555
559
|
command_line = "% s" % command_line.format(target = os.path.join('/src',Utils.remove_leading_slash(Config.iac_scan_target)))
|
|
556
560
|
Config.build_dir = Config.iac_scan_build_dir
|
|
557
561
|
container_output = docker.containers.run(docker_image, command_line, volumes={Config.iac_scan_build_dir: {
|
|
558
|
-
'bind': data['bind']}}, user=uid)
|
|
562
|
+
'bind': data['bind']}}, user=uid, remove=True)
|
|
559
563
|
logging.info('IaC Docker: SUCCESS!!! Message: %s Scan Completed',tool_name)
|
|
560
564
|
Config.iac_scan_message ='IaC Scan completed'
|
|
561
565
|
Config.iac_scan_status ='Completed'
|
|
@@ -591,13 +595,62 @@ def runImage(data=None,type=None):
|
|
|
591
595
|
logging.error('IaC Docker: Failed!!! Message: Error recorded while uploading the report %s',str(e))
|
|
592
596
|
Config.iac_scan_message ='Error recorded while uploading the report of IaC Scan, Please check your directory for the files.' ## need to change logic here -- MM
|
|
593
597
|
msg = 'Error recorded while uploading the report'
|
|
594
|
-
Utils.logError(msg,str(e))
|
|
598
|
+
Utils.logError(msg,str(e))
|
|
599
|
+
|
|
600
|
+
if type == 'reachability' and Config.sbom_scan_status.lower() != "failed":
|
|
601
|
+
Utils.checkImageAlreadyExsist(docker_image)
|
|
602
|
+
logging.info('Running %s',tool_name)
|
|
603
|
+
|
|
604
|
+
try:
|
|
605
|
+
command_line = "% s" % command_line.format(lang = Config.reachability_language)
|
|
606
|
+
Config.build_dir = Config.reachability_build_dir = Config.sca_build_dir
|
|
607
|
+
container_output = docker.containers.run(docker_image, command_line, volumes={'/tmp': {'bind': '/tmp'},
|
|
608
|
+
f'{os.environ["HOME"]}': {'bind': os.environ["HOME"]},Config.reachability_build_dir: {
|
|
609
|
+
'bind': data['bind'], 'mode': 'rw'}}, user=uid, remove=True)
|
|
610
|
+
logging.info('Reachability Docker: SUCCESS!!! Message: %s Scan Completed',tool_name)
|
|
611
|
+
reachables = Utils.reachability_analysis(f'{Config.sbom_build_dir}/{Config.sbom_output_file}',f'{Config.sca_build_dir}/{output_file}')
|
|
612
|
+
Config.reachability_message ='Reachability Completed'
|
|
613
|
+
Config.reachability_status ='Completed'
|
|
614
|
+
except errors.ContainerError as exc:
|
|
615
|
+
logging.error('Reachability Docker: Failed!!! Message: Some Error recorded while scanning %s',str(exc))
|
|
616
|
+
msg='\n The following error has been recorded while scanning IaC'
|
|
617
|
+
Config.reachability_status ='Failed'
|
|
618
|
+
Config.reachability_errors =f'{str(exc)}]'
|
|
619
|
+
Utils.logError(msg,str(exc))
|
|
620
|
+
|
|
621
|
+
try:
|
|
622
|
+
if will_generate_output == 1:
|
|
623
|
+
logging.info('Reachability: Uploading %s to the server',output_file)
|
|
624
|
+
output_reachability = {
|
|
625
|
+
'output_file': output_file,
|
|
626
|
+
'output': reachables
|
|
627
|
+
}
|
|
628
|
+
if uploadReport(output_reachability,tool_name,tool_id,scan_details_id,'reachability'):
|
|
629
|
+
Config.reachability_status ='Completed'
|
|
630
|
+
Config.reachability_upload_status = 'Completed'
|
|
631
|
+
Config.reachability_message ='Scan Completed'
|
|
632
|
+
else:
|
|
633
|
+
Config.reachability_status ='Failed'
|
|
634
|
+
Config.reachability_upload_status = 'Failed'
|
|
635
|
+
Config.reachability_message ='Error occured while uploading the report, Please check the cli logs'
|
|
636
|
+
else:
|
|
637
|
+
logging.error('reachability: Failed!!! Message: Cant upload files to the server',tool_name)
|
|
638
|
+
Config.reachability_message ='Cant upload files to the server for reachability, Please check your directory If output file is present.'
|
|
639
|
+
|
|
640
|
+
except EnvironmentError as e:
|
|
641
|
+
logging.error('reachability: Failed!!! Message: Error recorded while uploading the report %s',str(e))
|
|
642
|
+
Config.reachability_message ='Error recorded while uploading the report of reachability, Please check your directory If output file is present.' ## need to change logic here -- MM
|
|
643
|
+
msg = 'Error recorded while uploading the report'
|
|
644
|
+
Utils.logError(msg,str(e))
|
|
645
|
+
elif type == "reachability":
|
|
646
|
+
Config.reachability_status ='Failed'
|
|
647
|
+
Config.reachability_message ='Reachability: SBOM scan failed. Reachability analysis requires sbom file'
|
|
595
648
|
|
|
596
649
|
|
|
597
650
|
#### function to upload the test report to the server with other data -- MM ------------------------------------
|
|
598
651
|
def uploadReport(filename,toolname,tool_id,scan_details_id,type):
|
|
599
652
|
|
|
600
|
-
logging.info('Uploading %s report with filename: %s', toolname,filename)
|
|
653
|
+
# logging.info('Uploading %s report with filename: %s', toolname,filename)
|
|
601
654
|
if True:
|
|
602
655
|
#build_dir = '/home/boxuser/box/trainingdata/repos/youtube-dl/'
|
|
603
656
|
#print(Config.sast_build_dir+filename)
|
|
@@ -626,6 +679,9 @@ def uploadReport(filename,toolname,tool_id,scan_details_id,type):
|
|
|
626
679
|
elif type =="iac":
|
|
627
680
|
message = Config.iac_scan_message
|
|
628
681
|
errors = Config.iac_scan_errors
|
|
682
|
+
elif type =="reachability":
|
|
683
|
+
message = Config.reachability_message
|
|
684
|
+
errors = Config.reachability_errors
|
|
629
685
|
except:
|
|
630
686
|
message = 'NA'
|
|
631
687
|
errors = 'NA'
|
|
@@ -634,20 +690,29 @@ def uploadReport(filename,toolname,tool_id,scan_details_id,type):
|
|
|
634
690
|
|
|
635
691
|
|
|
636
692
|
try:
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
693
|
+
|
|
694
|
+
if type == 'reachability':
|
|
695
|
+
path_reachability = Path(str(Config.sca_build_dir)) / str("app.atom")
|
|
696
|
+
data = filename['output']
|
|
697
|
+
path_bom = Path(str(Config.sbom_build_dir)) / str("bom.json")
|
|
698
|
+
path = Path(str(Config.sca_build_dir)) / str(filename['output_file'])
|
|
699
|
+
logging.info('Uploading %s report with filename: %s', toolname,filename['output_file'])
|
|
700
|
+
|
|
701
|
+
else:
|
|
702
|
+
logging.info('Uploading %s report with filename: %s', toolname,filename)
|
|
703
|
+
logging.info('fetching the %s file from the directory %s',filename,Config.build_dir)
|
|
704
|
+
##path = '/home/boxuser/box/Vuln-code/boman_njsscan.json'
|
|
643
705
|
|
|
644
|
-
data_folder = Path(str(Config.build_dir))
|
|
645
706
|
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
707
|
+
# print(str(Config.build_dir))
|
|
708
|
+
# print(str(filename))
|
|
709
|
+
data_folder = Path(str(Config.build_dir))
|
|
710
|
+
path = data_folder / str(filename)
|
|
711
|
+
|
|
712
|
+
|
|
713
|
+
with open(path) as f:
|
|
714
|
+
f.seek(0)
|
|
715
|
+
data = json.load(f)
|
|
651
716
|
|
|
652
717
|
|
|
653
718
|
except EnvironmentError as e:
|
|
@@ -657,10 +722,24 @@ def uploadReport(filename,toolname,tool_id,scan_details_id,type):
|
|
|
657
722
|
Utils.logError(msg,str(e))
|
|
658
723
|
values = {'tool_name': toolname, 'time': time.time(),'scan_token':Config.scan_token, 'app_token':Config.app_token,'customer_token':Config.customer_token,'tool_id':tool_id,'scan_details_id':scan_details_id,"tool_results":None,"message":message,"errors":errors,"app_loc":Config.app_loc}
|
|
659
724
|
url = Config.boman_url+"/api/app/upload"
|
|
660
|
-
# with open(path) as f:
|
|
661
|
-
# file_obj = f
|
|
662
725
|
r = requests.post(url,json=values)
|
|
663
|
-
return 0
|
|
726
|
+
return 0
|
|
727
|
+
|
|
728
|
+
try:
|
|
729
|
+
logging.info('Removing the result file')
|
|
730
|
+
if type != "sbom" and type != "reachability":
|
|
731
|
+
os.remove(path)
|
|
732
|
+
elif Config.reachability_present is not True and type == 'sbom':
|
|
733
|
+
os.remove(path)
|
|
734
|
+
elif type == "reachability":
|
|
735
|
+
os.remove(path)
|
|
736
|
+
os.remove(Path(str(Config.sbom_build_dir))/Config.sbom_response[0]['output_file'])
|
|
737
|
+
os.remove(path_reachability)
|
|
738
|
+
os.remove(path_bom)
|
|
739
|
+
|
|
740
|
+
|
|
741
|
+
except Exception as e:
|
|
742
|
+
logging.error(f"unable to remove the file: {path} ---> Error: {e}")
|
|
664
743
|
|
|
665
744
|
tool_output = json.dumps(data, ensure_ascii=False, indent=4)
|
|
666
745
|
|
|
@@ -674,7 +753,10 @@ def uploadReport(filename,toolname,tool_id,scan_details_id,type):
|
|
|
674
753
|
r = requests.post(url,json=values)
|
|
675
754
|
#print(r.status_code)
|
|
676
755
|
if r.status_code == 200:
|
|
677
|
-
|
|
756
|
+
if type == "reachability":
|
|
757
|
+
logging.info('[COMPLETED]: %s Report uploaded Successfully! Report Name: %s',toolname,filename["output_file"])
|
|
758
|
+
else:
|
|
759
|
+
logging.info('[COMPLETED]: %s Report uploaded Successfully! Report Name: %s',toolname,filename)
|
|
678
760
|
logging.info('Removing the result file')
|
|
679
761
|
#os.remove(path)
|
|
680
762
|
return 1
|
|
@@ -769,37 +851,51 @@ def exitFunction():
|
|
|
769
851
|
customer_token = Config.customer_token
|
|
770
852
|
|
|
771
853
|
logging.info('Summary: Fetching Vulnerabilities reported by the tools')
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
response = x.json()
|
|
780
|
-
|
|
781
|
-
if response['status'] == True:
|
|
782
|
-
logging.info('Summary: Analyzing the vulnerabilities found')
|
|
783
|
-
for data in response['data'] :
|
|
784
|
-
vuln[data['_id']] = data['count']
|
|
785
|
-
|
|
786
|
-
Config.low_count = vuln['LOW']
|
|
787
|
-
Config.medium_count = vuln['MEDIUM']
|
|
788
|
-
Config.high_count = vuln['HIGH']
|
|
789
|
-
Config.critical_count = vuln['CRITICAL']
|
|
854
|
+
|
|
855
|
+
end_time = time.time() + Config.polling_time
|
|
856
|
+
while time.time() < end_time:
|
|
857
|
+
|
|
858
|
+
url = Config.boman_url+"/api/vuln/get"
|
|
859
|
+
values = {'app_token':app_token, 'scan_token':scan_token, 'customer_token':customer_token}
|
|
860
|
+
try:
|
|
790
861
|
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
862
|
+
x = requests.post(url,json=values)
|
|
863
|
+
response = x.json()
|
|
864
|
+
|
|
865
|
+
if not Config.fail_build:
|
|
866
|
+
logging.info("Fail Build was not configured")
|
|
867
|
+
Utils.get_summary_of_vulns(response)
|
|
868
|
+
break
|
|
869
|
+
|
|
870
|
+
if "ml_status" in response.keys():
|
|
871
|
+
if response["ml_status"] == True:
|
|
872
|
+
logging.info("Poll Status: ML scan is Done. Collecting the summary")
|
|
873
|
+
Utils.get_summary_of_vulns(response)
|
|
874
|
+
break
|
|
875
|
+
else:
|
|
876
|
+
logging.info("Poll status: Waiting for ML to complete......")
|
|
877
|
+
time.sleep(Config.polling_frequency)
|
|
796
878
|
|
|
879
|
+
except requests.ConnectionError as e:
|
|
880
|
+
|
|
881
|
+
logging.error(f"Connection Error: Can't connect to the Server, Please check your Internet connection. Error: {e}")
|
|
882
|
+
exit(1) #server/saas error
|
|
883
|
+
|
|
884
|
+
else:
|
|
885
|
+
logging.warning("Poll Status: Polling time reached the limit. But ml scan has not commpleted. Try using --pollTime to increase the polling time")
|
|
886
|
+
url = Config.boman_url+"/api/vuln/get"
|
|
887
|
+
values = {'app_token':app_token, 'scan_token':scan_token, 'customer_token':customer_token}
|
|
888
|
+
try:
|
|
889
|
+
|
|
890
|
+
x = requests.post(url,json=values)
|
|
891
|
+
response = x.json()
|
|
892
|
+
|
|
893
|
+
Utils.get_summary_of_vulns(response)
|
|
797
894
|
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
895
|
+
except requests.ConnectionError as e:
|
|
896
|
+
|
|
897
|
+
logging.error(f"Connection Error: Can't connect to the Server, Please check your Internet connection. Error: {e}")
|
|
898
|
+
exit(1) #server/saas error
|
|
803
899
|
|
|
804
900
|
|
|
805
901
|
|
|
@@ -861,7 +957,7 @@ def main():
|
|
|
861
957
|
|
|
862
958
|
if Config.sast_present is True:
|
|
863
959
|
|
|
864
|
-
if Config.sast_lang != 'sonar':
|
|
960
|
+
if (Config.sast_lang != 'sonar') and (Config.sast_lang != 'semgrep-pro'):
|
|
865
961
|
|
|
866
962
|
logging.info('SAST: Preparing SAST Scan')
|
|
867
963
|
logging.info('SAST: Working directory is %s',Config.sast_build_dir)
|
|
@@ -881,9 +977,9 @@ def main():
|
|
|
881
977
|
runImage(data=data,type='SAST')
|
|
882
978
|
logging.info("SAST: Successfull !!!")
|
|
883
979
|
else:
|
|
884
|
-
logging.warning('SAST: Configured with
|
|
980
|
+
logging.warning(f'SAST: Configured with {Config.sast_lang} it will run on SaaS')
|
|
885
981
|
Config.sast_scan_status = 'SUCCESS'
|
|
886
|
-
Config.sast_message = f'SAST Scan: Success.
|
|
982
|
+
Config.sast_message = f'SAST Scan: Success. {Config.sast_lang} is configured and will run on SaaS'
|
|
887
983
|
|
|
888
984
|
|
|
889
985
|
else:
|
|
@@ -919,7 +1015,7 @@ def main():
|
|
|
919
1015
|
|
|
920
1016
|
|
|
921
1017
|
if Config.sca_present is True:
|
|
922
|
-
if Config.sca_response[0]['tool'] != "SNYK":
|
|
1018
|
+
if Config.sca_response[0]['tool'] != "SNYK" and Config.sca_response[0]['tool'] != "Semgrep Pro":
|
|
923
1019
|
logging.info('SCA: Preparing scan')
|
|
924
1020
|
|
|
925
1021
|
|
|
@@ -932,33 +1028,36 @@ def main():
|
|
|
932
1028
|
runImage(data=data,type='SCA')
|
|
933
1029
|
logging.info("SCA: Successfull !!!")
|
|
934
1030
|
else:
|
|
935
|
-
logging.warning(
|
|
1031
|
+
logging.warning(f"SCA: Configured with {Config.sca_response[0]['tool']} it will run on SaaS")
|
|
936
1032
|
Config.sca_scan_status = 'SUCCESS'
|
|
937
|
-
Config.sca_message = f
|
|
1033
|
+
Config.sca_message = f"SCA Scan: Success. {Config.sca_response[0]['tool']} is configured and will run on SaaS"
|
|
938
1034
|
else:
|
|
939
1035
|
logging.info('SCA: Ignoring scan. Message: Not Configured')
|
|
940
1036
|
|
|
941
1037
|
if Config.secret_scan_present == True:
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
1038
|
+
if Config.secret_scan_response[0]['tool'] != "Semgrep Pro":
|
|
1039
|
+
if Utils.isGitDirectory(Config.sast_build_dir):
|
|
1040
|
+
logging.info('Secret Scan: Preparing Scan')
|
|
1041
|
+
for data in Config.secret_scan_response:
|
|
1042
|
+
initSecertScan(Config.sast_build_dir,data=Config.secret_scan_response)
|
|
1043
|
+
logging.info("Secret Scan: Successfull !!!")
|
|
1044
|
+
else:
|
|
1045
|
+
logging.error('Secret Scan: Failed !!!. Message: The Directory is not Git directory %s',Config.sast_build_dir)
|
|
1046
|
+
data=Config.secret_scan_response
|
|
1047
|
+
tool_name = data[0]['tool']
|
|
1048
|
+
file_name = data[0]['output_file']
|
|
1049
|
+
tool_id = data[0]['tool_id']
|
|
1050
|
+
scan_details_id = data[0]['scan_details_id']
|
|
1051
|
+
uploadReport(file_name,tool_name,tool_id,scan_details_id,'SS')
|
|
1052
|
+
Config.secret_scan_status = 'Failed'
|
|
1053
|
+
Config.secret_scan_upload_status ='NA'
|
|
1054
|
+
Config.secret_scan_errors = "Secret Scan: Failed !!!. Message: The Directory is not Git directory %s"
|
|
1055
|
+
Config.secret_scan_message = f'Secret Scan: Failed. The Directory is not Git directory {Config.sast_build_dir}'
|
|
1056
|
+
logging.warning('Secret Scan: Ignoring scan')
|
|
949
1057
|
else:
|
|
950
|
-
logging.
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
file_name = data[0]['output_file']
|
|
954
|
-
tool_id = data[0]['tool_id']
|
|
955
|
-
scan_details_id = data[0]['scan_details_id']
|
|
956
|
-
uploadReport(file_name,tool_name,tool_id,scan_details_id,'SS')
|
|
957
|
-
Config.secret_scan_status = 'Failed'
|
|
958
|
-
Config.secret_scan_upload_status ='NA'
|
|
959
|
-
Config.secret_scan_errors = "Secret Scan: Failed !!!. Message: The Directory is not Git directory %s"
|
|
960
|
-
Config.secret_scan_message = f'Secret Scan: Failed. The Directory is not Git directory {Config.sast_build_dir}'
|
|
961
|
-
logging.warning('Secret Scan: Ignoring scan')
|
|
1058
|
+
logging.warning(f"Secret Scan: Configured with {Config.secret_scan_response[0]['tool']} it will run on SaaS")
|
|
1059
|
+
Config.secret_scan_status ='SUCCESS'
|
|
1060
|
+
Config.secret_scan_message =f"Secret Scan: Success. {Config.secret_scan_response[0]['tool']} is configured and will run on SaaS"
|
|
962
1061
|
else:
|
|
963
1062
|
logging.warning('Secret Scan: Ignoring scan. Message: Not Configured')
|
|
964
1063
|
|
|
@@ -1012,7 +1111,16 @@ def main():
|
|
|
1012
1111
|
Config.iac_scan_message = f'IaC Scan: Success. SNYK is configured and will run on SaaS'
|
|
1013
1112
|
else:
|
|
1014
1113
|
logging.warning('IaC: Ignoring scan. Message: Not Configured')
|
|
1015
|
-
|
|
1114
|
+
|
|
1115
|
+
if Config.reachability_present is True:
|
|
1116
|
+
logging.info("Reachability: Preparing requirements")
|
|
1117
|
+
|
|
1118
|
+
for data in Config.reachability_response:
|
|
1119
|
+
Utils.copy_contents(f'{Config.sbom_build_dir}/{Config.sbom_output_file}',f'{Config.sca_build_dir}/bom.json')
|
|
1120
|
+
runImage(data=data,type='reachability')
|
|
1121
|
+
else:
|
|
1122
|
+
logging.warning('Reachability: Ignoring. Message: Not Configured')
|
|
1123
|
+
|
|
1016
1124
|
exitFunction()
|
|
1017
1125
|
return 1
|
|
1018
1126
|
|
|
@@ -1033,6 +1141,8 @@ def default():
|
|
|
1033
1141
|
parser.add_argument('-zap_session_script','--zap_custom_session_script',default='session_management.js',help="Pass the file name if you have any custom zap session script file name. eg:custom-script.js")
|
|
1034
1142
|
# parser.add_argument('-uid','--user_id',default='1000:1000',help="[internal] Pass the custom userid:groupid incase the lingu detec function is failed")
|
|
1035
1143
|
parser.add_argument('-semgrep_token','--semgrepToken',default='No',help="Pass the semgrep community token here")
|
|
1144
|
+
parser.add_argument('-pot','--pollTime',default=60,help="Polling Time. Min : 30s, Max: 5min, Default : 1min. Format: input the time in seconds eg: 1min => 60 ")
|
|
1145
|
+
parser.add_argument('-pof','--pollFrequency',default=10,help="Polling Frequency. Min : 5s, Max: 1min, Default : 10s. Format: input the time in seconds eg: 1min => 60 ")
|
|
1036
1146
|
args = parser.parse_args()
|
|
1037
1147
|
|
|
1038
1148
|
# if len(sys.args) == 1:
|
|
@@ -1128,6 +1238,24 @@ def default():
|
|
|
1128
1238
|
else:
|
|
1129
1239
|
logging.error(f"Authorization Config: Failed !!!, Exit Code: 4 (Misconfiguration/Validation). The {Config.boman_config_file} file is not found and tokens were not found in cli arguments as well")
|
|
1130
1240
|
exit(4) #validation error
|
|
1241
|
+
|
|
1242
|
+
|
|
1243
|
+
if (args.pollTime >= 30) and (args.pollTime <= 300):
|
|
1244
|
+
Config.polling_time = args.pollTime
|
|
1245
|
+
logging.info(f"Configuring polling time to {Config.polling_time}s")
|
|
1246
|
+
else:
|
|
1247
|
+
logging.info(f"Resorting to default polling time {Config.polling_time}s")
|
|
1248
|
+
|
|
1249
|
+
if (args.pollFrequency >= 5) and (args.pollFrequency <= 60):
|
|
1250
|
+
Config.polling_frequency = args.pollFrequency
|
|
1251
|
+
logging.info(f"Configuring polling frequency to {Config.polling_frequency}s")
|
|
1252
|
+
else:
|
|
1253
|
+
logging.info(f"Resorting to default polling frequency {Config.polling_frequency}s")
|
|
1254
|
+
|
|
1255
|
+
|
|
1256
|
+
if args.failBuild != "pass":
|
|
1257
|
+
Config.fail_build = True
|
|
1258
|
+
|
|
1131
1259
|
## auth method args validation
|
|
1132
1260
|
|
|
1133
1261
|
# if args.custom_dast_auth_config == True:
|
|
@@ -1140,13 +1268,13 @@ def default():
|
|
|
1140
1268
|
# exit(4)
|
|
1141
1269
|
|
|
1142
1270
|
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1271
|
+
# if Config.zap_custom_auth_method == 'form':
|
|
1272
|
+
# if Config.custom_zap_plan_present :
|
|
1273
|
+
# Config.dast_auth_present == True
|
|
1274
|
+
# Config.custom_zap_plan_present = True
|
|
1275
|
+
# else:
|
|
1276
|
+
# logging.error('Zap auth method "form" needs plan file')
|
|
1277
|
+
# exit(4)
|
|
1150
1278
|
|
|
1151
1279
|
|
|
1152
1280
|
|
|
@@ -1172,30 +1300,35 @@ def default():
|
|
|
1172
1300
|
if args.failBuild == 'fail':
|
|
1173
1301
|
total_vuln = Config.high_count + Config.medium_count + Config.low_count + Config.critical_count
|
|
1174
1302
|
if total_vuln > 0:
|
|
1303
|
+
logging.warning(f"Failing the build as {args.failBuild} is configured in failBuild argument. Boman has found {total_vuln} vulnerabilities")
|
|
1175
1304
|
exit(-1)
|
|
1176
1305
|
else:
|
|
1177
1306
|
exit(0)
|
|
1178
1307
|
|
|
1179
1308
|
elif args.failBuild == 'high':
|
|
1180
1309
|
if Config.high_count > 0 or Config.critical_count > 0:
|
|
1310
|
+
logging.warning(f"Failing the build as {args.failBuild} is configured in failBuild argument. Boman has found {Config.high_count} {args.failBuild} vulnerabilities")
|
|
1181
1311
|
exit(-1)
|
|
1182
1312
|
else:
|
|
1183
1313
|
exit(0)
|
|
1184
1314
|
|
|
1185
1315
|
elif args.failBuild == 'medium':
|
|
1186
1316
|
if Config.medium_count > 0 or Config.high_count > 0:
|
|
1317
|
+
logging.warning(f"Failing the build as {args.failBuild} is configured in failBuild argument. Boman has found {Config.medium_count} {args.failBuild} vulnerabilities")
|
|
1187
1318
|
exit(-1)
|
|
1188
1319
|
else:
|
|
1189
1320
|
exit(0)
|
|
1190
1321
|
|
|
1191
1322
|
elif args.failBuild == 'low':
|
|
1192
1323
|
if Config.low_count > 0 or Config.medium_count > 0 or Config.high_count > 0:
|
|
1324
|
+
logging.warning(f"Failing the build as {args.failBuild} is configured in failBuild argument. Boman has found {Config.low_count} {args.failBuild} vulnerabilities")
|
|
1193
1325
|
exit(-1)
|
|
1194
1326
|
else:
|
|
1195
1327
|
exit(0)
|
|
1196
1328
|
|
|
1197
1329
|
elif args.failBuild == 'critical':
|
|
1198
1330
|
if Config.critical_count > 0:
|
|
1331
|
+
logging.warning(f"Failing the build as {args.failBuild} is configured in failBuild argument. Boman has found {Config.critical_count} {args.failBuild} vulnerabilities")
|
|
1199
1332
|
exit(-1)
|
|
1200
1333
|
else:
|
|
1201
1334
|
exit(0)
|
|
@@ -1,139 +1,139 @@
|
|
|
1
|
-
---
|
|
2
|
-
env:
|
|
3
|
-
contexts:
|
|
4
|
-
- name: "Boman Authenticated Scan"
|
|
5
|
-
urls:
|
|
6
|
-
- "https://demo.testfire.net/"
|
|
7
|
-
authentication:
|
|
8
|
-
method: "form"
|
|
9
|
-
parameters: # May include any required for scripts. All of the parameters support vars except for the port
|
|
10
|
-
loginPageUrl: "https://demo.testfire.net/login.jsp"
|
|
11
|
-
loginRequestUrl: "https://demo.testfire.net/doLogin"
|
|
12
|
-
loginRequestBody: "uid={%username%}&passw={%password%}&btnSubmit=Login"
|
|
13
|
-
verification:
|
|
14
|
-
method: "both" # String, one of 'response', 'request', 'both', 'poll'
|
|
15
|
-
loggedOutRegex: ".*Sign In.*" # String, regex pattern for determining if logged
|
|
16
|
-
sessionManagement:
|
|
17
|
-
method: ""
|
|
18
|
-
parameters:
|
|
19
|
-
script: ""
|
|
20
|
-
scriptEngine: ""
|
|
21
|
-
users: # List of one or more users available to use for authentication
|
|
22
|
-
- name: "demoadmin" # String, the name to be used by the jobs
|
|
23
|
-
credentials: # List of user credentials - may include any required for scripts
|
|
24
|
-
username: "admin" # String, the username to use when authenticating, vars supported
|
|
25
|
-
password: "admin"
|
|
26
|
-
includePaths: []
|
|
27
|
-
excludePaths: []
|
|
28
|
-
technology:
|
|
29
|
-
exclude:
|
|
30
|
-
- "C"
|
|
31
|
-
- "ASP"
|
|
32
|
-
- "IBM DB2"
|
|
33
|
-
- "PHP"
|
|
34
|
-
- "CouchDB"
|
|
35
|
-
- "XML"
|
|
36
|
-
- "Microsoft SQL Server"
|
|
37
|
-
- "JSP/Servlet"
|
|
38
|
-
- "Firebird"
|
|
39
|
-
- "MongoDB"
|
|
40
|
-
- "HypersonicSQL"
|
|
41
|
-
- "SAP MaxDB"
|
|
42
|
-
- "Ruby"
|
|
43
|
-
- "SCM"
|
|
44
|
-
- "WS"
|
|
45
|
-
- "Microsoft Access"
|
|
46
|
-
- "Sybase"
|
|
47
|
-
- "Python"
|
|
48
|
-
parameters:
|
|
49
|
-
failOnError: true
|
|
50
|
-
failOnWarning: false
|
|
51
|
-
progressToStdout: true
|
|
52
|
-
vars: {}
|
|
53
|
-
jobs:
|
|
54
|
-
- parameters:
|
|
55
|
-
scanOnlyInScope: true
|
|
56
|
-
enableTags: false
|
|
57
|
-
disableAllRules: false
|
|
58
|
-
rules: []
|
|
59
|
-
name: "passiveScan-config"
|
|
60
|
-
type: "passiveScan-config"
|
|
61
|
-
- parameters:
|
|
62
|
-
context: "Demo testfire"
|
|
63
|
-
user: "demoadmin"
|
|
64
|
-
url: "https://demo.testfire.net"
|
|
65
|
-
maxDuration: 1
|
|
66
|
-
maxDepth: 2
|
|
67
|
-
maxChildren: 0
|
|
68
|
-
name: "spider"
|
|
69
|
-
type: "spider"
|
|
70
|
-
tests:
|
|
71
|
-
- onFail: "INFO"
|
|
72
|
-
statistic: "automation.spider.urls.added"
|
|
73
|
-
site: ""
|
|
74
|
-
operator: ">="
|
|
75
|
-
value: 100
|
|
76
|
-
name: "At least 100 URLs found"
|
|
77
|
-
type: "stats"
|
|
78
|
-
- name: "spider logged in" # Name of the test, optional
|
|
79
|
-
type: stats # Specifies that the test is of type 'stats'
|
|
80
|
-
statistic: "stats.auth.success" # Name of an integer / long statistic
|
|
81
|
-
operator: ">=" # One of '==', '!=', '>=', '>', '<', '<='
|
|
82
|
-
value: 2 # Value to compare statistic against
|
|
83
|
-
onFail: "info"
|
|
84
|
-
- name: "spider failed" # Name of the test, optional
|
|
85
|
-
type: stats # Specifies that the test is of type 'stats'
|
|
86
|
-
statistic: "stats.auth.failure" # Name of an integer / long statisti
|
|
87
|
-
operator: ">=" # One of '==', '!=', '>=', '>', '<', '<='
|
|
88
|
-
value: 2 # Value to compare statistic against
|
|
89
|
-
onFail: "info"
|
|
90
|
-
- parameters: {}
|
|
91
|
-
name: "passiveScan-wait"
|
|
92
|
-
type: "passiveScan-wait"
|
|
93
|
-
- parameters:
|
|
94
|
-
context: "Demo testfire"
|
|
95
|
-
user: "demoadmin"
|
|
96
|
-
policy: ""
|
|
97
|
-
maxRuleDurationInMins: 0
|
|
98
|
-
maxScanDurationInMins: 5
|
|
99
|
-
maxAlertsPerRule: 0
|
|
100
|
-
policyDefinition:
|
|
101
|
-
defaultStrength: "medium"
|
|
102
|
-
defaultThreshold: "medium"
|
|
103
|
-
rules: []
|
|
104
|
-
tests:
|
|
105
|
-
- name: "spider logged in" # Name of the test, optional
|
|
106
|
-
type: stats # Specifies that the test is of type 'stats'
|
|
107
|
-
statistic: "stats.auth.success" # Name of an integer / long statistic
|
|
108
|
-
operator: ">=" # One of '==', '!=', '>=', '>', '<', '<='
|
|
109
|
-
value: 2 # Value to compare statistic against
|
|
110
|
-
onFail: "info"
|
|
111
|
-
- name: "spider failed" # Name of the test, optional
|
|
112
|
-
type: stats # Specifies that the test is of type 'stats'
|
|
113
|
-
statistic: "stats.auth.failure" # Name of an integer / long statisti
|
|
114
|
-
operator: ">=" # One of '==', '!=', '>=', '>', '<', '<='
|
|
115
|
-
value: 2 # Value to compare statistic against
|
|
116
|
-
onFail: "info"
|
|
117
|
-
name: "activeScan"
|
|
118
|
-
type: "activeScan"
|
|
119
|
-
- parameters:
|
|
120
|
-
template: "traditional-json"
|
|
121
|
-
reportDir: ""
|
|
122
|
-
reportFile: ""
|
|
123
|
-
reportTitle: "Boman_Scanning_Report"
|
|
124
|
-
reportDescription: ""
|
|
125
|
-
displayReport: false
|
|
126
|
-
risks:
|
|
127
|
-
- "info"
|
|
128
|
-
- "low"
|
|
129
|
-
- "medium"
|
|
130
|
-
- "high"
|
|
131
|
-
confidences:
|
|
132
|
-
- "falsepositive"
|
|
133
|
-
- "low"
|
|
134
|
-
- "medium"
|
|
135
|
-
- "high"
|
|
136
|
-
- "confirmed"
|
|
137
|
-
sites: []
|
|
138
|
-
name: "report"
|
|
139
|
-
type: "report"
|
|
1
|
+
---
|
|
2
|
+
env:
|
|
3
|
+
contexts:
|
|
4
|
+
- name: "Boman Authenticated Scan"
|
|
5
|
+
urls:
|
|
6
|
+
- "https://demo.testfire.net/"
|
|
7
|
+
authentication:
|
|
8
|
+
method: "form"
|
|
9
|
+
parameters: # May include any required for scripts. All of the parameters support vars except for the port
|
|
10
|
+
loginPageUrl: "https://demo.testfire.net/login.jsp"
|
|
11
|
+
loginRequestUrl: "https://demo.testfire.net/doLogin"
|
|
12
|
+
loginRequestBody: "uid={%username%}&passw={%password%}&btnSubmit=Login"
|
|
13
|
+
verification:
|
|
14
|
+
method: "both" # String, one of 'response', 'request', 'both', 'poll'
|
|
15
|
+
loggedOutRegex: ".*Sign In.*" # String, regex pattern for determining if logged
|
|
16
|
+
sessionManagement:
|
|
17
|
+
method: ""
|
|
18
|
+
parameters:
|
|
19
|
+
script: ""
|
|
20
|
+
scriptEngine: ""
|
|
21
|
+
users: # List of one or more users available to use for authentication
|
|
22
|
+
- name: "demoadmin" # String, the name to be used by the jobs
|
|
23
|
+
credentials: # List of user credentials - may include any required for scripts
|
|
24
|
+
username: "admin" # String, the username to use when authenticating, vars supported
|
|
25
|
+
password: "admin"
|
|
26
|
+
includePaths: []
|
|
27
|
+
excludePaths: []
|
|
28
|
+
technology:
|
|
29
|
+
exclude:
|
|
30
|
+
- "C"
|
|
31
|
+
- "ASP"
|
|
32
|
+
- "IBM DB2"
|
|
33
|
+
- "PHP"
|
|
34
|
+
- "CouchDB"
|
|
35
|
+
- "XML"
|
|
36
|
+
- "Microsoft SQL Server"
|
|
37
|
+
- "JSP/Servlet"
|
|
38
|
+
- "Firebird"
|
|
39
|
+
- "MongoDB"
|
|
40
|
+
- "HypersonicSQL"
|
|
41
|
+
- "SAP MaxDB"
|
|
42
|
+
- "Ruby"
|
|
43
|
+
- "SCM"
|
|
44
|
+
- "WS"
|
|
45
|
+
- "Microsoft Access"
|
|
46
|
+
- "Sybase"
|
|
47
|
+
- "Python"
|
|
48
|
+
parameters:
|
|
49
|
+
failOnError: true
|
|
50
|
+
failOnWarning: false
|
|
51
|
+
progressToStdout: true
|
|
52
|
+
vars: {}
|
|
53
|
+
jobs:
|
|
54
|
+
- parameters:
|
|
55
|
+
scanOnlyInScope: true
|
|
56
|
+
enableTags: false
|
|
57
|
+
disableAllRules: false
|
|
58
|
+
rules: []
|
|
59
|
+
name: "passiveScan-config"
|
|
60
|
+
type: "passiveScan-config"
|
|
61
|
+
- parameters:
|
|
62
|
+
context: "Demo testfire"
|
|
63
|
+
user: "demoadmin"
|
|
64
|
+
url: "https://demo.testfire.net"
|
|
65
|
+
maxDuration: 1
|
|
66
|
+
maxDepth: 2
|
|
67
|
+
maxChildren: 0
|
|
68
|
+
name: "spider"
|
|
69
|
+
type: "spider"
|
|
70
|
+
tests:
|
|
71
|
+
- onFail: "INFO"
|
|
72
|
+
statistic: "automation.spider.urls.added"
|
|
73
|
+
site: ""
|
|
74
|
+
operator: ">="
|
|
75
|
+
value: 100
|
|
76
|
+
name: "At least 100 URLs found"
|
|
77
|
+
type: "stats"
|
|
78
|
+
- name: "spider logged in" # Name of the test, optional
|
|
79
|
+
type: stats # Specifies that the test is of type 'stats'
|
|
80
|
+
statistic: "stats.auth.success" # Name of an integer / long statistic
|
|
81
|
+
operator: ">=" # One of '==', '!=', '>=', '>', '<', '<='
|
|
82
|
+
value: 2 # Value to compare statistic against
|
|
83
|
+
onFail: "info"
|
|
84
|
+
- name: "spider failed" # Name of the test, optional
|
|
85
|
+
type: stats # Specifies that the test is of type 'stats'
|
|
86
|
+
statistic: "stats.auth.failure" # Name of an integer / long statisti
|
|
87
|
+
operator: ">=" # One of '==', '!=', '>=', '>', '<', '<='
|
|
88
|
+
value: 2 # Value to compare statistic against
|
|
89
|
+
onFail: "info"
|
|
90
|
+
- parameters: {}
|
|
91
|
+
name: "passiveScan-wait"
|
|
92
|
+
type: "passiveScan-wait"
|
|
93
|
+
- parameters:
|
|
94
|
+
context: "Demo testfire"
|
|
95
|
+
user: "demoadmin"
|
|
96
|
+
policy: ""
|
|
97
|
+
maxRuleDurationInMins: 0
|
|
98
|
+
maxScanDurationInMins: 5
|
|
99
|
+
maxAlertsPerRule: 0
|
|
100
|
+
policyDefinition:
|
|
101
|
+
defaultStrength: "medium"
|
|
102
|
+
defaultThreshold: "medium"
|
|
103
|
+
rules: []
|
|
104
|
+
tests:
|
|
105
|
+
- name: "spider logged in" # Name of the test, optional
|
|
106
|
+
type: stats # Specifies that the test is of type 'stats'
|
|
107
|
+
statistic: "stats.auth.success" # Name of an integer / long statistic
|
|
108
|
+
operator: ">=" # One of '==', '!=', '>=', '>', '<', '<='
|
|
109
|
+
value: 2 # Value to compare statistic against
|
|
110
|
+
onFail: "info"
|
|
111
|
+
- name: "spider failed" # Name of the test, optional
|
|
112
|
+
type: stats # Specifies that the test is of type 'stats'
|
|
113
|
+
statistic: "stats.auth.failure" # Name of an integer / long statisti
|
|
114
|
+
operator: ">=" # One of '==', '!=', '>=', '>', '<', '<='
|
|
115
|
+
value: 2 # Value to compare statistic against
|
|
116
|
+
onFail: "info"
|
|
117
|
+
name: "activeScan"
|
|
118
|
+
type: "activeScan"
|
|
119
|
+
- parameters:
|
|
120
|
+
template: "traditional-json"
|
|
121
|
+
reportDir: ""
|
|
122
|
+
reportFile: ""
|
|
123
|
+
reportTitle: "Boman_Scanning_Report"
|
|
124
|
+
reportDescription: ""
|
|
125
|
+
displayReport: false
|
|
126
|
+
risks:
|
|
127
|
+
- "info"
|
|
128
|
+
- "low"
|
|
129
|
+
- "medium"
|
|
130
|
+
- "high"
|
|
131
|
+
confidences:
|
|
132
|
+
- "falsepositive"
|
|
133
|
+
- "low"
|
|
134
|
+
- "medium"
|
|
135
|
+
- "high"
|
|
136
|
+
- "confirmed"
|
|
137
|
+
sites: []
|
|
138
|
+
name: "report"
|
|
139
|
+
type: "report"
|
|
@@ -270,6 +270,7 @@ def showSummary():
|
|
|
270
270
|
logging.info('----------------------------------------')
|
|
271
271
|
logging.info('-------- Vulnerabilities Found ---------')
|
|
272
272
|
logging.info('HIGH : %s | MEDIUM : %s | LOW : %s ', Config.high_count, Config.medium_count, Config.low_count)
|
|
273
|
+
logging.warning("The HIGH, MEDIUM and LOW counts are derived after excluding False Postive, Accepted Risk, Not Applicable and Muted Vulnerabilities")
|
|
273
274
|
logging.info('----------------------------------------')
|
|
274
275
|
logging.info('----------------------------------------')
|
|
275
276
|
logging.info('-------- SAST STATUS ---------')
|
|
@@ -1034,3 +1035,104 @@ def copy_file(source_path, dest_path):
|
|
|
1034
1035
|
return True
|
|
1035
1036
|
|
|
1036
1037
|
return False # Source file not found
|
|
1038
|
+
|
|
1039
|
+
def reachability_support_check(language):
|
|
1040
|
+
if language in Config.supported_languages_reachability:
|
|
1041
|
+
return language
|
|
1042
|
+
elif language == "nodejs":
|
|
1043
|
+
return "js"
|
|
1044
|
+
return False
|
|
1045
|
+
|
|
1046
|
+
|
|
1047
|
+
def reachability_analysis(bom_file, reachable_slices_file):
|
|
1048
|
+
"""Find and print reachable libraries by matching purls."""
|
|
1049
|
+
|
|
1050
|
+
# Load the SBOM and reachable slice JSON files
|
|
1051
|
+
|
|
1052
|
+
sbom_data = load_json(bom_file)
|
|
1053
|
+
|
|
1054
|
+
reachable_slice_data = load_json(reachable_slices_file)
|
|
1055
|
+
|
|
1056
|
+
# print(sbom_data)
|
|
1057
|
+
|
|
1058
|
+
# Extract purls from SBOM
|
|
1059
|
+
|
|
1060
|
+
sbom_purls = {}
|
|
1061
|
+
|
|
1062
|
+
for component in sbom_data.get("components", []):
|
|
1063
|
+
|
|
1064
|
+
purl = component.get("purl")
|
|
1065
|
+
|
|
1066
|
+
if purl:
|
|
1067
|
+
# print(purl)
|
|
1068
|
+
if purl not in sbom_purls.keys():
|
|
1069
|
+
|
|
1070
|
+
package_name = component.get("name")
|
|
1071
|
+
package_version = component.get("version")
|
|
1072
|
+
|
|
1073
|
+
if package_name and package_version:
|
|
1074
|
+
sbom_purls[purl] = f'{package_name}@{package_version}'
|
|
1075
|
+
else:
|
|
1076
|
+
sbom_purls[purl] = f'{package_name}'
|
|
1077
|
+
|
|
1078
|
+
|
|
1079
|
+
|
|
1080
|
+
|
|
1081
|
+
# Check for matches in the reachable slice file
|
|
1082
|
+
reachable_packages = []
|
|
1083
|
+
reachable_dict = {}
|
|
1084
|
+
for reachable in reachable_slice_data.get("reachables", []):
|
|
1085
|
+
# print(reachable)
|
|
1086
|
+
for purl in reachable.get("purls", []):
|
|
1087
|
+
# print(purl)
|
|
1088
|
+
if purl in sbom_purls.keys():
|
|
1089
|
+
|
|
1090
|
+
if purl in reachable_dict.keys():
|
|
1091
|
+
|
|
1092
|
+
reachable_dict[purl].append(reachable.get("flows",[]))
|
|
1093
|
+
|
|
1094
|
+
else:
|
|
1095
|
+
reachable_dict[purl] = []
|
|
1096
|
+
|
|
1097
|
+
# print(reachable_dict.keys())
|
|
1098
|
+
for key in reachable_dict.keys():
|
|
1099
|
+
reachable_packages.append({
|
|
1100
|
+
"package":sbom_purls[key],
|
|
1101
|
+
"purl":key,
|
|
1102
|
+
"flows": reachable_dict[key]
|
|
1103
|
+
})
|
|
1104
|
+
return reachable_packages
|
|
1105
|
+
|
|
1106
|
+
def load_json(file_path):
|
|
1107
|
+
|
|
1108
|
+
"""Load a JSON file."""
|
|
1109
|
+
|
|
1110
|
+
with open(file_path, "r") as f:
|
|
1111
|
+
|
|
1112
|
+
return json.load(f)
|
|
1113
|
+
|
|
1114
|
+
def copy_contents(source,destination):
|
|
1115
|
+
|
|
1116
|
+
# Copy the file
|
|
1117
|
+
with open(source, 'rb') as src_file:
|
|
1118
|
+
with open(destination, 'wb') as dest_file:
|
|
1119
|
+
dest_file.write(src_file.read())
|
|
1120
|
+
|
|
1121
|
+
logging.info(f"File copied from {source} to {destination}")
|
|
1122
|
+
|
|
1123
|
+
def get_summary_of_vulns(response):
|
|
1124
|
+
vuln = {"LOW":0,"MEDIUM":0,"HIGH":0,"CRITICAL":0}
|
|
1125
|
+
if response['status'] == True:
|
|
1126
|
+
logging.info('Summary: Analyzing the vulnerabilities found')
|
|
1127
|
+
for data in response['data'] :
|
|
1128
|
+
vuln[data['_id']] = data['count']
|
|
1129
|
+
|
|
1130
|
+
Config.low_count = vuln['LOW']
|
|
1131
|
+
Config.medium_count = vuln['MEDIUM']
|
|
1132
|
+
Config.high_count = vuln['HIGH']
|
|
1133
|
+
Config.critical_count = vuln['CRITICAL']
|
|
1134
|
+
|
|
1135
|
+
logging.info('Summary: Analyzing Vulnerabitlites Done')
|
|
1136
|
+
|
|
1137
|
+
else:
|
|
1138
|
+
logging.info('Summary: Error Analyzing Vulnerabitlites.')
|
|
@@ -365,7 +365,19 @@ def tool_configuration_validation():
|
|
|
365
365
|
Config.scan_name = json_response['data']['scan_name']
|
|
366
366
|
Config.con_scan_response = json_response['data']['cs']
|
|
367
367
|
Config.sbom_response = json_response['data']['sbom']
|
|
368
|
-
Config.iac_scan_response = json_response['data']['iac']
|
|
368
|
+
Config.iac_scan_response = json_response['data']['iac']
|
|
369
|
+
|
|
370
|
+
if 'reachability' in json_response['data'].keys():
|
|
371
|
+
Config.reachability_response = json_response['data']['reachability']
|
|
372
|
+
if 'code_language' in json_response.keys():
|
|
373
|
+
Config.reachability_language = json_response['code_language']
|
|
374
|
+
Config.reachability_present = True
|
|
375
|
+
else:
|
|
376
|
+
Config.reachability_present = False
|
|
377
|
+
logging.warning("Reachability: Not Configured!!!! Message: Code language was not found on JSON Response")
|
|
378
|
+
else:
|
|
379
|
+
Config.reachability_present = False
|
|
380
|
+
logging.warning("Reachability: Not Configured!!!! Message: Tool configuration data was not found on JSON Response")
|
|
369
381
|
|
|
370
382
|
|
|
371
383
|
# if Config.json_response['data']['advanced_zap_auth']:
|
|
@@ -411,19 +423,19 @@ def tool_configuration_validation():
|
|
|
411
423
|
logging.error(f'Tool Config: Failed!!! exit code: 4(CONFIG ERROR) Message: SaaS CONFIGURATION ERROR: {ke}')
|
|
412
424
|
exit(4) #configuration error
|
|
413
425
|
|
|
414
|
-
Config.sast_build_dir = Config.sca_build_dir = Config.con_scan_build_dir = Config.sbom_build_dir = Config.iac_scan_build_dir = os.getcwd()+'/'
|
|
426
|
+
Config.sast_build_dir = Config.sca_build_dir = Config.con_scan_build_dir = Config.sbom_build_dir = Config.iac_scan_build_dir = Config.reachability_build_dir = os.getcwd()+'/'
|
|
415
427
|
|
|
416
428
|
try:
|
|
417
429
|
if Config.sast_present:
|
|
418
|
-
if Config.sast_response[0]['lang'] != "sonar":
|
|
430
|
+
if (Config.sast_response[0]['lang'] != "sonar") and (Config.sast_response[0]['lang'] != "semgrep-pro"):
|
|
419
431
|
Config.sast_message = 'SAST is properly configured'
|
|
420
432
|
Config.sast_ignore = True if Config.sast_configuration['ignore_files'].lower() == "true" else False
|
|
421
433
|
Config.sast_target = Config.sast_configuration['target']
|
|
422
434
|
Config.sast_lang = "semgrep"
|
|
423
435
|
Config.sast_ignore_folders_and_files = Config.sast_configuration['sast_ignore_file_data']
|
|
424
436
|
else:
|
|
425
|
-
Config.sast_lang =
|
|
426
|
-
logging.warning('Tool Config: SAST was properly configured on SaaS. It will be running
|
|
437
|
+
Config.sast_lang = Config.sast_response[0]['lang']
|
|
438
|
+
logging.warning(f'Tool Config: SAST was properly configured on SaaS. It will be running {Config.sast_lang} from SaaS')
|
|
427
439
|
else:
|
|
428
440
|
Config.sast_message = 'SAST was not properly configured on SaaS'
|
|
429
441
|
logging.warning('Tool Config: SAST was not properly configured on SaaS')
|
|
@@ -472,7 +484,11 @@ def tool_configuration_validation():
|
|
|
472
484
|
|
|
473
485
|
try:
|
|
474
486
|
if Config.secret_scan_present:
|
|
475
|
-
Config.
|
|
487
|
+
if Config.secret_scan_response[0]['tool'] != "Semgrep Pro":
|
|
488
|
+
Config.secret_scan_message = 'Secret Scan is properly configured'
|
|
489
|
+
else:
|
|
490
|
+
Config.secret_scan_lang = Config.secret_scan_response[0]['tool'].lower()
|
|
491
|
+
logging.warning(f"Tool Config: Secret Scan was properly configured on SaaS. It will be running {Config.secret_scan_response[0]['tool']} from SaaS")
|
|
476
492
|
else:
|
|
477
493
|
Config.secret_scan_message = 'Secret Scan was not properly configured on SaaS'
|
|
478
494
|
logging.warning('Tool Config: Secret Scan was not properly configured on SaaS')
|
|
@@ -483,11 +499,17 @@ def tool_configuration_validation():
|
|
|
483
499
|
|
|
484
500
|
try:
|
|
485
501
|
if Config.sca_present:
|
|
486
|
-
if Config.sca_response[0]['tool'] != "SNYK":
|
|
502
|
+
if Config.sca_response[0]['tool'] != "SNYK" and Config.sca_response[0]['tool'] != "Semgrep Pro":
|
|
487
503
|
Config.sca_message = 'SCA is properly configured'
|
|
504
|
+
if Config.reachability_present:
|
|
505
|
+
if Utils.reachability_support_check(Config.reachability_language):
|
|
506
|
+
Config.reachability_language = Utils.reachability_support_check(Config.reachability_language)
|
|
507
|
+
Config.sbom_present = True
|
|
508
|
+
else:
|
|
509
|
+
Config.reachability_present = False
|
|
488
510
|
else:
|
|
489
|
-
Config.sca_lang =
|
|
490
|
-
logging.warning(
|
|
511
|
+
Config.sca_lang = Config.sca_response[0]['tool'].lower()
|
|
512
|
+
logging.warning(f"Tool Config: SCA was properly configured on SaaS. It will be running {Config.sca_response[0]['tool']} from SaaS")
|
|
491
513
|
|
|
492
514
|
else:
|
|
493
515
|
Config.sca_message = 'SCA was not properly configured on SaaS'
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|