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 +4 -4
- data/CHANGELOG.md +26 -1
- data/README.md +42 -3
- data/lib/scrubber/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 47f69ffa8ebd85bccc6260b500f57b6b73c36b14ec5de68fdf31d8a269e69882
|
|
4
|
+
data.tar.gz: e3061969dfd3168801a5f6750a8074b8dc80caa3e76b0bb394c21bab3e082f25
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
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.
|
|
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
|
-
|
|
250
|
-
|
|
251
|
-
`
|
|
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
|
data/lib/scrubber/version.rb
CHANGED