socketsecurity 1.0.1__tar.gz → 1.0.3__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.1/socketsecurity.egg-info → socketsecurity-1.0.3}/PKG-INFO +1 -1
- {socketsecurity-1.0.1 → socketsecurity-1.0.3}/socketsecurity/__init__.py +1 -1
- {socketsecurity-1.0.1 → socketsecurity-1.0.3}/socketsecurity/core/__init__.py +16 -5
- {socketsecurity-1.0.1 → socketsecurity-1.0.3}/socketsecurity/core/github.py +36 -0
- {socketsecurity-1.0.1 → socketsecurity-1.0.3}/socketsecurity/core/messages.py +21 -9
- {socketsecurity-1.0.1 → socketsecurity-1.0.3}/socketsecurity/core/scm_comments.py +24 -17
- {socketsecurity-1.0.1 → socketsecurity-1.0.3}/socketsecurity/socketcli.py +13 -5
- {socketsecurity-1.0.1 → socketsecurity-1.0.3/socketsecurity.egg-info}/PKG-INFO +1 -1
- {socketsecurity-1.0.1 → socketsecurity-1.0.3}/LICENSE +0 -0
- {socketsecurity-1.0.1 → socketsecurity-1.0.3}/README.md +0 -0
- {socketsecurity-1.0.1 → socketsecurity-1.0.3}/pyproject.toml +0 -0
- {socketsecurity-1.0.1 → socketsecurity-1.0.3}/setup.cfg +0 -0
- {socketsecurity-1.0.1 → socketsecurity-1.0.3}/socketsecurity/core/classes.py +0 -0
- {socketsecurity-1.0.1 → socketsecurity-1.0.3}/socketsecurity/core/exceptions.py +0 -0
- {socketsecurity-1.0.1 → socketsecurity-1.0.3}/socketsecurity/core/git_interface.py +0 -0
- {socketsecurity-1.0.1 → socketsecurity-1.0.3}/socketsecurity/core/gitlab.py +0 -0
- {socketsecurity-1.0.1 → socketsecurity-1.0.3}/socketsecurity/core/issues.py +0 -0
- {socketsecurity-1.0.1 → socketsecurity-1.0.3}/socketsecurity/core/licenses.py +0 -0
- {socketsecurity-1.0.1 → socketsecurity-1.0.3}/socketsecurity.egg-info/SOURCES.txt +0 -0
- {socketsecurity-1.0.1 → socketsecurity-1.0.3}/socketsecurity.egg-info/dependency_links.txt +0 -0
- {socketsecurity-1.0.1 → socketsecurity-1.0.3}/socketsecurity.egg-info/entry_points.txt +0 -0
- {socketsecurity-1.0.1 → socketsecurity-1.0.3}/socketsecurity.egg-info/requires.txt +0 -0
- {socketsecurity-1.0.1 → socketsecurity-1.0.3}/socketsecurity.egg-info/top_level.txt +0 -0
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
__author__ = 'socket.dev'
|
|
2
|
-
__version__ = '1.0.
|
|
2
|
+
__version__ = '1.0.3'
|
|
@@ -548,11 +548,13 @@ class Core:
|
|
|
548
548
|
head_packages = Core.create_sbom_dict(head_scan)
|
|
549
549
|
new_scan_alerts = {}
|
|
550
550
|
head_scan_alerts = {}
|
|
551
|
-
|
|
551
|
+
consolidated = []
|
|
552
552
|
for package_id in new_packages:
|
|
553
553
|
purl, package = Core.create_purl(package_id, new_packages)
|
|
554
|
-
|
|
554
|
+
base_purl = f"{purl.ecosystem}/{purl.name}@{purl.version}"
|
|
555
|
+
if package_id not in head_packages and package.direct and base_purl not in consolidated:
|
|
555
556
|
diff.new_packages.append(purl)
|
|
557
|
+
consolidated.append(base_purl)
|
|
556
558
|
new_scan_alerts = Core.create_issue_alerts(package, new_scan_alerts, new_packages)
|
|
557
559
|
for package_id in head_packages:
|
|
558
560
|
purl, package = Core.create_purl(package_id, head_packages)
|
|
@@ -633,18 +635,27 @@ class Core:
|
|
|
633
635
|
:param alerts: List of new alerts that are only in the new Full Scan
|
|
634
636
|
:return:
|
|
635
637
|
"""
|
|
638
|
+
consolidated_alerts = []
|
|
636
639
|
for alert_key in new_scan_alerts:
|
|
637
640
|
if alert_key not in head_scan_alerts:
|
|
638
641
|
new_alerts = new_scan_alerts[alert_key]
|
|
639
642
|
for alert in new_alerts:
|
|
643
|
+
alert: Issue
|
|
644
|
+
alert_str = f"{alert.purl},{alert.manifests},{alert.type}"
|
|
640
645
|
if alert.error or alert.warn:
|
|
641
|
-
|
|
646
|
+
if alert_str not in consolidated_alerts:
|
|
647
|
+
alerts.append(alert)
|
|
648
|
+
consolidated_alerts.append(alert_str)
|
|
642
649
|
else:
|
|
643
650
|
new_alerts = new_scan_alerts[alert_key]
|
|
644
651
|
head_alerts = head_scan_alerts[alert_key]
|
|
645
652
|
for alert in new_alerts:
|
|
646
|
-
|
|
647
|
-
|
|
653
|
+
alert: Issue
|
|
654
|
+
alert_str = f"{alert.purl},{alert.manifests},{alert.type}"
|
|
655
|
+
if alert not in head_alerts and alert_str not in consolidated_alerts:
|
|
656
|
+
if alert.error or alert.warn:
|
|
657
|
+
alerts.append(alert)
|
|
658
|
+
consolidated_alerts.append(alert_str)
|
|
648
659
|
return alerts
|
|
649
660
|
|
|
650
661
|
@staticmethod
|
|
@@ -207,4 +207,40 @@ class Github:
|
|
|
207
207
|
if security_alert is not None:
|
|
208
208
|
security_alert: Comment
|
|
209
209
|
new_body = Comments.process_security_comment(security_alert, comments)
|
|
210
|
+
Github.handle_ignore_reactions(comments)
|
|
210
211
|
Github.update_comment(new_body, str(security_alert.id))
|
|
212
|
+
|
|
213
|
+
@staticmethod
|
|
214
|
+
def handle_ignore_reactions(comments: dict) -> None:
|
|
215
|
+
for comment in comments["ignore"]:
|
|
216
|
+
comment: Comment
|
|
217
|
+
if "SocketSecurity ignore" in comment.body:
|
|
218
|
+
if not Github.comment_reaction_exists(comment.id):
|
|
219
|
+
Github.post_reaction(comment.id)
|
|
220
|
+
|
|
221
|
+
@staticmethod
|
|
222
|
+
def post_reaction(comment_id: int) -> None:
|
|
223
|
+
repo = github_repository.rsplit("/", 1)[1]
|
|
224
|
+
path = f"repos/{github_repository_owner}/{repo}/issues/comments/{comment_id}/reactions"
|
|
225
|
+
payload = {
|
|
226
|
+
"content": "+1"
|
|
227
|
+
}
|
|
228
|
+
payload = json.dumps(payload)
|
|
229
|
+
do_request(path, payload=payload, method="POST", headers=headers, base_url=github_api_url)
|
|
230
|
+
|
|
231
|
+
@staticmethod
|
|
232
|
+
def comment_reaction_exists(comment_id: int) -> bool:
|
|
233
|
+
repo = github_repository.rsplit("/", 1)[1]
|
|
234
|
+
path = f"repos/{github_repository_owner}/{repo}/issues/comments/{comment_id}/reactions"
|
|
235
|
+
response = do_request(path, headers=headers, base_url=github_api_url)
|
|
236
|
+
exists = False
|
|
237
|
+
try:
|
|
238
|
+
data = response.json()
|
|
239
|
+
for reaction in data:
|
|
240
|
+
content = reaction.get("content")
|
|
241
|
+
if content is not None and content == ":thumbsup:":
|
|
242
|
+
exists = True
|
|
243
|
+
except Exception as error:
|
|
244
|
+
log.error(f"Unable to get reaction for {comment_id} for PR {pr_number}")
|
|
245
|
+
log.error(error)
|
|
246
|
+
return exists
|
|
@@ -148,7 +148,7 @@ class Messages:
|
|
|
148
148
|
ignore = f"`SocketSecurity ignore {alert.purl}`"
|
|
149
149
|
if ignore not in ignore_commands:
|
|
150
150
|
ignore_commands.append(ignore)
|
|
151
|
-
manifest_str,
|
|
151
|
+
manifest_str, source_str = Messages.create_sources(alert)
|
|
152
152
|
purl_url = f"[{alert.purl}]({alert.url})"
|
|
153
153
|
if alert.error:
|
|
154
154
|
emoji = ':no_entry_sign:'
|
|
@@ -157,7 +157,7 @@ class Messages:
|
|
|
157
157
|
row = [
|
|
158
158
|
alert.title,
|
|
159
159
|
purl_url,
|
|
160
|
-
|
|
160
|
+
source_str,
|
|
161
161
|
manifest_str,
|
|
162
162
|
emoji
|
|
163
163
|
]
|
|
@@ -269,6 +269,7 @@ class Messages:
|
|
|
269
269
|
[
|
|
270
270
|
"Alert",
|
|
271
271
|
"Package",
|
|
272
|
+
"url",
|
|
272
273
|
"Introduced by",
|
|
273
274
|
"Manifest File",
|
|
274
275
|
"CI Status"
|
|
@@ -276,7 +277,7 @@ class Messages:
|
|
|
276
277
|
)
|
|
277
278
|
for alert in diff.new_alerts:
|
|
278
279
|
alert: Issue
|
|
279
|
-
manifest_str,
|
|
280
|
+
manifest_str, source_str = Messages.create_sources(alert, "console")
|
|
280
281
|
if alert.error:
|
|
281
282
|
state = "block"
|
|
282
283
|
elif alert.warn:
|
|
@@ -287,8 +288,9 @@ class Messages:
|
|
|
287
288
|
state = "ignore"
|
|
288
289
|
row = [
|
|
289
290
|
alert.title,
|
|
291
|
+
alert.purl,
|
|
290
292
|
alert.url,
|
|
291
|
-
|
|
293
|
+
source_str,
|
|
292
294
|
manifest_str,
|
|
293
295
|
state
|
|
294
296
|
]
|
|
@@ -296,18 +298,28 @@ class Messages:
|
|
|
296
298
|
return alert_table
|
|
297
299
|
|
|
298
300
|
@staticmethod
|
|
299
|
-
def create_sources(alert: Issue, style="md") -> [str,
|
|
301
|
+
def create_sources(alert: Issue, style="md") -> [str, str]:
|
|
300
302
|
sources = []
|
|
301
303
|
manifests = []
|
|
302
304
|
for source, manifest in alert.introduced_by:
|
|
303
|
-
sources.append(source)
|
|
304
305
|
if style == "md":
|
|
305
|
-
|
|
306
|
+
add_str = f"<li>{manifest}</li>"
|
|
307
|
+
source_str = f"<li>{source}</li>"
|
|
306
308
|
else:
|
|
307
|
-
|
|
309
|
+
add_str = f"{manifest};"
|
|
310
|
+
source_str = f"{source};"
|
|
311
|
+
if source_str not in sources:
|
|
312
|
+
sources.append(source_str)
|
|
313
|
+
if add_str not in manifests:
|
|
314
|
+
manifests.append(add_str)
|
|
308
315
|
manifest_list = "".join(manifests)
|
|
316
|
+
source_list = "".join(sources)
|
|
317
|
+
source_list = source_list.rstrip(";")
|
|
318
|
+
manifest_list = manifest_list.rstrip(";")
|
|
309
319
|
if style == "md":
|
|
310
320
|
manifest_str = f"<ul>{manifest_list}</ul>"
|
|
321
|
+
sources_str = f"<ul>{source_list}</ul>"
|
|
311
322
|
else:
|
|
312
323
|
manifest_str = manifest_list
|
|
313
|
-
|
|
324
|
+
sources_str = source_list
|
|
325
|
+
return manifest_str, sources_str
|
|
@@ -31,12 +31,13 @@ class Comments:
|
|
|
31
31
|
if ignore_all:
|
|
32
32
|
break
|
|
33
33
|
else:
|
|
34
|
-
|
|
35
|
-
|
|
34
|
+
full_name = f"{alert.pkg_type}/{alert.pkg_name}"
|
|
35
|
+
purl = (full_name, alert.pkg_version)
|
|
36
|
+
purl_star = (full_name, "*")
|
|
36
37
|
if purl in ignore_commands or purl_star in ignore_commands:
|
|
37
|
-
|
|
38
|
+
log.info(f"Alerts for {alert.pkg_name}@{alert.pkg_version} ignored")
|
|
38
39
|
else:
|
|
39
|
-
|
|
40
|
+
log.info(f"Adding alert {alert.type} for {alert.pkg_name}@{alert.pkg_version}")
|
|
40
41
|
alerts.append(alert)
|
|
41
42
|
return alerts
|
|
42
43
|
|
|
@@ -49,16 +50,20 @@ class Comments:
|
|
|
49
50
|
comment: Comment
|
|
50
51
|
first_line = comment.body_list[0]
|
|
51
52
|
if not ignore_all and "SocketSecurity ignore" in first_line:
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
53
|
+
try:
|
|
54
|
+
first_line = first_line.lstrip("@")
|
|
55
|
+
_, command = first_line.split("SocketSecurity ")
|
|
56
|
+
command = command.strip()
|
|
57
|
+
if command == "ignore-all":
|
|
58
|
+
ignore_all = True
|
|
59
|
+
else:
|
|
60
|
+
command = command.lstrip("ignore").strip()
|
|
61
|
+
name, version = command.split("@")
|
|
62
|
+
data = (name, version)
|
|
63
|
+
ignore_commands.append(data)
|
|
64
|
+
except Exception as error:
|
|
65
|
+
log.error(f"Unable to process ignore command for {comment}")
|
|
66
|
+
log.error(error)
|
|
62
67
|
return ignore_all, ignore_commands
|
|
63
68
|
|
|
64
69
|
@staticmethod
|
|
@@ -71,7 +76,7 @@ class Comments:
|
|
|
71
76
|
@staticmethod
|
|
72
77
|
def is_heading_line(line) -> bool:
|
|
73
78
|
is_heading_line = True
|
|
74
|
-
if line != "|Alert|Package|Introduced by|Manifest File|" and ":---" not in line:
|
|
79
|
+
if line != "|Alert|Package|Introduced by|Manifest File|CI|" and ":---" not in line:
|
|
75
80
|
is_heading_line = False
|
|
76
81
|
return is_heading_line
|
|
77
82
|
|
|
@@ -86,10 +91,12 @@ class Comments:
|
|
|
86
91
|
start = True
|
|
87
92
|
lines.append(line)
|
|
88
93
|
elif start and "end-socket-alerts-table" not in line and not Comments.is_heading_line(line) and line != '':
|
|
89
|
-
title, package, introduced_by, manifest = line.lstrip("|").rstrip("|").split("|")
|
|
94
|
+
title, package, introduced_by, manifest, ci = line.lstrip("|").rstrip("|").split("|")
|
|
90
95
|
details, _ = package.split("](")
|
|
91
96
|
ecosystem, details = details.split("/", 1)
|
|
97
|
+
ecosystem = ecosystem.lstrip("[")
|
|
92
98
|
pkg_name, pkg_version = details.split("@")
|
|
99
|
+
pkg_name = f"{ecosystem}/{pkg_name}"
|
|
93
100
|
ignore = False
|
|
94
101
|
for name, version in ignore_commands:
|
|
95
102
|
if ignore_all or Comments.is_ignore(pkg_name, pkg_version, name, version):
|
|
@@ -114,7 +121,7 @@ class Comments:
|
|
|
114
121
|
socket_comments["security"] = comment
|
|
115
122
|
elif "socket-overview-comment-actions" in comment.body:
|
|
116
123
|
socket_comments["overview"] = comment
|
|
117
|
-
elif "SocketSecurity ignore" in comment.
|
|
124
|
+
elif "SocketSecurity ignore".lower() in comment.body_list[0].lower():
|
|
118
125
|
if "ignore" not in socket_comments:
|
|
119
126
|
socket_comments["ignore"] = []
|
|
120
127
|
socket_comments["ignore"].append(comment)
|
|
@@ -5,7 +5,7 @@ from socketsecurity.core.classes import FullScanParams, Diff, Package, Alert
|
|
|
5
5
|
from socketsecurity.core.messages import Messages
|
|
6
6
|
from socketsecurity.core.scm_comments import Comments
|
|
7
7
|
from socketsecurity.core.git_interface import Git
|
|
8
|
-
from git import InvalidGitRepositoryError
|
|
8
|
+
from git import InvalidGitRepositoryError, NoSuchPathError
|
|
9
9
|
import os
|
|
10
10
|
import sys
|
|
11
11
|
import logging
|
|
@@ -245,6 +245,8 @@ def main_code():
|
|
|
245
245
|
except InvalidGitRepositoryError:
|
|
246
246
|
is_repo = False
|
|
247
247
|
pass
|
|
248
|
+
except NoSuchPathError:
|
|
249
|
+
raise Exception(f"Unable to find path {target_path}")
|
|
248
250
|
# git_repo = None
|
|
249
251
|
if repo is None:
|
|
250
252
|
log.info("Repo name needs to be set")
|
|
@@ -306,11 +308,17 @@ def main_code():
|
|
|
306
308
|
new_security_comment = True
|
|
307
309
|
new_overview_comment = True
|
|
308
310
|
if len(diff.new_alerts) == 0 or disable_security_issue:
|
|
309
|
-
|
|
310
|
-
|
|
311
|
+
if security_comment is None or security_comment == "":
|
|
312
|
+
new_security_comment = False
|
|
313
|
+
log.debug("No new alerts or security issue comment disabled")
|
|
314
|
+
else:
|
|
315
|
+
log.debug("Updated security comment with no new alerts")
|
|
311
316
|
if (len(diff.new_packages) == 0 and len(diff.removed_packages) == 0) or disable_overview:
|
|
312
|
-
|
|
313
|
-
|
|
317
|
+
if overview_comment is None or overview_comment == "":
|
|
318
|
+
new_overview_comment = False
|
|
319
|
+
log.debug("No new/removed packages or Dependency Overview comment disabled")
|
|
320
|
+
else:
|
|
321
|
+
log.debug("Updated overview comment with no dependencies")
|
|
314
322
|
log.debug(f"Adding comments for {scm_type}")
|
|
315
323
|
scm.add_socket_comments(
|
|
316
324
|
security_comment,
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|