scrubber_rb 0.1.0 → 0.1.1

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: c2ad9752a533c73935b72e5d66553a24ecc1f7aa3d89d1e4e420e64cd3e7d3be
4
- data.tar.gz: 68e7b9b45c4470c5e182e6c36fb498d7c3aad86c8ca852d3dfe1513bbdbb9a1c
3
+ metadata.gz: 47f69ffa8ebd85bccc6260b500f57b6b73c36b14ec5de68fdf31d8a269e69882
4
+ data.tar.gz: e3061969dfd3168801a5f6750a8074b8dc80caa3e76b0bb394c21bab3e082f25
5
5
  SHA512:
6
- metadata.gz: ca7640c6d91f3787336e5821f2448a995ff23059c73f132811738304e5a77708eaff82c3b5747a24a3453f21238d9cc7c44cb7917db6ed850a723e82cfbf8ca8
7
- data.tar.gz: 818fd4aabd8158ebdf47ced475893c60c8a0f26a4550aeccc996040cec8c531cf47ef8ea409749a38cfb7e7a50d625355043a1d7b89fa02b290d11921834159c
6
+ metadata.gz: a8929d2e00752f2936db1cff0e3b37d1b7b1a7e177c5b7cd1e37b879ad9796c2104a28aa67a93ab8bd46132a39e6b86e5c5caa6d2725781a51024df3fe1b580f
7
+ data.tar.gz: 1b38cb4de61590901ff2efc51164e5c9e746f1da2161340a3da47565943bc5d10a01303b82d2e4d7ed1cea4eff3cc8fafbae5fbaa22a52b2e7560ceed89bec06
data/CHANGELOG.md CHANGED
@@ -7,6 +7,30 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.1.1] - 2026-08-16
11
+
12
+ Documentation only. The native extension is byte-for-byte identical to 0.1.0 —
13
+ if you are already on 0.1.0 there is no functional reason to upgrade.
14
+
15
+ ### Added
16
+
17
+ - A `vs logstop` section in the README with a scope-matched benchmark
18
+ (`rake benchmark:logstop`). `scrubber_rb` is restricted to logstop's exact
19
+ detector set before anything is timed: 153.6 MB/s vs 9.1 MB/s over the 100MB
20
+ corpus, or 112.9 vs 8.7 with `ip` and `mac` enabled on both.
21
+ - A table of where the two disagree about *what* to redact, in both directions.
22
+ logstop's card pattern is sixteen digits with no checksum, so it redacts
23
+ numbers that fail Luhn and misses 15-digit Amex and 19-digit Visa; but it
24
+ matches percent-encoded values inline and this gem does not.
25
+
26
+ ### Documented
27
+
28
+ - **Percent-encoded input is not decoded.** `Scrubber.scrub("e=nik%40example.com")`
29
+ finds no email, because `%40` is not `@`. Decode before scrubbing;
30
+ `Scrubber::Middleware` already does this for query strings. This behaviour has
31
+ not changed — it was simply never written down, and it is the kind of gap that
32
+ should be on the tin rather than discovered in production.
33
+
10
34
  ## [0.1.0] - 2026-08-16
11
35
 
12
36
  First release.
@@ -55,5 +79,6 @@ First release.
55
79
  `aarch64-linux-musl`, `x86_64-darwin`, `arm64-darwin`, plus a best-effort
56
80
  `x64-mingw-ucrt` and the source gem.
57
81
 
58
- [Unreleased]: https://github.com/TheSoloHacker47/scrubber-rb/compare/v0.1.0...HEAD
82
+ [Unreleased]: https://github.com/TheSoloHacker47/scrubber-rb/compare/v0.1.1...HEAD
83
+ [0.1.1]: https://github.com/TheSoloHacker47/scrubber-rb/compare/v0.1.0...v0.1.1
59
84
  [0.1.0]: https://github.com/TheSoloHacker47/scrubber-rb/releases/tag/v0.1.0
data/README.md CHANGED
@@ -246,9 +246,42 @@ live on every byte. The Rust core runs one Aho-Corasick pass over the literal an
246
246
  (`AKIA`, `-----BEGIN`, `ghp_`, `password`) to eliminate roughly two thirds of the rules before
