Skip to content

Commit 80198b7

Browse files
authored
Merge pull request #5 from KroderDev/codex/sanitize-log-statements-in-gatewayguard
Sanitize JWT key logging in GatewayGuard
2 parents 20a3ed6 + 438710c commit 80198b7

File tree

2 files changed

+80
-4
lines changed

2 files changed

+80
-4
lines changed

src/Auth/GatewayGuard.php

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -84,11 +84,10 @@ protected function retrieveUserData(): ?array
8484
try {
8585
// Attempt to get the JWT public key from cache or load it from file
8686
$publicKey = Cache::remember('jwt_public_key', config('microservice.auth.jwt_cache_ttl', 3600), function () {
87-
Log::info('Attempting to load JWT public key for token validation.');
88-
$publicKey = file_get_contents(config('microservice.auth.jwt_public_key'));
89-
Log::info('JWT public key loaded.', ['publicKey' => substr($publicKey, 0, 30).'...']);
87+
$path = config('microservice.auth.jwt_public_key');
88+
Log::info('Loaded JWT public key for token validation', ['path' => $path]);
9089

91-
return $publicKey;
90+
return file_get_contents($path);
9291
});
9392

9493
// Try to decode the token to check if it's valid

tests/Auth/GatewayGuardTest.php

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@
22

33
namespace Tests\Auth;
44

5+
use Firebase\JWT\JWT;
56
use Illuminate\Support\Facades\Auth;
67
use Illuminate\Support\Facades\Config;
8+
use Illuminate\Support\Facades\Log;
79
use Illuminate\Support\Facades\Session;
810
use Kroderdev\LaravelMicroserviceCore\Auth\ExternalUser;
911
use Kroderdev\LaravelMicroserviceCore\Auth\GatewayGuard;
@@ -41,6 +43,12 @@ public function refresh(string $token): array
4143

4244
class GatewayGuardTest extends TestCase
4345
{
46+
protected string $privateKey;
47+
48+
protected string $publicKey;
49+
50+
protected string $tmpKeyPath;
51+
4452
protected function getPackageProviders($app)
4553
{
4654
return [MicroserviceServiceProvider::class];
@@ -52,6 +60,38 @@ protected function setUp(): void
5260

5361
$this->app->singleton(AuthServiceClient::class, fn () => new FakeAuthServiceClient());
5462

63+
$this->privateKey = <<<'EOD'
64+
-----BEGIN RSA PRIVATE KEY-----
65+
MIICXQIBAAKBgQCLU1enq5mXQfzAEM5KwPtHO2TwYW+I9/Y1Ulm2daUk3mR0Ug++
66+
G1nIGiM2OHMYwWG0O3k6i6dcQ7nZFreq7Dn4TqXbbeU22MTaRZi277RoR/Vv2a5/
67+
cQGoOdKBIgs8N1UQsJw5XVg47iU4glYnzYLIiGvWLB+5uf8kQwMQ2YpXpwIDAQAB
68+
AoGAdLBbxMFzBP0uXAp3TKKuke1L0Aw7JwNOgUA0hR2pL+TXS5kDOFyd6HsDrMDA
69+
nSYx14rMMN2QUTUj7Y8aSxxIO85jzqinuuqdUB5h8bZZHeCDTBox8yUUEEAzPFLh
70+
I5Aksmj/WWOAAZjTxge8GTfL8fhC2XoRwBWs/zOYce1OAhECQQDj8i7Gu2pson8N
71+
iRxnFxEYgsRvJLpJcMkzTnHw8V/U1EDEmVCpOJtIL11Ydd+Vvl5M6iT6G+6wow36
72+
rECXF9FfAkEAnHkGYXaY5eZWS5ax21N3ktc58JSAFMmvnXZslRW1OF9XTwhxfSb5
73+
n1AAcxXtWuedbYFNNuf/90D8QBEgexY2uQJBAIHeqs3pW7I3RsIUe0009DWN05Mr
74+
TsOm8cs8h2hqbVoZ8CjS3QT8zmPrMHjE97UeOCYERTsGjRCwZbeLSmWLWWsCQBmd
75+
FhZOO6kmk2m8OVEV0LUQ1kMzi+PbQAwenpeo/glEUh51214JS0Nw7SHprPj8gSCz
76+
0dfzEkt/L8utAgwkDsECQQCmkR0Ak3KNOmZrkECuRmrQ6yJ0VK/Pxl8R6oz1Wohu
77+
0vZG84wSA1KxbRDEsAt84FlocT3SS74HjBetys0fyOW9
78+
-----END RSA PRIVATE KEY-----
79+
EOD;
80+
81+
$this->publicKey = <<<'EOD'
82+
-----BEGIN PUBLIC KEY-----
83+
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCLU1enq5mXQfzAEM5KwPtHO2Tw
84+
YW+I9/Y1Ulm2daUk3mR0Ug++G1nIGiM2OHMYwWG0O3k6i6dcQ7nZFreq7Dn4TqXb
85+
beU22MTaRZi277RoR/Vv2a5/cQGoOdKBIgs8N1UQsJw5XVg47iU4glYnzYLIiGvW
86+
LB+5uf8kQwMQ2YpXpwIDAQAB
87+
-----END PUBLIC KEY-----
88+
EOD;
89+
90+
$this->tmpKeyPath = sys_get_temp_dir().'/gateway_guard_public.key';
91+
file_put_contents($this->tmpKeyPath, $this->publicKey);
92+
Config::set('microservice.auth.jwt_public_key', $this->tmpKeyPath);
93+
Config::set('microservice.auth.jwt_algorithm', 'RS256');
94+
5595
Auth::extend('gateway', function ($app, $name, array $config) {
5696
$provider = Auth::createUserProvider($config['provider'] ?? null);
5797

@@ -71,6 +111,15 @@ protected function setUp(): void
71111
Config::set('auth.guards.gateway', ['driver' => 'gateway', 'provider' => 'users']);
72112
}
73113

114+
protected function tearDown(): void
115+
{
116+
if (isset($this->tmpKeyPath) && file_exists($this->tmpKeyPath)) {
117+
unlink($this->tmpKeyPath);
118+
}
119+
120+
parent::tearDown();
121+
}
122+
74123
/** @test */
75124
public function attempt_sets_user_and_token()
76125
{
@@ -102,6 +151,34 @@ public function can_disable_access_loading()
102151
$this->assertEmpty($user->getRoleNames());
103152
}
104153

154+
/** @test */
155+
public function validates_token_without_logging_key_contents()
156+
{
157+
$guard = Auth::guard('gateway');
158+
159+
$payload = [
160+
'sub' => 'user-123',
161+
'iss' => 'auth-service',
162+
'exp' => time() + 60,
163+
];
164+
165+
$jwt = JWT::encode($payload, $this->privateKey, 'RS256');
166+
Session::put($guard->getName(), $jwt);
167+
168+
Log::spy();
169+
170+
$user = $guard->user();
171+
172+
$this->assertInstanceOf(ExternalUser::class, $user);
173+
$this->assertSame($jwt, Session::get($guard->getName()));
174+
175+
Log::shouldHaveReceived('info')
176+
->with('Loaded JWT public key for token validation', \Mockery::on(function ($context) {
177+
return array_key_exists('path', $context) && ! array_key_exists('publicKey', $context);
178+
}))
179+
->once();
180+
}
181+
105182
/** @test */
106183
public function token_method_returns_current_token()
107184
{

0 commit comments

Comments
 (0)