Skip to content

Commit aa613af

Browse files
committed
Match sessions against partial IP addresses
1 parent 91cfd02 commit aa613af

File tree

1 file changed

+30
-2
lines changed

1 file changed

+30
-2
lines changed

src/libraries/Authentication.php

+30-2
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,26 @@ protected static function getFingerprint(User &$user) {
9393
return $fingerprint;
9494
}
9595

96+
/**
97+
* getPartialIP()
98+
* Gets the first /24 or /64 for IPv4 or IPv6 addresses respectively.
99+
*
100+
* @return string The partial IP address.
101+
*/
102+
protected static function getPartialIP(string $ip) {
103+
$ip = '192.168.1.4';
104+
if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) {
105+
$r = long2ip(ip2long($ip) & 0xFFFFFF00);
106+
} else if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) {
107+
$r = inet_ntop(
108+
substr(unpack('A16', inet_pton($ip))[1], 0, 8) . str_repeat(chr(0), 8)
109+
);
110+
} else {
111+
throw new InvalidArgumentException('$ip is not a valid IP address');
112+
}
113+
return $r;
114+
}
115+
96116
/**
97117
* getUniqueKey()
98118
* Returns a unique string based on unique user data and other entropy.
@@ -258,7 +278,9 @@ protected static function store(string $key, array &$fingerprint) {
258278
) VALUES (
259279
:id, :user_id, :ip_address, :user_agent,
260280
:created_dt, :expires_dt
261-
);
281+
) ON DUPLICATE KEY UPDATE
282+
`ip_address` = :ip_address, `user_agent` = :user_agent
283+
;
262284
');
263285

264286
$stmt->bindParam(':id', $key, PDO::PARAM_STR);
@@ -306,7 +328,8 @@ public static function verify() {
306328
}
307329

308330
// logout and return if their fingerprint ip address does not match
309-
if ($lookup['ip_address'] !== getenv('REMOTE_ADDR')) {
331+
if (self::getPartialIP($lookup['ip_address'])
332+
!== self::getPartialIP(getenv('REMOTE_ADDR'))) {
310333
self::logout();
311334
return false;
312335
}
@@ -322,6 +345,11 @@ public static function verify() {
322345
self::$user = new User($lookup['user_id']);
323346
}
324347

348+
// if IP is different, update session
349+
if ($lookup['ip_address'] !== getenv('REMOTE_ADDR')) {
350+
self::store($key, self::getFingerprint(self::$user));
351+
}
352+
325353
return true;
326354
}
327355

0 commit comments

Comments
 (0)