Skip to content

Commit cbb33e9

Browse files
authored
Merge pull request #24 from fosslight/develop
Apply OWASP dependency-check to analyze jar file
2 parents f7e224c + a85fe32 commit cbb33e9

File tree

9 files changed

+229
-30
lines changed

9 files changed

+229
-30
lines changed

.reuse/dep5

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@ Files: tests/askalono_macos
3434
Copyright: 2018 Amazon.com, Inc. or its affiliates.
3535
License: Apache-2.0
3636

37+
Files: tests/error_prone_annotations-2.7.1.jar
38+
Copyright: 2015 The Error Prone Authors.
39+
License: Apache-2.0
40+
3741
Files: tests/test/askalono_macos
3842
Copyright: 2018 Amazon.com, Inc. or its affiliates.
3943
License: Apache-2.0

requirements.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,5 @@ py-tlsh
88
pytz
99
XlsxWriter
1010
PyYAML
11-
fosslight_util>=1.3.4
11+
fosslight_util>=1.3.8
12+
dependency-check

src/fosslight_binary/_binary.py

Lines changed: 39 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,26 @@ class OssItem:
1414
name = ""
1515
version = ""
1616
license = ""
17+
dl_url = ""
18+
comment = ""
19+
exclude = False
1720

18-
def __init__(self, name, version, license):
21+
def __init__(self, name, version, license, dl_url=""):
1922
self.name = name
2023
self.version = version
2124
self.license = license
25+
self.dl_url = dl_url
26+
self.exclude = False
27+
self.comment = ""
28+
29+
def set_comment(self, value):
30+
self.comment += value
31+
32+
def set_exclude(self, value):
33+
self.exclude = value
34+
35+
def get_comment(self):
36+
return self.comment
2237

2338

2439
class BinaryItem:
@@ -28,10 +43,12 @@ class BinaryItem:
2843
tlsh = _TLSH_CHECKSUM_NULL
2944
checksum = _TLSH_CHECKSUM_NULL
3045
oss_items = []
31-
exclude = ""
46+
exclude = False
47+
comment = ""
48+
found_in_db = False
3249

3350
def __init__(self, value):
34-
self.exclude = ""
51+
self.exclude = False
3552
self.binary_strip_root = ""
3653
self.checksum = _TLSH_CHECKSUM_NULL
3754
self.tlsh = _TLSH_CHECKSUM_NULL
@@ -42,33 +59,46 @@ def __init__(self, value):
4259
def __del__(self):
4360
pass
4461

45-
def set_oss_items(self, value):
46-
self.oss_items.append(value)
62+
def set_oss_items(self, new_oss_list, exclude_old=False, exclude_msg=""):
63+
if exclude_old:
64+
for old_oss in self.oss_items:
65+
old_oss.set_exclude(True)
66+
old_oss.set_comment(exclude_msg)
67+
# Append New input OSS
68+
self.oss_items.extend(new_oss_list)
69+
70+
def set_commnet(self, value):
71+
self.comment = value
4772

4873
def set_bin_name(self, value):
4974
self.bin_name = value
5075

5176
def set_exclude(self, value):
52-
self.exclude = _EXCLUDE_TRUE_VALUE if value else ""
77+
self.exclude = value
5378

5479
def set_checksum(self, value):
5580
self.checksum = value
5681

5782
def set_tlsh(self, value):
5883
self.tlsh = value
5984

85+
def get_comment(self):
86+
return self.comment
87+
6088
def get_print_binary_only(self):
6189
return (self.binary_strip_root + "\t" + self.checksum + "\t" + self.tlsh)
6290

