8000 [Uid] make UUIDv6 always return truly random nodes to prevent leaking… · symfony/symfony@77c7a3b · GitHub
[go: up one dir, main page]

Skip to content

Commit 77c7a3b

Browse files
[Uid] make UUIDv6 always return truly random nodes to prevent leaking the MAC of the host
1 parent 6349a1b commit 77c7a3b

File tree

3 files changed

+25
-0
lines changed

3 files changed

+25
-0
lines changed

src/Symfony/Component/Uid/CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
CHANGELOG
22
=========
33

4+
5.2.0
5+
-----
6+
7+
* made UUIDv6 always return truly random node fields to prevent leaking the MAC of the host
8+
49
5.1.0
510
-----
611

src/Symfony/Component/Uid/Tests/UuidTest.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,14 @@ public function testV6()
8989
$this->assertSame('3499710062d0', $uuid->getNode());
9090
}
9191

92+
public function testV6IsRandom()
93+
{
94+
$uuid1 = Uuid::v6();
95+
$uuid2 = Uuid::v6();
96+
97+
$this->assertNotSame(substr($uuid1, 24), substr($uuid2, 24));
98+
}
99+
92100
public function testBinary()
93101
{
94102
$uuid = new UuidV4(self::A_UUID_V4);

src/Symfony/Component/Uid/UuidV6.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
/**
1515
* A v6 UUID is lexicographically sortable and contains a 60-bit timestamp and 62 extra unique bits.
1616
*
17+
* Unlike UUIDv1, this implementation of UUIDv6 doesn't leak the MAC address of the host.
18+
*
1719
* @experimental in 5.1
1820
*
1921
* @author Nicolas Grekas <p@tchwork.com>
@@ -27,6 +29,16 @@ public function __construct(string $uuid = null)
2729
if (null === $uuid) {
2830
$uuid = uuid_create(\UUID_TYPE_TIME);
2931
$this->uid = substr($uuid, 15, 3).substr($uuid, 9, 4).$uuid[0].'-'.substr($uuid, 1, 4).'-6'.substr($uuid, 5, 3).substr($uuid, 18);
32+
33+
// uuid_create() returns a stable "node" that can leak the MAC of the host, but
34+
// UUIDv6 prefers a truly random number here, let's XOR both to preserve the entropy
35+
36+
$rnd = unpack('N2', hex2bin('00'.substr($uuid, 24, 6)).hex2bin('00'.substr($uuid, 30)));
37+
38+
$this->uid = substr_replace($this->uid, sprintf('%06x%06x',
39+
(random_int(0, 0xffffff) ^ $rnd[1]) | 0x010000,
40+
random_int(0, 0xffffff) ^ $rnd[2]
41+
), 24);
3042
} else {
3143
parent::__construct($uuid);
3244
}

0 commit comments

Comments
 (0)
0