leakferret 0.1.4 → 0.1.6

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 201cda08594a8bc6101f6b37f456693eaebd794b7fe6df3b6f2b2bc7cafc2834
4
- data.tar.gz: 5487023f2a3d58a2e663a045feb2b1b6dcedfb35217b499c69ac7dcda869ed27
3
+ metadata.gz: 9be1f2733f2b3a412f0c2511948949d402256ad0ecb3dc2f064d986c4cfb9ba0
4
+ data.tar.gz: aafb9746aef318b1134bafa91f070560e03a3fe742e7a6f6a0dfa4a6ebe6f3f8
5
5
  SHA512:
6
- metadata.gz: 7b4a92c0e4b2a7ee135fb3dc03e846e6ce60fb9cc5211227188b7745af012c18b56062fbe26e288380529cd71eaa26c1aa6e8af5a398ff4cb8b041c9c5293563
7
- data.tar.gz: 9478d9afba4e65e4fa0c9c15c943685f78eee187a073681662fbd408e4f23cedaced29fb979bef722349d06f080dd39bb11ce0808438f83cdedf39f64f3fd06b
6
+ metadata.gz: 3ef7e9118364341afce01bd53bc7f3063edffc4a9a5fba0538612f99221567239bf7493b23fb44d8b0f683899af058b3c6f7ab6025fbeb26f06ed0f059b25fd2
7
+ data.tar.gz: b889e172c85d72cc5a077e89b522f359ad8bb1bc801f4a2ddb2850885942055e32667eec7923c45802486bc6540e54e6b94ee604756e6eae7a5ef60fbc3d9822
data/README.md CHANGED
@@ -6,6 +6,10 @@
6
6
 
7
7
  > MCP-native secret scanner — verified findings, agent-applied rewrites.
8
8
 