247
247
  any regex runs, then one `RegexSet` pass for the rest.
248
248
 
249
- `logstop` solves a narrower problem (log filtering, pure Ruby, zero native code) and solves it
250
- well. If that's all you need, use it — it has no native extension to build. Run
251
- `rake benchmark:logstop` for a scope-matched comparison.
249
+ ### vs logstop
250
+
251
+ [`logstop`](https://github.com/ankane/logstop) solves a narrower problem — filtering log lines,
252
+ in pure Ruby, with no native extension to build — and has been doing it well since 2019. So the
253
+ comparison below restricts `scrubber_rb` to logstop's exact detector set first; running fourteen
254
+ detectors it never claimed to have and calling the result a win would prove nothing.
255
+
256
+ <!-- generated by `rake benchmark:logstop`; do not edit by hand -->
257
+
258
+ | detector scope | scrubber_rb | logstop | ratio |
259
+ |---|---|---|---|
260
+ | logstop defaults (`url_password`, `email`, `credit_card`, `phone`, `ssn`) | **153.6 MB/s** | 9.1 MB/s | 16.9x |
261
+ | + `ip` and `mac` | **112.9 MB/s** | 8.7 MB/s | 13.0x |
262
+
263
+ 100MB synthetic log corpus, single thread, ruby 3.3.0 on arm64-darwin24, logstop 0.4.1, best of
264
+ 3 passes.
265
+
266
+ The speed is the less interesting half. Where they differ on *what* to redact:
267
+
268
+ | input | scrubber_rb (logstop's scope) | scrubber_rb (all detectors) | logstop |
269
+ |---|---|---|---|
270
+ | Amex, valid Luhn, 15 digits | redacted | redacted | — |
271
+ | Visa, valid Luhn, 16 digits | redacted | redacted | redacted |
272
+ | Visa, valid Luhn, 19 digits | redacted | redacted | — |
273
+ | 16 digits, fails Luhn | — | — | redacted |
274
+ | percent-encoded email | — | — | redacted |
275
+ | JWT, AWS key, GitHub token, `password=`, private key, IBAN, IPv6 | — | redacted | — |
276
+ | Aadhaar, valid Verhoeff | — | redacted | — |
277
+
278
+ Read that in both directions. logstop's card regex is `\b[3456]\d{15}\b` — sixteen digits, no
279
+ checksum — so it redacts numbers that fail Luhn and misses the 15-digit Amex and 19-digit Visa
280
+ lengths entirely. But it also matches percent-encoded values (`%40`, `%2B`, `%3A`) inline, which
281
+ `scrubber_rb` does not; see the limitation below.
282
+
283
+ If log filtering is all you need and you'd rather not build a native extension, logstop is a
284
+ perfectly good answer. Reproduce this table with `rake benchmark:logstop`.
252
285
 
253
286
  ## Security
254
287
 
@@ -269,6 +302,12 @@ To report a vulnerability, see [SECURITY.md](SECURITY.md).
269
302
  Deterministic patterns can't catch free-form PII — **names, home addresses, medical notes**.
270
303
  That's NER-model territory. We'd rather be honest about this than give you false confidence.
271
304
 
305
+ **Percent-encoded values.** `Scrubber.scrub("e=nik%40example.com")` does not see an email —
306
+ detectors run on the literal bytes, and `%40` is not `@`. Decode before scrubbing.
307
+ `Scrubber::Middleware` does exactly that for query strings, which is why it reports
308
+ `env["scrubber.params"]` rather than scrubbing `QUERY_STRING` in place. If you feed raw encoded
309
+ data to `Scrubber.scrub` yourself, `CGI.unescape` it first.
310
+
272
311
  If your threat model includes free-text PII, layer a model-based pass behind this gem's fast
273
312
  structural pass: [`top_secret`](https://github.com/thoughtbot/top_secret) and its
274
313
  [`ruby_llm-top_secret`](https://github.com/thoughtbot/ruby_llm-top_secret) integration cover
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Scrubber
4
- VERSION = "0.1.0"
4
+ VERSION = "0.1.1"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: scrubber_rb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nikhil Nelson