guarddog 2.2.0__py3-none-any.whl → 2.4.0__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/analyzer.py +35 -4
- guarddog/analyzer/metadata/__init__.py +3 -0
- guarddog/analyzer/metadata/bundled_binary.py +6 -1
- guarddog/analyzer/metadata/github_action/__init__.py +11 -0
- guarddog/analyzer/sourcecode/__init__.py +22 -20
- guarddog/analyzer/sourcecode/dll-hijacking.yml +11 -7
- guarddog/analyzer/sourcecode/download-executable.yml +10 -2
- guarddog/analyzer/sourcecode/npm-dll-hijacking.yml +0 -2
- guarddog/analyzer/sourcecode/npm-exfiltrate-sensitive-data.yml +5 -3
- guarddog/analyzer/sourcecode/npm-obfuscation.yml +8 -2
- guarddog/analyzer/sourcecode/shady-links.yml +4 -4
- guarddog/ecosystems.py +3 -0
- guarddog/scanners/__init__.py +3 -0
- guarddog/scanners/github_action_scanner.py +51 -0
- {guarddog-2.2.0.dist-info → guarddog-2.4.0.dist-info}/METADATA +4 -5
- {guarddog-2.2.0.dist-info → guarddog-2.4.0.dist-info}/RECORD +21 -20
- {guarddog-2.2.0.dist-info → guarddog-2.4.0.dist-info}/WHEEL +1 -1
- guarddog/analyzer/sourcecode/bidirectional-characters.yml +0 -29
- {guarddog-2.2.0.dist-info → guarddog-2.4.0.dist-info}/LICENSE +0 -0
- {guarddog-2.2.0.dist-info → guarddog-2.4.0.dist-info}/LICENSE-3rdparty.csv +0 -0
- {guarddog-2.2.0.dist-info → guarddog-2.4.0.dist-info}/NOTICE +0 -0
- {guarddog-2.2.0.dist-info → guarddog-2.4.0.dist-info}/entry_points.txt +0 -0
guarddog/analyzer/analyzer.py
CHANGED
|
@@ -333,15 +333,19 @@ output: {e.output}
|
|
|
333
333
|
|
|
334
334
|
for result in response["results"]:
|
|
335
335
|
rule_name = rule or result["check_id"].split(".")[-1]
|
|
336
|
-
|
|
337
|
-
|
|
336
|
+
start_line = result["start"]["line"]
|
|
337
|
+
end_line = result["end"]["line"]
|
|
338
338
|
|
|
339
339
|
file_path = os.path.abspath(result["path"])
|
|
340
|
+
code = self.trim_code_snippet(
|
|
341
|
+
self.get_snippet(
|
|
342
|
+
file_path=file_path, start_line=start_line, end_line=end_line
|
|
343
|
+
)
|
|
344
|
+
)
|
|
340
345
|
if targetpath:
|
|
341
346
|
file_path = os.path.relpath(file_path, targetpath)
|
|
342
347
|
|
|
343
|
-
location = file_path + ":" + str(
|
|
344
|
-
code = self.trim_code_snippet(code_snippet)
|
|
348
|
+
location = file_path + ":" + str(start_line)
|
|
345
349
|
|
|
346
350
|
finding = {
|
|
347
351
|
'location': location,
|
|
@@ -356,6 +360,33 @@ output: {e.output}
|
|
|
356
360
|
|
|
357
361
|
return results
|
|
358
362
|
|
|
363
|
+
def get_snippet(self, file_path: str, start_line: int, end_line: int) -> str:
|
|
364
|
+
"""
|
|
365
|
+
Returns the code snippet between start_line and stop_line in a file
|
|
366
|
+
|
|
367
|
+
Args:
|
|
368
|
+
path (str): path to file
|
|
369
|
+
start_line (int): starting line number
|
|
370
|
+
end_line (int): ending line number
|
|
371
|
+
|
|
372
|
+
Returns:
|
|
373
|
+
str: code snippet
|
|
374
|
+
"""
|
|
375
|
+
snippet = []
|
|
376
|
+
try:
|
|
377
|
+
with open(file_path, 'r') as file:
|
|
378
|
+
for current_line_number, line in enumerate(file, start=1):
|
|
379
|
+
if start_line <= current_line_number <= end_line:
|
|
380
|
+
snippet.append(line)
|
|
381
|
+
elif current_line_number > end_line:
|
|
382
|
+
break
|
|
383
|
+
except FileNotFoundError:
|
|
384
|
+
log.error(f"File not found: {file_path}")
|
|
385
|
+
except Exception as e:
|
|
386
|
+
log.error(f"Error reading file {file_path}: {str(e)}")
|
|
387
|
+
|
|
388
|
+
return ''.join(snippet)
|
|
389
|
+
|
|
359
390
|
# Makes sure the matching code to be displayed isn't too long
|
|
360
391
|
def trim_code_snippet(self, code):
|
|
361
392
|
THRESHOLD = 250
|
|
@@ -2,6 +2,7 @@ from guarddog.analyzer.metadata.detector import Detector
|
|
|
2
2
|
from guarddog.analyzer.metadata.npm import NPM_METADATA_RULES
|
|
3
3
|
from guarddog.analyzer.metadata.pypi import PYPI_METADATA_RULES
|
|
4
4
|
from guarddog.analyzer.metadata.go import GO_METADATA_RULES
|
|
5
|
+
from guarddog.analyzer.metadata.github_action import GITHUB_ACTION_METADATA_RULES
|
|
5
6
|
from guarddog.ecosystems import ECOSYSTEM
|
|
6
7
|
|
|
7
8
|
|
|
@@ -13,3 +14,5 @@ def get_metadata_detectors(ecosystem: ECOSYSTEM) -> dict[str, Detector]:
|
|
|
13
14
|
return NPM_METADATA_RULES
|
|
14
15
|
case ECOSYSTEM.GO:
|
|
15
16
|
return GO_METADATA_RULES
|
|
17
|
+
case ECOSYSTEM.GITHUB_ACTION:
|
|
18
|
+
return GITHUB_ACTION_METADATA_RULES
|
|
@@ -14,7 +14,12 @@ class BundledBinary(Detector):
|
|
|
14
14
|
|
|
15
15
|
# magic bytes are the first few bytes of a file that can be used to identify the file type
|
|
16
16
|
# regardless of their extension
|
|
17
|
-
magic_bytes = {
|
|
17
|
+
magic_bytes = {
|
|
18
|
+
"exe": b"\x4D\x5A",
|
|
19
|
+
"elf": b"\x7F\x45\x4C\x46",
|
|
20
|
+
"macho32": b"\xFE\xED\xFA\xCE",
|
|
21
|
+
"macho64": b"\xFE\xED\xFA\xCF",
|
|
22
|
+
}
|
|
18
23
|
|
|
19
24
|
def __init__(self):
|
|
20
25
|
super().__init__(
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
from typing import Type
|
|
2
|
+
|
|
3
|
+
from guarddog.analyzer.metadata import Detector
|
|
4
|
+
|
|
5
|
+
GITHUB_ACTION_METADATA_RULES = {}
|
|
6
|
+
|
|
7
|
+
classes: list[Type[Detector]] = []
|
|
8
|
+
|
|
9
|
+
for detectorClass in classes:
|
|
10
|
+
detectorInstance = detectorClass() # type: ignore
|
|
11
|
+
GITHUB_ACTION_METADATA_RULES[detectorInstance.get_name()] = detectorInstance
|
|
@@ -71,34 +71,36 @@ for file_name in semgrep_rule_file_names:
|
|
|
71
71
|
data = yaml.load(fd, Loader=SafeLoader)
|
|
72
72
|
for rule in data["rules"]:
|
|
73
73
|
for lang in rule["languages"]:
|
|
74
|
-
|
|
74
|
+
ecosystems = set()
|
|
75
75
|
match lang:
|
|
76
76
|
case "python":
|
|
77
|
-
|
|
77
|
+
ecosystems.add(ECOSYSTEM.PYPI)
|
|
78
78
|
case "javascript" | "typescript" | "json":
|
|
79
|
-
|
|
79
|
+
ecosystems.add(ECOSYSTEM.NPM)
|
|
80
|
+
ecosystems.add(ECOSYSTEM.GITHUB_ACTION)
|
|
80
81
|
case "go":
|
|
81
|
-
|
|
82
|
+
ecosystems.add(ECOSYSTEM.GO)
|
|
82
83
|
case _:
|
|
83
84
|
continue
|
|
84
85
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
86
|
+
for ecosystem in ecosystems:
|
|
87
|
+
# avoids duplicates when multiple languages are supported by a rule
|
|
88
|
+
if not next(
|
|
89
|
+
filter(
|
|
90
|
+
lambda r: r.id == rule["id"],
|
|
91
|
+
get_sourcecode_rules(ecosystem, SempgrepRule),
|
|
92
|
+
),
|
|
93
|
+
None,
|
|
94
|
+
):
|
|
95
|
+
SOURCECODE_RULES.append(
|
|
96
|
+
SempgrepRule(
|
|
97
|
+
id=rule["id"],
|
|
98
|
+
ecosystem=ecosystem,
|
|
99
|
+
description=rule.get("metadata", {}).get("description", ""),
|
|
100
|
+
file=file_name,
|
|
101
|
+
rule_content=rule,
|
|
102
|
+
)
|
|
100
103
|
)
|
|
101
|
-
)
|
|
102
104
|
|
|
103
105
|
yara_rule_file_names = list(
|
|
104
106
|
filter(lambda x: x.endswith("yar"), os.listdir(current_dir))
|
|
@@ -62,11 +62,17 @@ rules:
|
|
|
62
62
|
- patterns:
|
|
63
63
|
# write a library to disk
|
|
64
64
|
- patterns:
|
|
65
|
-
- pattern:
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
65
|
+
- pattern-either:
|
|
66
|
+
- pattern: |
|
|
67
|
+
...
|
|
68
|
+
with open($DLL,'wb') as $FILE:
|
|
69
|
+
...
|
|
70
|
+
$FN(...,$EXE,...)
|
|
71
|
+
- pattern: |
|
|
72
|
+
...
|
|
73
|
+
$FILE = open($DLL,'wb')
|
|
74
|
+
...
|
|
75
|
+
$FN(...,$EXE,...)
|
|
70
76
|
- metavariable-pattern:
|
|
71
77
|
metavariable: $EXE
|
|
72
78
|
patterns:
|
|
@@ -82,5 +88,3 @@ rules:
|
|
|
82
88
|
- focus-metavariable: $DLL
|
|
83
89
|
|
|
84
90
|
severity: WARNING
|
|
85
|
-
options:
|
|
86
|
-
symbolic_propagation: true
|
|
@@ -12,6 +12,10 @@ rules:
|
|
|
12
12
|
- pattern-either:
|
|
13
13
|
- pattern: (...).urlretrieve(...,$EXE)
|
|
14
14
|
- pattern: open($EXE, ...).write($REQUEST)
|
|
15
|
+
- pattern: |
|
|
16
|
+
$FILE = open($EXE, ...)
|
|
17
|
+
...
|
|
18
|
+
$FILE.write($REQUEST)
|
|
15
19
|
- pattern: |
|
|
16
20
|
with open($EXE, ...) as $FILE:
|
|
17
21
|
...
|
|
@@ -30,6 +34,12 @@ rules:
|
|
|
30
34
|
...
|
|
31
35
|
$MAKE_EXEC
|
|
32
36
|
|
|
37
|
+
- pattern: |
|
|
38
|
+
$FILE = open($LOC, ...)
|
|
39
|
+
...
|
|
40
|
+
$FILE.write($REQUEST)
|
|
41
|
+
...
|
|
42
|
+
$MAKE_EXEC
|
|
33
43
|
- pattern: |
|
|
34
44
|
open($LOC, ...).write($REQUEST)
|
|
35
45
|
...
|
|
@@ -93,5 +103,3 @@ rules:
|
|
|
93
103
|
requests.get(...)
|
|
94
104
|
...
|
|
95
105
|
severity: WARNING
|
|
96
|
-
options:
|
|
97
|
-
symbolic_propagation: true
|
|
@@ -84,12 +84,14 @@ rules:
|
|
|
84
84
|
- pattern: $HTTP. ... .request(...)
|
|
85
85
|
- pattern: $HTTP. ... .get(...)
|
|
86
86
|
- pattern: $HTTP. ... .post(...)
|
|
87
|
-
- pattern:
|
|
87
|
+
- pattern: |
|
|
88
|
+
$FIRE=$HTTP.child(...)
|
|
89
|
+
...
|
|
90
|
+
$FIRE.push(...)
|
|
88
91
|
- pattern: $HTTP. ... .write(...)
|
|
89
92
|
- pattern: $HTTP(...)
|
|
90
93
|
languages:
|
|
91
94
|
- javascript
|
|
92
95
|
- typescript
|
|
93
96
|
severity: WARNING
|
|
94
|
-
|
|
95
|
-
symbolic_propagation: true
|
|
97
|
+
|
|
@@ -57,8 +57,14 @@ rules:
|
|
|
57
57
|
- pattern-not-inside: //...
|
|
58
58
|
- pattern-regex: ^(.*?);?[\h]{150,};?.{10,}$
|
|
59
59
|
|
|
60
|
+
# Packer
|
|
61
|
+
- pattern: |
|
|
62
|
+
eval(function(...){
|
|
63
|
+
...
|
|
64
|
+
$VAR.replace(new RegExp(...),...)
|
|
65
|
+
...
|
|
66
|
+
}(...))
|
|
67
|
+
|
|
60
68
|
languages:
|
|
61
69
|
- javascript
|
|
62
70
|
severity: WARNING
|
|
63
|
-
options:
|
|
64
|
-
symbolic_propagation: true
|
|
@@ -33,12 +33,12 @@ rules:
|
|
|
33
33
|
# complete domains: shorteners
|
|
34
34
|
- pattern-regex: ((?:https?:\/\/)?[^\n\[\/\?#"']*?(bit\.ly)\b)
|
|
35
35
|
# complete domains: ephimerals,tunnels
|
|
36
|
-
- pattern-regex: ((?:https?:\/\/)?[^\n\[\/\?#"']*?(workers\.dev|appdomain\.cloud|ngrok\.io|termbin\.com|localhost\.run|webhook\.site|oastify\.com|burpcollaborator\.(me|net)|trycloudflare\.com)\b)
|
|
37
|
-
- pattern-regex: ((?:https?:\/\/)?[^\n\[\/\?#"']*?(oast\.(pro|live|site|online|fun|me)|ply\.gg|pipedream\.net|dnslog\.cn|ngrok-free\.(app|dev))\b)
|
|
36
|
+
- pattern-regex: ((?:https?:\/\/)?[^\n\[\/\?#"']*?(workers\.dev|appdomain\.cloud|ngrok\.io|termbin\.com|localhost\.run|webhook\.(site|cool)|oastify\.com|burpcollaborator\.(me|net)|trycloudflare\.com)\b)
|
|
37
|
+
- pattern-regex: ((?:https?:\/\/)?[^\n\[\/\?#"']*?(oast\.(pro|live|site|online|fun|me)|ply\.gg|pipedream\.net|dnslog\.cn|webhook-test\.com|typedwebhook\.tools|beeceptor\.com|ngrok-free\.(app|dev))\b)
|
|
38
38
|
# complete domains: exfil
|
|
39
|
-
- pattern-regex: ((?:https?:\/\/)?[^\n\[\/\?#"']*?(discord\.com|transfer\.sh|filetransfer\.io|sendspace\.com|backblazeb2\.com|paste\.ee|pastebin\.com|api\.telegram\.org|rentry\.co)\b)
|
|
39
|
+
- pattern-regex: ((?:https?:\/\/)?[^\n\[\/\?#"']*?(discord\.com|transfer\.sh|filetransfer\.io|sendspace\.com|backblazeb2\.com|paste\.ee|pastebin\.com|hastebin\.com|ghostbin.site|api\.telegram\.org|rentry\.co)\b)
|
|
40
40
|
# complete domains: intel
|
|
41
|
-
- pattern-regex: ((?:https?:\/\/)?[^\n\[\/\?#"']*?(ipinfo\.io)\b)
|
|
41
|
+
- pattern-regex: ((?:https?:\/\/)?[^\n\[\/\?#"']*?(ipinfo\.io|checkip\.dyndns\.org|\bip\.me|jsonip\.com|ipify\.org|ifconfig\.me)\b)
|
|
42
42
|
|
|
43
43
|
# top-level domains
|
|
44
44
|
- pattern-regex: (https?:\/\/[^\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)\/)
|
guarddog/ecosystems.py
CHANGED
|
@@ -5,6 +5,7 @@ class ECOSYSTEM(Enum):
|
|
|
5
5
|
PYPI = "pypi"
|
|
6
6
|
NPM = "npm"
|
|
7
7
|
GO = "go"
|
|
8
|
+
GITHUB_ACTION = "github-action"
|
|
8
9
|
|
|
9
10
|
|
|
10
11
|
def get_friendly_name(ecosystem: ECOSYSTEM) -> str:
|
|
@@ -15,5 +16,7 @@ def get_friendly_name(ecosystem: ECOSYSTEM) -> str:
|
|
|
15
16
|
return "npm"
|
|
16
17
|
case ECOSYSTEM.GO:
|
|
17
18
|
return "go"
|
|
19
|
+
case ECOSYSTEM.GITHUB_ACTION:
|
|
20
|
+
return "GitHub Action"
|
|
18
21
|
case _:
|
|
19
22
|
return ecosystem.value
|
guarddog/scanners/__init__.py
CHANGED
|
@@ -6,6 +6,7 @@ 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 .github_action_scanner import GithubActionScanner
|
|
9
10
|
from .scanner import PackageScanner, ProjectScanner
|
|
10
11
|
from ..ecosystems import ECOSYSTEM
|
|
11
12
|
|
|
@@ -29,6 +30,8 @@ def get_package_scanner(ecosystem: ECOSYSTEM) -> Optional[PackageScanner]:
|
|
|
29
30
|
return NPMPackageScanner()
|
|
30
31
|
case ECOSYSTEM.GO:
|
|
31
32
|
return GoModuleScanner()
|
|
33
|
+
case ECOSYSTEM.GITHUB_ACTION:
|
|
34
|
+
return GithubActionScanner()
|
|
32
35
|
return None
|
|
33
36
|
|
|
34
37
|
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
import os
|
|
3
|
+
import pathlib
|
|
4
|
+
import typing
|
|
5
|
+
from urllib.parse import urlparse
|
|
6
|
+
|
|
7
|
+
from guarddog.analyzer.analyzer import Analyzer
|
|
8
|
+
from guarddog.ecosystems import ECOSYSTEM
|
|
9
|
+
from guarddog.scanners.scanner import PackageScanner
|
|
10
|
+
|
|
11
|
+
log = logging.getLogger("guarddog")
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class GithubActionScanner(PackageScanner):
|
|
15
|
+
def __init__(self) -> None:
|
|
16
|
+
super().__init__(Analyzer(ECOSYSTEM.GITHUB_ACTION))
|
|
17
|
+
|
|
18
|
+
def download_and_get_package_info(self, directory: str, package_name: str, version=None) -> typing.Tuple[dict, str]:
|
|
19
|
+
repo = self._get_repo(package_name)
|
|
20
|
+
tarball_url = self._get_git_tarball_url(repo, version)
|
|
21
|
+
|
|
22
|
+
log.debug(f"Downloading GitHub Action source from {tarball_url}")
|
|
23
|
+
|
|
24
|
+
file_extension = pathlib.Path(tarball_url).suffix
|
|
25
|
+
if file_extension == "":
|
|
26
|
+
file_extension = ".zip"
|
|
27
|
+
|
|
28
|
+
zippath = os.path.join(directory, package_name.replace("/", "-") + file_extension)
|
|
29
|
+
unzippedpath = zippath.removesuffix(file_extension)
|
|
30
|
+
self.download_compressed(tarball_url, zippath, unzippedpath)
|
|
31
|
+
|
|
32
|
+
return {}, unzippedpath
|
|
33
|
+
|
|
34
|
+
def _get_repo(self, url: str) -> str:
|
|
35
|
+
parsed_url = urlparse(url)
|
|
36
|
+
|
|
37
|
+
if parsed_url.hostname and parsed_url.hostname != "github.com":
|
|
38
|
+
raise ValueError("Invalid GitHub repo URL: " + url)
|
|
39
|
+
|
|
40
|
+
path = parsed_url.path.removesuffix(".git").strip("/")
|
|
41
|
+
|
|
42
|
+
if path.count("/") != 1:
|
|
43
|
+
raise ValueError("Invalid GitHub repo name: " + path)
|
|
44
|
+
|
|
45
|
+
return path
|
|
46
|
+
|
|
47
|
+
def _get_git_tarball_url(self, repo: str, version=None) -> str:
|
|
48
|
+
if not version:
|
|
49
|
+
return f"https://api.github.com/repos/{repo}/zipball"
|
|
50
|
+
else:
|
|
51
|
+
return f"https://github.com/{repo}/archive/refs/tags/{version}.zip"
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: guarddog
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.4.0
|
|
4
4
|
Summary: GuardDog is a CLI tool to Identify malicious PyPI packages
|
|
5
|
-
Home-page: https://github.com/DataDog/guarddog
|
|
6
5
|
License: Apache-2.0
|
|
7
6
|
Author: Ellen Wang
|
|
8
7
|
Requires-Python: >=3.10,<4
|
|
@@ -16,15 +15,15 @@ Requires-Dist: click (>=8.1.3,<9.0.0)
|
|
|
16
15
|
Requires-Dist: click-option-group (>=0.5.5,<0.6.0)
|
|
17
16
|
Requires-Dist: colorama (>=0.4.6,<0.5.0)
|
|
18
17
|
Requires-Dist: configparser (>=5.3,<8.0)
|
|
19
|
-
Requires-Dist: disposable-email-domains (>=0.0.103,<0.0.
|
|
18
|
+
Requires-Dist: disposable-email-domains (>=0.0.103,<0.0.118)
|
|
20
19
|
Requires-Dist: prettytable (>=3.6.0,<4.0.0)
|
|
21
|
-
Requires-Dist: pygit2 (>=1.11,<1.
|
|
20
|
+
Requires-Dist: pygit2 (>=1.11,<1.18)
|
|
22
21
|
Requires-Dist: python-dateutil (>=2.8.2,<3.0.0)
|
|
23
22
|
Requires-Dist: python-whois (>=0.8,<0.10)
|
|
24
23
|
Requires-Dist: pyyaml (>=6.0,<7.0)
|
|
25
24
|
Requires-Dist: requests (>=2.29.0,<3.0.0)
|
|
26
25
|
Requires-Dist: semantic-version (>=2.10.0,<3.0.0)
|
|
27
|
-
Requires-Dist: semgrep (>=1.
|
|
26
|
+
Requires-Dist: semgrep (>=1.102.0,<2.0.0)
|
|
28
27
|
Requires-Dist: setuptools (>=70.3,<76.0)
|
|
29
28
|
Requires-Dist: tarsafe (>=0.0.5,<0.0.6)
|
|
30
29
|
Requires-Dist: termcolor (>=2.1.0,<3.0.0)
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
guarddog/__init__.py,sha256=reb53KZG9b1nFmsDxj2fropaOceOCyM9bVMUdmZ2wS8,227
|
|
2
2
|
guarddog/__main__.py,sha256=GEdfW6I6g2c3H7bS0G43E4C-g7kXGUswzDCPFSwPgHY,246
|
|
3
3
|
guarddog/analyzer/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
4
|
-
guarddog/analyzer/analyzer.py,sha256=
|
|
5
|
-
guarddog/analyzer/metadata/__init__.py,sha256=
|
|
6
|
-
guarddog/analyzer/metadata/bundled_binary.py,sha256=
|
|
4
|
+
guarddog/analyzer/analyzer.py,sha256=GADeg_zWJYGXYtCv8NJYxIl3QhP204CYFTeJX4QZK2U,14575
|
|
5
|
+
guarddog/analyzer/metadata/__init__.py,sha256=xaN-DlSHgudKDjKkfpNFue8ANmq1QUmEoAvU_Bc2OUo,749
|
|
6
|
+
guarddog/analyzer/metadata/bundled_binary.py,sha256=8i5ZPnyPyaLv6MG3KNMDVAElv5bDCOlnlsDt9SGUFsg,2596
|
|
7
7
|
guarddog/analyzer/metadata/deceptive_author.py,sha256=nuFyQqKpOuBKAJxpgbcjwXt3FVLzdmOg2mioUZ1D2TI,2789
|
|
8
8
|
guarddog/analyzer/metadata/detector.py,sha256=6yGyOK6BW_J-yrInoRlbaKNTC0HudezZABzkn2MnDJc,609
|
|
9
9
|
guarddog/analyzer/metadata/empty_information.py,sha256=etCU6LUdIzE4dS90vin45cjtVGPt963nFPJ_OzikwI4,1166
|
|
10
|
+
guarddog/analyzer/metadata/github_action/__init__.py,sha256=hOtiXKW-v5slzYW2M3k35M_YFfuLm8CNv5MwNSdFYMM,311
|
|
10
11
|
guarddog/analyzer/metadata/go/__init__.py,sha256=apwPnP9D4WEqgtR4RY0YIuFN7oNJXxJE_vYlp0ffRvQ,391
|
|
11
12
|
guarddog/analyzer/metadata/go/typosquatting.py,sha256=8Ln-DoGWto6tnihUPNaQ6qITp7z0tmFVf1BMC6hdMUo,4004
|
|
12
13
|
guarddog/analyzer/metadata/npm/__init__.py,sha256=j1Ng74bb1yD9XHFoYmJPzWL7vYMmLt6c2Lbc8lCqnUI,1326
|
|
@@ -41,32 +42,32 @@ guarddog/analyzer/metadata/resources/top_pypi_packages.json,sha256=DWSWEOEsZs6Ri
|
|
|
41
42
|
guarddog/analyzer/metadata/typosquatting.py,sha256=EMtHwKWWEYUs7ikyaPNtXH0FGPNDPDc2IFMZSDiv3Mg,4560
|
|
42
43
|
guarddog/analyzer/metadata/unclaimed_maintainer_email_domain.py,sha256=qy8AZqbVxD1U3Q--h0FYV7lKPFNlhSzfZK0GwjvQxdQ,2343
|
|
43
44
|
guarddog/analyzer/metadata/utils.py,sha256=bOrkELPza4ScUx1DfQxlqU-9DQeA5weISF42c0QCtls,1768
|
|
44
|
-
guarddog/analyzer/sourcecode/__init__.py,sha256=
|
|
45
|
-
guarddog/analyzer/sourcecode/bidirectional-characters.yml,sha256=WNQb3EzaT6GAbiMOV3lx592KNczbhIyUAAVXH9m2ygQ,1310
|
|
45
|
+
guarddog/analyzer/sourcecode/__init__.py,sha256=6TsFMVYmL3nuAJjBplbAInQp7coldAxz1qdrZvZGcBc,3960
|
|
46
46
|
guarddog/analyzer/sourcecode/clipboard-access.yml,sha256=B36E7xKtAVgwZ29UWtvZa1AJcyfrhvehbLo6tlJqffk,524
|
|
47
47
|
guarddog/analyzer/sourcecode/cmd-overwrite.yml,sha256=l-tE3_G-LqCuCZnHab6v0PpCdMpoHPutBYcijeMZEA0,682
|
|
48
48
|
guarddog/analyzer/sourcecode/code-execution.yml,sha256=gbnbvpnmSCY3Q5BANziWCRA-JXIH2LQ8-5ZaFralqbM,5002
|
|
49
|
-
guarddog/analyzer/sourcecode/dll-hijacking.yml,sha256=
|
|
50
|
-
guarddog/analyzer/sourcecode/download-executable.yml,sha256=
|
|
49
|
+
guarddog/analyzer/sourcecode/dll-hijacking.yml,sha256=SH1lJ_-EoPfZKrsut9smnEmKPOiXc1c5qzqEBo6ubgQ,3497
|
|
50
|
+
guarddog/analyzer/sourcecode/download-executable.yml,sha256=VuSNkpVh3DxHG7wfep3eAErGsOY9EL_268sNULYbfW4,3361
|
|
51
51
|
guarddog/analyzer/sourcecode/exec-base64.yml,sha256=Wg1jI_ff9I58Xq8gt8wXOQMrwHcPnzkAPyAURxnKHgw,2371
|
|
52
52
|
guarddog/analyzer/sourcecode/exfiltrate-sensitive-data.yml,sha256=hUxQEsJ4qF_25oMF8pdzAFOzq59m6k28WKz280uyaMg,2264
|
|
53
|
-
guarddog/analyzer/sourcecode/npm-dll-hijacking.yml,sha256=
|
|
53
|
+
guarddog/analyzer/sourcecode/npm-dll-hijacking.yml,sha256=1TvI6UtCGCOMy4Ii-kM_oICYbMRGeOYdgXrG7-zmJ_Y,3460
|
|
54
54
|
guarddog/analyzer/sourcecode/npm-exec-base64.yml,sha256=zc5w2FTlHoZ7ot1flzlmYBkQu1I8eG1E63S5Aki7Goc,814
|
|
55
|
-
guarddog/analyzer/sourcecode/npm-exfiltrate-sensitive-data.yml,sha256=
|
|
55
|
+
guarddog/analyzer/sourcecode/npm-exfiltrate-sensitive-data.yml,sha256=UYWXdkAab-dg_6UwVjiauHmy-9nlKiF86qcyxAwUoXg,3488
|
|
56
56
|
guarddog/analyzer/sourcecode/npm-install-script.yml,sha256=6BLe_V0SGEi1C79Y-FEIcMYHl4vLOOz8bLPrCU5jre8,1329
|
|
57
|
-
guarddog/analyzer/sourcecode/npm-obfuscation.yml,sha256=
|
|
57
|
+
guarddog/analyzer/sourcecode/npm-obfuscation.yml,sha256=27lTt_Dy0G_ogD6woktg1t__R77vpOa-_8LJPQ1XU1k,2151
|
|
58
58
|
guarddog/analyzer/sourcecode/npm-serialize-environment.yml,sha256=gFpr58INp44ZwxYZlIHyzpOgbVMDLv1ZRPTGAczX5dw,835
|
|
59
59
|
guarddog/analyzer/sourcecode/npm-silent-process-execution.yml,sha256=qnJHGesNPNpxGa8n2kQMpttLGck-6vZjI_SsweDyk7M,3513
|
|
60
60
|
guarddog/analyzer/sourcecode/npm-steganography.yml,sha256=XH0udcriAQq_6WOHAG4TpIedw8GgKyWx9gsG_Q_Fki8,915
|
|
61
61
|
guarddog/analyzer/sourcecode/obfuscation.yml,sha256=dp0BeCYShcTS8QiijSa9U53r6jkCjrFBW5jjNVoXdUU,1224
|
|
62
|
-
guarddog/analyzer/sourcecode/shady-links.yml,sha256=
|
|
62
|
+
guarddog/analyzer/sourcecode/shady-links.yml,sha256=nbq1WLZGVGpriHcPcpBOo39vfYtFU3fU6w3glG2NeQk,3083
|
|
63
63
|
guarddog/analyzer/sourcecode/silent-process-execution.yml,sha256=b6RjenMv7si7lXGak3uMmD7PMtQRuKPeJFggPW6UDNI,418
|
|
64
64
|
guarddog/analyzer/sourcecode/steganography.yml,sha256=3ceO6SJhu4XpZEjfwelLdOxeZ4Ho1OgUjbcacwtOhR0,606
|
|
65
65
|
guarddog/cli.py,sha256=TJT2yxoUokhoDm7P_FF-x0B9zbtxgDou5BFbu4vSWm4,13168
|
|
66
|
-
guarddog/ecosystems.py,sha256=
|
|
66
|
+
guarddog/ecosystems.py,sha256=1-emct9cGLU3V0drEdNmGFEmxMEmJHEQOuyOiuuoCGA,489
|
|
67
67
|
guarddog/reporters/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
68
68
|
guarddog/reporters/sarif.py,sha256=92HjvASZFyv5otB1qbsUqj6423tNgZbmSQS4qApffAw,5820
|
|
69
|
-
guarddog/scanners/__init__.py,sha256=
|
|
69
|
+
guarddog/scanners/__init__.py,sha256=rWKVvLADz9G0nraNwiJIiSuLFb9p8u_V4qAl7HVt3jw,1762
|
|
70
|
+
guarddog/scanners/github_action_scanner.py,sha256=GxhUSetLvT8YxKUIZue9MWOE_IVugM2MdiluOy4f068,1745
|
|
70
71
|
guarddog/scanners/go_package_scanner.py,sha256=OdCbwtjJow9AxEv34z7WBfgTamqKj5DxJh7dly_1NuY,2926
|
|
71
72
|
guarddog/scanners/go_project_scanner.py,sha256=3D5dYSA7FVqc7IIM7uAHlCJZalshP_WhagWmOcYirog,2123
|
|
72
73
|
guarddog/scanners/npm_package_scanner.py,sha256=qBU0tCbW2pTL3cy5Y4JVAJyAGdvb-HY69qSQmjWbPxU,1968
|
|
@@ -79,10 +80,10 @@ guarddog/utils/archives.py,sha256=jOXAhxZx-mTtpDidGGKxQg052CvaQOAVklvOeUn9HTQ,25
|
|
|
79
80
|
guarddog/utils/config.py,sha256=Msz7altsmNKry0vBPtL2BJ_VdBXsBFZX5ksLvXc2ix4,1403
|
|
80
81
|
guarddog/utils/exceptions.py,sha256=23Kzl3exqYK6X-bcGUeb8wPmSglWNX3GIDPkJ6lQzo4,54
|
|
81
82
|
guarddog/utils/package_info.py,sha256=TFjE1xsGNf60SuHlIeDV2pzMUbogl5TKJdSzswat6jI,953
|
|
82
|
-
guarddog-2.
|
|
83
|
-
guarddog-2.
|
|
84
|
-
guarddog-2.
|
|
85
|
-
guarddog-2.
|
|
86
|
-
guarddog-2.
|
|
87
|
-
guarddog-2.
|
|
88
|
-
guarddog-2.
|
|
83
|
+
guarddog-2.4.0.dist-info/LICENSE,sha256=w1aNZxHyoyOPJ4fSdiyrr06tCJZbTjCsH9K1uqeDVyU,11377
|
|
84
|
+
guarddog-2.4.0.dist-info/LICENSE-3rdparty.csv,sha256=cS61ONZL_xlXaTMvQXyBEi3J3es-40Gg6G-6idoa5Qk,314
|
|
85
|
+
guarddog-2.4.0.dist-info/METADATA,sha256=WsXluo_bRC7j4N5BJMceuhQkvhdURMZMz7T3xY9e8fY,1432
|
|
86
|
+
guarddog-2.4.0.dist-info/NOTICE,sha256=nlyNt2IjG8IBoQkb7n6jszwAvmREpKAx0POzFO1s2JM,140
|
|
87
|
+
guarddog-2.4.0.dist-info/WHEEL,sha256=IYZQI976HJqqOpQU6PHkJ8fb3tMNBFjg-Cn-pwAbaFM,88
|
|
88
|
+
guarddog-2.4.0.dist-info/entry_points.txt,sha256=vX2fvhnNdkbEL4pDzrH2NqjWVxeOaEYi0sJYmNgS2-s,45
|
|
89
|
+
guarddog-2.4.0.dist-info/RECORD,,
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
rules:
|
|
2
|
-
- id: bidirectional-characters
|
|
3
|
-
message: This package contains bidirectional (bidi) characters
|
|
4
|
-
metadata:
|
|
5
|
-
description: Identify when a package contains bidirectional characters, which can be used to display source code differently than its actual execution. See more at https://trojansource.codes/
|
|
6
|
-
patterns:
|
|
7
|
-
- pattern-either:
|
|
8
|
-
# Try treating following text as left-to-right.
|
|
9
|
-
- pattern-regex:
|
|
10
|
-
# Try treating following text as right-to-left.
|
|
11
|
-
- pattern-regex:
|
|
12
|
-
# Force treating following text as left-to-right.
|
|
13
|
-
- pattern-regex:
|
|
14
|
-
# Force treating following text as right-to-left.
|
|
15
|
-
- pattern-regex:
|
|
16
|
-
# Force treating following text as left-to-right without affecting adjacent text.
|
|
17
|
-
- pattern-regex:
|
|
18
|
-
# Force treating following text as right-to-left without affecting adjacent text.
|
|
19
|
-
- pattern-regex:
|
|
20
|
-
# Force treating following text in direction indicated by the next character.
|
|
21
|
-
- pattern-regex:
|
|
22
|
-
# Terminate nearest LRE, RLE, LRO, or RLO.
|
|
23
|
-
- pattern-regex:
|
|
24
|
-
# Terminate nearest LRI or RLI.
|
|
25
|
-
- pattern-regex:
|
|
26
|
-
languages:
|
|
27
|
-
- python
|
|
28
|
-
- javascript
|
|
29
|
-
severity: WARNING
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|