Skip to content

Commit e855b08

Browse files
committed
Apply body key obfuscation to form-style request bodies
Added `id_token` to obfuscate.body_keys default
1 parent 6b7829e commit e855b08

File tree

4 files changed

+53
-4
lines changed

4 files changed

+53
-4
lines changed

CHANGELOG.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
# CHANGELOG
22

3-
## [v1.2.x (Unreleased)](https://github.com/onlime/laravel-http-client-global-logger/compare/v1.2.1...main)
3+
## [v1.2.x (Unreleased)](https://github.com/onlime/laravel-http-client-global-logger/compare/v1.2.2...main)
4+
5+
## [v1.2.2 (2025-06-16)](https://github.com/onlime/laravel-http-client-global-logger/compare/v1.2.1...v1.2.2)
6+
7+
- [Security] Body key obfuscation (`obfuscate.body_keys` config) is now also applied to form-style request bodies, not only JSON bodies. This prevents accidental logging of e.g. OpenID Connect (OAuth 2.0) tokens on `POST /token` endpoint, which may contain the `refresh_token` and `client_secret`.
8+
- [Security] Added `id_token` as additional body key for obfuscation to the `HTTP_CLIENT_GLOBAL_LOGGER_OBFUSCATE_BODY_KEYS` default.
49

510
## [v1.2.1 (2025-02-26)](https://github.com/onlime/laravel-http-client-global-logger/compare/v1.2.0...v1.2.1)
611

config/http-client-global-logger.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@
104104
)),
105105
'body_keys' => explode(',', env(
106106
'HTTP_CLIENT_GLOBAL_LOGGER_OBFUSCATE_BODY_KEYS',
107-
'pass,password,token,apikey,access_token,refresh_token,client_secret'
107+
'pass,password,token,apikey,access_token,refresh_token,id_token,client_secret'
108108
)),
109109
],
110110

src/Listeners/LogRequestSending.php

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,19 @@ public function handleEvent(RequestSending|SendingSaloonRequest $event): void
4646
$message = $formatter->format($psrRequest);
4747

4848
if ($obfuscate) {
49+
$replacement = config('http-client-global-logger.obfuscate.replacement');
4950
foreach (config('http-client-global-logger.obfuscate.body_keys') as $key) {
51+
$quoted = preg_quote($key, '/');
52+
// JSON-style: "key":"value"
5053
$message = preg_replace(
51-
'/(?<="'.$key.'":").*(?=")/mU',
52-
config('http-client-global-logger.obfuscate.replacement'),
54+
'/(?<="'.$quoted.'":")[^"]*(?=")/mU',
55+
$replacement,
56+
$message
57+
);
58+
// form-style: key=value (until & or end)
59+
$message = preg_replace(
60+
'/(?<=\b'. $quoted .'=)[^&]*(?=&|$)/',
61+
$replacement,
5362
$message
5463
);
5564
}

tests/HttpClientLoggerTest.php

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,3 +153,38 @@ function setupLogger(): MockInterface
153153
])->withHeader($withHeader ? 'X-Global-Logger-Trim-Always' : 'X-Dummy', 'true')
154154
->get('https://example.com');
155155
})->with([true, false]);
156+
157+
it('obfuscates header and body keys', function (string $body, string $expected) {
158+
$logger = setupLogger();
159+
160+
$logger->shouldReceive('info')->withArgs(function ($message) use ($expected) {
161+
expect($message)->toContain('REQUEST: GET https://example.com')
162+
->and($message)->toContain('Authorization: **********')
163+
->and($message)->toContain($expected);
164+
return true;
165+
})->once();
166+
167+
$logger->shouldReceive('info')->withArgs(function ($message) {
168+
expect($message)->toContain('RESPONSE: HTTP/1.1 200 OK');
169+
return true;
170+
})->once();
171+
172+
Http::fake([
173+
'*' => Http::response('', 200, [
174+
'Content-Type' => 'application/json',
175+
]),
176+
])->withHeader('Authorization', 'Bearer 123')
177+
->withBody($body)
178+
->get('https://example.com');
179+
})->with([
180+
'json-style' => [
181+
'{"key":"value","apikey":"s3cr3tK3y","token":"s0meT0k3n"}',
182+
'{"key":"value","apikey":"**********","token":"**********"}',
183+
],
184+
// OpenID Connect example for POST /token endpoint
185+
// see https://openid.net/specs/openid-connect-core-1_0.html#RefreshingAccessToken
186+
'openid-connect' => [
187+
'grant_type=refresh_token&refresh_token=r3fr3shT0k3n&client_id=1234&client_secret=53cr3t',
188+
'grant_type=refresh_token&refresh_token=**********&client_id=1234&client_secret=**********',
189+
],
190+
]);

0 commit comments

Comments
 (0)