auth-sanitizer 0.2.4 → 0.2.5
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
- checksums.yaml.gz.sig +0 -0
- data/CHANGELOG.md +27 -1
- data/README.md +31 -55
- data/lib/auth/sanitizer/core.rb +12 -0
- data/lib/auth/sanitizer/sanitized_logger.rb +2 -65
- data/lib/auth/sanitizer/value_sanitizer.rb +54 -0
- data/lib/auth/sanitizer/version.rb +1 -1
- data/lib/auth/sanitizer.rb +1 -0
- data/lib/auth_sanitizer/loader.rb +1 -0
- data/sig/auth/sanitizer.rbs +3 -0
- data.tar.gz.sig +0 -0
- metadata +7 -6
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: b0218d87fe77fa1705ba06cbd2b4cb5eae0e04b7769312f2d2c8270de81eb741
|
|
4
|
+
data.tar.gz: 005dbc3a409a7d06e18943d0441526a26d29ec325daf1df0745bd3819ec4ab37
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 5b171736f3d3d7d2d3ae43c783c172527b90d19aedf4b7c11685e1617108bdbeb5b2dc443b756334fc17532d8b4152a63e29b889c00c9d9d2e5b32dea881794a
|
|
7
|
+
data.tar.gz: ac8b6d5a01d765678224f729b16fd10104e126049baaee13f5de0dbd32eb027b7e4b3d05cb84f8c32d351654c37ef79fe72ae085481e56d86bf848d2dafb0e56
|
checksums.yaml.gz.sig
CHANGED
|
Binary file
|
data/CHANGELOG.md
CHANGED
|
@@ -30,6 +30,30 @@ Please file a bug if you notice a violation of semantic versioning.
|
|
|
30
30
|
|
|
31
31
|
### Security
|
|
32
32
|
|
|
33
|
+
## [0.2.5] - 2026-10-25
|
|
34
|
+
|
|
35
|
+
- TAG: [v0.2.5][0.2.5t]
|
|
36
|
+
- COVERAGE: 100.00% -- 184/184 lines in 8 files
|
|
37
|
+
- BRANCH COVERAGE: 100.00% -- 40/40 branches in 8 files
|
|
38
|
+
- 98.21% documented
|
|
39
|
+
|
|
40
|
+
### Added
|
|
41
|
+
|
|
42
|
+
- kettle-jem-template-20260720-001 - READMEs can now display configured
|
|
43
|
+
corporate sponsor logos.
|
|
44
|
+
|
|
45
|
+
### Changed
|
|
46
|
+
|
|
47
|
+
- [kc] kettle-jem/prepare: updated 15 project files:
|
|
48
|
+
- dependencies (15)
|
|
49
|
+
|
|
50
|
+
- [kc] kettle-jem/template: updated 7 project files:
|
|
51
|
+
- code and tests (1)
|
|
52
|
+
- dependencies (2)
|
|
53
|
+
- documentation (1)
|
|
54
|
+
- other (2)
|
|
55
|
+
- workflows (1)
|
|
56
|
+
|
|
33
57
|
## [0.2.4] - 2026-10-23
|
|
34
58
|
|
|
35
59
|
- TAG: [v0.2.4][0.2.4t]
|
|
@@ -295,7 +319,9 @@ Please file a bug if you notice a violation of semantic versioning.
|
|
|
295
319
|
|
|
296
320
|
- Initial release
|
|
297
321
|
|
|
298
|
-
[Unreleased]: https://github.com/ruby-oauth/auth-sanitizer/compare/v0.2.
|
|
322
|
+
[Unreleased]: https://github.com/ruby-oauth/auth-sanitizer/compare/v0.2.5...HEAD
|
|
323
|
+
[0.2.5]: https://github.com/ruby-oauth/auth-sanitizer/compare/v0.2.4...v0.2.5
|
|
324
|
+
[0.2.5t]: https://github.com/ruby-oauth/auth-sanitizer/releases/tag/v0.2.5
|
|
299
325
|
[0.2.4]: https://github.com/ruby-oauth/auth-sanitizer/compare/v0.2.3...v0.2.4
|
|
300
326
|
[0.2.4t]: https://github.com/ruby-oauth/auth-sanitizer/releases/tag/v0.2.4
|
|
301
327
|
[0.2.3]: https://github.com/ruby-oauth/auth-sanitizer/compare/v0.2.2...v0.2.3
|
data/README.md
CHANGED
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
`if ci_badges.map(&:color).all? { it == "green"}` 👇️ send money so I can do more of this. FLOSS maintenance is now my full-time job.
|
|
12
12
|
|
|
13
13
|
[![OpenCollective Backers][🖇osc-backers-i]][🖇osc-backers] [![OpenCollective Sponsors][🖇osc-sponsors-i]][🖇osc-sponsors] [![Sponsor Me on Github][🖇sponsor-img]][🖇sponsor] [![Liberapay Goal Progress][⛳liberapay-img]][⛳liberapay] [![Donate on PayPal][🖇paypal-img]][🖇paypal] [![Buy me a coffee][🖇buyme-small-img]][🖇buyme] [![Donate at ko-fi.com][🖇kofi-img]][🖇kofi]
|
|
14
|
+
<p><sub>Corporate sponsors: <a href="https://alpha-omega.dev"><img alt="Alpha-Omega" src="https://alpha-omega.dev/wp-content/uploads/sites/22/2023/05/logo.svg" height="24"/></a> <a href="https://serpapi.com"><img alt="SerpApi" src="https://serpapi.com/assets/media_kit/logo-with-wordmark.svg" height="24"/></a> <a href="#-floss-funding">Become a sponsor</a></sub></p>
|
|
14
15
|
|
|
15
16
|
<details markdown="1">
|
|
16
17
|
<summary>👣 How will this project approach the September 2025 hostile takeover of RubyGems? 🚑️</summary>
|
|
@@ -51,6 +52,15 @@ a provider, or per logger by passing `label:` to `Auth::Sanitizer::SanitizedLogg
|
|
|
51
52
|
The library snapshots filter configuration when a redacting object is initialized. That keeps already-created objects
|
|
52
53
|
and logger wrappers stable even if a host application changes its configuration later.
|
|
53
54
|
|
|
55
|
+
Use `Auth::Sanitizer.sanitize` when a value needs to be redacted before it is returned or included in an exception
|
|
56
|
+
message. It recursively copies hashes and arrays, redacts values under configured keys, and sanitizes strings using the
|
|
57
|
+
same formats as `SanitizedLogger`:
|
|
58
|
+
|
|
59
|
+
```ruby
|
|
60
|
+
Auth::Sanitizer.sanitize(opts)
|
|
61
|
+
Auth::Sanitizer.sanitize(opts, filtered_keys: MyClient.config.filtered_keys, label: MyClient.config.filtered_label)
|
|
62
|
+
```
|
|
63
|
+
|
|
54
64
|
Consumers that need to avoid defining the generic top-level `Auth` namespace can use the isolated loader:
|
|
55
65
|
|
|
56
66
|
```ruby
|
|
@@ -97,6 +107,7 @@ This gem is used by the following libraries to ensure clean output:
|
|
|
97
107
|
|
|
98
108
|
Compatible with MRI Ruby 2.2.0+, JRuby, and TruffleRuby.
|
|
99
109
|
CI workflows and Appraisals are generated for MRI Ruby 2.4+.
|
|
110
|
+
The current MRI CI lane runs on Linux and macOS.
|
|
100
111
|
This test floor is configured by `ruby.test_minimum` in `.kettle-jem.yml` and
|
|
101
112
|
may be higher than the gem's runtime compatibility floor when legacy Rubies are
|
|
102
113
|
not practical for the current toolchain.
|
|
@@ -121,23 +132,6 @@ The _amazing_ test matrix is powered by the kettle-dev stack.
|
|
|
121
132
|
|
|
122
133
|
</details>
|
|
123
134
|
|
|
124
|
-
### Runtime and Platform Support
|
|
125
|
-
|
|
126
|
-
Support tiers describe what this project's CI actually exercises, not what may
|
|
127
|
-
work in an untested environment:
|
|
128
|
-
|
|
129
|
-
- **Parallel support**: CI runs the test suite with multiple workers available.
|
|
130
|
-
- **Unsupported**: the engine/platform combination is not covered by CI and is
|
|
131
|
-
not a project compatibility claim.
|
|
132
|
-
|
|
133
|
-
| Ruby engine/version | Linux | macOS | Windows | Notes |
|
|
134
|
-
|---------------------|-------|-------|---------|-------|
|
|
135
|
-
| MRI 3.1-3.4 | Parallel support | Unsupported | Unsupported | Versioned Ruby workflows run on Linux. |
|
|
136
|
-
| MRI current | Parallel support | Parallel support | Unsupported | Current Ruby workflow covers the declared OS platforms. |
|
|
137
|
-
| MRI head | Parallel support | Unsupported | Unsupported | CI is allowed to fail while Ruby is in development. |
|
|
138
|
-
| JRuby (all CI lanes) | Parallel support | Unsupported | Unsupported | Engine workflows run on Linux; macOS and Windows are not exercised by CI. |
|
|
139
|
-
| TruffleRuby (all CI lanes) | Parallel support | Unsupported | Unsupported | Never shipped a Windows build (zero Windows assets across 66 releases scanned 2026-10-10); setup-ruby hard-fails ([source](https://github.com/ruby/setup-ruby/blob/master/README.md)) |
|
|
140
|
-
|
|
141
135
|
### Federated DVCS
|
|
142
136
|
|
|
143
137
|
<details markdown="1">
|
|
@@ -153,29 +147,12 @@ work in an untested environment:
|
|
|
153
147
|
|
|
154
148
|
### Enterprise Support
|
|
155
149
|
|
|
156
|
-
[
|
|
157
|
-
|
|
158
|
-
Available as part of the Tidelift Subscription.
|
|
159
|
-
|
|
160
|
-
<details markdown="1">
|
|
161
|
-
<summary>Need enterprise-level guarantees?</summary>
|
|
162
|
-
|
|
163
|
-
The maintainers of this and thousands of other packages are working with Tidelift to deliver commercial support and maintenance for the open source packages you use to build your applications. Save time, reduce risk, and improve code health, while paying the maintainers of the exact packages you use.
|
|
150
|
+
For enterprise support from the maintainer, use [Upwork][👨🏼🏫expsup-upwork] or [CodeMentor][👨🏼🏫expsup-codementor].
|
|
164
151
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
- 💡Subscribe for support guarantees covering _all_ your FLOSS dependencies
|
|
168
|
-
- 💡Tidelift is part of [Sonar][🏙️entsup-tidelift-sonar]
|
|
169
|
-
- 💡Tidelift pays maintainers to maintain the software you depend on!<br/>📊`@`Pointy Haired Boss: An [enterprise support][🏙️entsup-tidelift] subscription is "[never gonna let you down][🧮kloc]", and *supports* open source maintainers
|
|
170
|
-
|
|
171
|
-
Alternatively:
|
|
152
|
+
Other support channels:
|
|
172
153
|
|
|
173
154
|
- [![Ruby Users Forum][✉️ruby-forum-img]][✉️ruby-forum]
|
|
174
155
|
- [![Live Chat on Discord][✉️discord-invite-img-ftb]][✉️discord-invite]
|
|
175
|
-
- [![Get help from me on Upwork][👨🏼🏫expsup-upwork-img]][👨🏼🏫expsup-upwork]
|
|
176
|
-
- [![Get help from me on Codementor][👨🏼🏫expsup-codementor-img]][👨🏼🏫expsup-codementor]
|
|
177
|
-
|
|
178
|
-
</details>
|
|
179
156
|
|
|
180
157
|
## ✨ Installation
|
|
181
158
|
|
|
@@ -217,10 +194,10 @@ Libraries and applications that need to avoid the generic top-level `Auth` names
|
|
|
217
194
|
```ruby
|
|
218
195
|
require "auth_sanitizer/loader"
|
|
219
196
|
|
|
220
|
-
|
|
197
|
+
auth_sanitizer = AuthSanitizer::Loader.load_isolated
|
|
221
198
|
|
|
222
|
-
|
|
223
|
-
include
|
|
199
|
+
token_response = Class.new do
|
|
200
|
+
include auth_sanitizer.const_get(:FilteredAttributes)
|
|
224
201
|
end
|
|
225
202
|
```
|
|
226
203
|
|
|
@@ -264,7 +241,7 @@ auth_sanitizer_loader_namespace = AnonymousLoader.load_path(
|
|
|
264
241
|
version_file: "auth/sanitizer/version.rb"
|
|
265
242
|
)
|
|
266
243
|
|
|
267
|
-
|
|
244
|
+
auth_sanitizer = auth_sanitizer_loader_namespace
|
|
268
245
|
.const_get(:AuthSanitizer)
|
|
269
246
|
.const_get(:Loader)
|
|
270
247
|
.load_isolated
|
|
@@ -450,10 +427,10 @@ Or load it without defining top-level `Auth`. This still defines top-level `Auth
|
|
|
450
427
|
```ruby
|
|
451
428
|
require "auth_sanitizer/loader"
|
|
452
429
|
|
|
453
|
-
|
|
430
|
+
auth_sanitizer = AuthSanitizer::Loader.load_isolated
|
|
454
431
|
|
|
455
|
-
|
|
456
|
-
include
|
|
432
|
+
token_response = Class.new do
|
|
433
|
+
include auth_sanitizer.const_get(:FilteredAttributes)
|
|
457
434
|
end
|
|
458
435
|
```
|
|
459
436
|
|
|
@@ -576,19 +553,21 @@ We welcome both individual and corporate sponsors! We also offer a
|
|
|
576
553
|
wide array of funding channels to account for your preferences.
|
|
577
554
|
Currently, [Open Collective][🖇osc] is our preferred funding platform.
|
|
578
555
|
|
|
556
|
+
### Corporate Sponsorship
|
|
557
|
+
|
|
558
|
+
- <a href="https://alpha-omega.dev"><img alt="Alpha-Omega" src="https://alpha-omega.dev/wp-content/uploads/sites/22/2023/05/logo.svg" height="32"/></a> [Alpha-Omega](https://alpha-omega.dev) — backed by [Amazon Web Services](https://aws.amazon.com), [Google](https://www.google.com), [Microsoft](https://www.microsoft.com), [Anthropic](https://www.anthropic.com), [OpenAI](https://openai.com), [Citi](https://www.citigroup.com), [GitHub](https://github.com)
|
|
559
|
+
- <a href="https://serpapi.com"><img alt="SerpApi" src="https://serpapi.com/assets/media_kit/logo-with-wordmark.svg" height="32"/></a> [SerpApi](https://serpapi.com)
|
|
560
|
+
|
|
579
561
|
**If you're working in a company that's making significant use of ruby-oauth tools we'd
|
|
580
562
|
appreciate it if you suggest to your company to become a ruby-oauth sponsor.**
|
|
581
563
|
|
|
564
|
+
### Individual Support
|
|
565
|
+
|
|
582
566
|
You can support the development of ruby-oauth tools via
|
|
583
567
|
[GitHub Sponsors][🖇sponsor],
|
|
584
568
|
[Liberapay][⛳liberapay],
|
|
585
|
-
[
|
|
586
|
-
[
|
|
587
|
-
and [Tidelift][🏙️entsup-tidelift].
|
|
588
|
-
|
|
589
|
-
| 📍 NOTE |
|
|
590
|
-
|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
|
591
|
-
| If doing a sponsorship in the form of donation is problematic for your company <br/> from an accounting standpoint, we'd recommend the use of Tidelift, <br/> where you can get a support-like subscription instead. |
|
|
569
|
+
[Open Collective][🖇osc],
|
|
570
|
+
and [PayPal][🖇paypal].
|
|
592
571
|
|
|
593
572
|
### Open Collective for Individuals
|
|
594
573
|
|
|
@@ -803,9 +782,6 @@ Thanks for RTFM. ☺️
|
|
|
803
782
|
[👨🏼🏫expsup-upwork-img]: https://img.shields.io/badge/UpWork-13544E?style=for-the-badge&logo=Upwork&logoColor=white
|
|
804
783
|
[👨🏼🏫expsup-codementor]: https://www.codementor.io/peterboling?utm_source=github&utm_medium=button&utm_term=peterboling&utm_campaign=github
|
|
805
784
|
[👨🏼🏫expsup-codementor-img]: https://img.shields.io/badge/CodeMentor-Get_Help-1abc9c?style=for-the-badge&logo=CodeMentor&logoColor=white
|
|
806
|
-
[🏙️entsup-tidelift]: https://tidelift.com/subscription/pkg/rubygems-auth-sanitizer?utm_source=rubygems-auth-sanitizer&utm_medium=referral&utm_campaign=readme
|
|
807
|
-
[🏙️entsup-tidelift-img]: https://img.shields.io/badge/Tidelift_and_Sonar-Enterprise_Support-FD3456?style=for-the-badge&logo=sonar&logoColor=white
|
|
808
|
-
[🏙️entsup-tidelift-sonar]: https://blog.tidelift.com/tidelift-joins-sonar
|
|
809
785
|
[💁🏼♂️peterboling]: http://www.peterboling.com
|
|
810
786
|
[🚂railsbling]: http://www.railsbling.com
|
|
811
787
|
[📜src-gl-img]: https://img.shields.io/badge/GitLab-FBA326?style=for-the-badge&logo=Gitlab&logoColor=orange
|
|
@@ -921,7 +897,7 @@ Thanks for RTFM. ☺️
|
|
|
921
897
|
[📌gitmoji]: https://gitmoji.dev
|
|
922
898
|
[📌gitmoji-img]: https://img.shields.io/badge/gitmoji_commits-%20%F0%9F%98%9C%20%F0%9F%98%8D-34495e.svg?style=flat-square
|
|
923
899
|
[🧮kloc]: https://www.youtube.com/watch?v=dQw4w9WgXcQ
|
|
924
|
-
[🧮kloc-img]: https://img.shields.io/badge/KLOC-0.
|
|
900
|
+
[🧮kloc-img]: https://img.shields.io/badge/KLOC-0.184-FFDD67.svg?style=for-the-badge&logo=YouTube&logoColor=blue
|
|
925
901
|
[🔐security]: https://github.com/ruby-oauth/auth-sanitizer/blob/main/SECURITY.md
|
|
926
902
|
[🔐security-img]: https://img.shields.io/badge/security-policy-259D6C.svg?style=flat
|
|
927
903
|
[📄copyright-notice-explainer]: https://opensource.stackexchange.com/questions/5778/why-do-licenses-such-as-the-mit-license-specify-a-single-year
|
|
@@ -951,5 +927,5 @@ Thanks for RTFM. ☺️
|
|
|
951
927
|
| Homepage | https://github.com/ruby-oauth/auth-sanitizer |
|
|
952
928
|
| Source | https://github.com/ruby-oauth/auth-sanitizer |
|
|
953
929
|
| License | `MIT` |
|
|
954
|
-
| Funding | https://github.com/sponsors/pboling, https://ko-fi.com/pboling, https://liberapay.com/pboling/donate, https://opencollective.com/ruby-oauth, https://thanks.dev/u/gh/pboling, https://
|
|
930
|
+
| Funding | https://github.com/sponsors/pboling, https://ko-fi.com/pboling, https://liberapay.com/pboling/donate, https://opencollective.com/ruby-oauth, https://thanks.dev/u/gh/pboling, https://www.buymeacoffee.com/pboling |
|
|
955
931
|
<!-- kettle-jem:metadata:end -->
|
data/lib/auth/sanitizer/core.rb
CHANGED
|
@@ -62,6 +62,18 @@ module Auth
|
|
|
62
62
|
def default_filtered_keys
|
|
63
63
|
DEFAULT_FILTERED_KEYS
|
|
64
64
|
end
|
|
65
|
+
|
|
66
|
+
# Sanitize a value using the configured key names and replacement label.
|
|
67
|
+
# Hashes and arrays are traversed recursively; strings are filtered using
|
|
68
|
+
# the same formats supported by {SanitizedLogger}.
|
|
69
|
+
#
|
|
70
|
+
# @param value [Object] Value to sanitize
|
|
71
|
+
# @param filtered_keys [Array<String>] Key names whose values should be redacted
|
|
72
|
+
# @param label [String] Replacement label for redacted values
|
|
73
|
+
# @return [Object] Sanitized copy of the value
|
|
74
|
+
def sanitize(value, filtered_keys: default_filtered_keys, label: filtered_label, **options)
|
|
75
|
+
ValueSanitizer.new(filtered_keys: filtered_keys, label: label, **options).sanitize(value)
|
|
76
|
+
end
|
|
65
77
|
end
|
|
66
78
|
end
|
|
67
79
|
end
|
|
@@ -24,7 +24,7 @@ module Auth
|
|
|
24
24
|
# Defaults to {Auth::Sanitizer.filtered_label}.
|
|
25
25
|
def initialize(logger, filtered_keys: Auth::Sanitizer.default_filtered_keys, label: Auth::Sanitizer.filtered_label)
|
|
26
26
|
@logger = logger
|
|
27
|
-
@
|
|
27
|
+
@value_sanitizer = ValueSanitizer.new(filtered_keys: filtered_keys, label: label)
|
|
28
28
|
end
|
|
29
29
|
|
|
30
30
|
# Add a log entry after sanitizing any string payloads.
|
|
@@ -200,70 +200,7 @@ module Auth
|
|
|
200
200
|
def sanitize(message)
|
|
201
201
|
return message unless message.is_a?(String)
|
|
202
202
|
|
|
203
|
-
|
|
204
|
-
# raise on an invalid encoding while logging a request.
|
|
205
|
-
sanitized = message.dup.scrub
|
|
206
|
-
sanitized = sanitize_authorization_header(sanitized)
|
|
207
|
-
sanitized = sanitize_json_pairs(sanitized)
|
|
208
|
-
sanitized = sanitize_inspect_pairs(sanitized)
|
|
209
|
-
sanitize_form_and_query_pairs(sanitized)
|
|
210
|
-
end
|
|
211
|
-
|
|
212
|
-
# The initialized thing filter used by this logger.
|
|
213
|
-
#
|
|
214
|
-
# This is a per-logger snapshot created during initialization.
|
|
215
|
-
#
|
|
216
|
-
# @return [ThingFilter]
|
|
217
|
-
attr_reader :thing_filter
|
|
218
|
-
|
|
219
|
-
# Redact Authorization header values.
|
|
220
|
-
#
|
|
221
|
-
# @param message [String] Logger message
|
|
222
|
-
# @return [String] Sanitized logger message
|
|
223
|
-
def sanitize_authorization_header(message)
|
|
224
|
-
message.gsub(/(Authorization:\s*)(?:"[^"]*"|[^\r\n]+)/i, "\\1\"#{thing_filter.label}\"")
|
|
225
|
-
end
|
|
226
|
-
|
|
227
|
-
# Redact JSON-style values for configured sensitive key names.
|
|
228
|
-
#
|
|
229
|
-
# @param message [String] Logger message
|
|
230
|
-
# @return [String] Sanitized logger message
|
|
231
|
-
def sanitize_json_pairs(message)
|
|
232
|
-
message.gsub(/(["'])(#{thing_filter.pattern_source})\1(\s*:\s*)(["'])(.*?)\4/i) do
|
|
233
|
-
%(#{$1}#{$2}#{$1}#{$3}#{$4}#{thing_filter.label}#{$4})
|
|
234
|
-
end
|
|
235
|
-
end
|
|
236
|
-
|
|
237
|
-
# Redact values in Ruby `Hash#inspect` output for configured sensitive key names.
|
|
238
|
-
#
|
|
239
|
-
# Faraday's debug logger renders non-String bodies (such as the params Hash an OAuth client
|
|
240
|
-
# builds for a token request) with `pretty_inspect`, so secrets reach the logger in Ruby
|
|
241
|
-
# inspect syntax rather than JSON or form encoding. Handles both Ruby 3.4+ formats
|
|
242
|
-
# (`{"key" => "value"}`, `{key: "value"}`) and the pre-3.4 formats (`{"key"=>"value"}`,
|
|
243
|
-
# `{:key=>"value"}`), case-insensitively.
|
|
244
|
-
#
|
|
245
|
-
# @param message [String] Logger message
|
|
246
|
-
# @return [String] Sanitized logger message
|
|
247
|
-
def sanitize_inspect_pairs(message)
|
|
248
|
-
key = thing_filter.pattern_source
|
|
249
|
-
label = thing_filter.label
|
|
250
|
-
# Hash-rocket pairs: "key" => "value" / "key"=>"value" / :key=>"value"
|
|
251
|
-
message = message.gsub(/((?:"(?:#{key})"|:#{key})\s*=>\s*")[^"]*(")/i) { "#{$1}#{label}#{$2}" }
|
|
252
|
-
# Symbol shorthand pairs: key: "value" (not preceded by a quote, so
|
|
253
|
-
# already-sanitized JSON pairs are not reprocessed)
|
|
254
|
-
message.gsub(/(?<!["'])((?:\b(?:#{key})):\s*")[^"]*(")/i) { "#{$1}#{label}#{$2}" }
|
|
255
|
-
end
|
|
256
|
-
|
|
257
|
-
# Redact form-encoded and query-string values for configured sensitive key names.
|
|
258
|
-
#
|
|
259
|
-
# The value class excludes `"` and `>` so the pattern neither crosses
|
|
260
|
-
# into quoted strings nor mangles `Hash#inspect` hash-rocket pairs
|
|
261
|
-
# (`:key=>"value"`), which {sanitize_inspect_pairs} handles instead.
|
|
262
|
-
#
|
|
263
|
-
# @param message [String] Logger message
|
|
264
|
-
# @return [String] Sanitized logger message
|
|
265
|
-
def sanitize_form_and_query_pairs(message)
|
|
266
|
-
message.gsub(/(\b(?:#{thing_filter.pattern_source})=)([^&\s">]+)/i, "\\1#{thing_filter.label}")
|
|
203
|
+
@value_sanitizer.sanitize(message)
|
|
267
204
|
end
|
|
268
205
|
end
|
|
269
206
|
end
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Auth
|
|
4
|
+
module Sanitizer
|
|
5
|
+
# Sanitizes arbitrary values using a configured {ThingFilter}.
|
|
6
|
+
class ValueSanitizer
|
|
7
|
+
# @param filtered_keys [Array<String>] Sensitive key names
|
|
8
|
+
# @param label [String] Replacement label
|
|
9
|
+
def initialize(filtered_keys: Auth::Sanitizer.default_filtered_keys, label: Auth::Sanitizer.filtered_label, **options)
|
|
10
|
+
@thing_filter = ThingFilter.new(filtered_keys, label: label)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# Return a sanitized copy. Matching Hash keys are replaced as well as
|
|
14
|
+
# their values, so a secret used as a key cannot leak through inspect.
|
|
15
|
+
#
|
|
16
|
+
# @param value [Object] Value to sanitize
|
|
17
|
+
# @return [Object]
|
|
18
|
+
def sanitize(value)
|
|
19
|
+
case value
|
|
20
|
+
when Hash
|
|
21
|
+
value.each_with_object({}) do |(key, nested), sanitized|
|
|
22
|
+
sanitized_key = sanitize(key)
|
|
23
|
+
sanitized[sanitized_key] = sensitive_key?(key) ? @thing_filter.label : sanitize(nested)
|
|
24
|
+
end
|
|
25
|
+
when Array
|
|
26
|
+
value.map { |nested| sanitize(nested) }
|
|
27
|
+
when String
|
|
28
|
+
sanitize_string(value)
|
|
29
|
+
else
|
|
30
|
+
value
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
private
|
|
35
|
+
|
|
36
|
+
def sensitive_key?(key)
|
|
37
|
+
@thing_filter.filtered?(key)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def sanitize_string(message)
|
|
41
|
+
sanitized = message.dup.scrub
|
|
42
|
+
sanitized = sanitized.gsub(/(Authorization:\s*)(?:"[^"]*"|[^\r\n]+)/i, "\\1\"#{@thing_filter.label}\"")
|
|
43
|
+
sanitized = sanitized.gsub(/(["'])(#{@thing_filter.pattern_source})\1(\s*:\s*)(["'])(.*?)\4/i) do
|
|
44
|
+
%(#{$1}#{$2}#{$1}#{$3}#{$4}#{@thing_filter.label}#{$4})
|
|
45
|
+
end
|
|
46
|
+
key = @thing_filter.pattern_source
|
|
47
|
+
label = @thing_filter.label
|
|
48
|
+
sanitized = sanitized.gsub(/((?:"(?:#{key})"|:#{key})\s*=>\s*")[^"]*(")/i) { "#{$1}#{label}#{$2}" }
|
|
49
|
+
sanitized = sanitized.gsub(/(?<!["'])((?:\b(?:#{key})):\s*")[^"]*(")/i) { "#{$1}#{label}#{$2}" }
|
|
50
|
+
sanitized.gsub(/(\b(?:#{key})=)([^&\s">]+)/i, "\\1#{label}")
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
@@ -5,7 +5,7 @@ module Auth
|
|
|
5
5
|
# Version namespace for this gem.
|
|
6
6
|
module Version
|
|
7
7
|
# Current gem version.
|
|
8
|
-
VERSION = "0.2.
|
|
8
|
+
VERSION = "0.2.5"
|
|
9
9
|
end
|
|
10
10
|
# Current gem version exposed at the traditional constant location.
|
|
11
11
|
VERSION = Version::VERSION # Traditional Constant Location
|
data/lib/auth/sanitizer.rb
CHANGED
|
@@ -4,6 +4,7 @@ require "version_gem"
|
|
|
4
4
|
|
|
5
5
|
require_relative "sanitizer/thing_filter"
|
|
6
6
|
require_relative "sanitizer/core"
|
|
7
|
+
require_relative "sanitizer/value_sanitizer"
|
|
7
8
|
require_relative "sanitizer/filtered_attributes"
|
|
8
9
|
require_relative "sanitizer/sanitized_logger"
|
|
9
10
|
require_relative "sanitizer/version"
|
data/sig/auth/sanitizer.rbs
CHANGED
|
@@ -12,5 +12,8 @@ module Auth
|
|
|
12
12
|
VERSION: String
|
|
13
13
|
end
|
|
14
14
|
VERSION: String
|
|
15
|
+
def self.default_filtered_keys: () -> Array[String]
|
|
16
|
+
def self.filtered_label: () -> String
|
|
17
|
+
def self.sanitize: (untyped value, ?filtered_keys: Array[String], ?label: String, **untyped options) -> untyped
|
|
15
18
|
end
|
|
16
19
|
end
|
data.tar.gz.sig
CHANGED
|
Binary file
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: auth-sanitizer
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.2.
|
|
4
|
+
version: 0.2.5
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Peter H. Boling
|
|
@@ -66,7 +66,7 @@ dependencies:
|
|
|
66
66
|
version: '3.1'
|
|
67
67
|
- - ">="
|
|
68
68
|
- !ruby/object:Gem::Version
|
|
69
|
-
version: 3.1.
|
|
69
|
+
version: 3.1.24
|
|
70
70
|
type: :development
|
|
71
71
|
prerelease: false
|
|
72
72
|
version_requirements: !ruby/object:Gem::Requirement
|
|
@@ -76,7 +76,7 @@ dependencies:
|
|
|
76
76
|
version: '3.1'
|
|
77
77
|
- - ">="
|
|
78
78
|
- !ruby/object:Gem::Version
|
|
79
|
-
version: 3.1.
|
|
79
|
+
version: 3.1.24
|
|
80
80
|
- !ruby/object:Gem::Dependency
|
|
81
81
|
name: bundler-audit
|
|
82
82
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -274,6 +274,7 @@ files:
|
|
|
274
274
|
- lib/auth/sanitizer/filtered_attributes.rb
|
|
275
275
|
- lib/auth/sanitizer/sanitized_logger.rb
|
|
276
276
|
- lib/auth/sanitizer/thing_filter.rb
|
|
277
|
+
- lib/auth/sanitizer/value_sanitizer.rb
|
|
277
278
|
- lib/auth/sanitizer/version.rb
|
|
278
279
|
- lib/auth_sanitizer/loader.rb
|
|
279
280
|
- sig/auth/sanitizer.rbs
|
|
@@ -282,10 +283,10 @@ licenses:
|
|
|
282
283
|
- MIT
|
|
283
284
|
metadata:
|
|
284
285
|
homepage_uri: https://auth-sanitizer.galtzo.com
|
|
285
|
-
source_code_uri: https://github.com/ruby-oauth/auth-sanitizer/tree/v0.2.
|
|
286
|
-
changelog_uri: https://github.com/ruby-oauth/auth-sanitizer/blob/v0.2.
|
|
286
|
+
source_code_uri: https://github.com/ruby-oauth/auth-sanitizer/tree/v0.2.5
|
|
287
|
+
changelog_uri: https://github.com/ruby-oauth/auth-sanitizer/blob/v0.2.5/CHANGELOG.md
|
|
287
288
|
bug_tracker_uri: https://github.com/ruby-oauth/auth-sanitizer/issues
|
|
288
|
-
documentation_uri: https://www.rubydoc.info/gems/auth-sanitizer/0.2.
|
|
289
|
+
documentation_uri: https://www.rubydoc.info/gems/auth-sanitizer/0.2.5
|
|
289
290
|
funding_uri: https://github.com/sponsors/pboling
|
|
290
291
|
wiki_uri: https://github.com/ruby-oauth/auth-sanitizer/wiki
|
|
291
292
|
news_uri: https://www.railsbling.com/tags/auth-sanitizer
|
metadata.gz.sig
CHANGED
|
Binary file
|