verikloak-bff 0.1.0 → 0.1.2
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 +22 -0
- data/README.md +10 -3
- data/lib/verikloak/bff/configuration.rb +4 -3
- data/lib/verikloak/bff/consistency_checks.rb +4 -5
- data/lib/verikloak/bff/constants.rb +9 -0
- data/lib/verikloak/bff/forwarded_token.rb +10 -2
- data/lib/verikloak/bff/header_guard.rb +82 -43
- data/lib/verikloak/bff/proxy_trust.rb +2 -2
- data/lib/verikloak/bff/version.rb +1 -1
- metadata +11 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 6901b11146849ea25306d9f78b3cf7d8903dce4374efcf1322a7aed6a3d52872
|
|
4
|
+
data.tar.gz: 9a9cd3f59250aa57599de7e973009dedff8d075a395632eef1a19a889fb6257c
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: eed7006bf01e9a51b4824d8e4fdd2a759210270fdf5fdb07617a21b5b6e40862232dc162f8bec8e65fdb89cea59443eee7a030c7fdd2e335446c182b2745936a
|
|
7
|
+
data.tar.gz: d89ca6f1f4032198704a0167d1c3cad7b8b2b1adc68948bb06b0abbf45c4f51157e2d00f3906ad070c4c59c56ed7ddb31bd8f8a58cd06884304b890889685b91
|
data/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,28 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
---
|
|
9
9
|
|
|
10
|
+
## [0.1.2] - 2025-09-21
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
- Configuration option `claims_consistency_mode` supporting `:log_only` so deployments can record mismatches without rejecting requests.
|
|
14
|
+
|
|
15
|
+
### Changed
|
|
16
|
+
- Sanitize log payload strings (including JWT tags) before invoking hooks or emitting to loggers to mitigate log forging attempts.
|
|
17
|
+
|
|
18
|
+
### Documentation
|
|
19
|
+
- Document trusted proxy hygiene, sanitized logging hooks, and the new log-only mode in the README and Rails guide.
|
|
20
|
+
|
|
21
|
+
## [0.1.1] - 2025-09-15
|
|
22
|
+
|
|
23
|
+
### Changed
|
|
24
|
+
- Centralize `MAX_TOKEN_BYTES` in `Verikloak::BFF::Constants` and refactor usages in `HeaderGuard` and `ConsistencyChecks` to avoid duplication.
|
|
25
|
+
|
|
26
|
+
### Fixed
|
|
27
|
+
- Preserve full token content when forwarded header includes control characters (e.g., `Bearer tok\r\nmal`) by adjusting Bearer parsing in `ForwardedToken.normalize_forwarded`; combined with existing sanitization, Authorization now normalizes to `Bearer tokmal`.
|
|
28
|
+
|
|
29
|
+
### Tests
|
|
30
|
+
- Add boundary tests for token size limits in `ConsistencyChecks` and `HeaderGuard`.
|
|
31
|
+
|
|
10
32
|
## [0.1.0] - 2025-09-14
|
|
11
33
|
|
|
12
34
|
### Added
|
data/README.md
CHANGED
|
@@ -42,17 +42,18 @@ See `examples/rack.ru` for a tiny Rack app demo.
|
|
|
42
42
|
|
|
43
43
|
| Key | Type | Default | Description |
|
|
44
44
|
|----------------------------- |--------------------------------------|--------------|-------------|
|
|
45
|
-
| `trusted_proxies` | Array[String/Regexp/Proc] |
|
|
45
|
+
| `trusted_proxies` | Array[String/Regexp/Proc] | *(required)* | Allowlist for proxy peers (by IP/CIDR/regex/proc). |
|
|
46
46
|
| `prefer_forwarded` | Boolean | `true` | Prefer `X-Forwarded-Access-Token` over `Authorization`. |
|
|
47
47
|
| `require_forwarded_header` | Boolean | `false` | Reject when no `X-Forwarded-Access-Token` (blocks direct access). |
|
|
48
48
|
| `enforce_header_consistency` | Boolean | `true` | If both headers exist, require identical token values. |
|
|
49
49
|
| `enforce_claims_consistency` | Hash | `{}` | Mapping of header→claim to compare (e.g., `{ email: :email, user: :sub, groups: :realm_roles }`). |
|
|
50
|
+
| `claims_consistency_mode` | Symbol (`:enforce`/`:log_only`) | `:enforce` | When `:log_only`, mismatches are logged but the request continues (still require downstream JWT verification). |
|
|
50
51
|
| `strip_suspicious_headers` | Boolean | `true` | Remove external `X-Auth-Request-*` before passing downstream. |
|
|
51
52
|
| `xff_strategy` | Symbol (`:rightmost`/`:leftmost`) | `:rightmost` | Which peer to pick from `X-Forwarded-For`. |
|
|
52
53
|
| `peer_preference` | Symbol (`:remote_then_xff`/`:xff_only`) | `:remote_then_xff` | Whether to prefer `REMOTE_ADDR` before falling back to XFF. |
|
|
53
54
|
| `clock_skew_leeway` | Integer (seconds) | `30` | Reserved for small exp/nbf skew handled by core verifier. |
|
|
54
55
|
| `logger` | `Logger` or `nil` | `nil` | Logger for audit tags (`rid`, `sub`, `kid`, `iss/aud`). |
|
|
55
|
-
| `token_header_priority` | Array[String] |
|
|
56
|
+
| `token_header_priority` | Array[String] | `['HTTP_X_FORWARDED_ACCESS_TOKEN']` | When Authorization is empty and no token chosen, seed it from these env headers in order. `HTTP_AUTHORIZATION` is ignored as a source; forwarded header is considered only from trusted peers. |
|
|
56
57
|
| `forwarded_header_name` | String | `HTTP_X_FORWARDED_ACCESS_TOKEN` | Env key for forwarded access token. |
|
|
57
58
|
| `auth_request_headers` | Hash | see code | Mapping for `X-Auth-Request-*` env keys: `{ email, user, groups }`. |
|
|
58
59
|
|
|
@@ -69,6 +70,9 @@ For full reverse proxy examples (Nginx auth_request / oauth2-proxy), see [docs/r
|
|
|
69
70
|
- Set `peer_preference: :remote_then_xff` (default) to evaluate trust using the direct peer first, then fall back to the nearest (rightmost) `X-Forwarded-For` value.
|
|
70
71
|
- If you run only behind a single, known proxy chain and want to rely solely on XFF ordering, use `peer_preference: :xff_only` and control position with `xff_strategy`.
|
|
71
72
|
|
|
73
|
+
- Trusted proxy hygiene
|
|
74
|
+
- Keep `trusted_proxies` as specific as possible (individual IPs, tight CIDR ranges, or regexes). Review the list whenever proxy topology changes to avoid unintentionally widening the trust boundary.
|
|
75
|
+
|
|
72
76
|
- Header name customization
|
|
73
77
|
- Forwarded-access-token header can be changed via:
|
|
74
78
|
- `forwarded_header_name: 'HTTP_X_CUSTOM_FORWARD_TOKEN'`
|
|
@@ -81,9 +85,12 @@ For full reverse proxy examples (Nginx auth_request / oauth2-proxy), see [docs/r
|
|
|
81
85
|
|
|
82
86
|
- Observability helpers
|
|
83
87
|
- Downstream can inspect `env['verikloak.bff.token']` (chosen token, unverified) and `env['verikloak.bff.selected_peer']` (peer IP selected for trust decisions).
|
|
84
|
-
- Provide a structured log hook with `log_with: ->(payload) { logger.info(payload.to_json) }` to consume the same fields emitted to `logger`.
|
|
88
|
+
- Provide a structured log hook with `log_with: ->(payload) { logger.info(payload.to_json) }` to consume the same fields emitted to `logger`. Payload strings are sanitized (control characters removed) before hooks and loggers run to mitigate log forging.
|
|
85
89
|
- Caution: avoid logging the entire Rack `env` in application logs. Treat `env['verikloak.bff.token']` as sensitive; never emit raw tokens or PII (e.g., emails) to logs.
|
|
86
90
|
|
|
91
|
+
- Claims consistency modes
|
|
92
|
+
- Default `:enforce` mode rejects requests with mismatches. Switch to `claims_consistency_mode: :log_only` when you only need observability signals; downstream services must continue verifying JWT signatures, issuer, audience, and expirations.
|
|
93
|
+
|
|
87
94
|
## Development (for contributors)
|
|
88
95
|
Clone and install dependencies:
|
|
89
96
|
|
|
@@ -30,7 +30,8 @@ module Verikloak
|
|
|
30
30
|
:enforce_header_consistency, :enforce_claims_consistency,
|
|
31
31
|
:strip_suspicious_headers, :xff_strategy, :clock_skew_leeway,
|
|
32
32
|
:logger, :token_header_priority, :peer_preference,
|
|
33
|
-
:forwarded_header_name, :auth_request_headers, :log_with
|
|
33
|
+
:forwarded_header_name, :auth_request_headers, :log_with,
|
|
34
|
+
:claims_consistency_mode
|
|
34
35
|
|
|
35
36
|
# enforce_claims_consistency example:
|
|
36
37
|
# { email: :email, user: :sub, groups: :realm_roles }
|
|
@@ -40,6 +41,7 @@ module Verikloak
|
|
|
40
41
|
@require_forwarded_header = false
|
|
41
42
|
@enforce_header_consistency = true
|
|
42
43
|
@enforce_claims_consistency = {}
|
|
44
|
+
@claims_consistency_mode = :enforce
|
|
43
45
|
@strip_suspicious_headers = true
|
|
44
46
|
@xff_strategy = :rightmost
|
|
45
47
|
@peer_preference = :remote_then_xff
|
|
@@ -53,10 +55,9 @@ module Verikloak
|
|
|
53
55
|
groups: 'HTTP_X_AUTH_REQUEST_GROUPS'
|
|
54
56
|
}
|
|
55
57
|
# When Authorization is empty and no chosen token exists, try these env headers (in order)
|
|
56
|
-
# to seed Authorization, similar to verikloak-rails behavior. HTTP_AUTHORIZATION is ignored as a source.
|
|
58
|
+
# to seed Authorization, similar to verikloak-rails behavior. HTTP_AUTHORIZATION is always ignored as a source.
|
|
57
59
|
@token_header_priority = %w[
|
|
58
60
|
HTTP_X_FORWARDED_ACCESS_TOKEN
|
|
59
|
-
HTTP_AUTHORIZATION
|
|
60
61
|
]
|
|
61
62
|
end
|
|
62
63
|
end
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
require 'json'
|
|
9
9
|
require 'jwt' # used only to parse segments safely without verify
|
|
10
|
+
require 'verikloak/bff/constants'
|
|
10
11
|
|
|
11
12
|
module Verikloak
|
|
12
13
|
module BFF
|
|
@@ -19,14 +20,12 @@ module Verikloak
|
|
|
19
20
|
#
|
|
20
21
|
# @param token [String, nil]
|
|
21
22
|
# @return [Hash] claims or empty hash on error
|
|
23
|
+
|
|
22
24
|
def decode_claims(token)
|
|
23
25
|
return {} unless token
|
|
26
|
+
return {} if token.bytesize > Constants::MAX_TOKEN_BYTES
|
|
24
27
|
|
|
25
|
-
|
|
26
|
-
return {} unless parts.size >= 2
|
|
27
|
-
|
|
28
|
-
payload = JWT::Base64.url_decode(parts[1])
|
|
29
|
-
JSON.parse(payload)
|
|
28
|
+
JWT.decode(token, nil, false).first
|
|
30
29
|
rescue StandardError
|
|
31
30
|
{}
|
|
32
31
|
end
|
|
@@ -45,7 +45,7 @@ module Verikloak
|
|
|
45
45
|
return nil unless raw
|
|
46
46
|
|
|
47
47
|
token = raw.to_s.strip
|
|
48
|
-
|
|
48
|
+
token = token.sub(/^Bearer\s+/i, '') if token =~ /^Bearer\s+/i
|
|
49
49
|
|
|
50
50
|
token.empty? ? nil : token
|
|
51
51
|
end
|
|
@@ -57,7 +57,7 @@ module Verikloak
|
|
|
57
57
|
# @param token [String]
|
|
58
58
|
# @return [String]
|
|
59
59
|
def ensure_bearer(token)
|
|
60
|
-
s = token
|
|
60
|
+
s = sanitize(token)
|
|
61
61
|
# Case-insensitive 'Bearer' with spaces/tabs after
|
|
62
62
|
if s =~ /\ABearer[ \t]+/i
|
|
63
63
|
rest = s.sub(/\ABearer[ \t]+/i, '')
|
|
@@ -86,6 +86,14 @@ module Verikloak
|
|
|
86
86
|
env[AUTH_HEADER] = ensure_bearer(token)
|
|
87
87
|
end
|
|
88
88
|
|
|
89
|
+
# Remove CRLF and other control characters to prevent header injection.
|
|
90
|
+
#
|
|
91
|
+
# @param token [String]
|
|
92
|
+
# @return [String]
|
|
93
|
+
def sanitize(token)
|
|
94
|
+
token.to_s.gsub(/[[:cntrl:]]/, '').strip
|
|
95
|
+
end
|
|
96
|
+
|
|
89
97
|
# Remove potentially forged X-Auth-Request-* headers before passing
|
|
90
98
|
# downstream when not emitted by a trusted proxy.
|
|
91
99
|
#
|
|
@@ -11,16 +11,74 @@
|
|
|
11
11
|
# headers against JWT claims, and normalizes the request into
|
|
12
12
|
# `HTTP_AUTHORIZATION: Bearer <token>` for the downstream verifier.
|
|
13
13
|
require 'rack'
|
|
14
|
+
require 'rack/utils'
|
|
14
15
|
require 'json'
|
|
15
16
|
require 'jwt'
|
|
17
|
+
require 'digest'
|
|
16
18
|
require 'verikloak/bff/configuration'
|
|
17
19
|
require 'verikloak/bff/errors'
|
|
18
20
|
require 'verikloak/bff/proxy_trust'
|
|
19
21
|
require 'verikloak/bff/forwarded_token'
|
|
20
22
|
require 'verikloak/bff/consistency_checks'
|
|
23
|
+
require 'verikloak/bff/constants'
|
|
21
24
|
|
|
22
25
|
module Verikloak
|
|
23
26
|
module BFF
|
|
27
|
+
# Internal helpers that sanitize tokens and log payloads for HeaderGuard.
|
|
28
|
+
module HeaderGuardSanitizer
|
|
29
|
+
LOG_CONTROL_CHARS = /[[:cntrl:]]/
|
|
30
|
+
|
|
31
|
+
module_function
|
|
32
|
+
|
|
33
|
+
def token_tags(token)
|
|
34
|
+
return {} unless token
|
|
35
|
+
|
|
36
|
+
payload, header = decode_unverified(token)
|
|
37
|
+
aud = payload['aud']
|
|
38
|
+
aud = aud.join(' ') if aud.is_a?(Array)
|
|
39
|
+
{
|
|
40
|
+
sub: sanitize_log_field(payload['sub']&.to_s),
|
|
41
|
+
iss: sanitize_log_field(payload['iss']&.to_s),
|
|
42
|
+
aud: sanitize_log_field(aud&.to_s),
|
|
43
|
+
kid: sanitize_log_field(header['kid']&.to_s)
|
|
44
|
+
}.compact
|
|
45
|
+
rescue StandardError
|
|
46
|
+
{}
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def decode_unverified(token)
|
|
50
|
+
return [{}, {}] if token.nil? || token.bytesize > Constants::MAX_TOKEN_BYTES
|
|
51
|
+
|
|
52
|
+
JWT.decode(token, nil, false)
|
|
53
|
+
rescue StandardError
|
|
54
|
+
[{}, {}]
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def sanitize_payload(payload)
|
|
58
|
+
payload.transform_values { |value| sanitize_log_field(value) }.compact
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def sanitize_log_field(value)
|
|
62
|
+
case value
|
|
63
|
+
when nil
|
|
64
|
+
nil
|
|
65
|
+
when String
|
|
66
|
+
sanitized = sanitize_string(value)
|
|
67
|
+
sanitized.empty? ? nil : sanitized
|
|
68
|
+
when Array
|
|
69
|
+
sanitized = value.map { |item| item.is_a?(String) ? sanitize_string(item) : item }
|
|
70
|
+
sanitized.reject! { |item| item.nil? || (item.is_a?(String) && item.empty?) }
|
|
71
|
+
sanitized.empty? ? nil : sanitized
|
|
72
|
+
else
|
|
73
|
+
value
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def sanitize_string(value)
|
|
78
|
+
value.to_s.encode('UTF-8', invalid: :replace, undef: :replace, replace: '').gsub(LOG_CONTROL_CHARS, '')
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
24
82
|
# Rack middleware that enforces BFF boundary and header/claims consistency.
|
|
25
83
|
class HeaderGuard
|
|
26
84
|
# Accept both Rack 2 and Rack 3 builder call styles:
|
|
@@ -38,6 +96,10 @@ module Verikloak
|
|
|
38
96
|
combined.merge!(opts) if opts.is_a?(Hash)
|
|
39
97
|
combined.merge!(opts_kw) if opts_kw && !opts_kw.empty?
|
|
40
98
|
apply_overrides!(combined)
|
|
99
|
+
|
|
100
|
+
return unless @config.trusted_proxies.nil? || @config.trusted_proxies.empty?
|
|
101
|
+
|
|
102
|
+
raise ArgumentError, 'trusted_proxies must be configured'
|
|
41
103
|
end
|
|
42
104
|
|
|
43
105
|
# Process a Rack request.
|
|
@@ -99,45 +161,6 @@ module Verikloak
|
|
|
99
161
|
end
|
|
100
162
|
end
|
|
101
163
|
|
|
102
|
-
# Extract selected JWT tags for audit logging (best-effort, unverified).
|
|
103
|
-
#
|
|
104
|
-
# @param token [String, nil]
|
|
105
|
-
# @return [Hash] subset of {sub, iss, aud, kid}
|
|
106
|
-
def token_tags(token)
|
|
107
|
-
return {} unless token
|
|
108
|
-
|
|
109
|
-
payload, header = decode_unverified(token)
|
|
110
|
-
{
|
|
111
|
-
sub: payload['sub'],
|
|
112
|
-
iss: payload['iss'],
|
|
113
|
-
aud: (payload['aud'].is_a?(Array) ? payload['aud'].join(' ') : payload['aud']).to_s,
|
|
114
|
-
kid: header['kid']
|
|
115
|
-
}.compact
|
|
116
|
-
rescue StandardError
|
|
117
|
-
{}
|
|
118
|
-
end
|
|
119
|
-
|
|
120
|
-
# Decode JWT header/payload without validation (for logging only).
|
|
121
|
-
#
|
|
122
|
-
# @param token [String]
|
|
123
|
-
# @return [Array(Hash, Hash)] [payload, header]
|
|
124
|
-
def decode_unverified(token)
|
|
125
|
-
parts = token.to_s.split('.')
|
|
126
|
-
return [{}, {}] unless parts.size >= 2
|
|
127
|
-
|
|
128
|
-
payload = begin
|
|
129
|
-
JSON.parse(::JWT::Base64.url_decode(parts[1]))
|
|
130
|
-
rescue StandardError
|
|
131
|
-
{}
|
|
132
|
-
end
|
|
133
|
-
header = begin
|
|
134
|
-
JSON.parse(::JWT::Base64.url_decode(parts[0]))
|
|
135
|
-
rescue StandardError
|
|
136
|
-
{}
|
|
137
|
-
end
|
|
138
|
-
[payload, header]
|
|
139
|
-
end
|
|
140
|
-
|
|
141
164
|
# Extract request id for logging from common headers.
|
|
142
165
|
#
|
|
143
166
|
# @param env [Hash]
|
|
@@ -162,16 +185,17 @@ module Verikloak
|
|
|
162
185
|
def log_event(env, kind, **attrs)
|
|
163
186
|
lg = logger(env)
|
|
164
187
|
payload = { event: 'bff.header_guard', kind: kind, rid: request_id(env) }.merge(attrs).compact
|
|
188
|
+
sanitized = HeaderGuardSanitizer.sanitize_payload(payload)
|
|
165
189
|
if @config.log_with.respond_to?(:call)
|
|
166
190
|
begin
|
|
167
|
-
@config.log_with.call(
|
|
191
|
+
@config.log_with.call(sanitized)
|
|
168
192
|
rescue StandardError
|
|
169
193
|
# ignore log hook failures
|
|
170
194
|
end
|
|
171
195
|
end
|
|
172
196
|
return unless lg
|
|
173
197
|
|
|
174
|
-
msg =
|
|
198
|
+
msg = sanitized.map { |k, v| v.nil? || v.to_s.empty? ? nil : "#{k}=#{v}" }.compact.join(' ')
|
|
175
199
|
level = (kind == :ok ? :info : :warn)
|
|
176
200
|
lg.public_send(level, msg)
|
|
177
201
|
rescue StandardError
|
|
@@ -203,7 +227,10 @@ module Verikloak
|
|
|
203
227
|
def enforce_header_consistency!(env, auth_token, fwd_token)
|
|
204
228
|
return unless @config.enforce_header_consistency
|
|
205
229
|
return unless auth_token && fwd_token
|
|
206
|
-
|
|
230
|
+
|
|
231
|
+
digest_a = ::Digest::SHA256.hexdigest(auth_token)
|
|
232
|
+
digest_b = ::Digest::SHA256.hexdigest(fwd_token)
|
|
233
|
+
return if Rack::Utils.secure_compare(digest_a, digest_b)
|
|
207
234
|
|
|
208
235
|
log_event(env, :mismatch, reason: 'authorization_vs_forwarded')
|
|
209
236
|
raise HeaderMismatchError
|
|
@@ -219,9 +246,21 @@ module Verikloak
|
|
|
219
246
|
|
|
220
247
|
field = res.last
|
|
221
248
|
log_event(env, :claims_mismatch, field: field.to_s)
|
|
249
|
+
return if claims_consistency_log_only?
|
|
250
|
+
|
|
222
251
|
raise ClaimsMismatchError, field
|
|
223
252
|
end
|
|
224
253
|
|
|
254
|
+
# Determine whether claims mismatches should only be logged.
|
|
255
|
+
#
|
|
256
|
+
# @return [Boolean]
|
|
257
|
+
def claims_consistency_log_only?
|
|
258
|
+
mode = @config.claims_consistency_mode || :enforce
|
|
259
|
+
mode = mode.to_sym if mode.is_a?(String)
|
|
260
|
+
mode = :enforce unless %i[enforce log_only].include?(mode)
|
|
261
|
+
mode == :log_only
|
|
262
|
+
end
|
|
263
|
+
|
|
225
264
|
# Set normalized Authorization header and emit success log.
|
|
226
265
|
#
|
|
227
266
|
# @param env [Hash]
|
|
@@ -232,7 +271,7 @@ module Verikloak
|
|
|
232
271
|
return unless chosen
|
|
233
272
|
|
|
234
273
|
ForwardedToken.set_authorization!(env, chosen)
|
|
235
|
-
log_event(env, :ok, source: token_source(auth_token, fwd_token), **token_tags(chosen))
|
|
274
|
+
log_event(env, :ok, source: token_source(auth_token, fwd_token), **HeaderGuardSanitizer.token_tags(chosen))
|
|
236
275
|
end
|
|
237
276
|
|
|
238
277
|
# Build a minimal RFC6750-style error response.
|
|
@@ -23,7 +23,7 @@ module Verikloak
|
|
|
23
23
|
# @example CIDR + Regex allowlist
|
|
24
24
|
# ProxyTrust.trusted?(env, ["10.0.0.0/8", /^192\.168\./], :rightmost)
|
|
25
25
|
def trusted?(env, trusted, strategy = :rightmost)
|
|
26
|
-
return
|
|
26
|
+
return false if trusted.nil? || trusted.empty?
|
|
27
27
|
|
|
28
28
|
# Rails-aligned: prefer REMOTE_ADDR; fallback to nearest XFF entry
|
|
29
29
|
remote = (env['REMOTE_ADDR'] || '').to_s.strip
|
|
@@ -108,7 +108,7 @@ module Verikloak
|
|
|
108
108
|
# @param trusted [Array<String, Regexp, Proc>, nil]
|
|
109
109
|
# @return [Boolean]
|
|
110
110
|
def self.from_trusted_proxy?(env, trusted)
|
|
111
|
-
return
|
|
111
|
+
return false if trusted.nil? || trusted.empty?
|
|
112
112
|
|
|
113
113
|
ip = (env['REMOTE_ADDR'] || '').to_s.strip
|
|
114
114
|
ip = env['HTTP_X_FORWARDED_FOR'].to_s.split(',').last.to_s.strip if ip.empty? && env['HTTP_X_FORWARDED_FOR']
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: verikloak-bff
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- taiyaky
|
|
@@ -13,16 +13,22 @@ dependencies:
|
|
|
13
13
|
name: jwt
|
|
14
14
|
requirement: !ruby/object:Gem::Requirement
|
|
15
15
|
requirements:
|
|
16
|
-
- - "
|
|
16
|
+
- - ">="
|
|
17
17
|
- !ruby/object:Gem::Version
|
|
18
18
|
version: '2.7'
|
|
19
|
+
- - "<"
|
|
20
|
+
- !ruby/object:Gem::Version
|
|
21
|
+
version: '4.0'
|
|
19
22
|
type: :runtime
|
|
20
23
|
prerelease: false
|
|
21
24
|
version_requirements: !ruby/object:Gem::Requirement
|
|
22
25
|
requirements:
|
|
23
|
-
- - "
|
|
26
|
+
- - ">="
|
|
24
27
|
- !ruby/object:Gem::Version
|
|
25
28
|
version: '2.7'
|
|
29
|
+
- - "<"
|
|
30
|
+
- !ruby/object:Gem::Version
|
|
31
|
+
version: '4.0'
|
|
26
32
|
- !ruby/object:Gem::Dependency
|
|
27
33
|
name: rack
|
|
28
34
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -76,6 +82,7 @@ files:
|
|
|
76
82
|
- lib/verikloak/bff.rb
|
|
77
83
|
- lib/verikloak/bff/configuration.rb
|
|
78
84
|
- lib/verikloak/bff/consistency_checks.rb
|
|
85
|
+
- lib/verikloak/bff/constants.rb
|
|
79
86
|
- lib/verikloak/bff/errors.rb
|
|
80
87
|
- lib/verikloak/bff/forwarded_token.rb
|
|
81
88
|
- lib/verikloak/bff/header_guard.rb
|
|
@@ -88,7 +95,7 @@ metadata:
|
|
|
88
95
|
source_code_uri: https://github.com/taiyaky/verikloak-bff
|
|
89
96
|
changelog_uri: https://github.com/taiyaky/verikloak-bff/blob/main/CHANGELOG.md
|
|
90
97
|
bug_tracker_uri: https://github.com/taiyaky/verikloak-bff/issues
|
|
91
|
-
documentation_uri: https://rubydoc.info/gems/verikloak-bff/0.1.
|
|
98
|
+
documentation_uri: https://rubydoc.info/gems/verikloak-bff/0.1.2
|
|
92
99
|
rubygems_mfa_required: 'true'
|
|
93
100
|
rdoc_options: []
|
|
94
101
|
require_paths:
|