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.
@@ -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
@@ -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,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
@@ -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.2.0
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.115)
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.17)
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.97.0,<2.0.0)
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=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
@@ -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=A2mbib72TDZkMIWb94Yq9lf_3xU5WOY_Gva0wHGqObE,3769
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=GwsOIN8lgmKhMk9IibDm1lHE6roPNYVnTx62Cd470qc,3337
50
- 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
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=TPIXvWm8Ot9RVtDXWFmoNZw9-3PH7NuXK6x1fQCiRt4,3506
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=saKpH8qhxS-icKSEgseLhInRbwGo94Zcq4w9hlSBNz0,3462
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=FAW9toHYU8adzKv5E68M29OQ4sLO89GwORsXpSr2-50,2026
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=RuPLPxQh6T0mbkb1QVFvUv9AeENoaxR151qsQ2EaM34,2929
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=kgM4v5E8PZBQksWgzuWwODS5R7P16klDi1SGWKLy1e0,380
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=yEsDvThkIAhFkP59gSCFxYe5HTLmoSzfjAkDrtFT1LY,1628
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.2.0.dist-info/LICENSE,sha256=w1aNZxHyoyOPJ4fSdiyrr06tCJZbTjCsH9K1uqeDVyU,11377
83
- guarddog-2.2.0.dist-info/LICENSE-3rdparty.csv,sha256=cS61ONZL_xlXaTMvQXyBEi3J3es-40Gg6G-6idoa5Qk,314
84
- guarddog-2.2.0.dist-info/METADATA,sha256=KZqSAiszhaBSmSa-L7wuf8lF7XlGVbcyiPXKaZdmBOA,1478
85
- guarddog-2.2.0.dist-info/NOTICE,sha256=nlyNt2IjG8IBoQkb7n6jszwAvmREpKAx0POzFO1s2JM,140
86
- guarddog-2.2.0.dist-info/WHEEL,sha256=RaoafKOydTQ7I_I3JTrPCg6kUmTgtm4BornzOqyEfJ8,88
87
- guarddog-2.2.0.dist-info/entry_points.txt,sha256=vX2fvhnNdkbEL4pDzrH2NqjWVxeOaEYi0sJYmNgS2-s,45
88
- guarddog-2.2.0.dist-info/RECORD,,
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,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: poetry-core 2.0.0
2
+ Generator: poetry-core 2.0.1
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
@@ -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