63-
def get_print_oss_report(self):
91+
def get_oss_report(self):
6492
print_rows = []
6593
if len(self.oss_items) > 0:
6694
for oss in self.oss_items:
95+
exclude = _EXCLUDE_TRUE_VALUE if (self.exclude or oss.exclude) else ""
6796
print_rows.append([self.binary_strip_root, oss.name, oss.version,
68-
oss.license, '', '', '', self.exclude, ''])
97+
oss.license, oss.dl_url, '', '', exclude, oss.comment])
6998
else:
99+
exclude = _EXCLUDE_TRUE_VALUE if self.exclude else ""
70100
print_rows.append([self.binary_strip_root, '',
71-
'', '', '', '', '', self.exclude, ''])
101+
'', '', '', '', '', exclude, ''])
72102

73103
return print_rows
74104

src/fosslight_binary/_binary_dao.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ def get_oss_info_from_db(bin_info_list, dburl=""):
2626

2727
if conn != "" and cur != "":
2828
for item in bin_info_list:
29+
bin_oss_items = []
2930
tlsh_value = item.tlsh
3031
checksum_value = item.checksum
3132
bin_file_name = item.binary_name_without_path
@@ -37,8 +38,12 @@ def get_oss_info_from_db(bin_info_list, dburl=""):
3738
for idx, row in df_result.iterrows():
3839
oss_from_db = OssItem(
3940
row['ossname'], row['ossversion'], row['license'])
40-
item.set_oss_items(oss_from_db)
41+
oss_from_db.set_comment("Binary DB Result")
42+
bin_oss_items.append(oss_from_db)
4143

44+
if bin_oss_items:
45+
item.found_in_db = True
46+
item.set_oss_items(bin_oss_items, True, "Excluded due to Binary DB.")
4247
disconnect_lge_bin_db()
4348
return bin_info_list, _cnt_auto_identified
4449

