The portal derives the device MAC instead of trusting the caller
This commit is contained in:
@@ -133,30 +133,24 @@ class PortalController extends Controller
|
||||
return redirect()->route('login');
|
||||
}
|
||||
|
||||
$clientMac = strtolower($request->input('mac', $request->input('id', '')));
|
||||
$ssid = $request->input('ssid', '');
|
||||
$apMac = $request->input('ap', '');
|
||||
$apMac = (string) $request->input('ap', '');
|
||||
$ssid = (string) $request->input('ssid', '');
|
||||
|
||||
if (! $clientMac) {
|
||||
return response('Missing MAC address', 400);
|
||||
$device = app(\Dashboard\Unifi\Services\DeviceResolver::class)->resolve($request, $apMac);
|
||||
|
||||
if (! $device->ok) {
|
||||
return Inertia::render('Unifi/PortalDenied', [
|
||||
'reason' => match ($device->reason) {
|
||||
'ap_mismatch' => 'That device is not connected to this access point. Reconnect and try again.',
|
||||
'proxy_untrusted' => 'Wi-Fi sign-in is misconfigured and cannot identify your device. Please tell IT.',
|
||||
default => 'Still connecting — wait a moment and try again.',
|
||||
},
|
||||
'resolveFailure' => $device->reason,
|
||||
]);
|
||||
}
|
||||
|
||||
// SECURITY: everything identifying the device is request-supplied, and this
|
||||
// endpoint WRITES network state (authorizeGuest puts a MAC on the mapped VLAN).
|
||||
// Before this check any signed-in account — a student, a parent — could call
|
||||
// GET /portal/wifi/callback?mac=<someone else's MAC>&url=…
|
||||
// and admit a device they do not own, up to max_devices.
|
||||
//
|
||||
// A well-formed MAC is the floor, not a fix: it stops the parameter being used
|
||||
// to smuggle junk into authorizeGuest and into the PortalSession row, but it
|
||||
// cannot prove the caller owns the device. Properly binding it needs the AP
|
||||
// handshake — UniFi can sign the redirect, or we ask the controller whether this
|
||||
// MAC is CURRENTLY associated to $apMac before admitting it. Both need testing
|
||||
// against real hardware, so they are deliberately not guessed at here.
|
||||
$clientMac = str_replace('-', ':', $clientMac);
|
||||
if (! preg_match('/^([0-9a-f]{2}:){5}[0-9a-f]{2}$/', $clientMac)) {
|
||||
return response('Malformed MAC address', 400);
|
||||
}
|
||||
$clientMac = $device->mac;
|
||||
$isRandomized = $device->isRandomized;
|
||||
|
||||
// Find the VLAN mapping for this user's group/OU
|
||||
$mapping = $this->resolveMapping($user);
|
||||
|
||||
Reference in New Issue
Block a user