socketsecurity 1.0.39__tar.gz → 1.0.41__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.
- {socketsecurity-1.0.39/socketsecurity.egg-info → socketsecurity-1.0.41}/PKG-INFO +3 -2
- {socketsecurity-1.0.39 → socketsecurity-1.0.41}/README.md +2 -1
- {socketsecurity-1.0.39 → socketsecurity-1.0.41}/socketsecurity/__init__.py +1 -1
- {socketsecurity-1.0.39 → socketsecurity-1.0.41}/socketsecurity/core/__init__.py +70 -59
- {socketsecurity-1.0.39 → socketsecurity-1.0.41}/socketsecurity/core/exceptions.py +4 -0
- {socketsecurity-1.0.39 → socketsecurity-1.0.41}/socketsecurity/socketcli.py +13 -1
- {socketsecurity-1.0.39 → socketsecurity-1.0.41/socketsecurity.egg-info}/PKG-INFO +3 -2
- {socketsecurity-1.0.39 → socketsecurity-1.0.41}/LICENSE +0 -0
- {socketsecurity-1.0.39 → socketsecurity-1.0.41}/pyproject.toml +0 -0
- {socketsecurity-1.0.39 → socketsecurity-1.0.41}/setup.cfg +0 -0
- {socketsecurity-1.0.39 → socketsecurity-1.0.41}/socketsecurity/core/classes.py +0 -0
- {socketsecurity-1.0.39 → socketsecurity-1.0.41}/socketsecurity/core/git_interface.py +0 -0
- {socketsecurity-1.0.39 → socketsecurity-1.0.41}/socketsecurity/core/github.py +0 -0
- {socketsecurity-1.0.39 → socketsecurity-1.0.41}/socketsecurity/core/gitlab.py +0 -0
- {socketsecurity-1.0.39 → socketsecurity-1.0.41}/socketsecurity/core/issues.py +0 -0
- {socketsecurity-1.0.39 → socketsecurity-1.0.41}/socketsecurity/core/licenses.py +0 -0
- {socketsecurity-1.0.39 → socketsecurity-1.0.41}/socketsecurity/core/messages.py +0 -0
- {socketsecurity-1.0.39 → socketsecurity-1.0.41}/socketsecurity/core/scm_comments.py +0 -0
- {socketsecurity-1.0.39 → socketsecurity-1.0.41}/socketsecurity.egg-info/SOURCES.txt +0 -0
- {socketsecurity-1.0.39 → socketsecurity-1.0.41}/socketsecurity.egg-info/dependency_links.txt +0 -0
- {socketsecurity-1.0.39 → socketsecurity-1.0.41}/socketsecurity.egg-info/entry_points.txt +0 -0
- {socketsecurity-1.0.39 → socketsecurity-1.0.41}/socketsecurity.egg-info/requires.txt +0 -0
- {socketsecurity-1.0.39 → socketsecurity-1.0.41}/socketsecurity.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.2
|
|
2
2
|
Name: socketsecurity
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.41
|
|
4
4
|
Summary: Socket Security CLI for CI/CD
|
|
5
5
|
Author-email: Douglas Coburn <douglas@socket.dev>
|
|
6
6
|
Maintainer-email: Douglas Coburn <douglas@socket.dev>
|
|
@@ -31,7 +31,7 @@ The Socket Security CLI was created to enable integrations with other tools like
|
|
|
31
31
|
socketcli [-h] [--api_token API_TOKEN] [--repo REPO] [--branch BRANCH] [--committer COMMITTER] [--pr_number PR_NUMBER]
|
|
32
32
|
[--commit_message COMMIT_MESSAGE] [--default_branch] [--target_path TARGET_PATH] [--scm {api,github,gitlab}] [--sbom-file SBOM_FILE]
|
|
33
33
|
[--commit-sha COMMIT_SHA] [--generate-license GENERATE_LICENSE] [-v] [--enable-debug] [--enable-json] [--disable-overview]
|
|
34
|
-
[--disable-security-issue] [--files FILES] [--ignore-commit-files]
|
|
34
|
+
[--disable-security-issue] [--files FILES] [--ignore-commit-files] [--timeout]
|
|
35
35
|
````
|
|
36
36
|
|
|
37
37
|
If you don't want to provide the Socket API Token every time then you can use the environment variable `SOCKET_SECURITY_API_KEY`
|
|
@@ -61,3 +61,4 @@ If you don't want to provide the Socket API Token every time then you can use th
|
|
|
61
61
|
| --files | | False | | If provided in the format of `["file1", "file2"]` will be used to determine if there have been supported file changes. This is used if it isn't a git repo and you would like to only run if it supported files have changed. |
|
|
62
62
|
| --ignore-commit-files | | False | False | If enabled then the CLI will ignore what files are changed in the commit and look for all manifest files |
|
|
63
63
|
| --disable-blocking | | False | False | Disables failing checks and will only exit with an exit code of 0 |
|
|
64
|
+
| --timeout | | False | 1200 | The timeout per request for the CLI |
|
|
@@ -8,7 +8,7 @@ The Socket Security CLI was created to enable integrations with other tools like
|
|
|
8
8
|
socketcli [-h] [--api_token API_TOKEN] [--repo REPO] [--branch BRANCH] [--committer COMMITTER] [--pr_number PR_NUMBER]
|
|
9
9
|
[--commit_message COMMIT_MESSAGE] [--default_branch] [--target_path TARGET_PATH] [--scm {api,github,gitlab}] [--sbom-file SBOM_FILE]
|
|
10
10
|
[--commit-sha COMMIT_SHA] [--generate-license GENERATE_LICENSE] [-v] [--enable-debug] [--enable-json] [--disable-overview]
|
|
11
|
-
[--disable-security-issue] [--files FILES] [--ignore-commit-files]
|
|
11
|
+
[--disable-security-issue] [--files FILES] [--ignore-commit-files] [--timeout]
|
|
12
12
|
````
|
|
13
13
|
|
|
14
14
|
If you don't want to provide the Socket API Token every time then you can use the environment variable `SOCKET_SECURITY_API_KEY`
|
|
@@ -38,3 +38,4 @@ If you don't want to provide the Socket API Token every time then you can use th
|
|
|
38
38
|
| --files | | False | | If provided in the format of `["file1", "file2"]` will be used to determine if there have been supported file changes. This is used if it isn't a git repo and you would like to only run if it supported files have changed. |
|
|
39
39
|
| --ignore-commit-files | | False | False | If enabled then the CLI will ignore what files are changed in the commit and look for all manifest files |
|
|
40
40
|
| --disable-blocking | | False | False | Disables failing checks and will only exit with an exit code of 0 |
|
|
41
|
+
| --timeout | | False | 1200 | The timeout per request for the CLI |
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
__author__ = 'socket.dev'
|
|
2
|
-
__version__ = '1.0.
|
|
2
|
+
__version__ = '1.0.41'
|
|
@@ -1,12 +1,18 @@
|
|
|
1
1
|
import logging
|
|
2
2
|
from pathlib import PurePath
|
|
3
|
-
|
|
3
|
+
from requests.exceptions import ReadTimeout
|
|
4
4
|
import requests
|
|
5
5
|
from urllib.parse import urlencode
|
|
6
6
|
import base64
|
|
7
7
|
import json
|
|
8
8
|
from socketsecurity.core.exceptions import (
|
|
9
|
-
APIFailure,
|
|
9
|
+
APIFailure,
|
|
10
|
+
APIKeyMissing,
|
|
11
|
+
APIAccessDenied,
|
|
12
|
+
APIInsufficientQuota,
|
|
13
|
+
APIResourceNotFound,
|
|
14
|
+
APICloudflareError,
|
|
15
|
+
RequestTimeoutExceeded
|
|
10
16
|
)
|
|
11
17
|
from socketsecurity import __version__
|
|
12
18
|
from socketsecurity.core.licenses import Licenses
|
|
@@ -182,15 +188,18 @@ def do_request(
|
|
|
182
188
|
verify = True
|
|
183
189
|
if allow_unverified_ssl:
|
|
184
190
|
verify = False
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
191
|
+
try:
|
|
192
|
+
response = requests.request(
|
|
193
|
+
method.upper(),
|
|
194
|
+
url,
|
|
195
|
+
headers=headers,
|
|
196
|
+
data=payload,
|
|
197
|
+
files=files,
|
|
198
|
+
timeout=timeout,
|
|
199
|
+
verify=verify
|
|
200
|
+
)
|
|
201
|
+
except ReadTimeout:
|
|
202
|
+
raise RequestTimeoutExceeded(f"Configured timeout {timeout} reached for request for path {url}")
|
|
194
203
|
output_headers = headers.copy()
|
|
195
204
|
output_headers['Authorization'] = "API_KEY_REDACTED"
|
|
196
205
|
output = {
|
|
@@ -437,25 +446,17 @@ class Core:
|
|
|
437
446
|
for ecosystem in socket_globs:
|
|
438
447
|
patterns = socket_globs[ecosystem]
|
|
439
448
|
for file_name in patterns:
|
|
440
|
-
pattern = patterns[file_name]["pattern"]
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
glob_start = time.time()
|
|
452
|
-
glob_files = glob(file_path, recursive=True)
|
|
453
|
-
for glob_file in glob_files:
|
|
454
|
-
if glob_file not in files:
|
|
455
|
-
files.add(glob_file)
|
|
456
|
-
glob_end = time.time()
|
|
457
|
-
glob_total_time = glob_end - glob_start
|
|
458
|
-
log.debug(f"Glob for pattern {file_path} took {glob_total_time:.2f} seconds")
|
|
449
|
+
pattern = Core.to_case_insensitive_regex(patterns[file_name]["pattern"])
|
|
450
|
+
file_path = f"{path}/**/{pattern}"
|
|
451
|
+
log.debug(f"Globbing {file_path}")
|
|
452
|
+
glob_start = time.time()
|
|
453
|
+
glob_files = glob(file_path, recursive=True)
|
|
454
|
+
for glob_file in glob_files:
|
|
455
|
+
if glob_file not in files:
|
|
456
|
+
files.add(glob_file)
|
|
457
|
+
glob_end = time.time()
|
|
458
|
+
glob_total_time = glob_end - glob_start
|
|
459
|
+
log.debug(f"Glob for pattern {file_path} took {glob_total_time:.2f} seconds")
|
|
459
460
|
|
|
460
461
|
log.debug("Finished Find Files")
|
|
461
462
|
end_time = time.time()
|
|
@@ -475,10 +476,6 @@ class Core:
|
|
|
475
476
|
send_files = []
|
|
476
477
|
create_full_start = time.time()
|
|
477
478
|
log.debug("Creating new full scan")
|
|
478
|
-
|
|
479
|
-
# Track unique paths (case-insensitive) to avoid duplicates
|
|
480
|
-
seen_paths = {}
|
|
481
|
-
|
|
482
479
|
for file in files:
|
|
483
480
|
if platform.system() == "Windows":
|
|
484
481
|
file = file.replace("\\", "/")
|
|
@@ -488,27 +485,20 @@ class Core:
|
|
|
488
485
|
path = "."
|
|
489
486
|
name = file
|
|
490
487
|
full_path = f"{path}/{name}"
|
|
491
|
-
|
|
492
488
|
if full_path.startswith(workspace):
|
|
493
489
|
key = full_path[len(workspace):]
|
|
494
490
|
else:
|
|
495
491
|
key = full_path
|
|
496
492
|
key = key.lstrip("/")
|
|
497
493
|
key = key.lstrip("./")
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
payload = (
|
|
504
|
-
key,
|
|
505
|
-
(
|
|
506
|
-
name,
|
|
507
|
-
open(full_path, 'rb')
|
|
508
|
-
)
|
|
494
|
+
payload = (
|
|
495
|
+
key,
|
|
496
|
+
(
|
|
497
|
+
name,
|
|
498
|
+
open(full_path, 'rb')
|
|
509
499
|
)
|
|
510
|
-
|
|
511
|
-
|
|
500
|
+
)
|
|
501
|
+
send_files.append(payload)
|
|
512
502
|
query_params = urlencode(params.__dict__)
|
|
513
503
|
full_uri = f"{full_scan_path}?{query_params}"
|
|
514
504
|
response = do_request(full_uri, method="POST", files=send_files)
|
|
@@ -813,15 +803,18 @@ class Core:
|
|
|
813
803
|
else:
|
|
814
804
|
for top_id in package.topLevelAncestors:
|
|
815
805
|
top_package: Package
|
|
816
|
-
top_package = packages
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
806
|
+
top_package = packages.get(top_id)
|
|
807
|
+
if top_package:
|
|
808
|
+
manifests = ""
|
|
809
|
+
top_purl = f"{top_package.type}/{top_package.name}@{top_package.version}"
|
|
810
|
+
for manifest_data in top_package.manifestFiles:
|
|
811
|
+
manifest_file = manifest_data.get("file")
|
|
812
|
+
manifests += f"{manifest_file};"
|
|
813
|
+
manifests = manifests.rstrip(";")
|
|
814
|
+
source = (top_purl, manifests)
|
|
815
|
+
introduced_by.append(source)
|
|
816
|
+
else:
|
|
817
|
+
log.debug(f"Unable to get top level package info for {top_id}")
|
|
825
818
|
return introduced_by
|
|
826
819
|
|
|
827
820
|
@staticmethod
|
|
@@ -860,21 +853,29 @@ class Core:
|
|
|
860
853
|
"""
|
|
861
854
|
packages = {}
|
|
862
855
|
top_level_count = {}
|
|
856
|
+
top_levels = {}
|
|
863
857
|
for item in sbom:
|
|
864
858
|
package = Package(**item)
|
|
865
859
|
if package.id in packages:
|
|
866
|
-
|
|
860
|
+
log.debug("Duplicate package?")
|
|
867
861
|
else:
|
|
868
862
|
package = Core.get_license_details(package)
|
|
869
863
|
packages[package.id] = package
|
|
870
864
|
for top_id in package.topLevelAncestors:
|
|
871
865
|
if top_id not in top_level_count:
|
|
872
866
|
top_level_count[top_id] = 1
|
|
867
|
+
top_levels[top_id] = [package.id]
|
|
873
868
|
else:
|
|
874
869
|
top_level_count[top_id] += 1
|
|
870
|
+
if package.id not in top_levels[top_id]:
|
|
871
|
+
top_levels[top_id].append(package.id)
|
|
875
872
|
if len(top_level_count) > 0:
|
|
876
873
|
for package_id in top_level_count:
|
|
877
|
-
|
|
874
|
+
if package_id not in packages:
|
|
875
|
+
details = top_levels.get(package_id)
|
|
876
|
+
log.debug(f"Orphaned top level package id {package_id} for packages {details}")
|
|
877
|
+
else:
|
|
878
|
+
packages[package_id].transitives = top_level_count[package_id]
|
|
878
879
|
return packages
|
|
879
880
|
|
|
880
881
|
@staticmethod
|
|
@@ -883,6 +884,16 @@ class Core:
|
|
|
883
884
|
file.write(content)
|
|
884
885
|
file.close()
|
|
885
886
|
|
|
887
|
+
@staticmethod
|
|
888
|
+
def to_case_insensitive_regex(input_string: str) -> str:
|
|
889
|
+
"""
|
|
890
|
+
Converts a string into a case-insensitive regex format.
|
|
891
|
+
Example: "pipfile" -> "[Pp][Ii][Pp][Ff][Ii][Ll][Ee]"
|
|
892
|
+
:param input_string: The input string to convert.
|
|
893
|
+
:return: A case-insensitive regex string.
|
|
894
|
+
"""
|
|
895
|
+
return ''.join(f'[{char.lower()}{char.upper()}]' if char.isalpha() else char for char in input_string)
|
|
896
|
+
|
|
886
897
|
# @staticmethod
|
|
887
898
|
# def create_license_file(diff: Diff) -> None:
|
|
888
899
|
# output = []
|
|
@@ -161,6 +161,16 @@ parser.add_argument(
|
|
|
161
161
|
default=False
|
|
162
162
|
)
|
|
163
163
|
|
|
164
|
+
parser.add_argument(
|
|
165
|
+
'--timeout',
|
|
166
|
+
default=1200,
|
|
167
|
+
help='Timeout configuration for each request. Defaults to 1200 and applies to each unique HTTP request',
|
|
168
|
+
required=False,
|
|
169
|
+
type=float
|
|
170
|
+
)
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
|
|
164
174
|
|
|
165
175
|
def output_console_comments(diff_report: Diff, sbom_file_name: str = None) -> None:
|
|
166
176
|
if diff_report.id != "NO_DIFF_RAN":
|
|
@@ -252,6 +262,8 @@ def main_code():
|
|
|
252
262
|
ignore_commit_files = arguments.ignore_commit_files
|
|
253
263
|
disable_blocking = arguments.disable_blocking
|
|
254
264
|
allow_unverified = arguments.allow_unverified
|
|
265
|
+
timeout = arguments.timeout
|
|
266
|
+
|
|
255
267
|
if disable_blocking:
|
|
256
268
|
global blocking_disabled
|
|
257
269
|
blocking_disabled = True
|
|
@@ -308,7 +320,7 @@ def main_code():
|
|
|
308
320
|
default_branch = scm.is_default_branch
|
|
309
321
|
|
|
310
322
|
base_api_url = os.getenv("BASE_API_URL") or None
|
|
311
|
-
core = Core(token=api_token, request_timeout=
|
|
323
|
+
core = Core(token=api_token, request_timeout=timeout, base_api_url=base_api_url, allow_unverified=allow_unverified)
|
|
312
324
|
no_change = True
|
|
313
325
|
if ignore_commit_files:
|
|
314
326
|
no_change = False
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.2
|
|
2
2
|
Name: socketsecurity
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.41
|
|
4
4
|
Summary: Socket Security CLI for CI/CD
|
|
5
5
|
Author-email: Douglas Coburn <douglas@socket.dev>
|
|
6
6
|
Maintainer-email: Douglas Coburn <douglas@socket.dev>
|
|
@@ -31,7 +31,7 @@ The Socket Security CLI was created to enable integrations with other tools like
|
|
|
31
31
|
socketcli [-h] [--api_token API_TOKEN] [--repo REPO] [--branch BRANCH] [--committer COMMITTER] [--pr_number PR_NUMBER]
|
|
32
32
|
[--commit_message COMMIT_MESSAGE] [--default_branch] [--target_path TARGET_PATH] [--scm {api,github,gitlab}] [--sbom-file SBOM_FILE]
|
|
33
33
|
[--commit-sha COMMIT_SHA] [--generate-license GENERATE_LICENSE] [-v] [--enable-debug] [--enable-json] [--disable-overview]
|
|
34
|
-
[--disable-security-issue] [--files FILES] [--ignore-commit-files]
|
|
34
|
+
[--disable-security-issue] [--files FILES] [--ignore-commit-files] [--timeout]
|
|
35
35
|
````
|
|
36
36
|
|
|
37
37
|
If you don't want to provide the Socket API Token every time then you can use the environment variable `SOCKET_SECURITY_API_KEY`
|
|
@@ -61,3 +61,4 @@ If you don't want to provide the Socket API Token every time then you can use th
|
|
|
61
61
|
| --files | | False | | If provided in the format of `["file1", "file2"]` will be used to determine if there have been supported file changes. This is used if it isn't a git repo and you would like to only run if it supported files have changed. |
|
|
62
62
|
| --ignore-commit-files | | False | False | If enabled then the CLI will ignore what files are changed in the commit and look for all manifest files |
|
|
63
63
|
| --disable-blocking | | False | False | Disables failing checks and will only exit with an exit code of 0 |
|
|
64
|
+
| --timeout | | False | 1200 | The timeout per request for the CLI |
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{socketsecurity-1.0.39 → socketsecurity-1.0.41}/socketsecurity.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|