src/fosslight_binary/_help.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
1616
Options:
1717
-h\t\t\t\t Print help message
18+
-v\t\t\t\t Print FOSSLight Binary Scanner version
1819
-a <target_architecture>\t Target Architecture(x86-64, ARM, MIPS, Mach-O, and etc.)
1920
-o <output_path>\t\t Output path
2021
\t\t\t\t (If you want to generate the specific file name, add the output path with file name.)
Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
#!/usr/bin/env python
2+
# -*- coding: utf-8 -*-
3+
# Copyright (c) 2022 LG Electronics Inc.
4+
# SPDX-License-Identifier: Apache-2.0
5+
6+
import logging
7+
import json
8+
import os
9+
import subprocess
10+
import fosslight_util.constant as constant
11+
from ._binary import BinaryItem, OssItem
12+
13+
14+
logger = logging.getLogger(constant.LOGGER_NAME)
15+
16+
17+
def get_oss_ver(version):
18+
oss_version = ""
19+
20+
if version['source'] == 'pom':
21+
if version['name'] == 'version':
22+
oss_version = version['value']
23+
24+
return oss_version
25+
26+
27+
def get_oss_lic_in_jar(data):
28+
license = ""
29+
license_raw = str(data.get("license"))
30+
split_lic = license_raw.split(':')[0]
31+
32+
# Not NoneType but string 'None'
33+
if license_raw == "None":
34+
license = ""
35+
else:
36+
if not split_lic.startswith('http'):
37+
license = split_lic.replace(',', '')
38+
else:
39+
license = license_raw
40+
41+
return license
42+
43+
44+
def merge_binary_list(owasp_items, bin_list):
45+
not_found_bin = []
46+
47+
# key : file_path / value : oss_list for one binary
48+
for key, value in owasp_items.items():
49+
found = False
50+
for bin in bin_list:
51+
if bin.binary_strip_root == key:
52+
bin.set_oss_items(value, False)
53+
found = True
54+
break
55+
56+
if not found:
57+
bin_item = BinaryItem(os.path.abspath(key))
58+
bin_item.binary_name_without_path = os.path.basename(key)
59+
bin_item.binary_strip_root = key
60+
bin_item.set_oss_items(value)
61+
not_found_bin.append(bin_item)
62+
63+
bin_list += not_found_bin
64+
return bin_list
65+
66+
67+
def ananlyze_jar_file(path_to_find_bin):
68+
remove_owasp_item = []
69+
owasp_items = {}
70+
71+
try:
72+
command = f"dependency-check --scan {path_to_find_bin} --out {path_to_find_bin} --disableArchive --disableAssembly --disableRetireJS --disableNodeJS \
73+
--disableNodeAudit --disableNugetconf --disableNuspec --disableOpenSSL --disableOssIndex --disableBundleAudit -f ALL"
74+
subprocess.run(command, shell=True)
75+
76+
json_file = os.path.join(path_to_find_bin, 'dependency-check-report.json')
77+
78+
try:
79+
with open(json_file, 'r') as f:
80+
jar_contents = json.load(f)
81+
82+
dependencies = jar_contents.get("dependencies")
83+
for val in dependencies:
84+
bin_with_path = ""
85+
oss_name = ""
86+
oss_ver = ""
87+
oss_artifactid = ""
88+
oss_groupid = ""
89+
oss_dl_url = ""
90+
oss_license = get_oss_lic_in_jar(val)
91+
get_oss_info = False
92+
93+
all_evidence = val.get("evidenceCollected")
94+
vendor_evidences = all_evidence.get('vendorEvidence')
95+
product_evidences = all_evidence.get('productEvidence')
96+
version_evidences = all_evidence.get('versionEvidence')
97+
98+
# Check if the file is .jar file
99+
# Even if the oss info is from pom.xml in jar file, the file name will be .jar file.
100+
# But the oss info from pom.xml could be different from .jar file.
101+
bin_with_path = val.get("filePath")
102+
if not bin_with_path.endswith('.jar'):
103+
bin_with_path = bin_with_path.split('.jar')[0] + '.jar'
104+
105+
file_with_path = os.path.relpath(bin_with_path, path_to_find_bin)
106+
# Get Version info from versionEvidence
107+
for version_info in version_evidences:
108+
oss_ver = get_oss_ver(version_info)
109+
110+
# Get Artifact ID, Group ID, OSS Name from vendorEvidence
111+
for vendor_info in vendor_evidences:
112+
# Get OSS Info from POM
113+
if vendor_info['source'] == 'pom':
114+
if vendor_info['name'] == 'artifactid':
115+
oss_artifactid = vendor_info['value']
116+
if vendor_info['name'] == 'groupid':
117+
oss_groupid = vendor_info['value']
118+
if vendor_info['name'] == 'url':
119+
oss_dl_url = vendor_info['value']
120+
if oss_artifactid != "" and oss_groupid != "":
121+
oss_name = f"{oss_groupid}:{oss_artifactid}"
122+
123+
# Check if get oss_name and version from pom
124+
if oss_name != "" and oss_ver != "":
125+
get_oss_info = True
126+
127+
# If there is no pom.mxl in .jar file, get oss info from MANIFEST.MF file
128+
if get_oss_info is False:
129+
for product_info in product_evidences:
130+
if product_info['source'] == 'Manifest':
131+
if oss_name == "" and (product_info['name'] == 'Implementation-Title' or product_info['name'] == 'specification-title'):
132+
oss_name = product_info['value']
133+
if oss_ver == "" and (product_info['name'] == 'Implementation-Version' or product_info['name'] == 'Bundle-Version'):
134+
oss_ver = product_info['value']
135+
136+
oss = OssItem(oss_name, oss_ver, oss_license, oss_dl_url)
137+
oss.set_comment("OWASP Result. ")
138+
139+
remove_owasp_item = owasp_items.get(file_with_path)
140+
if remove_owasp_item:
141+
remove_owasp_item.append(oss)
142+
else:
143+
owasp_items[file_with_path] = [oss]
144+
145+
except Exception as ex:
146+
logger.warning(f"Error to read json file : {ex}")
147+
except Exception as ex:
148+
logger.warning(f"Error to use dependency-check : {ex}")
149+
150+
return owasp_items

0 commit comments

Comments
 (0)