fosslight-binary 5.1.8__tar.gz → 5.1.10__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.
- {fosslight_binary-5.1.8 → fosslight_binary-5.1.10}/PKG-INFO +1 -2
- {fosslight_binary-5.1.8 → fosslight_binary-5.1.10}/requirements.txt +0 -1
- {fosslight_binary-5.1.8 → fosslight_binary-5.1.10}/setup.py +1 -1
- fosslight_binary-5.1.10/src/fosslight_binary/__init__.py +149 -0
- {fosslight_binary-5.1.8 → fosslight_binary-5.1.10}/src/fosslight_binary/_binary.py +18 -5
- {fosslight_binary-5.1.8 → fosslight_binary-5.1.10}/src/fosslight_binary/_binary_dao.py +60 -38
- {fosslight_binary-5.1.8 → fosslight_binary-5.1.10}/src/fosslight_binary/_jar_analysis.py +84 -40
- {fosslight_binary-5.1.8 → fosslight_binary-5.1.10}/src/fosslight_binary/binary_analysis.py +10 -3
- {fosslight_binary-5.1.8 → fosslight_binary-5.1.10}/src/fosslight_binary.egg-info/PKG-INFO +1 -2
- {fosslight_binary-5.1.8 → fosslight_binary-5.1.10}/src/fosslight_binary.egg-info/requires.txt +0 -1
- fosslight_binary-5.1.8/src/fosslight_binary/__init__.py +0 -0
- {fosslight_binary-5.1.8 → fosslight_binary-5.1.10}/LICENSE +0 -0
- {fosslight_binary-5.1.8 → fosslight_binary-5.1.10}/LICENSES/Apache-2.0.txt +0 -0
- {fosslight_binary-5.1.8 → fosslight_binary-5.1.10}/LICENSES/LicenseRef-3rd_party_licenses.txt +0 -0
- {fosslight_binary-5.1.8 → fosslight_binary-5.1.10}/MANIFEST.in +0 -0
- {fosslight_binary-5.1.8 → fosslight_binary-5.1.10}/README.md +0 -0
- {fosslight_binary-5.1.8 → fosslight_binary-5.1.10}/setup.cfg +0 -0
- {fosslight_binary-5.1.8 → fosslight_binary-5.1.10}/src/fosslight_binary/LICENSES/LICENSE +0 -0
- {fosslight_binary-5.1.8 → fosslight_binary-5.1.10}/src/fosslight_binary/LICENSES/LicenseRef-3rd_party_licenses.txt +0 -0
- {fosslight_binary-5.1.8 → fosslight_binary-5.1.10}/src/fosslight_binary/_help.py +0 -0
- {fosslight_binary-5.1.8 → fosslight_binary-5.1.10}/src/fosslight_binary/_simple_mode.py +0 -0
- {fosslight_binary-5.1.8 → fosslight_binary-5.1.10}/src/fosslight_binary/cli.py +0 -0
- {fosslight_binary-5.1.8 → fosslight_binary-5.1.10}/src/fosslight_binary.egg-info/SOURCES.txt +0 -0
- {fosslight_binary-5.1.8 → fosslight_binary-5.1.10}/src/fosslight_binary.egg-info/dependency_links.txt +0 -0
- {fosslight_binary-5.1.8 → fosslight_binary-5.1.10}/src/fosslight_binary.egg-info/entry_points.txt +0 -0
- {fosslight_binary-5.1.8 → fosslight_binary-5.1.10}/src/fosslight_binary.egg-info/top_level.txt +0 -0
- {fosslight_binary-5.1.8 → fosslight_binary-5.1.10}/tests/test_fosslight_binary.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: fosslight_binary
|
|
3
|
-
Version: 5.1.
|
|
3
|
+
Version: 5.1.10
|
|
4
4
|
Summary: FOSSLight Binary Scanner
|
|
5
5
|
Home-page: https://github.com/fosslight/fosslight_binary_scanner
|
|
6
6
|
Download-URL: https://github.com/fosslight/fosslight_binary_scanner
|
|
@@ -27,7 +27,6 @@ Requires-Dist: pytz
|
|
|
27
27
|
Requires-Dist: XlsxWriter
|
|
28
28
|
Requires-Dist: PyYAML
|
|
29
29
|
Requires-Dist: fosslight_util>=2.1.13
|
|
30
|
-
Requires-Dist: dependency-check
|
|
31
30
|
Requires-Dist: python-magic-bin; sys_platform == "win32"
|
|
32
31
|
Requires-Dist: python-magic; "darwin" in sys_platform
|
|
33
32
|
Requires-Dist: python-magic; "linux" in sys_platform
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
# Copyright (c) 2025 LG Electronics Inc.
|
|
4
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
import logging
|
|
6
|
+
import os
|
|
7
|
+
import stat
|
|
8
|
+
import subprocess
|
|
9
|
+
import tempfile
|
|
10
|
+
import urllib.request
|
|
11
|
+
import zipfile
|
|
12
|
+
import sys
|
|
13
|
+
|
|
14
|
+
logger = logging.getLogger(__name__)
|
|
15
|
+
DEPENDENCY_CHECK_VERSION = "12.1.7"
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def _install_dependency_check():
|
|
19
|
+
"""Install OWASP dependency-check"""
|
|
20
|
+
try:
|
|
21
|
+
# Skip if explicitly disabled
|
|
22
|
+
if os.environ.get('FOSSLIGHT_SKIP_AUTO_INSTALL', '').lower() in ('1', 'true', 'yes'):
|
|
23
|
+
logger.info("Auto-install disabled by environment variable")
|
|
24
|
+
return
|
|
25
|
+
|
|
26
|
+
env_home = os.environ.get('DEPENDENCY_CHECK_HOME', '').strip()
|
|
27
|
+
install_dir = None
|
|
28
|
+
forced_env = False
|
|
29
|
+
if env_home:
|
|
30
|
+
# Normalize
|
|
31
|
+
env_home_abs = os.path.abspath(env_home)
|
|
32
|
+
# Detect if env_home already the actual extracted root (ends with dependency-check)
|
|
33
|
+
candidate_bin_win = os.path.join(env_home_abs, 'bin', 'dependency-check.bat')
|
|
34
|
+
candidate_bin_nix = os.path.join(env_home_abs, 'bin', 'dependency-check.sh')
|
|
35
|
+
if os.path.exists(candidate_bin_win) or os.path.exists(candidate_bin_nix):
|
|
36
|
+
# env points directly to dependency-check root; install_dir is its parent
|
|
37
|
+
install_dir = os.path.dirname(env_home_abs)
|
|
38
|
+
forced_env = True
|
|
39
|
+
else:
|
|
40
|
+
# Assume env_home is the base directory where we should extract dependency-check/
|
|
41
|
+
install_dir = env_home_abs
|
|
42
|
+
|
|
43
|
+
if not install_dir:
|
|
44
|
+
# Fallback hierarchy: executable dir (if frozen) -> CWD
|
|
45
|
+
candidate_base = None
|
|
46
|
+
if getattr(sys, 'frozen', False):
|
|
47
|
+
exe_dir = os.path.dirname(os.path.abspath(sys.executable))
|
|
48
|
+
candidate_base = os.path.join(exe_dir, 'fosslight_dc_bin')
|
|
49
|
+
|
|
50
|
+
if not os.access(exe_dir, os.W_OK):
|
|
51
|
+
candidate_base = None
|
|
52
|
+
else:
|
|
53
|
+
logger.debug(f"Using executable directory base: {candidate_base}")
|
|
54
|
+
if not candidate_base:
|
|
55
|
+
candidate_base = os.path.abspath(os.path.join(os.getcwd(), 'fosslight_dc_bin'))
|
|
56
|
+
install_dir = candidate_base
|
|
57
|
+
else:
|
|
58
|
+
logger.debug(f"Resolved install_dir: {install_dir}")
|
|
59
|
+
bin_dir = os.path.join(install_dir, 'dependency-check', 'bin')
|
|
60
|
+
if sys.platform.startswith('win'):
|
|
61
|
+
dc_path = os.path.join(bin_dir, 'dependency-check.bat')
|
|
62
|
+
else:
|
|
63
|
+
dc_path = os.path.join(bin_dir, 'dependency-check.sh')
|
|
64
|
+
|
|
65
|
+
# Check if dependency-check already exists
|
|
66
|
+
if os.path.exists(dc_path):
|
|
67
|
+
try:
|
|
68
|
+
result = subprocess.run([dc_path, '--version'], capture_output=True, text=True, timeout=10)
|
|
69
|
+
if result.returncode == 0:
|
|
70
|
+
logger.debug("dependency-check already installed and working")
|
|
71
|
+
# If we detected an existing root via env, retain it, else set home now.
|
|
72
|
+
if forced_env:
|
|
73
|
+
os.environ['DEPENDENCY_CHECK_HOME'] = env_home_abs
|
|
74
|
+
else:
|
|
75
|
+
os.environ['DEPENDENCY_CHECK_HOME'] = os.path.join(install_dir, 'dependency-check')
|
|
76
|
+
os.environ['DEPENDENCY_CHECK_VERSION'] = DEPENDENCY_CHECK_VERSION
|
|
77
|
+
return
|
|
78
|
+
except (subprocess.TimeoutExpired, FileNotFoundError) as ex:
|
|
79
|
+
logger.debug(f"Exception in dependency-check --version: {ex}")
|
|
80
|
+
pass
|
|
81
|
+
|
|
82
|
+
# Download URL
|
|
83
|
+
download_url = (f"https://github.com/dependency-check/DependencyCheck/releases/"
|
|
84
|
+
f"download/v{DEPENDENCY_CHECK_VERSION}/"
|
|
85
|
+
f"dependency-check-{DEPENDENCY_CHECK_VERSION}-release.zip")
|
|
86
|
+
|
|
87
|
+
os.makedirs(install_dir, exist_ok=True)
|
|
88
|
+
logger.info(f"Downloading dependency-check {DEPENDENCY_CHECK_VERSION} from {download_url} ...")
|
|
89
|
+
|
|
90
|
+
# Download and extract
|
|
91
|
+
with urllib.request.urlopen(download_url) as response:
|
|
92
|
+
content = response.read()
|
|
93
|
+
|
|
94
|
+
with tempfile.NamedTemporaryFile(suffix='.zip', delete=False) as tmp_file:
|
|
95
|
+
tmp_file.write(content)
|
|
96
|
+
tmp_zip_path = tmp_file.name
|
|
97
|
+
|
|
98
|
+
with zipfile.ZipFile(tmp_zip_path, 'r') as zip_ref:
|
|
99
|
+
zip_ref.extractall(install_dir)
|
|
100
|
+
os.unlink(tmp_file.name)
|
|
101
|
+
|
|
102
|
+
# Make shell scripts executable
|
|
103
|
+
if os.path.exists(bin_dir):
|
|
104
|
+
if sys.platform.startswith('win'):
|
|
105
|
+
# Windows: .bat files only
|
|
106
|
+
scripts = ["dependency-check.bat"]
|
|
107
|
+
else:
|
|
108
|
+
# Linux/macOS: .sh files only
|
|
109
|
+
scripts = ["dependency-check.sh", "completion-for-dependency-check.sh"]
|
|
110
|
+
|
|
111
|
+
for script in scripts:
|
|
112
|
+
script_path = os.path.join(bin_dir, script)
|
|
113
|
+
if os.path.exists(script_path):
|
|
114
|
+
st = os.stat(script_path)
|
|
115
|
+
os.chmod(script_path, st.st_mode | stat.S_IEXEC)
|
|
116
|
+
|
|
117
|
+
logger.info("✅ OWASP dependency-check installed successfully!")
|
|
118
|
+
logger.info(f"Installed to: {os.path.join(install_dir, 'dependency-check')}")
|
|
119
|
+
|
|
120
|
+
# Set environment variables after successful installation
|
|
121
|
+
os.environ['DEPENDENCY_CHECK_VERSION'] = DEPENDENCY_CHECK_VERSION
|
|
122
|
+
os.environ['DEPENDENCY_CHECK_HOME'] = os.path.join(install_dir, 'dependency-check')
|
|
123
|
+
|
|
124
|
+
return True
|
|
125
|
+
|
|
126
|
+
except Exception as e:
|
|
127
|
+
logger.error(f"Failed to install dependency-check: {e}")
|
|
128
|
+
logger.info("dependency-check can be installed manually from: https://github.com/dependency-check/DependencyCheck/releases")
|
|
129
|
+
return False
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
def _auto_install_dependencies():
|
|
133
|
+
"""Auto-install required dependencies if not present."""
|
|
134
|
+
# Only run this once per session
|
|
135
|
+
if hasattr(_auto_install_dependencies, '_already_run'):
|
|
136
|
+
return
|
|
137
|
+
_auto_install_dependencies._already_run = True
|
|
138
|
+
|
|
139
|
+
try:
|
|
140
|
+
# Install binary version
|
|
141
|
+
_install_dependency_check()
|
|
142
|
+
|
|
143
|
+
logger.info(f"✅ dependency-check setup completed with version {DEPENDENCY_CHECK_VERSION}")
|
|
144
|
+
except Exception as e:
|
|
145
|
+
logger.warning(f"Auto-install failed: {e}")
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
# Auto-install on import
|
|
149
|
+
_auto_install_dependencies()
|
|
@@ -2,14 +2,18 @@
|
|
|
2
2
|
# -*- coding: utf-8 -*-
|
|
3
3
|
# Copyright (c) 2020 LG Electronics Inc.
|
|
4
4
|
# SPDX-License-Identifier: Apache-2.0
|
|
5
|
-
|
|
5
|
+
import os
|
|
6
6
|
import urllib.parse
|
|
7
7
|
import logging
|
|
8
8
|
import fosslight_util.constant as constant
|
|
9
|
+
from typing import Tuple
|
|
10
|
+
from fosslight_util.oss_item import FileItem
|
|
9
11
|
|
|
10
12
|
EXCLUDE_TRUE_VALUE = "Exclude"
|
|
11
13
|
TLSH_CHECKSUM_NULL = "0"
|
|
12
14
|
MAX_EXCEL_URL_LENGTH = 255
|
|
15
|
+
EXCEEDED_VUL_URL_LENGTH_COMMENT = f"Exceeded the maximum vulnerability URL length of {MAX_EXCEL_URL_LENGTH} characters."
|
|
16
|
+
_PACKAGE_DIR = ["node_modules", "venv", "Pods", "Carthage"]
|
|
13
17
|
|
|
14
18
|
logger = logging.getLogger(constant.LOGGER_NAME)
|
|
15
19
|
|
|
@@ -54,12 +58,9 @@ class BinaryItem(FileItem):
|
|
|
54
58
|
nvd_url = ", ".join(nvd_url).strip()
|
|
55
59
|
|
|
56
60
|
if nvd_url and len(nvd_url) > MAX_EXCEL_URL_LENGTH:
|
|
57
|
-
oss.comment =
|
|
61
|
+
oss.comment = EXCEEDED_VUL_URL_LENGTH_COMMENT
|
|
58
62
|
return nvd_url
|
|
59
63
|
|
|
60
|
-
def get_print_binary_only(self):
|
|
61
|
-
return (self.source_name_or_path + "\t" + self.checksum + "\t" + self.tlsh)
|
|
62
|
-
|
|
63
64
|
def get_print_array(self):
|
|
64
65
|
items = []
|
|
65
66
|
if self.oss_items:
|
|
@@ -110,3 +111,15 @@ class BinaryItem(FileItem):
|
|
|
110
111
|
if self.comment:
|
|
111
112
|
json_item["comment"] = self.comment
|
|
112
113
|
return items
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
def is_package_dir(bin_with_path: str, _root_path: str) -> Tuple[bool, str]:
|
|
117
|
+
is_pkg = False
|
|
118
|
+
pkg_path = ""
|
|
119
|
+
path_parts = bin_with_path.split(os.path.sep)
|
|
120
|
+
for pkg_dir in _PACKAGE_DIR:
|
|
121
|
+
if pkg_dir in path_parts:
|
|
122
|
+
pkg_index = path_parts.index(pkg_dir)
|
|
123
|
+
pkg_path = os.path.sep.join(path_parts[:pkg_index + 1]).replace(_root_path, '', 1)
|
|
124
|
+
is_pkg = True
|
|
125
|
+
return is_pkg, pkg_path
|
|
@@ -7,8 +7,9 @@ import tlsh
|
|
|
7
7
|
import logging
|
|
8
8
|
import psycopg2
|
|
9
9
|
import pandas as pd
|
|
10
|
+
import socket
|
|
10
11
|
from urllib.parse import urlparse
|
|
11
|
-
from ._binary import TLSH_CHECKSUM_NULL
|
|
12
|
+
from fosslight_binary._binary import TLSH_CHECKSUM_NULL
|
|
12
13
|
from fosslight_util.oss_item import OssItem
|
|
13
14
|
import fosslight_util.constant as constant
|
|
14
15
|
|
|
@@ -18,47 +19,67 @@ columns = ['filename', 'pathname', 'checksum', 'tlshchecksum', 'ossname',
|
|
|
18
19
|
conn = ""
|
|
19
20
|
cur = ""
|
|
20
21
|
logger = logging.getLogger(constant.LOGGER_NAME)
|
|
22
|
+
DB_URL_DEFAULT = "postgresql://bin_analysis_script_user:script_123@bat.lge.com:5432/bat"
|
|
21
23
|
|
|
22
24
|
|
|
23
25
|
def get_oss_info_from_db(bin_info_list, dburl=""):
|
|
24
26
|
_cnt_auto_identified = 0
|
|
25
|
-
conn_str = get_connection_string(dburl)
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
27
|
+
conn_str, dbc = get_connection_string(dburl)
|
|
28
|
+
# DB URL에서 host 추출
|
|
29
|
+
try:
|
|
30
|
+
db_host = dbc.hostname
|
|
31
|
+
except Exception as ex:
|
|
32
|
+
logger.warning(f"Failed to parse DB URL for host: {ex}")
|
|
33
|
+
db_host = None
|
|
34
|
+
|
|
35
|
+
is_internal = False
|
|
36
|
+
if db_host:
|
|
37
|
+
try:
|
|
38
|
+
# DNS lookup 시도
|
|
39
|
+
socket.gethostbyname(db_host)
|
|
40
|
+
is_internal = True
|
|
41
|
+
except Exception:
|
|
42
|
+
is_internal = False
|
|
43
|
+
|
|
44
|
+
if is_internal:
|
|
45
|
+
connect_to_lge_bin_db(conn_str)
|
|
46
|
+
if conn != "" and cur != "":
|
|
47
|
+
for item in bin_info_list:
|
|
48
|
+
bin_oss_items = []
|
|
49
|
+
tlsh_value = item.tlsh
|
|
50
|
+
checksum_value = item.checksum
|
|
51
|
+
bin_file_name = item.binary_name_without_path
|
|
52
|
+
|
|
53
|
+
df_result = get_oss_info_by_tlsh_and_filename(
|
|
54
|
+
bin_file_name, checksum_value, tlsh_value)
|
|
55
|
+
if df_result is not None and len(df_result) > 0:
|
|
56
|
+
_cnt_auto_identified += 1
|
|
57
|
+
# Initialize the saved contents at .jar analyzing only once
|
|
58
|
+
if not item.found_in_owasp and item.oss_items:
|
|
59
|
+
item.oss_items = []
|
|
60
|
+
|
|
61
|
+
for idx, row in df_result.iterrows():
|
|
62
|
+
if not item.found_in_owasp:
|
|
63
|
+
oss_from_db = OssItem(row['ossname'], row['ossversion'], row['license'])
|
|
64
|
+
|
|
65
|
+
if bin_oss_items:
|
|
66
|
+
if not any(oss_item.name == oss_from_db.name
|
|
67
|
+
and oss_item.version == oss_from_db.version
|
|
68
|
+
and oss_item.license == oss_from_db.license
|
|
69
|
+
for oss_item in bin_oss_items):
|
|
70
|
+
bin_oss_items.append(oss_from_db)
|
|
71
|
+
else:
|
|
52
72
|
bin_oss_items.append(oss_from_db)
|
|
53
|
-
else:
|
|
54
|
-
bin_oss_items.append(oss_from_db)
|
|
55
|
-
|
|
56
|
-
if bin_oss_items:
|
|
57
|
-
item.set_oss_items(bin_oss_items)
|
|
58
|
-
item.comment = "Binary DB result"
|
|
59
|
-
item.found_in_binary = True
|
|
60
73
|
|
|
61
|
-
|
|
74
|
+
if bin_oss_items:
|
|
75
|
+
item.set_oss_items(bin_oss_items)
|
|
76
|
+
item.comment = "Binary DB result"
|
|
77
|
+
item.found_in_binary = True
|
|
78
|
+
else:
|
|
79
|
+
logger.warning(f"Internal network detected, but DB connection to '{db_host}' failed. Skipping DB query.")
|
|
80
|
+
disconnect_lge_bin_db()
|
|
81
|
+
else:
|
|
82
|
+
logger.debug(f"Binary DB host '{db_host}' is not reachable. Skipping DB query.")
|
|
62
83
|
return bin_info_list, _cnt_auto_identified
|
|
63
84
|
|
|
64
85
|
|
|
@@ -66,9 +87,10 @@ def get_connection_string(dburl):
|
|
|
66
87
|
# dburl format : 'postgresql://username:password@host:port/database_name'
|
|
67
88
|
connection_string = ""
|
|
68
89
|
user_dburl = True
|
|
90
|
+
dbc = ""
|
|
69
91
|
if dburl == "" or dburl is None:
|
|
70
92
|
user_dburl = False
|
|
71
|
-
dburl =
|
|
93
|
+
dburl = DB_URL_DEFAULT
|
|
72
94
|
try:
|
|
73
95
|
if user_dburl:
|
|
74
96
|
logger.debug("DB URL:" + dburl)
|
|
@@ -83,7 +105,7 @@ def get_connection_string(dburl):
|
|
|
83
105
|
if user_dburl:
|
|
84
106
|
logger.warning(f"(Minor) Failed to parsing db url : {ex}")
|
|
85
107
|
|
|
86
|
-
return connection_string
|
|
108
|
+
return connection_string, dbc
|
|
87
109
|
|
|
88
110
|
|
|
89
111
|
def get_oss_info_by_tlsh_and_filename(file_name, checksum_value, tlsh_value):
|
|
@@ -7,23 +7,26 @@ import logging
|
|
|
7
7
|
import json
|
|
8
8
|
import os
|
|
9
9
|
import sys
|
|
10
|
+
import subprocess
|
|
10
11
|
import fosslight_util.constant as constant
|
|
11
|
-
from ._binary import BinaryItem, VulnerabilityItem
|
|
12
|
+
from fosslight_binary._binary import BinaryItem, VulnerabilityItem, is_package_dir
|
|
12
13
|
from fosslight_util.oss_item import OssItem
|
|
13
|
-
from dependency_check import run as dependency_check_run
|
|
14
|
-
|
|
15
14
|
|
|
16
15
|
logger = logging.getLogger(constant.LOGGER_NAME)
|
|
17
16
|
|
|
18
17
|
|
|
19
|
-
def run_analysis(
|
|
18
|
+
def run_analysis(command):
|
|
20
19
|
try:
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
20
|
+
result = subprocess.run(command, text=True, timeout=600)
|
|
21
|
+
if result.returncode != 0:
|
|
22
|
+
logger.error(f"dependency-check failed with return code {result.returncode}")
|
|
23
|
+
raise Exception(f"dependency-check failed with return code {result.returncode}")
|
|
24
|
+
except subprocess.TimeoutExpired:
|
|
25
|
+
logger.error("dependency-check command timed out")
|
|
26
|
+
raise
|
|
25
27
|
except Exception as ex:
|
|
26
28
|
logger.error(f"Run Analysis : {ex}")
|
|
29
|
+
raise
|
|
27
30
|
|
|
28
31
|
|
|
29
32
|
def get_oss_ver(version_info):
|
|
@@ -57,29 +60,42 @@ def get_oss_lic_in_jar(data):
|
|
|
57
60
|
return license
|
|
58
61
|
|
|
59
62
|
|
|
63
|
+
def merge_oss_and_vul_items(bin, key, oss_list, vulnerability_items):
|
|
64
|
+
bin.set_oss_items(oss_list)
|
|
65
|
+
if vulnerability_items and vulnerability_items.get(key):
|
|
66
|
+
bin.vulnerability_items.extend(vulnerability_items.get(key, []))
|
|
67
|
+
|
|
68
|
+
|
|
60
69
|
def merge_binary_list(owasp_items, vulnerability_items, bin_list):
|
|
61
70
|
not_found_bin = []
|
|
62
71
|
|
|
63
|
-
# key : file_path / value : oss_list for one binary
|
|
72
|
+
# key : file_path / value : {"oss_list": [oss], "sha1": sha1} for one binary
|
|
64
73
|
for key, value in owasp_items.items():
|
|
65
74
|
found = False
|
|
75
|
+
oss_list = value["oss_list"]
|
|
76
|
+
sha1 = value.get("sha1", "")
|
|
66
77
|
for bin in bin_list:
|
|
67
78
|
if bin.source_name_or_path == key:
|
|
68
|
-
|
|
79
|
+
found = True
|
|
80
|
+
for oss in oss_list:
|
|
69
81
|
if oss.name and oss.license:
|
|
70
82
|
bin.found_in_owasp = True
|
|
71
83
|
break
|
|
72
|
-
bin
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
break
|
|
84
|
+
merge_oss_and_vul_items(bin, key, oss_list, vulnerability_items)
|
|
85
|
+
else:
|
|
86
|
+
if bin.checksum == sha1:
|
|
87
|
+
merge_oss_and_vul_items(bin, key, oss_list, vulnerability_items)
|
|
77
88
|
|
|
78
89
|
if not found:
|
|
79
90
|
bin_item = BinaryItem(os.path.abspath(key))
|
|
80
91
|
bin_item.binary_name_without_path = os.path.basename(key)
|
|
81
92
|
bin_item.source_name_or_path = key
|
|
82
|
-
|
|
93
|
+
|
|
94
|
+
is_pkg, _ = is_package_dir(bin_item.source_name_or_path, '')
|
|
95
|
+
if is_pkg:
|
|
96
|
+
continue
|
|
97
|
+
|
|
98
|
+
bin_item.set_oss_items(oss_list)
|
|
83
99
|
not_found_bin.append(bin_item)
|
|
84
100
|
|
|
85
101
|
bin_list += not_found_bin
|
|
@@ -172,12 +188,27 @@ def analyze_jar_file(path_to_find_bin, path_to_exclude):
|
|
|
172
188
|
success = True
|
|
173
189
|
json_file = ""
|
|
174
190
|
|
|
175
|
-
|
|
191
|
+
# Use fixed install path: ./fosslight_dc_bin/dependency-check/bin/dependency-check.sh or .bat
|
|
192
|
+
if sys.platform.startswith('win'):
|
|
193
|
+
depcheck_path = os.path.abspath(os.path.join(os.getcwd(), 'fosslight_dc_bin', 'dependency-check', 'bin', 'dependency-check.bat'))
|
|
194
|
+
elif sys.platform.startswith('linux'):
|
|
195
|
+
depcheck_path = os.path.abspath(os.path.join(os.getcwd(), 'fosslight_dc_bin', 'dependency-check', 'bin', 'dependency-check.sh'))
|
|
196
|
+
elif sys.platform.startswith('darwin'):
|
|
197
|
+
depcheck_path = os.path.abspath(os.path.join(os.getcwd(), 'dependency-check'))
|
|
198
|
+
|
|
199
|
+
if not (os.path.isfile(depcheck_path) and os.access(depcheck_path, os.X_OK)):
|
|
200
|
+
logger.error(f'dependency-check script not found or not executable at {depcheck_path}')
|
|
201
|
+
success = False
|
|
202
|
+
return owasp_items, vulnerability_items, success
|
|
203
|
+
|
|
204
|
+
command = [depcheck_path, '--scan', f'{path_to_find_bin}', '--out', f'{path_to_find_bin}',
|
|
176
205
|
'--disableArchive', '--disableAssembly', '--disableRetireJS', '--disableNodeJS',
|
|
177
206
|
'--disableNodeAudit', '--disableNugetconf', '--disableNuspec', '--disableOpenSSL',
|
|
178
|
-
'--disableOssIndex', '--disableBundleAudit', '--
|
|
207
|
+
'--disableOssIndex', '--disableBundleAudit', '--disableOssIndex', '--nvdValidForHours', '168',
|
|
208
|
+
'--nvdDatafeed', 'https://nvd.nist.gov/feeds/json/cve/2.0/nvdcve-2.0-{0}.json.gz', '-f', 'JSON']
|
|
209
|
+
|
|
179
210
|
try:
|
|
180
|
-
run_analysis(command
|
|
211
|
+
run_analysis(command)
|
|
181
212
|
except Exception as ex:
|
|
182
213
|
logger.info(f"Error to analyze .jar file - OSS information for .jar file isn't included in report.\n {ex}")
|
|
183
214
|
success = False
|
|
@@ -192,7 +223,8 @@ def analyze_jar_file(path_to_find_bin, path_to_exclude):
|
|
|
192
223
|
success = False
|
|
193
224
|
return owasp_items, vulnerability_items, success
|
|
194
225
|
|
|
195
|
-
dependencies = jar_contents.get("dependencies")
|
|
226
|
+
dependencies = jar_contents.get("dependencies", [])
|
|
227
|
+
|
|
196
228
|
try:
|
|
197
229
|
for val in dependencies:
|
|
198
230
|
bin_with_path = ""
|
|
@@ -204,6 +236,8 @@ def analyze_jar_file(path_to_find_bin, path_to_exclude):
|
|
|
204
236
|
oss_license = get_oss_lic_in_jar(val)
|
|
205
237
|
oss_name_found = False
|
|
206
238
|
|
|
239
|
+
sha1 = val.get("sha1", "")
|
|
240
|
+
|
|
207
241
|
all_evidence = val.get("evidenceCollected", {})
|
|
208
242
|
vulnerability = val.get("vulnerabilityIds", [])
|
|
209
243
|
all_pkg_info = val.get("packages", [])
|
|
@@ -223,7 +257,22 @@ def analyze_jar_file(path_to_find_bin, path_to_exclude):
|
|
|
223
257
|
if not bin_with_path.endswith('.jar'):
|
|
224
258
|
bin_with_path = bin_with_path.split('.jar')[0] + '.jar'
|
|
225
259
|
|
|
226
|
-
|
|
260
|
+
try:
|
|
261
|
+
path_to_fild_bin_abs = os.path.abspath(path_to_find_bin)
|
|
262
|
+
bin_with_path_abs = os.path.abspath(bin_with_path)
|
|
263
|
+
if os.name == 'nt': # Windows
|
|
264
|
+
drive_bin = os.path.splitdrive(bin_with_path_abs)[0].lower()
|
|
265
|
+
drive_root = os.path.splitdrive(path_to_fild_bin_abs)[0].lower()
|
|
266
|
+
# Different drive or UNC root -> fallback to basename
|
|
267
|
+
if drive_bin and drive_root and drive_bin != drive_root:
|
|
268
|
+
file_with_path = os.path.basename(bin_with_path_abs)
|
|
269
|
+
else:
|
|
270
|
+
file_with_path = os.path.relpath(bin_with_path_abs, path_to_fild_bin_abs)
|
|
271
|
+
else:
|
|
272
|
+
file_with_path = os.path.relpath(bin_with_path_abs, path_to_fild_bin_abs)
|
|
273
|
+
except Exception as e:
|
|
274
|
+
file_with_path = os.path.basename(bin_with_path)
|
|
275
|
+
logger.error(f"relpath error: {e}; fallback basename: {file_with_path}")
|
|
227
276
|
|
|
228
277
|
# First, Get OSS Name and Version info from pkg_info
|
|
229
278
|
for pkg_info in all_pkg_info:
|
|
@@ -259,31 +308,26 @@ def analyze_jar_file(path_to_find_bin, path_to_exclude):
|
|
|
259
308
|
# Get Vulnerability Info.
|
|
260
309
|
vulnerability_items = get_vulnerability_info(file_with_path, vulnerability, vulnerability_items, remove_vulnerability_items)
|
|
261
310
|
|
|
262
|
-
if oss_name
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
existing_oss = None
|
|
266
|
-
for item in oss_list_for_file:
|
|
267
|
-
if item.name == oss_name and item.version == oss_ver:
|
|
268
|
-
existing_oss = item
|
|
269
|
-
break
|
|
270
|
-
|
|
271
|
-
if not existing_oss:
|
|
272
|
-
oss = OssItem(oss_name, oss_ver, oss_license, oss_dl_url)
|
|
273
|
-
oss.comment = "OWASP result"
|
|
311
|
+
if oss_name or oss_license or oss_dl_url:
|
|
312
|
+
oss = OssItem(oss_name, oss_ver, oss_license, oss_dl_url)
|
|
313
|
+
oss.comment = "OWASP result"
|
|
274
314
|
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
315
|
+
if file_with_path in owasp_items:
|
|
316
|
+
owasp_items[file_with_path]["oss_list"].append(oss)
|
|
317
|
+
# Update sha1 if not already set or if current sha1 is empty
|
|
318
|
+
if not owasp_items[file_with_path]["sha1"] and sha1:
|
|
319
|
+
owasp_items[file_with_path]["sha1"] = sha1
|
|
320
|
+
else:
|
|
321
|
+
owasp_items[file_with_path] = {
|
|
322
|
+
"oss_list": [oss],
|
|
323
|
+
"sha1": sha1
|
|
324
|
+
}
|
|
279
325
|
except Exception as ex:
|
|
280
|
-
logger.debug(f"Error to get
|
|
281
|
-
success = False
|
|
326
|
+
logger.debug(f"Error to get dependency Info in jar_contents: {ex}")
|
|
282
327
|
|
|
283
328
|
try:
|
|
284
329
|
if os.path.isfile(json_file):
|
|
285
330
|
os.remove(json_file)
|
|
286
331
|
except Exception as ex:
|
|
287
332
|
logger.debug(f"Error - There is no .json file : {ex}")
|
|
288
|
-
|
|
289
333
|
return owasp_items, vulnerability_items, success
|
|
@@ -16,7 +16,7 @@ from fosslight_util.set_log import init_log
|
|
|
16
16
|
import fosslight_util.constant as constant
|
|
17
17
|
from fosslight_util.output_format import check_output_formats_v2, write_output_file
|
|
18
18
|
from ._binary_dao import get_oss_info_from_db
|
|
19
|
-
from ._binary import BinaryItem, TLSH_CHECKSUM_NULL
|
|
19
|
+
from ._binary import BinaryItem, TLSH_CHECKSUM_NULL, is_package_dir
|
|
20
20
|
from ._jar_analysis import analyze_jar_file, merge_binary_list
|
|
21
21
|
from ._simple_mode import print_simple_mode, filter_binary, init_simple
|
|
22
22
|
from fosslight_util.correct import correct_with_yaml
|
|
@@ -165,8 +165,15 @@ def get_file_list(path_to_find, abs_path_to_exclude):
|
|
|
165
165
|
bin_with_path = os.path.join(root, file)
|
|
166
166
|
bin_item = BinaryItem(bin_with_path)
|
|
167
167
|
bin_item.binary_name_without_path = file
|
|
168
|
-
bin_item.source_name_or_path = bin_with_path.replace(
|
|
169
|
-
|
|
168
|
+
bin_item.source_name_or_path = bin_with_path.replace(_root_path, '', 1)
|
|
169
|
+
|
|
170
|
+
is_pkg, pkg_path = is_package_dir(bin_with_path, _root_path)
|
|
171
|
+
if is_pkg:
|
|
172
|
+
bin_item.source_name_or_path = pkg_path
|
|
173
|
+
if not any(x.source_name_or_path == bin_item.source_name_or_path for x in bin_list):
|
|
174
|
+
bin_item.exclude = True
|
|
175
|
+
bin_list.append(bin_item)
|
|
176
|
+
continue
|
|
170
177
|
|
|
171
178
|
if any(dir_name in dir_path for dir_name in _EXCLUDE_DIR):
|
|
172
179
|
bin_item.exclude = True
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: fosslight_binary
|
|
3
|
-
Version: 5.1.
|
|
3
|
+
Version: 5.1.10
|
|
4
4
|
Summary: FOSSLight Binary Scanner
|
|
5
5
|
Home-page: https://github.com/fosslight/fosslight_binary_scanner
|
|
6
6
|
Download-URL: https://github.com/fosslight/fosslight_binary_scanner
|
|
@@ -27,7 +27,6 @@ Requires-Dist: pytz
|
|
|
27
27
|
Requires-Dist: XlsxWriter
|
|
28
28
|
Requires-Dist: PyYAML
|
|
29
29
|
Requires-Dist: fosslight_util>=2.1.13
|
|
30
|
-
Requires-Dist: dependency-check
|
|
31
30
|
Requires-Dist: python-magic-bin; sys_platform == "win32"
|
|
32
31
|
Requires-Dist: python-magic; "darwin" in sys_platform
|
|
33
32
|
Requires-Dist: python-magic; "linux" in sys_platform
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fosslight_binary-5.1.8 → fosslight_binary-5.1.10}/LICENSES/LicenseRef-3rd_party_licenses.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fosslight_binary-5.1.8 → fosslight_binary-5.1.10}/src/fosslight_binary.egg-info/SOURCES.txt
RENAMED
|
File without changes
|
|
File without changes
|
{fosslight_binary-5.1.8 → fosslight_binary-5.1.10}/src/fosslight_binary.egg-info/entry_points.txt
RENAMED
|
File without changes
|
{fosslight_binary-5.1.8 → fosslight_binary-5.1.10}/src/fosslight_binary.egg-info/top_level.txt
RENAMED
|
File without changes
|
|
File without changes
|