leftblock 0.4.2__tar.gz → 0.4.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {leftblock-0.4.2 → leftblock-0.4.3}/PKG-INFO +4 -4
- {leftblock-0.4.2 → leftblock-0.4.3}/README.md +3 -3
- {leftblock-0.4.2 → leftblock-0.4.3}/leftblock/cli.py +1 -1
- {leftblock-0.4.2 → leftblock-0.4.3}/leftblock/data/gitleaks.toml +6 -0
- {leftblock-0.4.2 → leftblock-0.4.3}/leftblock.egg-info/PKG-INFO +4 -4
- {leftblock-0.4.2 → leftblock-0.4.3}/pyproject.toml +1 -1
- {leftblock-0.4.2 → leftblock-0.4.3}/tests/test_bypasses.py +1 -1
- {leftblock-0.4.2 → leftblock-0.4.3}/tests/test_kanbus_advice.py +1 -1
- {leftblock-0.4.2 → leftblock-0.4.3}/tests/test_recorded_overrides.py +3 -3
- {leftblock-0.4.2 → leftblock-0.4.3}/tests/test_sensitive_rules.py +23 -6
- {leftblock-0.4.2 → leftblock-0.4.3}/LICENSE +0 -0
- {leftblock-0.4.2 → leftblock-0.4.3}/leftblock/__init__.py +0 -0
- {leftblock-0.4.2 → leftblock-0.4.3}/leftblock/allow.py +0 -0
- {leftblock-0.4.2 → leftblock-0.4.3}/leftblock/bypass.py +0 -0
- {leftblock-0.4.2 → leftblock-0.4.3}/leftblock/core.py +0 -0
- {leftblock-0.4.2 → leftblock-0.4.3}/leftblock/hooks.py +0 -0
- {leftblock-0.4.2 → leftblock-0.4.3}/leftblock/merge.py +0 -0
- {leftblock-0.4.2 → leftblock-0.4.3}/leftblock.egg-info/SOURCES.txt +0 -0
- {leftblock-0.4.2 → leftblock-0.4.3}/leftblock.egg-info/dependency_links.txt +0 -0
- {leftblock-0.4.2 → leftblock-0.4.3}/leftblock.egg-info/entry_points.txt +0 -0
- {leftblock-0.4.2 → leftblock-0.4.3}/leftblock.egg-info/requires.txt +0 -0
- {leftblock-0.4.2 → leftblock-0.4.3}/leftblock.egg-info/top_level.txt +0 -0
- {leftblock-0.4.2 → leftblock-0.4.3}/setup.cfg +0 -0
- {leftblock-0.4.2 → leftblock-0.4.3}/tests/test_branding.py +0 -0
- {leftblock-0.4.2 → leftblock-0.4.3}/tests/test_commit_gate.py +0 -0
- {leftblock-0.4.2 → leftblock-0.4.3}/tests/test_default_config.py +0 -0
- {leftblock-0.4.2 → leftblock-0.4.3}/tests/test_false_positives.py +0 -0
- {leftblock-0.4.2 → leftblock-0.4.3}/tests/test_install.py +0 -0
- {leftblock-0.4.2 → leftblock-0.4.3}/tests/test_local_install.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: leftblock
|
|
3
|
-
Version: 0.4.
|
|
3
|
+
Version: 0.4.3
|
|
4
4
|
Summary: LeftBlock: a pluggable inspection gate for Git commits
|
|
5
5
|
License: MIT License
|
|
6
6
|
|
|
@@ -124,7 +124,7 @@ configures the integration; it does not install scanner binaries.
|
|
|
124
124
|
In the intended Python environment:
|
|
125
125
|
|
|
126
126
|
```bash
|
|
127
|
-
python -m pip install leftblock==0.4.
|
|
127
|
+
python -m pip install leftblock==0.4.3
|
|
128
128
|
python -m leftblock.cli --help
|
|
129
129
|
```
|
|
130
130
|
|
|
@@ -397,7 +397,7 @@ PEM private keys, and other standard secret formats.
|
|
|
397
397
|
|
|
398
398
|
| Rule | What it catches |
|
|
399
399
|
|---|---|
|
|
400
|
-
| `leftblock-personal-email` | Personal email addresses (infrastructure identities like `git@github.com`, `@users.noreply.github.com`, no-reply addresses
|
|
400
|
+
| `leftblock-personal-email` | Personal email addresses (infrastructure identities like `git@github.com`, `@users.noreply.github.com`, no-reply addresses, `@example.*` placeholders, `@example.edu` and any address on a `.test`, `.example`, `.invalid` or `.localhost` domain are allowlisted) |
|
|
401
401
|
| `leftblock-home-path-posix` | Home-folder paths `/Users/<name>`, `/home/<name>` |
|
|
402
402
|
| `leftblock-home-path-windows` | `C:\Users\<name>` and `\Users\<name>` |
|
|
403
403
|
| `leftblock-session-uuid` | Potential session UUIDs (not flagged in Kanbus board data; example values and the `.kanbus.yml` `project_id` line are also allowed) |
|
|
@@ -409,7 +409,7 @@ PEM private keys, and other standard secret formats.
|
|
|
409
409
|
| `leftblock-bip39-mnemonic` | BIP-39 seed phrases (12–24 words) in seed/mnemonic/recovery context |
|
|
410
410
|
|
|
411
411
|
A blocked check prints a one-line hint after each rule's findings (once per
|
|
412
|
-
rule): use a role or placeholder
|
|
412
|
+
rule): use a role address or a reserved placeholder for personal emails; a relative path,
|
|
413
413
|
`$HOME` or `~` for home paths; drop or describe session and actor identifiers;
|
|
414
414
|
and for API, private and wallet keys, remove the value **and rotate the key**,
|
|
415
415
|
since it may already be exposed. Findings in Kanbus board data
|
|
@@ -91,7 +91,7 @@ configures the integration; it does not install scanner binaries.
|
|
|
91
91
|
In the intended Python environment:
|
|
92
92
|
|
|
93
93
|
```bash
|
|
94
|
-
python -m pip install leftblock==0.4.
|
|
94
|
+
python -m pip install leftblock==0.4.3
|
|
95
95
|
python -m leftblock.cli --help
|
|
96
96
|
```
|
|
97
97
|
|
|
@@ -364,7 +364,7 @@ PEM private keys, and other standard secret formats.
|
|
|
364
364
|
|
|
365
365
|
| Rule | What it catches |
|
|
366
366
|
|---|---|
|
|
367
|
-
| `leftblock-personal-email` | Personal email addresses (infrastructure identities like `git@github.com`, `@users.noreply.github.com`, no-reply addresses
|
|
367
|
+
| `leftblock-personal-email` | Personal email addresses (infrastructure identities like `git@github.com`, `@users.noreply.github.com`, no-reply addresses, `@example.*` placeholders, `@example.edu` and any address on a `.test`, `.example`, `.invalid` or `.localhost` domain are allowlisted) |
|
|
368
368
|
| `leftblock-home-path-posix` | Home-folder paths `/Users/<name>`, `/home/<name>` |
|
|
369
369
|
| `leftblock-home-path-windows` | `C:\Users\<name>` and `\Users\<name>` |
|
|
370
370
|
| `leftblock-session-uuid` | Potential session UUIDs (not flagged in Kanbus board data; example values and the `.kanbus.yml` `project_id` line are also allowed) |
|
|
@@ -376,7 +376,7 @@ PEM private keys, and other standard secret formats.
|
|
|
376
376
|
| `leftblock-bip39-mnemonic` | BIP-39 seed phrases (12–24 words) in seed/mnemonic/recovery context |
|
|
377
377
|
|
|
378
378
|
A blocked check prints a one-line hint after each rule's findings (once per
|
|
379
|
-
rule): use a role or placeholder
|
|
379
|
+
rule): use a role address or a reserved placeholder for personal emails; a relative path,
|
|
380
380
|
`$HOME` or `~` for home paths; drop or describe session and actor identifiers;
|
|
381
381
|
and for API, private and wallet keys, remove the value **and rotate the key**,
|
|
382
382
|
since it may already be exposed. Findings in Kanbus board data
|
|
@@ -335,7 +335,7 @@ _REMOVE_AND_ROTATE = "Remove it AND rotate the key: it may already be exposed."
|
|
|
335
335
|
_HOME_PATH = "Use a relative path, $HOME or ~ instead."
|
|
336
336
|
_DESCRIBE_ID = "Drop the identifier or describe it instead."
|
|
337
337
|
RULE_HINTS = {
|
|
338
|
-
"leftblock-personal-email": "Use a role or placeholder
|
|
338
|
+
"leftblock-personal-email": "Use a role address or a reserved placeholder (example.com/.org/.net, or any .test, .example or .invalid domain), or describe it instead.",
|
|
339
339
|
"leftblock-home-path-posix": _HOME_PATH,
|
|
340
340
|
"leftblock-home-path-windows": _HOME_PATH,
|
|
341
341
|
"leftblock-session-uuid": _DESCRIBE_ID,
|
|
@@ -67,6 +67,12 @@ regexes = [
|
|
|
67
67
|
'''(^|[^a-zA-Z0-9._%+\-'])no-?reply@[a-zA-Z0-9.\-]+\.[a-zA-Z]{2,}''',
|
|
68
68
|
'''git@github\.com''',
|
|
69
69
|
'''@(example|github)\.(com|org|net|io|ai)''',
|
|
70
|
+
# Domains reserved for documentation and testing: the TLDs .test, .example,
|
|
71
|
+
# .invalid and .localhost (RFC 2606 section 2, RFC 6761 section 6) at any
|
|
72
|
+
# subdomain depth, and example.edu (RFC 2606 section 3). Anchored on the end
|
|
73
|
+
# of the address so look-alikes such as test.com or example.test.co still flag.
|
|
74
|
+
'''@(?:[a-zA-Z0-9\-]+\.)*(?:test|example|invalid|localhost)$''',
|
|
75
|
+
'''@example\.edu$''',
|
|
70
76
|
]
|
|
71
77
|
|
|
72
78
|
[[rules]]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: leftblock
|
|
3
|
-
Version: 0.4.
|
|
3
|
+
Version: 0.4.3
|
|
4
4
|
Summary: LeftBlock: a pluggable inspection gate for Git commits
|
|
5
5
|
License: MIT License
|
|
6
6
|
|
|
@@ -124,7 +124,7 @@ configures the integration; it does not install scanner binaries.
|
|
|
124
124
|
In the intended Python environment:
|
|
125
125
|
|
|
126
126
|
```bash
|
|
127
|
-
python -m pip install leftblock==0.4.
|
|
127
|
+
python -m pip install leftblock==0.4.3
|
|
128
128
|
python -m leftblock.cli --help
|
|
129
129
|
```
|
|
130
130
|
|
|
@@ -397,7 +397,7 @@ PEM private keys, and other standard secret formats.
|
|
|
397
397
|
|
|
398
398
|
| Rule | What it catches |
|
|
399
399
|
|---|---|
|
|
400
|
-
| `leftblock-personal-email` | Personal email addresses (infrastructure identities like `git@github.com`, `@users.noreply.github.com`, no-reply addresses
|
|
400
|
+
| `leftblock-personal-email` | Personal email addresses (infrastructure identities like `git@github.com`, `@users.noreply.github.com`, no-reply addresses, `@example.*` placeholders, `@example.edu` and any address on a `.test`, `.example`, `.invalid` or `.localhost` domain are allowlisted) |
|
|
401
401
|
| `leftblock-home-path-posix` | Home-folder paths `/Users/<name>`, `/home/<name>` |
|
|
402
402
|
| `leftblock-home-path-windows` | `C:\Users\<name>` and `\Users\<name>` |
|
|
403
403
|
| `leftblock-session-uuid` | Potential session UUIDs (not flagged in Kanbus board data; example values and the `.kanbus.yml` `project_id` line are also allowed) |
|
|
@@ -409,7 +409,7 @@ PEM private keys, and other standard secret formats.
|
|
|
409
409
|
| `leftblock-bip39-mnemonic` | BIP-39 seed phrases (12–24 words) in seed/mnemonic/recovery context |
|
|
410
410
|
|
|
411
411
|
A blocked check prints a one-line hint after each rule's findings (once per
|
|
412
|
-
rule): use a role or placeholder
|
|
412
|
+
rule): use a role address or a reserved placeholder for personal emails; a relative path,
|
|
413
413
|
`$HOME` or `~` for home paths; drop or describe session and actor identifiers;
|
|
414
414
|
and for API, private and wallet keys, remove the value **and rotate the key**,
|
|
415
415
|
since it may already be exposed. Findings in Kanbus board data
|
|
@@ -10,7 +10,7 @@ from leftblock import bypass
|
|
|
10
10
|
from test_commit_gate import GITLEAKS, RepositoryFixture
|
|
11
11
|
|
|
12
12
|
MARKER = "gitleaks" + ":allow"
|
|
13
|
-
EMAIL = "info" + "@" + "public-role.
|
|
13
|
+
EMAIL = "info" + "@" + "public-role" + ".co"
|
|
14
14
|
REASON = "Reviewed: documentation example, not a real finding"
|
|
15
15
|
|
|
16
16
|
|
|
@@ -24,7 +24,7 @@ class RuleHintTests(unittest.TestCase):
|
|
|
24
24
|
for rule in ("openai-key", "anthropic-key", "eth-private-key", "wif-key", "bip39-mnemonic"):
|
|
25
25
|
self.assertIn("rotate", cli.RULE_HINTS["leftblock-" + rule])
|
|
26
26
|
self.assertIn("relative path", cli.RULE_HINTS["leftblock-home-path-posix"])
|
|
27
|
-
self.assertIn("
|
|
27
|
+
self.assertIn("reserved placeholder", cli.RULE_HINTS["leftblock-personal-email"])
|
|
28
28
|
|
|
29
29
|
|
|
30
30
|
@unittest.skipUnless(GITLEAKS, "Gitleaks must be installed for actual scanner tests")
|
|
@@ -12,8 +12,8 @@ from test_commit_gate import GITLEAKS, RepositoryFixture
|
|
|
12
12
|
|
|
13
13
|
# Flagged by the shipped personal-email rule; the rule allowlists only
|
|
14
14
|
# example.* and GitHub identities.
|
|
15
|
-
EMAIL = "info" + "@" + "public-role.
|
|
16
|
-
OTHER_EMAIL = "help" + "@" + "public-role.
|
|
15
|
+
EMAIL = "info" + "@" + "public-role" + ".co"
|
|
16
|
+
OTHER_EMAIL = "help" + "@" + "public-role" + ".co"
|
|
17
17
|
PAGE = "page.tsx"
|
|
18
18
|
REASON = "Public role address for the site"
|
|
19
19
|
|
|
@@ -100,7 +100,7 @@ class RecordedOverrideTests(RepositoryFixture):
|
|
|
100
100
|
detail = [l for l in proc.stderr.splitlines() if l.startswith(" ")]
|
|
101
101
|
self.assertEqual(detail, [
|
|
102
102
|
f" {PAGE}:2: leftblock-personal-email [id {ident}] (Personal email address)",
|
|
103
|
-
" Hint: Use a role or placeholder
|
|
103
|
+
" Hint: Use a role address or a reserved placeholder (example.com/.org/.net, or any .test, .example or .invalid domain), or describe it instead.",
|
|
104
104
|
])
|
|
105
105
|
self.assertIn(f"leftblock-personal-email in {PAGE}:2 [id {ident}]", proc.stderr.splitlines()[-1])
|
|
106
106
|
self.assertNotIn(EMAIL, proc.stdout + proc.stderr)
|
|
@@ -109,7 +109,7 @@ class SensitiveFixtureTests(unittest.TestCase):
|
|
|
109
109
|
# Synthetic personal values are assembled at test time so this
|
|
110
110
|
# test source is itself clean under the shipped ruleset.
|
|
111
111
|
user = "jd" + "oe"
|
|
112
|
-
email = "jane." + "doe@" + "example-corp
|
|
112
|
+
email = "jane." + "doe@" + "example-corp" + ".co"
|
|
113
113
|
findings = scan_and_rule_ids({
|
|
114
114
|
"issues/one.json": (
|
|
115
115
|
'{"assignee_email": "%s", "session_id": "%s",'
|
|
@@ -225,14 +225,31 @@ class NegativeTests(unittest.TestCase):
|
|
|
225
225
|
def test_no_reply_addresses_pass_but_lookalikes_still_flag(self):
|
|
226
226
|
at = "@"
|
|
227
227
|
self.assertEqual(scan_and_rule_ids({"CHANGELOG.md": "\n".join([
|
|
228
|
-
"Co-Authored-By: Bot <noreply" + at + "vendor.
|
|
229
|
-
"From: no-reply" + at + "vendor.
|
|
228
|
+
"Co-Authored-By: Bot <noreply" + at + "vendor" + ".co" + ">",
|
|
229
|
+
"From: no-reply" + at + "vendor" + ".co",
|
|
230
230
|
]) + "\n"}), [])
|
|
231
|
-
self.assertEqual(scan_and_rule_ids({"notes.md": "mail jo" + at + "vendor.
|
|
231
|
+
self.assertEqual(scan_and_rule_ids({"notes.md": "mail jo" + at + "vendor" + ".co\n"}),
|
|
232
232
|
["leftblock-personal-email"])
|
|
233
|
-
self.assertEqual(scan_and_rule_ids({"notes.md": "mail notnoreply" + at + "vendor.
|
|
233
|
+
self.assertEqual(scan_and_rule_ids({"notes.md": "mail notnoreply" + at + "vendor" + ".co\n"}),
|
|
234
234
|
["leftblock-personal-email"])
|
|
235
235
|
|
|
236
|
+
def test_reserved_placeholder_domains_pass_but_lookalikes_still_flag(self):
|
|
237
|
+
at = "@"
|
|
238
|
+
passing = [
|
|
239
|
+
"person" + at + "example.invalid",
|
|
240
|
+
"a" + at + "mail.acme.test",
|
|
241
|
+
"b" + at + "deep.sub.host.example",
|
|
242
|
+
"c" + at + "app.localhost",
|
|
243
|
+
"d" + at + "example.edu",
|
|
244
|
+
"e" + at + "x.test",
|
|
245
|
+
]
|
|
246
|
+
self.assertEqual(scan_and_rule_ids({"notes.md": "\n".join("mail " + a for a in passing) + "\n"}), [])
|
|
247
|
+
for domain in ["test" + ".com", "invalid" + ".org", "example.test" + ".co", "mytest" + ".dev",
|
|
248
|
+
"example" + ".edu.co", "notexample" + ".edu"]:
|
|
249
|
+
with self.subTest(domain=domain):
|
|
250
|
+
self.assertEqual(scan_and_rule_ids({"notes.md": "mail jo" + at + domain + "\n"}),
|
|
251
|
+
["leftblock-personal-email"])
|
|
252
|
+
|
|
236
253
|
def test_public_wallet_addresses_and_hashes_not_flagged(self):
|
|
237
254
|
rng = _rng()
|
|
238
255
|
findings = scan_and_rule_ids({
|
|
@@ -466,7 +483,7 @@ class KanbusBoardAllowlistTests(unittest.TestCase):
|
|
|
466
483
|
scan_and_rule_ids({path: content}))
|
|
467
484
|
|
|
468
485
|
def test_personal_email_home_path_and_key_still_flagged_in_board_files(self):
|
|
469
|
-
email = "jane." + "doe@" + "example-corp
|
|
486
|
+
email = "jane." + "doe@" + "example-corp" + ".co"
|
|
470
487
|
user = "jd" + "oe"
|
|
471
488
|
cases = {
|
|
472
489
|
"leftblock-personal-email": json.dumps(
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|