guarddog 2.3.0__py3-none-any.whl → 2.5.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.
@@ -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
- code_snippet = result["extra"]["lines"]
337
- line = result["start"]["line"]
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(line)
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 = {"exe": b"\x4D\x5A", "elf": b"\x7F\x45\x4C\x46"}
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
@@ -39,7 +39,7 @@ class PypiTyposquatDetector(TyposquatDetector):
39
39
  }
40
40
  """
41
41
 
42
- popular_packages_url = "https://hugovk.github.io/top-pypi-packages/top-pypi-packages-30-days.min.json"
42
+ popular_packages_url = "https://hugovk.github.io/top-pypi-packages/top-pypi-packages.min.json"
43
43
 
44
44
  top_packages_filename = "top_pypi_packages.json"
45
45
  resources_dir = TOP_PACKAGES_CACHE_LOCATION
@@ -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
- ecosystem = None
74
+ ecosystems = set()
75
75
  match lang:
76
76
  case "python":
77
- ecosystem = ECOSYSTEM.PYPI
77
+ ecosystems.add(ECOSYSTEM.PYPI)
78
78
  case "javascript" | "typescript" | "json":
79
- ecosystem = ECOSYSTEM.NPM
79
+ ecosystems.add(ECOSYSTEM.NPM)
80
+ ecosystems.add(ECOSYSTEM.GITHUB_ACTION)
80
81
  case "go":
81
- ecosystem = ECOSYSTEM.GO
82
+ ecosystems.add(ECOSYSTEM.GO)
82
83
  case _:
83
84
  continue
84
85
 
85
- # avoids duplicates when multiple languages are supported by a rule
86
- if not next(
87
- filter(
88
- lambda r: r.id == rule["id"],
89
- get_sourcecode_rules(ecosystem, SempgrepRule),
90
- ),
91
- None,
92
- ):
93
- SOURCECODE_RULES.append(
94
- SempgrepRule(
95
- id=rule["id"],
96
- ecosystem=ecosystem,
97
- description=rule.get("metadata", {}).get("description", ""),
98
- file=file_name,
99
- rule_content=rule,
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
- open($DLL,'wb')
68
- ...
69
- $FN(...,$EXE,...)
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
@@ -86,5 +86,3 @@ rules:
86
86
  - focus-metavariable: $DLL
87
87
 
88
88
  severity: WARNING
89
- options:
90
- 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: $HTTP. ... .push(...)
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
- options:
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,15 +33,15 @@ 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
- - 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)\/)
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|zip)\/)
45
45
  # IPv4
46
46
  - pattern-regex: (https?:\/\/[^\n\[\/\?#"']*?(?:\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}))
47
47
  # IPv6
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
@@ -1,11 +1,13 @@
1
1
  from typing import Optional
2
2
 
3
+ from .github_action_project_scanner import GitHubActionDependencyScanner
3
4
  from .npm_package_scanner import NPMPackageScanner
4
5
  from .npm_project_scanner import NPMRequirementsScanner
5
6
  from .pypi_package_scanner import PypiPackageScanner
6
7
  from .pypi_project_scanner import PypiRequirementsScanner
7
8
  from .go_package_scanner import GoModuleScanner
8
9
  from .go_project_scanner import GoDependenciesScanner
10
+ from .github_action_scanner import GithubActionScanner
9
11
  from .scanner import PackageScanner, ProjectScanner
10
12
  from ..ecosystems import ECOSYSTEM
11
13
 
@@ -29,6 +31,8 @@ def get_package_scanner(ecosystem: ECOSYSTEM) -> Optional[PackageScanner]:
29
31
  return NPMPackageScanner()
30
32
  case ECOSYSTEM.GO:
31
33
  return GoModuleScanner()
34
+ case ECOSYSTEM.GITHUB_ACTION:
35
+ return GithubActionScanner()
32
36
  return None
33
37
 
34
38
 
@@ -51,4 +55,6 @@ def get_project_scanner(ecosystem: ECOSYSTEM) -> Optional[ProjectScanner]:
51
55
  return NPMRequirementsScanner()
52
56
  case ECOSYSTEM.GO:
53
57
  return GoDependenciesScanner()
58
+ case ECOSYSTEM.GITHUB_ACTION:
59
+ return GitHubActionDependencyScanner()
54
60
  return None
@@ -0,0 +1,101 @@
1
+ import logging
2
+ from typing import List, Dict, TypedDict
3
+ from typing_extensions import NotRequired
4
+
5
+ import yaml
6
+ import re
7
+
8
+ from guarddog.scanners.github_action_scanner import GithubActionScanner
9
+ from guarddog.scanners.scanner import ProjectScanner
10
+
11
+ log = logging.getLogger("guarddog")
12
+
13
+
14
+ class GitHubWorkflowStep(TypedDict):
15
+ name: NotRequired[str]
16
+ uses: NotRequired[str]
17
+
18
+
19
+ class GitHubWorkflowJob(TypedDict):
20
+ name: str
21
+ uses: str
22
+ runs_on: str
23
+ steps: List[GitHubWorkflowStep]
24
+
25
+
26
+ class GitHubWorkflowFile(TypedDict):
27
+ name: str
28
+ jobs: Dict[str, GitHubWorkflowJob]
29
+
30
+
31
+ class GitHubAction(TypedDict):
32
+ name: str
33
+ ref: str
34
+
35
+
36
+ def parse_action_from_step(step: GitHubWorkflowStep) -> GitHubAction | None:
37
+ """
38
+ Parses a step in a GitHub workflow file and returns a GitHub action reference if it exists.
39
+
40
+ Args:
41
+ step (GitHubWorkflowStep): Step in a GitHub workflow file
42
+
43
+ Returns:
44
+ GitHubAction | None: GitHub action reference if it exists, None otherwise
45
+ """
46
+ if "uses" not in step:
47
+ return None
48
+
49
+ if step["uses"].startswith("/") or step["uses"].startswith("./"):
50
+ return None
51
+ parts = step["uses"].split("@", 1)
52
+ if len(parts) != 2:
53
+ log.debug(f"Invalid action reference: {step['uses']}")
54
+ return None
55
+
56
+ if re.search(r"^([\w-])+/([\w./-])+$", parts[0]):
57
+ return GitHubAction(name=parts[0], ref=parts[1])
58
+ return None
59
+
60
+
61
+ class GitHubActionDependencyScanner(ProjectScanner):
62
+ """
63
+ Scans all 3rd party actions in a GitHub workflow file.
64
+ """
65
+
66
+ def __init__(self) -> None:
67
+ super().__init__(GithubActionScanner())
68
+
69
+ def parse_requirements(self, raw_requirements: str) -> dict[str, set[str]]:
70
+ actions = self.parse_workflow_3rd_party_actions(raw_requirements)
71
+
72
+ requirements: dict[str, set[str]] = {}
73
+ for action in actions:
74
+ repo, version = action["name"], action["ref"]
75
+ if repo in requirements:
76
+ requirements[repo].add(version)
77
+ else:
78
+ requirements[repo] = {version}
79
+ return requirements
80
+
81
+ def parse_workflow_3rd_party_actions(
82
+ self, workflow_file: str
83
+ ) -> List[GitHubAction]:
84
+ """
85
+ Parses a GitHub workflow file and returns a list of 3rd party actions
86
+ used in the workflow.
87
+
88
+ Args:
89
+ workflow_file (str): Contents of the GitHub workflow file
90
+
91
+ Returns:
92
+ List[GitHubAction]: List of 3rd party actions used in the workflow
93
+ """
94
+ f: GitHubWorkflowFile = yaml.safe_load(workflow_file)
95
+ actions = []
96
+ for job in f.get("jobs", {}).values():
97
+ for step in job.get("steps", []):
98
+ action = parse_action_from_step(step)
99
+ if action:
100
+ actions.append(action)
101
+ return actions
@@ -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,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: guarddog
3
- Version: 2.3.0
3
+ Version: 2.5.0
4
4
  Summary: GuardDog is a CLI tool to Identify malicious PyPI packages
5
5
  License: Apache-2.0
6
6
  Author: Ellen Wang
@@ -15,15 +15,15 @@ Requires-Dist: click (>=8.1.3,<9.0.0)
15
15
  Requires-Dist: click-option-group (>=0.5.5,<0.6.0)
16
16
  Requires-Dist: colorama (>=0.4.6,<0.5.0)
17
17
  Requires-Dist: configparser (>=5.3,<8.0)
18
- Requires-Dist: disposable-email-domains (>=0.0.103,<0.0.115)
18
+ Requires-Dist: disposable-email-domains (>=0.0.103,<0.0.119)
19
19
  Requires-Dist: prettytable (>=3.6.0,<4.0.0)
20
- Requires-Dist: pygit2 (>=1.11,<1.17)
20
+ Requires-Dist: pygit2 (>=1.11,<1.18)
21
21
  Requires-Dist: python-dateutil (>=2.8.2,<3.0.0)
22
22
  Requires-Dist: python-whois (>=0.8,<0.10)
23
23
  Requires-Dist: pyyaml (>=6.0,<7.0)
24
24
  Requires-Dist: requests (>=2.29.0,<3.0.0)
25
25
  Requires-Dist: semantic-version (>=2.10.0,<3.0.0)
26
- Requires-Dist: semgrep (==1.97.0)
26
+ Requires-Dist: semgrep (>=1.102.0,<2.0.0)
27
27
  Requires-Dist: setuptools (>=70.3,<76.0)
28
28
  Requires-Dist: tarsafe (>=0.0.5,<0.0.6)
29
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=pwzXHgPbpYpfeM-nkzMXl_l0y_3iCaDf2UrD6AvtcOM,13477
5
- guarddog/analyzer/metadata/__init__.py,sha256=LH4oLBr2vtkGdUXkb8C6JgN35h4NmpswxE7wOOmOdrQ,581
6
- guarddog/analyzer/metadata/bundled_binary.py,sha256=6YvVcV8MqkTpM4z-kma7wmnMEeXh1nsAnnSJ0Xf0B-Q,2493
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
@@ -29,7 +30,7 @@ guarddog/analyzer/metadata/pypi/potentially_compromised_email_domain.py,sha256=3
29
30
  guarddog/analyzer/metadata/pypi/release_zero.py,sha256=GSHap4VSVF9_s3gD95kUD_5eZDHxrqQQoV5aFTgzrCw,716
30
31
  guarddog/analyzer/metadata/pypi/repository_integrity_mismatch.py,sha256=HNVEOj3cz43qHD47Chul05vpX_9uhfaPgjo6Q-fuCfA,11635
31
32
  guarddog/analyzer/metadata/pypi/single_python_file.py,sha256=CLAWaOJ_JNofGmtuCOT-37saryHeZzZAjfJQp31H6jU,1369
32
- guarddog/analyzer/metadata/pypi/typosquatting.py,sha256=Cn3r_2apz2rP2UGMggYNmtQlrDCq3ZDS_ix5TVj9FIk,4726
33
+ guarddog/analyzer/metadata/pypi/typosquatting.py,sha256=Lk0MoIfsMw557PrpUxLAynqNhWSjZDSVI7GJPdyvoG8,4718
33
34
  guarddog/analyzer/metadata/pypi/unclaimed_maintainer_email_domain.py,sha256=4u3s4Jq51arMznv-_0NwZst40x7jGtLJQIEd3Pp2U30,406
34
35
  guarddog/analyzer/metadata/pypi/utils.py,sha256=7ipsnFN1KHcFwU9u1GK8wqINKDCXJ1vQEpTwwZfJFp4,199
35
36
  guarddog/analyzer/metadata/release_zero.py,sha256=7cIdReF3TU3XJq6ALemK81tqaG3Cz1HNwwtH65Y9uPU,438
@@ -41,31 +42,33 @@ 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=A2mbib72TDZkMIWb94Yq9lf_3xU5WOY_Gva0wHGqObE,3769
45
+ guarddog/analyzer/sourcecode/__init__.py,sha256=6TsFMVYmL3nuAJjBplbAInQp7coldAxz1qdrZvZGcBc,3960
45
46
  guarddog/analyzer/sourcecode/clipboard-access.yml,sha256=B36E7xKtAVgwZ29UWtvZa1AJcyfrhvehbLo6tlJqffk,524
46
47
  guarddog/analyzer/sourcecode/cmd-overwrite.yml,sha256=l-tE3_G-LqCuCZnHab6v0PpCdMpoHPutBYcijeMZEA0,682
47
48
  guarddog/analyzer/sourcecode/code-execution.yml,sha256=gbnbvpnmSCY3Q5BANziWCRA-JXIH2LQ8-5ZaFralqbM,5002
48
- guarddog/analyzer/sourcecode/dll-hijacking.yml,sha256=GwsOIN8lgmKhMk9IibDm1lHE6roPNYVnTx62Cd470qc,3337
49
- guarddog/analyzer/sourcecode/download-executable.yml,sha256=8Q1Swughd3xuYA_yYfrWJItJOaZet2-xO8pc5WMCjk8,3055
49
+ guarddog/analyzer/sourcecode/dll-hijacking.yml,sha256=SH1lJ_-EoPfZKrsut9smnEmKPOiXc1c5qzqEBo6ubgQ,3497
50
+ guarddog/analyzer/sourcecode/download-executable.yml,sha256=VuSNkpVh3DxHG7wfep3eAErGsOY9EL_268sNULYbfW4,3361
50
51
  guarddog/analyzer/sourcecode/exec-base64.yml,sha256=Wg1jI_ff9I58Xq8gt8wXOQMrwHcPnzkAPyAURxnKHgw,2371
51
52
  guarddog/analyzer/sourcecode/exfiltrate-sensitive-data.yml,sha256=hUxQEsJ4qF_25oMF8pdzAFOzq59m6k28WKz280uyaMg,2264
52
- guarddog/analyzer/sourcecode/npm-dll-hijacking.yml,sha256=TPIXvWm8Ot9RVtDXWFmoNZw9-3PH7NuXK6x1fQCiRt4,3506
53
+ guarddog/analyzer/sourcecode/npm-dll-hijacking.yml,sha256=1TvI6UtCGCOMy4Ii-kM_oICYbMRGeOYdgXrG7-zmJ_Y,3460
53
54
  guarddog/analyzer/sourcecode/npm-exec-base64.yml,sha256=zc5w2FTlHoZ7ot1flzlmYBkQu1I8eG1E63S5Aki7Goc,814
54
- guarddog/analyzer/sourcecode/npm-exfiltrate-sensitive-data.yml,sha256=saKpH8qhxS-icKSEgseLhInRbwGo94Zcq4w9hlSBNz0,3462
55
+ guarddog/analyzer/sourcecode/npm-exfiltrate-sensitive-data.yml,sha256=UYWXdkAab-dg_6UwVjiauHmy-9nlKiF86qcyxAwUoXg,3488
55
56
  guarddog/analyzer/sourcecode/npm-install-script.yml,sha256=6BLe_V0SGEi1C79Y-FEIcMYHl4vLOOz8bLPrCU5jre8,1329
56
- guarddog/analyzer/sourcecode/npm-obfuscation.yml,sha256=FAW9toHYU8adzKv5E68M29OQ4sLO89GwORsXpSr2-50,2026
57
+ guarddog/analyzer/sourcecode/npm-obfuscation.yml,sha256=27lTt_Dy0G_ogD6woktg1t__R77vpOa-_8LJPQ1XU1k,2151
57
58
  guarddog/analyzer/sourcecode/npm-serialize-environment.yml,sha256=gFpr58INp44ZwxYZlIHyzpOgbVMDLv1ZRPTGAczX5dw,835
58
59
  guarddog/analyzer/sourcecode/npm-silent-process-execution.yml,sha256=qnJHGesNPNpxGa8n2kQMpttLGck-6vZjI_SsweDyk7M,3513
59
60
  guarddog/analyzer/sourcecode/npm-steganography.yml,sha256=XH0udcriAQq_6WOHAG4TpIedw8GgKyWx9gsG_Q_Fki8,915
60
61
  guarddog/analyzer/sourcecode/obfuscation.yml,sha256=dp0BeCYShcTS8QiijSa9U53r6jkCjrFBW5jjNVoXdUU,1224
61
- guarddog/analyzer/sourcecode/shady-links.yml,sha256=RuPLPxQh6T0mbkb1QVFvUv9AeENoaxR151qsQ2EaM34,2929
62
+ guarddog/analyzer/sourcecode/shady-links.yml,sha256=Jl2XO6O9vwyhfaj7K3u7-OtB4oQxKcdyb6-_qCrBdUo,3087
62
63
  guarddog/analyzer/sourcecode/silent-process-execution.yml,sha256=b6RjenMv7si7lXGak3uMmD7PMtQRuKPeJFggPW6UDNI,418
63
64
  guarddog/analyzer/sourcecode/steganography.yml,sha256=3ceO6SJhu4XpZEjfwelLdOxeZ4Ho1OgUjbcacwtOhR0,606
64
65
  guarddog/cli.py,sha256=TJT2yxoUokhoDm7P_FF-x0B9zbtxgDou5BFbu4vSWm4,13168
65
- guarddog/ecosystems.py,sha256=kgM4v5E8PZBQksWgzuWwODS5R7P16klDi1SGWKLy1e0,380
66
+ guarddog/ecosystems.py,sha256=1-emct9cGLU3V0drEdNmGFEmxMEmJHEQOuyOiuuoCGA,489
66
67
  guarddog/reporters/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
67
68
  guarddog/reporters/sarif.py,sha256=92HjvASZFyv5otB1qbsUqj6423tNgZbmSQS4qApffAw,5820
68
- guarddog/scanners/__init__.py,sha256=yEsDvThkIAhFkP59gSCFxYe5HTLmoSzfjAkDrtFT1LY,1628
69
+ guarddog/scanners/__init__.py,sha256=KNZcGjKNPOs60qpOE8Hr_HsiaRIpJLNzA8qbyvebRIk,1924
70
+ guarddog/scanners/github_action_project_scanner.py,sha256=FY5UEIGeQlmyyjh2Z1LDXsHnzfs2gCQ-wIurpbPvXN4,2847
71
+ guarddog/scanners/github_action_scanner.py,sha256=GxhUSetLvT8YxKUIZue9MWOE_IVugM2MdiluOy4f068,1745
69
72
  guarddog/scanners/go_package_scanner.py,sha256=OdCbwtjJow9AxEv34z7WBfgTamqKj5DxJh7dly_1NuY,2926
70
73
  guarddog/scanners/go_project_scanner.py,sha256=3D5dYSA7FVqc7IIM7uAHlCJZalshP_WhagWmOcYirog,2123
71
74
  guarddog/scanners/npm_package_scanner.py,sha256=qBU0tCbW2pTL3cy5Y4JVAJyAGdvb-HY69qSQmjWbPxU,1968
@@ -78,10 +81,10 @@ guarddog/utils/archives.py,sha256=jOXAhxZx-mTtpDidGGKxQg052CvaQOAVklvOeUn9HTQ,25
78
81
  guarddog/utils/config.py,sha256=Msz7altsmNKry0vBPtL2BJ_VdBXsBFZX5ksLvXc2ix4,1403
79
82
  guarddog/utils/exceptions.py,sha256=23Kzl3exqYK6X-bcGUeb8wPmSglWNX3GIDPkJ6lQzo4,54
80
83
  guarddog/utils/package_info.py,sha256=TFjE1xsGNf60SuHlIeDV2pzMUbogl5TKJdSzswat6jI,953
81
- guarddog-2.3.0.dist-info/LICENSE,sha256=w1aNZxHyoyOPJ4fSdiyrr06tCJZbTjCsH9K1uqeDVyU,11377
82
- guarddog-2.3.0.dist-info/LICENSE-3rdparty.csv,sha256=cS61ONZL_xlXaTMvQXyBEi3J3es-40Gg6G-6idoa5Qk,314
83
- guarddog-2.3.0.dist-info/METADATA,sha256=2uRo486G0w2WROtGFETEOfkVS1XEunCgxhPbQyPb8Po,1424
84
- guarddog-2.3.0.dist-info/NOTICE,sha256=nlyNt2IjG8IBoQkb7n6jszwAvmREpKAx0POzFO1s2JM,140
85
- guarddog-2.3.0.dist-info/WHEEL,sha256=IYZQI976HJqqOpQU6PHkJ8fb3tMNBFjg-Cn-pwAbaFM,88
86
- guarddog-2.3.0.dist-info/entry_points.txt,sha256=vX2fvhnNdkbEL4pDzrH2NqjWVxeOaEYi0sJYmNgS2-s,45
87
- guarddog-2.3.0.dist-info/RECORD,,
84
+ guarddog-2.5.0.dist-info/LICENSE,sha256=w1aNZxHyoyOPJ4fSdiyrr06tCJZbTjCsH9K1uqeDVyU,11377
85
+ guarddog-2.5.0.dist-info/LICENSE-3rdparty.csv,sha256=cS61ONZL_xlXaTMvQXyBEi3J3es-40Gg6G-6idoa5Qk,314
86
+ guarddog-2.5.0.dist-info/METADATA,sha256=ZqDqDVCnZh05Dgy9jpJ4SKqEX9ltSWJR15Qd5ATC9QI,1432
87
+ guarddog-2.5.0.dist-info/NOTICE,sha256=nlyNt2IjG8IBoQkb7n6jszwAvmREpKAx0POzFO1s2JM,140
88
+ guarddog-2.5.0.dist-info/WHEEL,sha256=XbeZDeTWKc1w7CSIyre5aMDU_-PohRwTQceYnisIYYY,88
89
+ guarddog-2.5.0.dist-info/entry_points.txt,sha256=vX2fvhnNdkbEL4pDzrH2NqjWVxeOaEYi0sJYmNgS2-s,45
90
+ guarddog-2.5.0.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: poetry-core 2.0.1
2
+ Generator: poetry-core 2.1.1
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any