socketsecurity 0.0.81__tar.gz → 0.0.83__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-0.0.81/socketsecurity.egg-info → socketsecurity-0.0.83}/PKG-INFO +1 -1
- {socketsecurity-0.0.81 → socketsecurity-0.0.83}/socketsecurity/__init__.py +1 -1
- {socketsecurity-0.0.81 → socketsecurity-0.0.83}/socketsecurity/core/__init__.py +12 -14
- {socketsecurity-0.0.81 → socketsecurity-0.0.83}/socketsecurity/core/classes.py +15 -1
- socketsecurity-0.0.83/socketsecurity/core/git_interface.py +25 -0
- {socketsecurity-0.0.81 → socketsecurity-0.0.83}/socketsecurity/core/github.py +8 -116
- {socketsecurity-0.0.81 → socketsecurity-0.0.83}/socketsecurity/core/gitlab.py +9 -85
- socketsecurity-0.0.83/socketsecurity/core/scm_comments.py +103 -0
- {socketsecurity-0.0.81 → socketsecurity-0.0.83}/socketsecurity/socketcli.py +41 -8
- {socketsecurity-0.0.81 → socketsecurity-0.0.83/socketsecurity.egg-info}/PKG-INFO +1 -1
- {socketsecurity-0.0.81 → socketsecurity-0.0.83}/socketsecurity.egg-info/SOURCES.txt +3 -1
- {socketsecurity-0.0.81 → socketsecurity-0.0.83}/LICENSE +0 -0
- {socketsecurity-0.0.81 → socketsecurity-0.0.83}/README.md +0 -0
- {socketsecurity-0.0.81 → socketsecurity-0.0.83}/pyproject.toml +0 -0
- {socketsecurity-0.0.81 → socketsecurity-0.0.83}/setup.cfg +0 -0
- {socketsecurity-0.0.81 → socketsecurity-0.0.83}/socketsecurity/core/exceptions.py +0 -0
- {socketsecurity-0.0.81 → socketsecurity-0.0.83}/socketsecurity/core/issues.py +0 -0
- {socketsecurity-0.0.81 → socketsecurity-0.0.83}/socketsecurity/core/licenses.py +0 -0
- {socketsecurity-0.0.81 → socketsecurity-0.0.83}/socketsecurity/core/messages.py +0 -0
- {socketsecurity-0.0.81 → socketsecurity-0.0.83}/socketsecurity.egg-info/dependency_links.txt +0 -0
- {socketsecurity-0.0.81 → socketsecurity-0.0.83}/socketsecurity.egg-info/entry_points.txt +0 -0
- {socketsecurity-0.0.81 → socketsecurity-0.0.83}/socketsecurity.egg-info/requires.txt +0 -0
- {socketsecurity-0.0.81 → socketsecurity-0.0.83}/socketsecurity.egg-info/top_level.txt +0 -0
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
__author__ = 'socket.dev'
|
|
2
|
-
__version__ = '0.0.
|
|
2
|
+
__version__ = '0.0.83'
|
|
@@ -22,6 +22,7 @@ from socketsecurity.core.classes import (
|
|
|
22
22
|
)
|
|
23
23
|
import platform
|
|
24
24
|
from glob import glob
|
|
25
|
+
import fnmatch
|
|
25
26
|
import time
|
|
26
27
|
|
|
27
28
|
__all__ = [
|
|
@@ -306,25 +307,15 @@ class Core:
|
|
|
306
307
|
return sbom
|
|
307
308
|
|
|
308
309
|
@staticmethod
|
|
309
|
-
def find_files(path: str) -> list:
|
|
310
|
+
def find_files(path: str, new_files: list = None) -> list:
|
|
310
311
|
"""
|
|
311
312
|
Globs the path for supported manifest files.
|
|
312
313
|
Note: Might move the source to a JSON file
|
|
313
314
|
:param path: Str - path to where the manifest files are located
|
|
315
|
+
:param new_files:
|
|
314
316
|
:return:
|
|
315
317
|
"""
|
|
316
318
|
socket_globs = {
|
|
317
|
-
"general": {
|
|
318
|
-
"readme": {
|
|
319
|
-
"pattern": "*readme*"
|
|
320
|
-
},
|
|
321
|
-
"notice": {
|
|
322
|
-
"pattern": "*notice*"
|
|
323
|
-
},
|
|
324
|
-
"license": {
|
|
325
|
-
"pattern": "{licen{s,c}e{,-*},copying}"
|
|
326
|
-
}
|
|
327
|
-
},
|
|
328
319
|
"npm": {
|
|
329
320
|
"package.json": {
|
|
330
321
|
"pattern": "package.json"
|
|
@@ -399,6 +390,12 @@ class Core:
|
|
|
399
390
|
file_path = f"{path}/**/{pattern}"
|
|
400
391
|
files = glob(file_path, recursive=True)
|
|
401
392
|
for file in files:
|
|
393
|
+
if "/" in file:
|
|
394
|
+
_, base_name = file.rsplit("/", 1)
|
|
395
|
+
else:
|
|
396
|
+
base_name = file
|
|
397
|
+
if new_files is not None and base_name not in new_files:
|
|
398
|
+
continue
|
|
402
399
|
if platform.system() == "Windows":
|
|
403
400
|
file = file.replace("\\", "/")
|
|
404
401
|
found_path, file_name = file.rsplit("/", 1)
|
|
@@ -478,7 +475,7 @@ class Core:
|
|
|
478
475
|
return full_scan
|
|
479
476
|
|
|
480
477
|
@staticmethod
|
|
481
|
-
def create_new_diff(path: str, params: FullScanParams, workspace: str) -> Diff:
|
|
478
|
+
def create_new_diff(path: str, params: FullScanParams, workspace: str, new_files: list = None) -> Diff:
|
|
482
479
|
"""
|
|
483
480
|
1. Get the head full scan. If it isn't present because this repo doesn't exist yet return an Empty full scan.
|
|
484
481
|
2. Create a new Full scan for the current run
|
|
@@ -487,9 +484,10 @@ class Core:
|
|
|
487
484
|
:param path: Str - path of where to look for manifest files for the new Full Scan
|
|
488
485
|
:param params: FullScanParams - Query params for the Full Scan endpoint
|
|
489
486
|
:param workspace: str - Path for workspace
|
|
487
|
+
:param new_files:
|
|
490
488
|
:return:
|
|
491
489
|
"""
|
|
492
|
-
files = Core.find_files(path)
|
|
490
|
+
files = Core.find_files(path, new_files)
|
|
493
491
|
try:
|
|
494
492
|
head_full_scan_id = Core.get_head_scan_for_repo(params.repo)
|
|
495
493
|
if head_full_scan_id is None or head_full_scan_id == "":
|
|
@@ -13,7 +13,7 @@ __all__ = [
|
|
|
13
13
|
"Repository",
|
|
14
14
|
"Diff",
|
|
15
15
|
"Purl",
|
|
16
|
-
"
|
|
16
|
+
"Comment"
|
|
17
17
|
]
|
|
18
18
|
|
|
19
19
|
|
|
@@ -423,3 +423,17 @@ class GitlabComment:
|
|
|
423
423
|
def __str__(self):
|
|
424
424
|
return json.dumps(self.__dict__)
|
|
425
425
|
|
|
426
|
+
class Comment:
|
|
427
|
+
id: int
|
|
428
|
+
body: str
|
|
429
|
+
body_list: list
|
|
430
|
+
|
|
431
|
+
def __init__(self, **kwargs):
|
|
432
|
+
if kwargs:
|
|
433
|
+
for key, value in kwargs.items():
|
|
434
|
+
setattr(self, key, value)
|
|
435
|
+
if not hasattr(self, "body_list"):
|
|
436
|
+
self.body_list = []
|
|
437
|
+
|
|
438
|
+
def __str__(self):
|
|
439
|
+
return json.dumps(self.__dict__)
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
from git import Repo
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class Git:
|
|
5
|
+
repo: Repo
|
|
6
|
+
path: str
|
|
7
|
+
|
|
8
|
+
def __init__(self, path: str):
|
|
9
|
+
self.path = path
|
|
10
|
+
self.repo = Repo(path)
|
|
11
|
+
assert self.repo
|
|
12
|
+
self.head = self.repo.head
|
|
13
|
+
self.reference = self.head.reference
|
|
14
|
+
self.commit = self.reference.commit
|
|
15
|
+
self.repo_name = self.repo.remotes.origin.url.split('.git')[0].split('/')[-1]
|
|
16
|
+
self.branch = self.repo.active_branch
|
|
17
|
+
self.author = self.commit.author
|
|
18
|
+
self.commit_sha = self.commit.binsha
|
|
19
|
+
self.commit_message = self.commit.message
|
|
20
|
+
self.committer = self.commit.committer
|
|
21
|
+
self.show_files = self.repo.git.show(self.commit, name_only=True, format="%n").splitlines()
|
|
22
|
+
self.changed_files = []
|
|
23
|
+
for item in self.show_files:
|
|
24
|
+
if item != "":
|
|
25
|
+
self.changed_files.append(item)
|
|
@@ -3,7 +3,8 @@ import os
|
|
|
3
3
|
from socketsecurity.core import log
|
|
4
4
|
import requests
|
|
5
5
|
from socketsecurity.core.exceptions import *
|
|
6
|
-
from socketsecurity.core.classes import
|
|
6
|
+
from socketsecurity.core.classes import Comment
|
|
7
|
+
from socketsecurity.core.scm_comments import Comments
|
|
7
8
|
import sys
|
|
8
9
|
|
|
9
10
|
|
|
@@ -174,13 +175,13 @@ class Github:
|
|
|
174
175
|
existing_security_comment = comments.get("security")
|
|
175
176
|
if new_overview_comment:
|
|
176
177
|
if existing_overview_comment is not None:
|
|
177
|
-
existing_overview_comment:
|
|
178
|
+
existing_overview_comment: Comment
|
|
178
179
|
Github.update_comment(overview_comment, str(existing_overview_comment.id))
|
|
179
180
|
else:
|
|
180
181
|
Github.post_comment(overview_comment)
|
|
181
182
|
if new_security_comment:
|
|
182
183
|
if existing_security_comment is not None:
|
|
183
|
-
existing_security_comment:
|
|
184
|
+
existing_security_comment: Comment
|
|
184
185
|
Github.update_comment(security_comment, str(existing_security_comment.id))
|
|
185
186
|
else:
|
|
186
187
|
Github.post_comment(security_comment)
|
|
@@ -219,128 +220,19 @@ class Github:
|
|
|
219
220
|
comments = {}
|
|
220
221
|
if "error" not in raw_comments:
|
|
221
222
|
for item in raw_comments:
|
|
222
|
-
comment =
|
|
223
|
+
comment = Comment(**item)
|
|
223
224
|
comments[comment.id] = comment
|
|
224
225
|
for line in comment.body.split("\n"):
|
|
225
226
|
comment.body_list.append(line)
|
|
226
227
|
else:
|
|
227
228
|
log.error(raw_comments)
|
|
228
|
-
socket_comments =
|
|
229
|
+
socket_comments = Comments.check_for_socket_comments(comments)
|
|
229
230
|
return socket_comments
|
|
230
231
|
|
|
231
|
-
@staticmethod
|
|
232
|
-
def check_for_socket_comments(comments: dict):
|
|
233
|
-
socket_comments = {}
|
|
234
|
-
for comment_id in comments:
|
|
235
|
-
comment = comments[comment_id]
|
|
236
|
-
comment: GithubComment
|
|
237
|
-
if "socket-security-comment-actions" in comment.body:
|
|
238
|
-
socket_comments["security"] = comment
|
|
239
|
-
elif "socket-overview-comment-actions" in comment.body:
|
|
240
|
-
socket_comments["overview"] = comment
|
|
241
|
-
elif "SocketSecurity ignore" in comment.body:
|
|
242
|
-
if "ignore" not in socket_comments:
|
|
243
|
-
socket_comments["ignore"] = []
|
|
244
|
-
socket_comments["ignore"].append(comment)
|
|
245
|
-
return socket_comments
|
|
246
|
-
|
|
247
|
-
@staticmethod
|
|
248
|
-
def remove_alerts(comments: dict, new_alerts: list) -> list:
|
|
249
|
-
alerts = []
|
|
250
|
-
if "ignore" not in comments:
|
|
251
|
-
return new_alerts
|
|
252
|
-
ignore_all, ignore_commands = Github.get_ignore_options(comments)
|
|
253
|
-
for alert in new_alerts:
|
|
254
|
-
alert: Issue
|
|
255
|
-
if ignore_all:
|
|
256
|
-
break
|
|
257
|
-
else:
|
|
258
|
-
purl = f"{alert.pkg_name}, {alert.pkg_version}"
|
|
259
|
-
purl_star = f"{alert.pkg_name}, *"
|
|
260
|
-
if purl in ignore_commands or purl_star in ignore_commands:
|
|
261
|
-
log.debug(f"Alerts for {alert.pkg_name}@{alert.pkg_version} ignored")
|
|
262
|
-
else:
|
|
263
|
-
log.debug(f"Adding alert {alert.type} for {alert.pkg_name}@{alert.pkg_version}")
|
|
264
|
-
alerts.append(alert)
|
|
265
|
-
return alerts
|
|
266
|
-
|
|
267
|
-
@staticmethod
|
|
268
|
-
def get_ignore_options(comments: dict) -> [bool, list]:
|
|
269
|
-
ignore_commands = []
|
|
270
|
-
ignore_all = False
|
|
271
|
-
|
|
272
|
-
for comment in comments["ignore"]:
|
|
273
|
-
comment: GithubComment
|
|
274
|
-
first_line = comment.body_list[0]
|
|
275
|
-
if not ignore_all and "SocketSecurity ignore" in first_line:
|
|
276
|
-
first_line = first_line.lstrip("@")
|
|
277
|
-
_, command = first_line.split("SocketSecurity ")
|
|
278
|
-
command = command.strip()
|
|
279
|
-
if command == "ignore-all":
|
|
280
|
-
ignore_all = True
|
|
281
|
-
else:
|
|
282
|
-
command = command.lstrip("ignore").strip()
|
|
283
|
-
name, version = command.rsplit("@", 1)
|
|
284
|
-
ecosystem, name = name.split("/", 1)
|
|
285
|
-
data = (ecosystem, name, version)
|
|
286
|
-
ignore_commands.append(data)
|
|
287
|
-
return ignore_all, ignore_commands
|
|
288
|
-
|
|
289
|
-
@staticmethod
|
|
290
|
-
def is_ignore(
|
|
291
|
-
pkg_ecosystem: str,
|
|
292
|
-
pkg_name: str,
|
|
293
|
-
pkg_version: str,
|
|
294
|
-
ecosystem: str,
|
|
295
|
-
name: str,
|
|
296
|
-
version: str
|
|
297
|
-
) -> bool:
|
|
298
|
-
result = False
|
|
299
|
-
if pkg_ecosystem == ecosystem and pkg_name == name and (pkg_version == version or version == "*"):
|
|
300
|
-
result = True
|
|
301
|
-
return result
|
|
302
|
-
|
|
303
232
|
@staticmethod
|
|
304
233
|
def remove_comment_alerts(comments: dict):
|
|
305
234
|
security_alert = comments.get("security")
|
|
306
235
|
if security_alert is not None:
|
|
307
|
-
security_alert:
|
|
308
|
-
new_body =
|
|
236
|
+
security_alert: Comment
|
|
237
|
+
new_body = Comments.process_security_comment(security_alert, comments)
|
|
309
238
|
Github.update_comment(new_body, str(security_alert.id))
|
|
310
|
-
|
|
311
|
-
@staticmethod
|
|
312
|
-
def is_heading_line(line) -> bool:
|
|
313
|
-
is_heading_line = True
|
|
314
|
-
if line != "|Alert|Package|Introduced by|Manifest File|" and ":---" not in line:
|
|
315
|
-
is_heading_line = False
|
|
316
|
-
return is_heading_line
|
|
317
|
-
|
|
318
|
-
@staticmethod
|
|
319
|
-
def process_security_comment(comment: GithubComment, comments) -> str:
|
|
320
|
-
lines = []
|
|
321
|
-
start = False
|
|
322
|
-
ignore_all, ignore_commands = Github.get_ignore_options(comments)
|
|
323
|
-
for line in comment.body_list:
|
|
324
|
-
line = line.strip()
|
|
325
|
-
if "start-socket-alerts-table" in line:
|
|
326
|
-
start = True
|
|
327
|
-
lines.append(line)
|
|
328
|
-
elif start and "end-socket-alerts-table" not in line and not Github.is_heading_line(line) and line != '':
|
|
329
|
-
title, package, introduced_by, manifest = line.strip("|").split("|")
|
|
330
|
-
details, _ = package.split("](")
|
|
331
|
-
pkg_ecosystem, details = details.strip("[").split("/", 1)
|
|
332
|
-
pkg_name, pkg_version = details.split("@")
|
|
333
|
-
ignore = False
|
|
334
|
-
for ecosystem, name, version in ignore_commands:
|
|
335
|
-
if ignore_all or Github.is_ignore(pkg_ecosystem, pkg_name, pkg_version, ecosystem, name, version):
|
|
336
|
-
ignore = True
|
|
337
|
-
if not ignore:
|
|
338
|
-
lines.append(line)
|
|
339
|
-
elif "end-socket-alerts-table" in line:
|
|
340
|
-
start = False
|
|
341
|
-
lines.append(line)
|
|
342
|
-
else:
|
|
343
|
-
lines.append(line)
|
|
344
|
-
new_body = "\n".join(lines)
|
|
345
|
-
return new_body
|
|
346
|
-
|
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
import json
|
|
2
1
|
import os
|
|
3
2
|
from socketsecurity.core import log
|
|
4
3
|
import requests
|
|
5
4
|
from socketsecurity.core.exceptions import *
|
|
6
|
-
from socketsecurity.core.
|
|
5
|
+
from socketsecurity.core.scm_comments import Comments
|
|
7
6
|
import sys
|
|
8
|
-
|
|
7
|
+
from socketsecurity.core.classes import Comment, Issue
|
|
9
8
|
|
|
10
9
|
global ci_commit_sha
|
|
11
10
|
global ci_api_v4_url
|
|
@@ -24,8 +23,6 @@ global is_default_branch
|
|
|
24
23
|
global committer
|
|
25
24
|
global gitlab_token
|
|
26
25
|
|
|
27
|
-
|
|
28
|
-
|
|
29
26
|
gitlab_variables = [
|
|
30
27
|
"CI_COMMIT_SHA",
|
|
31
28
|
"CI_API_V4_URL",
|
|
@@ -170,13 +167,13 @@ class Gitlab:
|
|
|
170
167
|
existing_security_comment = comments.get("security")
|
|
171
168
|
if new_overview_comment:
|
|
172
169
|
if existing_overview_comment is not None:
|
|
173
|
-
existing_overview_comment:
|
|
170
|
+
existing_overview_comment: Comment
|
|
174
171
|
Gitlab.update_comment(overview_comment, str(existing_overview_comment.id))
|
|
175
172
|
else:
|
|
176
173
|
Gitlab.post_comment(overview_comment)
|
|
177
174
|
if new_security_comment:
|
|
178
175
|
if existing_security_comment is not None:
|
|
179
|
-
existing_security_comment:
|
|
176
|
+
existing_security_comment: Comment
|
|
180
177
|
Gitlab.update_comment(security_comment, str(existing_security_comment.id))
|
|
181
178
|
else:
|
|
182
179
|
Gitlab.post_comment(security_comment)
|
|
@@ -206,58 +203,22 @@ class Gitlab:
|
|
|
206
203
|
comments = {}
|
|
207
204
|
if "message" not in raw_comments:
|
|
208
205
|
for item in raw_comments:
|
|
209
|
-
comment =
|
|
206
|
+
comment = Comment(**item)
|
|
210
207
|
comments[comment.id] = comment
|
|
211
208
|
for line in comment.body.split("\n"):
|
|
212
209
|
comment.body_list.append(line)
|
|
213
210
|
else:
|
|
214
211
|
log.error(raw_comments)
|
|
215
|
-
socket_comments =
|
|
216
|
-
return socket_comments
|
|
217
|
-
|
|
218
|
-
@staticmethod
|
|
219
|
-
def check_for_socket_comments(comments: dict):
|
|
220
|
-
socket_comments = {}
|
|
221
|
-
for comment_id in comments:
|
|
222
|
-
comment = comments[comment_id]
|
|
223
|
-
comment: GitlabComment
|
|
224
|
-
if "socket-security-comment-actions" in comment.body:
|
|
225
|
-
socket_comments["security"] = comment
|
|
226
|
-
elif "socket-overview-comment-actions" in comment.body:
|
|
227
|
-
socket_comments["overview"] = comment
|
|
228
|
-
elif "SocketSecurity ignore" in comment.body:
|
|
229
|
-
if "ignore" not in socket_comments:
|
|
230
|
-
socket_comments["ignore"] = []
|
|
231
|
-
socket_comments["ignore"].append(comment)
|
|
212
|
+
socket_comments = Comments.check_for_socket_comments(comments)
|
|
232
213
|
return socket_comments
|
|
233
214
|
|
|
234
|
-
@staticmethod
|
|
235
|
-
def remove_alerts(comments: dict, new_alerts: list) -> list:
|
|
236
|
-
alerts = []
|
|
237
|
-
if "ignore" not in comments:
|
|
238
|
-
return new_alerts
|
|
239
|
-
ignore_all, ignore_commands = Gitlab.get_ignore_options(comments)
|
|
240
|
-
for alert in new_alerts:
|
|
241
|
-
alert: Issue
|
|
242
|
-
if ignore_all:
|
|
243
|
-
break
|
|
244
|
-
else:
|
|
245
|
-
purl = f"{alert.pkg_name}, {alert.pkg_version}"
|
|
246
|
-
purl_star = f"{alert.pkg_name}, *"
|
|
247
|
-
if purl in ignore_commands or purl_star in ignore_commands:
|
|
248
|
-
print(f"Alerts for {alert.pkg_name}@{alert.pkg_version} ignored")
|
|
249
|
-
else:
|
|
250
|
-
print(f"Adding alert {alert.type} for {alert.pkg_name}@{alert.pkg_version}")
|
|
251
|
-
alerts.append(alert)
|
|
252
|
-
return alerts
|
|
253
|
-
|
|
254
215
|
@staticmethod
|
|
255
216
|
def get_ignore_options(comments: dict) -> [bool, list]:
|
|
256
217
|
ignore_commands = []
|
|
257
218
|
ignore_all = False
|
|
258
219
|
|
|
259
220
|
for comment in comments["ignore"]:
|
|
260
|
-
comment:
|
|
221
|
+
comment: Comment
|
|
261
222
|
first_line = comment.body_list[0]
|
|
262
223
|
if not ignore_all and "SocketSecurity ignore" in first_line:
|
|
263
224
|
first_line = first_line.lstrip("@")
|
|
@@ -283,43 +244,6 @@ class Gitlab:
|
|
|
283
244
|
def remove_comment_alerts(comments: dict):
|
|
284
245
|
security_alert = comments.get("security")
|
|
285
246
|
if security_alert is not None:
|
|
286
|
-
security_alert:
|
|
287
|
-
new_body =
|
|
247
|
+
security_alert: Comment
|
|
248
|
+
new_body = Comments.process_security_comment(security_alert, comments)
|
|
288
249
|
Gitlab.update_comment(new_body, str(security_alert.id))
|
|
289
|
-
|
|
290
|
-
@staticmethod
|
|
291
|
-
def is_heading_line(line) -> bool:
|
|
292
|
-
is_heading_line = True
|
|
293
|
-
if line != "|Alert|Package|Introduced by|Manifest File|" and ":---" not in line:
|
|
294
|
-
is_heading_line = False
|
|
295
|
-
return is_heading_line
|
|
296
|
-
|
|
297
|
-
@staticmethod
|
|
298
|
-
def process_security_comment(comment: GitlabComment, comments) -> str:
|
|
299
|
-
lines = []
|
|
300
|
-
start = False
|
|
301
|
-
ignore_all, ignore_commands = Gitlab.get_ignore_options(comments)
|
|
302
|
-
for line in comment.body_list:
|
|
303
|
-
line = line.strip()
|
|
304
|
-
if "start-socket-alerts-table" in line:
|
|
305
|
-
start = True
|
|
306
|
-
lines.append(line)
|
|
307
|
-
elif start and "end-socket-alerts-table" not in line and not Gitlab.is_heading_line(line) and line != '':
|
|
308
|
-
title, package, introduced_by, manifest = line.lstrip("|").rstrip("|").split("|")
|
|
309
|
-
details, _ = package.split("](")
|
|
310
|
-
ecosystem, details = details.split("/", 1)
|
|
311
|
-
pkg_name, pkg_version = details.split("@")
|
|
312
|
-
ignore = False
|
|
313
|
-
for name, version in ignore_commands:
|
|
314
|
-
if ignore_all or Gitlab.is_ignore(pkg_name, pkg_version, name, version):
|
|
315
|
-
ignore = True
|
|
316
|
-
if not ignore:
|
|
317
|
-
lines.append(line)
|
|
318
|
-
elif "end-socket-alerts-table" in line:
|
|
319
|
-
start = False
|
|
320
|
-
lines.append(line)
|
|
321
|
-
else:
|
|
322
|
-
lines.append(line)
|
|
323
|
-
new_body = "\n".join(lines)
|
|
324
|
-
return new_body
|
|
325
|
-
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
from socketsecurity.core.classes import Comment, Issue
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class Comments:
|
|
5
|
+
@staticmethod
|
|
6
|
+
def remove_alerts(comments: dict, new_alerts: list) -> list:
|
|
7
|
+
alerts = []
|
|
8
|
+
if "ignore" not in comments:
|
|
9
|
+
return new_alerts
|
|
10
|
+
ignore_all, ignore_commands = Comments.get_ignore_options(comments)
|
|
11
|
+
for alert in new_alerts:
|
|
12
|
+
alert: Issue
|
|
13
|
+
if ignore_all:
|
|
14
|
+
break
|
|
15
|
+
else:
|
|
16
|
+
purl = f"{alert.pkg_name}, {alert.pkg_version}"
|
|
17
|
+
purl_star = f"{alert.pkg_name}, *"
|
|
18
|
+
if purl in ignore_commands or purl_star in ignore_commands:
|
|
19
|
+
print(f"Alerts for {alert.pkg_name}@{alert.pkg_version} ignored")
|
|
20
|
+
else:
|
|
21
|
+
print(f"Adding alert {alert.type} for {alert.pkg_name}@{alert.pkg_version}")
|
|
22
|
+
alerts.append(alert)
|
|
23
|
+
return alerts
|
|
24
|
+
|
|
25
|
+
@staticmethod
|
|
26
|
+
def get_ignore_options(comments: dict) -> [bool, list]:
|
|
27
|
+
ignore_commands = []
|
|
28
|
+
ignore_all = False
|
|
29
|
+
|
|
30
|
+
for comment in comments["ignore"]:
|
|
31
|
+
comment: Comment
|
|
32
|
+
first_line = comment.body_list[0]
|
|
33
|
+
if not ignore_all and "SocketSecurity ignore" in first_line:
|
|
34
|
+
first_line = first_line.lstrip("@")
|
|
35
|
+
_, command = first_line.split("SocketSecurity ")
|
|
36
|
+
command = command.strip()
|
|
37
|
+
if command == "ignore-all":
|
|
38
|
+
ignore_all = True
|
|
39
|
+
else:
|
|
40
|
+
command = command.lstrip("ignore").strip()
|
|
41
|
+
name, version = command.split("@")
|
|
42
|
+
data = f"{name}, {version}"
|
|
43
|
+
ignore_commands.append(data)
|
|
44
|
+
return ignore_all, ignore_commands
|
|
45
|
+
|
|
46
|
+
@staticmethod
|
|
47
|
+
def is_ignore(pkg_name: str, pkg_version: str, name: str, version: str) -> bool:
|
|
48
|
+
result = False
|
|
49
|
+
if pkg_name == name and (pkg_version == version or version == "*"):
|
|
50
|
+
result = True
|
|
51
|
+
return result
|
|
52
|
+
|
|
53
|
+
@staticmethod
|
|
54
|
+
def is_heading_line(line) -> bool:
|
|
55
|
+
is_heading_line = True
|
|
56
|
+
if line != "|Alert|Package|Introduced by|Manifest File|" and ":---" not in line:
|
|
57
|
+
is_heading_line = False
|
|
58
|
+
return is_heading_line
|
|
59
|
+
|
|
60
|
+
@staticmethod
|
|
61
|
+
def process_security_comment(comment: Comment, comments) -> str:
|
|
62
|
+
lines = []
|
|
63
|
+
start = False
|
|
64
|
+
ignore_all, ignore_commands = Comments.get_ignore_options(comments)
|
|
65
|
+
for line in comment.body_list:
|
|
66
|
+
line = line.strip()
|
|
67
|
+
if "start-socket-alerts-table" in line:
|
|
68
|
+
start = True
|
|
69
|
+
lines.append(line)
|
|
70
|
+
elif start and "end-socket-alerts-table" not in line and not Comments.is_heading_line(line) and line != '':
|
|
71
|
+
title, package, introduced_by, manifest = line.lstrip("|").rstrip("|").split("|")
|
|
72
|
+
details, _ = package.split("](")
|
|
73
|
+
ecosystem, details = details.split("/", 1)
|
|
74
|
+
pkg_name, pkg_version = details.split("@")
|
|
75
|
+
ignore = False
|
|
76
|
+
for name, version in ignore_commands:
|
|
77
|
+
if ignore_all or Comments.is_ignore(pkg_name, pkg_version, name, version):
|
|
78
|
+
ignore = True
|
|
79
|
+
if not ignore:
|
|
80
|
+
lines.append(line)
|
|
81
|
+
elif "end-socket-alerts-table" in line:
|
|
82
|
+
start = False
|
|
83
|
+
lines.append(line)
|
|
84
|
+
else:
|
|
85
|
+
lines.append(line)
|
|
86
|
+
new_body = "\n".join(lines)
|
|
87
|
+
return new_body
|
|
88
|
+
|
|
89
|
+
@staticmethod
|
|
90
|
+
def check_for_socket_comments(comments: dict):
|
|
91
|
+
socket_comments = {}
|
|
92
|
+
for comment_id in comments:
|
|
93
|
+
comment = comments[comment_id]
|
|
94
|
+
comment: Comment
|
|
95
|
+
if "socket-security-comment-actions" in comment.body:
|
|
96
|
+
socket_comments["security"] = comment
|
|
97
|
+
elif "socket-overview-comment-actions" in comment.body:
|
|
98
|
+
socket_comments["overview"] = comment
|
|
99
|
+
elif "SocketSecurity ignore" in comment.body:
|
|
100
|
+
if "ignore" not in socket_comments:
|
|
101
|
+
socket_comments["ignore"] = []
|
|
102
|
+
socket_comments["ignore"].append(comment)
|
|
103
|
+
return socket_comments
|
|
@@ -3,6 +3,9 @@ import json
|
|
|
3
3
|
from socketsecurity.core import Core, __version__
|
|
4
4
|
from socketsecurity.core.classes import FullScanParams, Diff, Package
|
|
5
5
|
from socketsecurity.core.messages import Messages
|
|
6
|
+
from socketsecurity.core.scm_comments import Comments
|
|
7
|
+
from socketsecurity.core.git_interface import Git
|
|
8
|
+
from git import InvalidGitRepositoryError
|
|
6
9
|
import os
|
|
7
10
|
import sys
|
|
8
11
|
import logging
|
|
@@ -26,7 +29,7 @@ parser.add_argument(
|
|
|
26
29
|
)
|
|
27
30
|
parser.add_argument(
|
|
28
31
|
'--branch',
|
|
29
|
-
default='
|
|
32
|
+
default='',
|
|
30
33
|
help='The name of the branch',
|
|
31
34
|
required=False
|
|
32
35
|
)
|
|
@@ -112,6 +115,12 @@ parser.add_argument(
|
|
|
112
115
|
default=False
|
|
113
116
|
)
|
|
114
117
|
|
|
118
|
+
parser.add_argument(
|
|
119
|
+
'--files',
|
|
120
|
+
help='Specify a list of files in the format of ["file1", "file2"]',
|
|
121
|
+
default="[]"
|
|
122
|
+
)
|
|
123
|
+
|
|
115
124
|
|
|
116
125
|
def output_console_comments(diff_report) -> None:
|
|
117
126
|
console_security_comment = Messages.create_console_security_alert_table(diff_report)
|
|
@@ -159,17 +168,41 @@ def main_code():
|
|
|
159
168
|
sbom_file = arguments.sbom_file
|
|
160
169
|
license_mode = arguments.generate_license
|
|
161
170
|
enable_json = arguments.enable_json
|
|
162
|
-
|
|
163
|
-
if branch is not None:
|
|
164
|
-
license_file += f"_{branch}"
|
|
165
|
-
license_file += ".json"
|
|
171
|
+
files = arguments.files
|
|
166
172
|
api_token = os.getenv("SOCKET_SECURITY_API_KEY") or arguments.api_token
|
|
173
|
+
try:
|
|
174
|
+
files = json.loads(files)
|
|
175
|
+
except Exception as error:
|
|
176
|
+
log.error(f"Unable to parse {files}")
|
|
177
|
+
log.error(error)
|
|
178
|
+
sys.exit(3)
|
|
167
179
|
if api_token is None:
|
|
168
180
|
log.info("Unable to find Socket API Token")
|
|
169
181
|
sys.exit(3)
|
|
182
|
+
try:
|
|
183
|
+
git_repo = Git(target_path)
|
|
184
|
+
if repo is None:
|
|
185
|
+
repo = git_repo.repo_name
|
|
186
|
+
if commit_sha is None or commit_sha == '':
|
|
187
|
+
commit_sha = git_repo.commit
|
|
188
|
+
if branch is None or branch == '':
|
|
189
|
+
branch = git_repo.branch
|
|
190
|
+
if committer is None or committer == '':
|
|
191
|
+
committer = git_repo.committer
|
|
192
|
+
if commit_message is None or commit_message == '':
|
|
193
|
+
commit_message = git_repo.commit_message
|
|
194
|
+
if len(files) == 0:
|
|
195
|
+
files = git_repo.changed_files
|
|
196
|
+
except InvalidGitRepositoryError:
|
|
197
|
+
pass
|
|
198
|
+
# git_repo = None
|
|
170
199
|
if repo is None:
|
|
171
200
|
log.info("Repo name needs to be set")
|
|
172
201
|
sys.exit(2)
|
|
202
|
+
license_file = f"{repo}"
|
|
203
|
+
if branch is not None:
|
|
204
|
+
license_file += f"_{branch}"
|
|
205
|
+
license_file += ".json"
|
|
173
206
|
log.info(f"Starting Socket Security Scan version {__version__}")
|
|
174
207
|
scm = None
|
|
175
208
|
if scm_type == "github":
|
|
@@ -204,10 +237,10 @@ def main_code():
|
|
|
204
237
|
elif scm is not None and scm.check_event_type() != "comment":
|
|
205
238
|
log.info("Push initiated flow")
|
|
206
239
|
diff: Diff
|
|
207
|
-
diff = core.create_new_diff(target_path, params, workspace=target_path)
|
|
240
|
+
diff = core.create_new_diff(target_path, params, workspace=target_path, new_files=files)
|
|
208
241
|
if scm.check_event_type() == "diff":
|
|
209
242
|
comments = scm.get_comments_for_pr(repo, str(pr_number))
|
|
210
|
-
diff.new_alerts =
|
|
243
|
+
diff.new_alerts = Comments.remove_alerts(comments, diff.new_alerts)
|
|
211
244
|
overview_comment = Messages.dependency_overview_template(diff)
|
|
212
245
|
security_comment = Messages.security_comment_template(diff)
|
|
213
246
|
new_security_comment = True
|
|
@@ -230,7 +263,7 @@ def main_code():
|
|
|
230
263
|
else:
|
|
231
264
|
log.info("API Mode")
|
|
232
265
|
diff: Diff
|
|
233
|
-
diff = core.create_new_diff(target_path, params, workspace=target_path)
|
|
266
|
+
diff = core.create_new_diff(target_path, params, workspace=target_path, new_files=files)
|
|
234
267
|
if enable_json:
|
|
235
268
|
output_console_json(diff)
|
|
236
269
|
else:
|
|
@@ -12,8 +12,10 @@ socketsecurity.egg-info/top_level.txt
|
|
|
12
12
|
socketsecurity/core/__init__.py
|
|
13
13
|
socketsecurity/core/classes.py
|
|
14
14
|
socketsecurity/core/exceptions.py
|
|
15
|
+
socketsecurity/core/git_interface.py
|
|
15
16
|
socketsecurity/core/github.py
|
|
16
17
|
socketsecurity/core/gitlab.py
|
|
17
18
|
socketsecurity/core/issues.py
|
|
18
19
|
socketsecurity/core/licenses.py
|
|
19
|
-
socketsecurity/core/messages.py
|
|
20
|
+
socketsecurity/core/messages.py
|
|
21
|
+
socketsecurity/core/scm_comments.py
|
|
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-0.0.81 → socketsecurity-0.0.83}/socketsecurity.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|