9
+ <p align="center">
10
+ <img src="https://raw.githubusercontent.com/leakferrethq/leakferret/master/brand/demo.gif" alt="leakferret finds, verifies, and rewrites a leaked secret" width="760">
11
+ </p>
12
+
9
13
  Ruby gem wrapper around the native [`leakferret`](https://github.com/leakferrethq/leakferret)
10
14
  binary. This gem ships no scanning logic of its own: it installs a tiny Ruby
11
15
  shim plus a small executable, and downloads the prebuilt, statically-linked
@@ -18,6 +18,20 @@ module Leakferret
18
18
  # A binary vendored inside the gem, if one was shipped (normally empty).
19
19
  BUNDLED_DIR = Pathname.new(__dir__).join('bin').freeze
20
20
 
21
+ # SHA256 of each release tarball, pinned to BINARY_VERSION. The download is
22
+ # verified against these before the archive is ever unpacked, so a tampered
23
+ # or corrupted release asset is rejected instead of being executed. Because
24
+ # the digests live in the gem source, auditing the published gem tells you
25
+ # exactly which binary bytes it will run. Regenerate on every binary bump
26
+ # from the release's `*.tar.gz.sha256` files.
27
+ CHECKSUMS = {
28
+ 'aarch64-apple-darwin' => '62d7152954e3e2e50d8423c8a1e792ba1783123b8a9d8c5fbc2a71013e890992',
29
+ 'aarch64-pc-windows-msvc' => '6ad3eb20a661579c11857259159f8fb55b26f72608c75ecc206fff5f9da9c800',
30
+ 'x86_64-apple-darwin' => 'd8b28edf427b975412458007069a848e16cea45825e43dff3652bdcd3fd3f1d3',
31
+ 'x86_64-pc-windows-msvc' => 'f447424f148a6874dc2ead208eb460a9f6b20d6ddbce6f74ca9b2d47655e1b2b',
32
+ 'x86_64-unknown-linux-gnu' => 'bf24746f1188d14b2b420e760ebd374a4f88a68ea1b718e7977d8c7309a9f1da'
33
+ }.freeze
34
+
21
35
  module_function
22
36
 
23
37
  # Absolute path to the native binary, downloading it on first use if
@@ -77,23 +91,44 @@ module Leakferret
77
91
  require 'fileutils'
78
92
  require 'open-uri'
79
93
  require 'zlib'
94
+ require 'digest'
95
+ require 'stringio'
80
96
  require 'rubygems/package'
81
97
 
98
+ expected = CHECKSUMS[Platform.triple]
99
+ if expected.nil?
100
+ raise BinaryNotFoundError,
101
+ "no pinned checksum for platform #{Platform.triple}; refusing to run an " \
102
+ 'unverified binary. Build from source and set LEAKFERRET_BIN instead.'
103
+ end
104
+
82
105
  FileUtils.mkdir_p(dest.dirname)
83
- # Stream download -> gunzip -> untar in pure Ruby (no external `tar`,
84
- # which on Windows mis-reads `C:\` as a remote host). The archive nests
85
- # everything under leakferret-<version>-<triple>/, so match by basename.
106
+
107
+ # Download the whole tarball, verify its SHA256 against the pinned value,
108
+ # and only then unpack. Nothing is written to the cache (let alone marked
109
+ # executable) until the bytes match, so a tampered or truncated release
110
+ # asset is rejected rather than run.
111
+ tarball = URI.open(download_url, &:read) # rubocop:disable Security/Open
112
+ actual = Digest::SHA256.hexdigest(tarball)
113
+ unless actual.casecmp?(expected)
114
+ raise BinaryNotFoundError,
115
+ "checksum mismatch for #{download_url}\n" \
116
+ " expected #{expected}\n got #{actual}\n" \
117
+ 'Refusing to install a binary that does not match the pinned hash.'
118
+ end
119
+
120
+ # Unpack in pure Ruby (no external `tar`, which on Windows mis-reads `C:\`
121
+ # as a remote host). The archive nests everything under
122
+ # leakferret-<version>-<triple>/, so match by basename.
86
123
  found = false
87
- URI.open(download_url) do |io| # rubocop:disable Security/Open
88
- Zlib::GzipReader.wrap(io) do |gz|
89
- Gem::Package::TarReader.new(gz) do |tar|
90
- tar.each do |entry|
91
- next unless entry.file?
92
- next unless File.basename(entry.full_name) == Platform.binary_name
93
-
94
- File.binwrite(dest, entry.read)
95
- found = true
96
- end
124
+ Zlib::GzipReader.wrap(StringIO.new(tarball)) do |gz|
125
+ Gem::Package::TarReader.new(gz) do |tar|
126
+ tar.each do |entry|
127
+ next unless entry.file?
128
+ next unless File.basename(entry.full_name) == Platform.binary_name
129
+
130
+ File.binwrite(dest, entry.read)
131
+ found = true
97
132
  end
98
133
  end
99
134
  end
@@ -2,10 +2,10 @@
2
2
 
3
3
  module Leakferret
4
4
  # The gem's own version.
5
- VERSION = '0.1.4'
5
+ VERSION = '0.1.6'
6
6
 
7
7
  # The native binary release this gem downloads. Tracks the leakferret
8
8
  # core release, which may move independently of the gem's own version
9
9
  # (e.g. a gem-only bugfix).
10
- BINARY_VERSION = '0.1.2'
10
+ BINARY_VERSION = '0.1.3'
11
11
  end
metadata CHANGED
@@ -1,13 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: leakferret
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.4
4
+ version: 0.1.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Maria Khan
8
+ autorequire:
8
9
  bindir: exe
9
10
  cert_chain: []
10
- date: 1980-01-02 00:00:00.000000000 Z
11
+ date: 2026-06-01 00:00:00.000000000 Z
11
12
  dependencies: []
12
13
  description: |
13
14
  Context-aware secret scanning for Ruby projects. A thin wrapper around the
@@ -44,6 +45,7 @@ metadata:
44
45
  source_code_uri: https://github.com/leakferrethq/leakferret-ruby
45
46
  changelog_uri: https://github.com/leakferrethq/leakferret-ruby/blob/main/CHANGELOG.md
46
47
  rubygems_mfa_required: 'true'
48
+ post_install_message:
47
49
  rdoc_options: []
48
50
  require_paths:
49
51
  - lib
@@ -58,7 +60,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
58
60
  - !ruby/object:Gem::Version
59
61
  version: '0'
60
62
  requirements: []
61
- rubygems_version: 3.6.9
63
+ rubygems_version: 3.5.22
64
+ signing_key:
62
65
  specification_version: 4
63
66
  summary: Context-aware secret detection (Ruby wrapper for the leakferret binary).
64
67
  test_files: []