Skip to content

Commit c45bb8b

Browse files
lcobucciarokettuOcramius
committed
Ensure key contents is used for all hashing algorithms
On v3.4.0 we introduced the `Lcobucci\JWT\Signer\Key\LocalFileReference`, which was designed to be used with OpenSSL-based algorithms and avoid having to load the file contents into user-land to sign/verify tokens. However, other algorithms don't understand the scheme `file://` and will incorrectly use the file path as the signing key. This modifies and deprecates `LocalFileReference` to avoid that misleading behaviour. Co-authored-by: Anton Smirnov <sandfox@sandfox.me> Co-authored-by: Marco Pivetta <ocramius@gmail.com>
1 parent 511629a commit c45bb8b

File tree

4 files changed

+45
-14
lines changed

4 files changed

+45
-14
lines changed

docs/configuration.md

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,8 @@ Or provide a file path:
4141

4242
```php
4343
use Lcobucci\JWT\Signer\Key\InMemory;
44-
use Lcobucci\JWT\Signer\Key\LocalFileReference;
4544

4645
$key = InMemory::file(__DIR__ . '/path-to-my-key-stored-in-a-file.pem'); // this reads the file and keeps its contents in memory
47-
$key = LocalFileReference::file(__DIR__ . '/path-to-my-key-stored-in-a-file.pem'); // this just keeps a reference to file
4846
```
4947

5048
#### For symmetric algorithms
@@ -78,13 +76,12 @@ This means that it's fine to distribute your **public key**. However, the **priv
7876
```php
7977
use Lcobucci\JWT\Configuration;
8078
use Lcobucci\JWT\Signer;
81-
use Lcobucci\JWT\Signer\Key\LocalFileReference;
8279
use Lcobucci\JWT\Signer\Key\InMemory;
8380

8481
$configuration = Configuration::forAsymmetricSigner(
8582
// You may use RSA or ECDSA and all their variations (256, 384, and 512)
8683
new Signer\RSA\Sha256(),
87-
LocalFileReference::file(__DIR__ . '/my-private-key.pem'),
84+
InMemory::file(__DIR__ . '/my-private-key.pem'),
8885
InMemory::base64Encoded('mBC5v1sOKVvbdEitdSBenu59nfNfhwkedkJVNabosTw=')
8986
// You may also override the JOSE encoder/decoder if needed by providing extra arguments here
9087
);

docs/upgrading.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,9 +96,8 @@ You can find more information on how to use the configuration object, [here](con
9696
### Use new `Key` objects
9797

9898
`Lcobucci\JWT\Signer\Key` has been converted to an interface in `v4.0`.
99-
We provide two new implementations: `Lcobucci\JWT\Signer\Key\InMemory` and `Lcobucci\JWT\Signer\Key\LocalFileReference`.
10099

101-
`Lcobucci\JWT\Signer\Key\InMemory` is a drop-in replacement of the behaviour for `Lcobucci\JWT\Signer\Key` in `v3.x`.
100+
We provide `Lcobucci\JWT\Signer\Key\InMemory`, a drop-in replacement of the behaviour for `Lcobucci\JWT\Signer\Key` in `v3.x`.
102101
You will need to pick the appropriated named constructor to migrate your code:
103102

104103
```diff

src/Signer/Key/LocalFileReference.php

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
use function strpos;
99
use function substr;
1010

11+
/** @deprecated Use \Lcobucci\JWT\Signer\Key\InMemory::file() instead */
1112
final class LocalFileReference extends Key
1213
{
1314
const PATH_PREFIX = 'file://';
@@ -26,13 +27,6 @@ public static function file($path, $passphrase = '')
2627
$path = substr($path, 7);
2728
}
2829

29-
if (! file_exists($path)) {
30-
throw FileCouldNotBeRead::onPath($path);
31-
}
32-
33-
$key = new self('', $passphrase);
34-
$key->content = self::PATH_PREFIX . $path;
35-
36-
return $key;
30+
return new self(self::PATH_PREFIX . $path, $passphrase);
3731
}
3832
}

test/functional/HmacTokenTest.php

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,16 @@
1010
use Lcobucci\JWT\Builder;
1111
use Lcobucci\JWT\CheckForDeprecations;
1212
use Lcobucci\JWT\Parser;
13+
use Lcobucci\JWT\Signer\Key\InMemory;
14+
use Lcobucci\JWT\Signer\Key\LocalFileReference;
1315
use Lcobucci\JWT\Token;
1416
use Lcobucci\JWT\Signature;
1517
use Lcobucci\JWT\Signer\Hmac\Sha256;
1618
use Lcobucci\JWT\Signer\Hmac\Sha512;
19+
use ReflectionProperty;
20+
use function file_put_contents;
21+
use function sys_get_temp_dir;
22+
use function tempnam;
1723

1824
/**
1925
* @author Luís Otávio Cobucci Oblonczyk <lcobucci@gmail.com>
@@ -197,4 +203,39 @@ public function everythingShouldWorkWhenUsingATokenGeneratedByOtherLibs()
197203
$this->assertEquals('world', $token->getClaim('hello'));
198204
$this->assertTrue($token->verify($this->signer, 'testing'));
199205
}
206+
207+
/**
208+
* @test
209+
*
210+
* @coversNothing
211+
*
212+
* @see \Lcobucci\JWT\Signer\Key::setContent()
213+
*/
214+
public function signatureValidationWithLocalFileKeyReferenceWillOperateWithKeyContents()
215+
{
216+
$key = tempnam(sys_get_temp_dir(), 'key');
217+
file_put_contents($key, 'just a dummy key');
218+
219+
$validKey = LocalFileReference::file($key);
220+
$invalidKey = InMemory::plainText($key);
221+
$signer = new Sha256();
222+
223+
// 3.4.x implicitly extracts key contents, when `file://` is detected
224+
$reflectionContents = new ReflectionProperty(InMemory::class, 'content');
225+
$reflectionContents->setAccessible(true);
226+
$reflectionContents->setValue($invalidKey, 'file://' . $key);
227+
228+
$token = (new Builder())
229+
->withClaim('foo', 'bar')
230+
->getToken($signer, $validKey);
231+
232+
self::assertFalse(
233+
$token->verify($signer, $invalidKey),
234+
'Token cannot be validated against the **path** of the key'
235+
);
236+
self::assertTrue(
237+
$token->verify($signer, $validKey),
238+
'Token can be validated against the **contents** of the key'
239+
);
240+
}
200241
}

0 commit comments

Comments
 (0)