diff --git a/clientapi/routing/register.go b/clientapi/routing/register.go index 279ae22d7..c97876594 100644 --- a/clientapi/routing/register.go +++ b/clientapi/routing/register.go @@ -73,10 +73,13 @@ func init() { // It shouldn't be passed by value because it contains a mutex. type sessionsDict struct { sync.RWMutex - sessions map[string][]authtypes.LoginType - params map[string]registerRequest - timer map[string]*time.Timer - sessionToDevice map[string]string + sessions map[string][]authtypes.LoginType + params map[string]registerRequest + timer map[string]*time.Timer + // deleteSessionToDeviceID protects requests to DELETE /devices/{deviceID} from being abused. + // If a UIA session is started by trying to delete device1, and then UIA is completed by deleting device2, + // the delete request will fail for device2 since the UIA was initiated by trying to delete device1. + deleteSessionToDeviceID map[string]string } // defaultTimeout is the timeout used to clean up sessions @@ -116,7 +119,7 @@ func (d *sessionsDict) deleteSession(sessionID string) { defer d.Unlock() delete(d.params, sessionID) delete(d.sessions, sessionID) - delete(d.sessionToDevice, sessionID) + delete(d.deleteSessionToDeviceID, sessionID) // stop the timer, e.g. because the registration was completed if t, ok := d.timer[sessionID]; ok { if !t.Stop() { @@ -131,10 +134,10 @@ func (d *sessionsDict) deleteSession(sessionID string) { func newSessionsDict() *sessionsDict { return &sessionsDict{ - sessions: make(map[string][]authtypes.LoginType), - params: make(map[string]registerRequest), - timer: make(map[string]*time.Timer), - sessionToDevice: make(map[string]string), + sessions: make(map[string][]authtypes.LoginType), + params: make(map[string]registerRequest), + timer: make(map[string]*time.Timer), + deleteSessionToDeviceID: make(map[string]string), } } @@ -172,13 +175,13 @@ func (d *sessionsDict) addDeviceToDelete(sessionID, deviceID string) { d.startTimer(defaultTimeOut, sessionID) d.Lock() defer d.Unlock() - d.sessionToDevice[sessionID] = deviceID + d.deleteSessionToDeviceID[sessionID] = deviceID } func (d *sessionsDict) getDeviceToDelete(sessionID string) (string, bool) { d.RLock() defer d.RUnlock() - deviceID, ok := d.sessionToDevice[sessionID] + deviceID, ok := d.deleteSessionToDeviceID[sessionID] return deviceID, ok }