Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit f4c9254

Browse files
committed
feature #32194 [HttpFoundation] Add a way to anonymize IPs (Seldaek)
This PR was merged into the 4.4 branch. Discussion ---------- [HttpFoundation] Add a way to anonymize IPs | Q | A | ------------- | --- | Branch? | 4.4 | Bug fix? | no | New feature? | yes | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | | License | MIT | Doc PR | symfony/symfony-docs#... <!-- required for new features --> TODO This is helpful for GDPR compliance reasons, and it isn't much code saved but it's also good if you don't have to think about how to do it. Commits ------- 9e62330 [HttpFoundation] Add a way to anonymize IPs
2 parents 9e554ce + 9e62330 commit f4c9254

File tree

3 files changed

+60
-1
lines changed

3 files changed

+60
-1
lines changed

src/Symfony/Component/HttpFoundation/CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ CHANGELOG
1111
make sure to run `CREATE INDEX EXPIRY ON sessions (sess_lifetime)` to update your database
1212
to speed up garbage collection of expired sessions.
1313
* added `SessionHandlerFactory` to create session handlers with a DSN
14-
14+
* added `IpUtils::anonymize()` to help with GDPR compliance.
15+
1516
4.3.0
1617
-----
1718

src/Symfony/Component/HttpFoundation/IpUtils.php

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,4 +153,36 @@ public static function checkIp6($requestIp, $ip)
153153

154154
return self::$checkedIps[$cacheKey] = true;
155155
}
156+
157+
/**
158+
* Anonymizes an IP/IPv6.
159+
*
160+
* Removes the last byte for v4 and the last 8 bytes for v6 IPs
161+
*/
162+
public static function anonymize(string $ip): string
163+
{
164+
$wrappedIPv6 = false;
165+
if ('[' === substr($ip, 0, 1) && ']' === substr($ip, -1, 1)) {
166+
$wrappedIPv6 = true;
167+
$ip = substr($ip, 1, -1);
168+
}
169+
170+
$packedAddress = inet_pton($ip);
171+
if (4 === \strlen($packedAddress)) {
172+
$mask = '255.255.255.0';
173+
} elseif ($ip === inet_ntop($packedAddress & inet_pton('::ffff:ffff:ffff'))) {
174+
$mask = '::ffff:ffff:ff00';
175+
} elseif ($ip === inet_ntop($packedAddress & inet_pton('::ffff:ffff'))) {
176+
$mask = '::ffff:ff00';
177+
} else {
178+
$mask = 'ffff:ffff:ffff:ffff:0000:0000:0000:0000';
179+
}
180+
$ip = inet_ntop($packedAddress & inet_pton($mask));
181+
182+
if ($wrappedIPv6) {
183+
$ip = '['.$ip.']';
184+
}
185+
186+
return $ip;
187+
}
156188
}

src/Symfony/Component/HttpFoundation/Tests/IpUtilsTest.php

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,4 +101,30 @@ public function invalidIpAddressData()
101101
'invalid request IP with invalid proxy wildcard' => ['0.0.0.0', '*'],
102102
];
103103
}
104+
105+
/**
106+
* @dataProvider anonymizedIpData
107+
*/
108+
public function testAnonymize($ip, $expected)
109+
{
110+
$this->assertSame($expected, IpUtils::anonymize($ip));
111+
}
112+
113+
public function anonymizedIpData()
114+
{
115+
return [
116+
['192.168.1.1', '192.168.1.0'],
117+
['1.2.3.4', '1.2.3.0'],
118+
['2a01:198:603:0:396e:4789:8e99:890f', '2a01:198:603::'],
119+
['2a01:198:603:10:396e:4789:8e99:890f', '2a01:198:603:10::'],
120+
['::1', '::'],
121+
['0:0:0:0:0:0:0:1', '::'],
122+
['1:0:0:0:0:0:0:1', '1::'],
123+
['0:0:603:50:396e:4789:8e99:0001', '0:0:603:50::'],
124+
['[0:0:603:50:396e:4789:8e99:0001]', '[0:0:603:50::]'],
125+
['[2a01:198::3]', '[2a01:198::]'],
126+
['::ffff:123.234.235.236', '::ffff:123.234.235.0'], // IPv4-mapped IPv6 addresses
127+
['::123.234.235.236', '::123.234.235.0'], // deprecated IPv4-compatible IPv6 address
128+
];
129+
}
104130
}

0 commit comments

Comments
 (0)