guarddog 2.0.0__py3-none-any.whl → 2.0.1__py3-none-any.whl
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.
- guarddog/analyzer/sourcecode/npm-install-script.yml +11 -0
- guarddog/analyzer/sourcecode/shady-links.yml +11 -9
- guarddog/cli.py +25 -35
- guarddog/scanners/__init__.py +38 -11
- guarddog/scanners/scanner.py +4 -24
- guarddog/utils/archives.py +30 -26
- {guarddog-2.0.0.dist-info → guarddog-2.0.1.dist-info}/METADATA +1 -1
- {guarddog-2.0.0.dist-info → guarddog-2.0.1.dist-info}/RECORD +13 -13
- {guarddog-2.0.0.dist-info → guarddog-2.0.1.dist-info}/LICENSE +0 -0
- {guarddog-2.0.0.dist-info → guarddog-2.0.1.dist-info}/LICENSE-3rdparty.csv +0 -0
- {guarddog-2.0.0.dist-info → guarddog-2.0.1.dist-info}/NOTICE +0 -0
- {guarddog-2.0.0.dist-info → guarddog-2.0.1.dist-info}/WHEEL +0 -0
- {guarddog-2.0.0.dist-info → guarddog-2.0.1.dist-info}/entry_points.txt +0 -0
|
@@ -10,6 +10,17 @@ rules:
|
|
|
10
10
|
# (typically when a dependency is a git repository, see https://github.com/npm/cli/issues/6031#issuecomment-1449119423)
|
|
11
11
|
# however this happens pretty rarely so reporting every package with a "prepare" script would be too noisy;
|
|
12
12
|
# see https://github.com/DataDog/guarddog/issues/308
|
|
13
|
+
- pattern-not: |
|
|
14
|
+
"...": "npx only-allow pnpm"
|
|
15
|
+
- pattern-not: |
|
|
16
|
+
"...": ""
|
|
17
|
+
- pattern-not: |
|
|
18
|
+
"...": "patch-package"
|
|
19
|
+
- pattern-not: |
|
|
20
|
+
"...": "husky"
|
|
21
|
+
- pattern-not: |
|
|
22
|
+
"preinstall": "echo \"preinstall script\""
|
|
23
|
+
|
|
13
24
|
- pattern-either:
|
|
14
25
|
- pattern: |
|
|
15
26
|
"preinstall": "..."
|
|
@@ -5,10 +5,9 @@ rules:
|
|
|
5
5
|
metadata:
|
|
6
6
|
description: Identify when a package contains an URL to a domain with a suspicious extension
|
|
7
7
|
patterns:
|
|
8
|
-
# Semgrep not robust enough to ignore comments in lists
|
|
9
|
-
- pattern-not-regex: \# .*
|
|
10
8
|
|
|
11
9
|
# ignore comments
|
|
10
|
+
- pattern-not-regex: ^\s*\# .*
|
|
12
11
|
- pattern-not-regex: ^\s*\/\*(.|\n)*?\*\/\s*$
|
|
13
12
|
- pattern-not-regex: ^\s*\/\/.*$
|
|
14
13
|
|
|
@@ -16,19 +15,22 @@ rules:
|
|
|
16
15
|
- pattern-not-regex: ^\s*"""(.|\n)*?"""\s*$
|
|
17
16
|
|
|
18
17
|
# Exclude local IPv4 sometimes used in tests
|
|
19
|
-
- pattern-not-regex: (http[s]?:\/\/[
|
|
18
|
+
- pattern-not-regex: (http[s]?:\/\/[^\n\[\/\?#"']*?(?:192\.168|10\.\d{1,3}|172\.(?:1[6-9]|2\d|3[0-1])|127\.\d{1,3})\.\d{1,3}\.\d{1,3}|0\.0\.0\.0|localhost)
|
|
20
19
|
|
|
21
20
|
# Exclude public IPv4 sometimes used in tests
|
|
22
|
-
- pattern-not-regex: (http[s]?:\/\/[
|
|
21
|
+
- pattern-not-regex: (http[s]?:\/\/[^\n\[\/\?#"']*?(?:1\.1\.1\.1|8\.8\.8\.8))
|
|
23
22
|
|
|
24
23
|
- patterns:
|
|
25
24
|
- pattern: ("...")
|
|
26
25
|
- pattern-either:
|
|
27
|
-
|
|
28
|
-
- pattern-regex: (http[s]
|
|
29
|
-
|
|
30
|
-
- pattern-regex: (http[s]?:\/\/[
|
|
31
|
-
|
|
26
|
+
# complete domains
|
|
27
|
+
- pattern-regex: (http[s]?:\/\/[^\n\[\/\?#"']*?(bit\.ly|discord\.com|workers\.dev|transfer\.sh|filetransfer\.io|sendspace\.com|appdomain\.cloud|backblazeb2\.com\|paste\.ee|ngrok\.io|termbin\.com|localhost\.run|webhook\.site|oastify\.com|burpcollaborator\.me)\/)
|
|
28
|
+
# top-level domains
|
|
29
|
+
- pattern-regex: (http[s]?:\/\/[^\n\[\/\?#"']*?\.(link|xyz|tk|ml|ga|cf|gq|pw|top|club|mw|bd|ke|am|sbs|date|quest|cd|bid|cd|ws|icu|cam|uno|email|stream)\/)
|
|
30
|
+
# IPv4
|
|
31
|
+
- pattern-regex: (http[s]?:\/\/[^\n\[\/\?#"']*?(?:\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}))
|
|
32
|
+
# IPv6
|
|
33
|
+
- pattern-regex: (http[s]?:\/\/[^\n\[\/\?#"']*?(?:\[(([A-Fa-f0-9]{1,4}:){0,7}|:):?[A-Fa-f0-9]{1,4}(:[A-Fa-f0-9]{1,4}){0,7})\])
|
|
32
34
|
paths:
|
|
33
35
|
exclude:
|
|
34
36
|
- "*/test/*"
|
guarddog/cli.py
CHANGED
|
@@ -9,7 +9,8 @@ import json as js
|
|
|
9
9
|
import logging
|
|
10
10
|
import os
|
|
11
11
|
import sys
|
|
12
|
-
|
|
12
|
+
import tempfile
|
|
13
|
+
from typing import Optional
|
|
13
14
|
|
|
14
15
|
import click
|
|
15
16
|
from prettytable import PrettyTable
|
|
@@ -19,8 +20,8 @@ from guarddog.analyzer.metadata import get_metadata_detectors
|
|
|
19
20
|
from guarddog.analyzer.sourcecode import get_sourcecode_rules
|
|
20
21
|
from guarddog.ecosystems import ECOSYSTEM
|
|
21
22
|
from guarddog.reporters.sarif import report_verify_sarif
|
|
22
|
-
from guarddog.scanners import
|
|
23
|
-
from guarddog.
|
|
23
|
+
from guarddog.scanners import get_package_scanner, get_project_scanner
|
|
24
|
+
from guarddog.utils.archives import safe_extract
|
|
24
25
|
|
|
25
26
|
EXIT_CODE_ISSUES_FOUND = 1
|
|
26
27
|
|
|
@@ -156,7 +157,7 @@ def _verify(
|
|
|
156
157
|
"""
|
|
157
158
|
return_value = None
|
|
158
159
|
rule_param = _get_rule_param(rules, exclude_rules, ecosystem)
|
|
159
|
-
scanner =
|
|
160
|
+
scanner = get_project_scanner(ecosystem)
|
|
160
161
|
if scanner is None:
|
|
161
162
|
sys.stderr.write(f"Command verify is not supported for ecosystem {ecosystem}")
|
|
162
163
|
exit(1)
|
|
@@ -208,46 +209,35 @@ def _scan(
|
|
|
208
209
|
"""
|
|
209
210
|
|
|
210
211
|
rule_param = _get_rule_param(rules, exclude_rules, ecosystem)
|
|
211
|
-
scanner =
|
|
212
|
+
scanner = get_package_scanner(ecosystem)
|
|
212
213
|
if scanner is None:
|
|
213
214
|
sys.stderr.write(f"Command scan is not supported for ecosystem {ecosystem}")
|
|
214
215
|
sys.exit(1)
|
|
215
216
|
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
result
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
result["package"] = identifier
|
|
233
|
-
results.append(result)
|
|
234
|
-
except Exception as e:
|
|
235
|
-
sys.stderr.write(f"\nError '{e}' occurred while scanning remote package.")
|
|
236
|
-
sys.exit(1)
|
|
217
|
+
result = {"package": identifier}
|
|
218
|
+
try:
|
|
219
|
+
if os.path.isdir(identifier):
|
|
220
|
+
log.debug(f"Considering that '{identifier}' is a local directory")
|
|
221
|
+
result |= scanner.scan_local(identifier, rule_param)
|
|
222
|
+
elif os.path.isfile(identifier):
|
|
223
|
+
log.debug(f"Considering that '{identifier}' is a local archive file")
|
|
224
|
+
with tempfile.TemporaryDirectory() as tempdir:
|
|
225
|
+
safe_extract(identifier, tempdir)
|
|
226
|
+
result |= scanner.scan_local(tempdir, rule_param)
|
|
227
|
+
else:
|
|
228
|
+
log.debug(f"Considering that '{identifier}' is a remote target")
|
|
229
|
+
result |= scanner.scan_remote(identifier, version, rule_param)
|
|
230
|
+
except Exception as e:
|
|
231
|
+
sys.stderr.write(f"Error occurred while scanning target {identifier}: '{e}'\n")
|
|
232
|
+
sys.exit(1)
|
|
237
233
|
|
|
238
234
|
if output_format == "json":
|
|
239
|
-
|
|
240
|
-
# return only a json like {}
|
|
241
|
-
print(js.dumps(results[0]))
|
|
242
|
-
else:
|
|
243
|
-
# Return a list of result like [{},{}]
|
|
244
|
-
print(js.dumps(results))
|
|
235
|
+
print(js.dumps(result))
|
|
245
236
|
else:
|
|
246
|
-
|
|
247
|
-
print_scan_results(result, result["package"])
|
|
237
|
+
print_scan_results(result, result["package"])
|
|
248
238
|
|
|
249
239
|
if exit_non_zero_on_finding:
|
|
250
|
-
exit_with_status_code(
|
|
240
|
+
exit_with_status_code([result])
|
|
251
241
|
|
|
252
242
|
|
|
253
243
|
def _list_rules(ecosystem: ECOSYSTEM):
|
guarddog/scanners/__init__.py
CHANGED
|
@@ -6,22 +6,49 @@ from .pypi_package_scanner import PypiPackageScanner
|
|
|
6
6
|
from .pypi_project_scanner import PypiRequirementsScanner
|
|
7
7
|
from .go_package_scanner import GoModuleScanner
|
|
8
8
|
from .go_project_scanner import GoDependenciesScanner
|
|
9
|
-
from .scanner import
|
|
9
|
+
from .scanner import PackageScanner, ProjectScanner
|
|
10
10
|
from ..ecosystems import ECOSYSTEM
|
|
11
11
|
|
|
12
12
|
|
|
13
|
-
def
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
def get_package_scanner(ecosystem: ECOSYSTEM) -> Optional[PackageScanner]:
|
|
14
|
+
"""
|
|
15
|
+
Return a `PackageScanner` for the given ecosystem or `None` if it
|
|
16
|
+
is not yet supported.
|
|
17
|
+
|
|
18
|
+
Args:
|
|
19
|
+
ecosystem (ECOSYSTEM): The ecosystem of the desired scanner
|
|
20
|
+
|
|
21
|
+
Returns:
|
|
22
|
+
Optional[PackageScanner]: The result of the scanner request
|
|
23
|
+
|
|
24
|
+
"""
|
|
25
|
+
match ecosystem:
|
|
26
|
+
case ECOSYSTEM.PYPI:
|
|
16
27
|
return PypiPackageScanner()
|
|
17
|
-
case
|
|
18
|
-
return PypiRequirementsScanner()
|
|
19
|
-
case (ECOSYSTEM.NPM, False):
|
|
28
|
+
case ECOSYSTEM.NPM:
|
|
20
29
|
return NPMPackageScanner()
|
|
21
|
-
case
|
|
22
|
-
return NPMRequirementsScanner()
|
|
23
|
-
case (ECOSYSTEM.GO, False):
|
|
30
|
+
case ECOSYSTEM.GO:
|
|
24
31
|
return GoModuleScanner()
|
|
25
|
-
|
|
32
|
+
return None
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def get_project_scanner(ecosystem: ECOSYSTEM) -> Optional[ProjectScanner]:
|
|
36
|
+
"""
|
|
37
|
+
Return a `ProjectScanner` for the given ecosystem or `None` if
|
|
38
|
+
it is not yet supported.
|
|
39
|
+
|
|
40
|
+
Args:
|
|
41
|
+
ecosystem (ECOSYSTEM): The ecosystem of the desired scanner
|
|
42
|
+
|
|
43
|
+
Returns:
|
|
44
|
+
Optional[ProjectScanner]: The result of the scanner request
|
|
45
|
+
|
|
46
|
+
"""
|
|
47
|
+
match ecosystem:
|
|
48
|
+
case ECOSYSTEM.PYPI:
|
|
49
|
+
return PypiRequirementsScanner()
|
|
50
|
+
case ECOSYSTEM.NPM:
|
|
51
|
+
return NPMRequirementsScanner()
|
|
52
|
+
case ECOSYSTEM.GO:
|
|
26
53
|
return GoDependenciesScanner()
|
|
27
54
|
return None
|
guarddog/scanners/scanner.py
CHANGED
|
@@ -21,18 +21,7 @@ def noop(arg: typing.Any) -> None:
|
|
|
21
21
|
pass
|
|
22
22
|
|
|
23
23
|
|
|
24
|
-
class
|
|
25
|
-
def __init__(self) -> None:
|
|
26
|
-
pass
|
|
27
|
-
|
|
28
|
-
@abstractmethod
|
|
29
|
-
def scan_local(
|
|
30
|
-
self, path, rules=None, callback: typing.Callable[[dict], None] = noop
|
|
31
|
-
):
|
|
32
|
-
pass
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
class ProjectScanner(Scanner):
|
|
24
|
+
class ProjectScanner:
|
|
36
25
|
def __init__(self, package_scanner):
|
|
37
26
|
super().__init__()
|
|
38
27
|
self.package_scanner = package_scanner
|
|
@@ -212,7 +201,7 @@ class ProjectScanner(Scanner):
|
|
|
212
201
|
pass
|
|
213
202
|
|
|
214
203
|
|
|
215
|
-
class PackageScanner
|
|
204
|
+
class PackageScanner:
|
|
216
205
|
"""
|
|
217
206
|
Scans package for attack vectors based on source code and metadata rules
|
|
218
207
|
|
|
@@ -231,7 +220,7 @@ class PackageScanner(Scanner):
|
|
|
231
220
|
Scans local package
|
|
232
221
|
|
|
233
222
|
Args:
|
|
234
|
-
path (str):
|
|
223
|
+
path (str): Path to the directory containing the package to analyze
|
|
235
224
|
rules (set, optional): Set of rule names to use. Defaults to all rules.
|
|
236
225
|
callback (typing.Callable[[dict], None], optional): Callback to apply to Analyzer output
|
|
237
226
|
|
|
@@ -245,16 +234,7 @@ class PackageScanner(Scanner):
|
|
|
245
234
|
if rules is not None:
|
|
246
235
|
rules = set(rules)
|
|
247
236
|
|
|
248
|
-
results =
|
|
249
|
-
if os.path.isdir(path):
|
|
250
|
-
results = self.analyzer.analyze_sourcecode(path, rules=rules)
|
|
251
|
-
elif os.path.isfile(path):
|
|
252
|
-
with tempfile.TemporaryDirectory() as tempdir:
|
|
253
|
-
safe_extract(path, tempdir)
|
|
254
|
-
results = self.analyzer.analyze_sourcecode(tempdir, rules=rules)
|
|
255
|
-
else:
|
|
256
|
-
raise Exception(f"Local scan target {path} is neither a directory nor a file.")
|
|
257
|
-
|
|
237
|
+
results = self.analyzer.analyze_sourcecode(path, rules=rules)
|
|
258
238
|
callback(results)
|
|
259
239
|
|
|
260
240
|
return results
|
guarddog/utils/archives.py
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import logging
|
|
2
2
|
import os
|
|
3
|
+
import stat
|
|
3
4
|
import zipfile
|
|
4
5
|
|
|
5
6
|
import tarsafe # type:ignore
|
|
@@ -9,41 +10,25 @@ log = logging.getLogger("guarddog")
|
|
|
9
10
|
|
|
10
11
|
def is_supported_archive(path: str) -> bool:
|
|
11
12
|
"""
|
|
12
|
-
Decide whether a file contains a supported archive
|
|
13
|
+
Decide whether a file contains a supported archive based on its
|
|
14
|
+
file extension.
|
|
13
15
|
|
|
14
16
|
Args:
|
|
15
17
|
path (str): The local filesystem path to examine
|
|
16
18
|
|
|
17
19
|
Returns:
|
|
18
20
|
bool: Represents the decision reached for the file
|
|
19
|
-
"""
|
|
20
|
-
return is_tar_archive(path) or is_zip_archive(path)
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
def is_tar_archive(path: str) -> bool:
|
|
24
|
-
"""
|
|
25
|
-
Decide whether a file contains a tar archive.
|
|
26
|
-
|
|
27
|
-
Args:
|
|
28
|
-
path (str): The local filesystem path to examine
|
|
29
21
|
|
|
30
|
-
Returns:
|
|
31
|
-
bool: Represents the decision reached for the file
|
|
32
22
|
"""
|
|
33
|
-
|
|
23
|
+
def is_tar_archive(path: str) -> bool:
|
|
24
|
+
tar_exts = [".bz2", ".bzip2", ".gz", ".gzip", ".tgz", ".xz"]
|
|
34
25
|
|
|
26
|
+
return any(path.endswith(ext) for ext in tar_exts)
|
|
35
27
|
|
|
36
|
-
def is_zip_archive(path: str) -> bool:
|
|
37
|
-
|
|
38
|
-
Decide whether a file contains a zip, whl or egg archive.
|
|
28
|
+
def is_zip_archive(path: str) -> bool:
|
|
29
|
+
return any(path.endswith(ext) for ext in [".zip", ".whl", ".egg"])
|
|
39
30
|
|
|
40
|
-
|
|
41
|
-
path (str): The local filesystem path to examine
|
|
42
|
-
|
|
43
|
-
Returns:
|
|
44
|
-
bool: Represents the decision reached for the file
|
|
45
|
-
"""
|
|
46
|
-
return any(path.endswith(ext) for ext in [".zip", ".whl", ".egg"])
|
|
31
|
+
return is_tar_archive(path) or is_zip_archive(path)
|
|
47
32
|
|
|
48
33
|
|
|
49
34
|
def safe_extract(source_archive: str, target_directory: str) -> None:
|
|
@@ -61,9 +46,28 @@ def safe_extract(source_archive: str, target_directory: str) -> None:
|
|
|
61
46
|
|
|
62
47
|
"""
|
|
63
48
|
log.debug(f"Extracting archive {source_archive} to directory {target_directory}")
|
|
64
|
-
if
|
|
49
|
+
if tarsafe.is_tarfile(source_archive):
|
|
50
|
+
|
|
51
|
+
def add_exec(path):
|
|
52
|
+
st = os.stat(path)
|
|
53
|
+
os.chmod(path, st.st_mode | stat.S_IEXEC)
|
|
54
|
+
|
|
55
|
+
def add_read(path):
|
|
56
|
+
st = os.stat(path)
|
|
57
|
+
os.chmod(path, st.st_mode | stat.S_IREAD)
|
|
58
|
+
|
|
59
|
+
def recurse_add_perms(path):
|
|
60
|
+
add_exec(path)
|
|
61
|
+
for root, dirs, files in os.walk(path):
|
|
62
|
+
for d in dirs:
|
|
63
|
+
add_exec(os.path.join(root, d))
|
|
64
|
+
for f in files:
|
|
65
|
+
add_read(os.path.join(root, f))
|
|
66
|
+
|
|
65
67
|
tarsafe.open(source_archive).extractall(target_directory)
|
|
66
|
-
|
|
68
|
+
recurse_add_perms(target_directory)
|
|
69
|
+
|
|
70
|
+
elif zipfile.is_zipfile(source_archive):
|
|
67
71
|
with zipfile.ZipFile(source_archive, 'r') as zip:
|
|
68
72
|
for file in zip.namelist():
|
|
69
73
|
# Note: zip.extract cleans up any malicious file name
|
|
@@ -51,36 +51,36 @@ guarddog/analyzer/sourcecode/exfiltrate-sensitive-data.yml,sha256=e8dj10HABb36rS
|
|
|
51
51
|
guarddog/analyzer/sourcecode/npm-dll-hijacking.yml,sha256=TPIXvWm8Ot9RVtDXWFmoNZw9-3PH7NuXK6x1fQCiRt4,3506
|
|
52
52
|
guarddog/analyzer/sourcecode/npm-exec-base64.yml,sha256=xNIwJAmGP19wvxH_w1ySgDsxrUU3GkrxRcFjjnB9fWM,576
|
|
53
53
|
guarddog/analyzer/sourcecode/npm-exfiltrate-sensitive-data.yml,sha256=UP-GlZ5VykHWFebgIiHrkrQL9PdtjxR99_m2FZddmuw,3011
|
|
54
|
-
guarddog/analyzer/sourcecode/npm-install-script.yml,sha256=
|
|
54
|
+
guarddog/analyzer/sourcecode/npm-install-script.yml,sha256=0resBD7upjukUWsUEYv9sWLC1bCN8xD1pgCVDAxYa_I,1355
|
|
55
55
|
guarddog/analyzer/sourcecode/npm-obfuscation.yml,sha256=BIyf7PP8F2dTX4BIWDiBOqDg0Wlj6_PRxe5pWMXUqeQ,1815
|
|
56
56
|
guarddog/analyzer/sourcecode/npm-serialize-environment.yml,sha256=gFpr58INp44ZwxYZlIHyzpOgbVMDLv1ZRPTGAczX5dw,835
|
|
57
57
|
guarddog/analyzer/sourcecode/npm-silent-process-execution.yml,sha256=qnJHGesNPNpxGa8n2kQMpttLGck-6vZjI_SsweDyk7M,3513
|
|
58
58
|
guarddog/analyzer/sourcecode/npm-steganography.yml,sha256=XH0udcriAQq_6WOHAG4TpIedw8GgKyWx9gsG_Q_Fki8,915
|
|
59
59
|
guarddog/analyzer/sourcecode/obfuscation.yml,sha256=QgvqJJ8ovyZ4NSjNGJabQiRJTKIExUCevnhLksueh9M,582
|
|
60
|
-
guarddog/analyzer/sourcecode/shady-links.yml,sha256=
|
|
60
|
+
guarddog/analyzer/sourcecode/shady-links.yml,sha256=a0TDoyVXes13VjSeg6NECtNVJWNigqQU54aELiJZ5qQ,1961
|
|
61
61
|
guarddog/analyzer/sourcecode/silent-process-execution.yml,sha256=b6RjenMv7si7lXGak3uMmD7PMtQRuKPeJFggPW6UDNI,418
|
|
62
62
|
guarddog/analyzer/sourcecode/steganography.yml,sha256=3ceO6SJhu4XpZEjfwelLdOxeZ4Ho1OgUjbcacwtOhR0,606
|
|
63
|
-
guarddog/cli.py,sha256=
|
|
63
|
+
guarddog/cli.py,sha256=P5pc_qkX_SHPHRoPnjjq7au2Vj7GYW906r7dh6ADzg4,13201
|
|
64
64
|
guarddog/ecosystems.py,sha256=kgM4v5E8PZBQksWgzuWwODS5R7P16klDi1SGWKLy1e0,380
|
|
65
65
|
guarddog/reporters/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
66
66
|
guarddog/reporters/sarif.py,sha256=44Ixtfk9IhHHaU0MtRLsaBUnPl23kDRuCbtWJ84Z9LA,5866
|
|
67
|
-
guarddog/scanners/__init__.py,sha256=
|
|
67
|
+
guarddog/scanners/__init__.py,sha256=yEsDvThkIAhFkP59gSCFxYe5HTLmoSzfjAkDrtFT1LY,1628
|
|
68
68
|
guarddog/scanners/go_package_scanner.py,sha256=OdCbwtjJow9AxEv34z7WBfgTamqKj5DxJh7dly_1NuY,2926
|
|
69
69
|
guarddog/scanners/go_project_scanner.py,sha256=3D5dYSA7FVqc7IIM7uAHlCJZalshP_WhagWmOcYirog,2123
|
|
70
70
|
guarddog/scanners/npm_package_scanner.py,sha256=qBU0tCbW2pTL3cy5Y4JVAJyAGdvb-HY69qSQmjWbPxU,1968
|
|
71
71
|
guarddog/scanners/npm_project_scanner.py,sha256=L_gqinZit6KHE0dJTRnuJ49U4E3izNf4UBVGkHkiPjw,3585
|
|
72
72
|
guarddog/scanners/pypi_package_scanner.py,sha256=Tg7M837vhNZim3Jy9OMJSQY2C_m9C75UDy0S_5WKT6M,2375
|
|
73
73
|
guarddog/scanners/pypi_project_scanner.py,sha256=NY-xO27r9xIGik7y-btoBKX54_VPSV_RJfeClJDKAkA,5049
|
|
74
|
-
guarddog/scanners/scanner.py,sha256=
|
|
74
|
+
guarddog/scanners/scanner.py,sha256=7-OGs8GoRfyexEYOfVRSmV7P-7ZJDXtgj2Z1UrKGx30,10929
|
|
75
75
|
guarddog/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
76
|
-
guarddog/utils/archives.py,sha256=
|
|
76
|
+
guarddog/utils/archives.py,sha256=jOXAhxZx-mTtpDidGGKxQg052CvaQOAVklvOeUn9HTQ,2593
|
|
77
77
|
guarddog/utils/config.py,sha256=KCiGsaeautOo-1p0CSbHY5HWT8cC17-_8tqKH7hPa1E,883
|
|
78
78
|
guarddog/utils/exceptions.py,sha256=23Kzl3exqYK6X-bcGUeb8wPmSglWNX3GIDPkJ6lQzo4,54
|
|
79
79
|
guarddog/utils/package_info.py,sha256=TFjE1xsGNf60SuHlIeDV2pzMUbogl5TKJdSzswat6jI,953
|
|
80
|
-
guarddog-2.0.
|
|
81
|
-
guarddog-2.0.
|
|
82
|
-
guarddog-2.0.
|
|
83
|
-
guarddog-2.0.
|
|
84
|
-
guarddog-2.0.
|
|
85
|
-
guarddog-2.0.
|
|
86
|
-
guarddog-2.0.
|
|
80
|
+
guarddog-2.0.1.dist-info/LICENSE,sha256=w1aNZxHyoyOPJ4fSdiyrr06tCJZbTjCsH9K1uqeDVyU,11377
|
|
81
|
+
guarddog-2.0.1.dist-info/LICENSE-3rdparty.csv,sha256=cS61ONZL_xlXaTMvQXyBEi3J3es-40Gg6G-6idoa5Qk,314
|
|
82
|
+
guarddog-2.0.1.dist-info/METADATA,sha256=HRjSkYeNAJ7XuQA5C_namTiG6vt0-qpaE-6nNGMhX88,1417
|
|
83
|
+
guarddog-2.0.1.dist-info/NOTICE,sha256=nlyNt2IjG8IBoQkb7n6jszwAvmREpKAx0POzFO1s2JM,140
|
|
84
|
+
guarddog-2.0.1.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
|
85
|
+
guarddog-2.0.1.dist-info/entry_points.txt,sha256=vX2fvhnNdkbEL4pDzrH2NqjWVxeOaEYi0sJYmNgS2-s,45
|
|
86
|
+
guarddog-2.0.1.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|