Insecure session expiration time - Swift

Insecure session expiration time - Swift

Need

Enforce secure session expiration time

Context

  • Usage of Swift for iOS and macOS app development
  • Usage of UIKit for building modern and responsive user interfaces

Description

Non compliant code

        import UIKit

class SessionManager {
    static let shared = SessionManager()
    var timer: Timer?
    var sessionDuration: TimeInterval = 60 * 60 // 1 hour

    private init() {}

    func startSession() {
        stopSession()
        timer = Timer.scheduledTimer(timeInterval: sessionDuration, target: self, selector: #selector(endSession), userInfo: nil, repeats: false)
    }

    @objc func endSession() {
        // Invalidate session here
    }

    func stopSession() {
        timer?.invalidate()
        timer = nil
    }
}
        
        

In the above Swift code, we have a SessionManager singleton class that manages the user session. It uses a Timer to determine when to end the session. The sessionDuration is set to 60 minutes.

The startSession function starts a new session. If there is an existing session, it ends it first. It then starts a new Timer that ends the session after sessionDuration has passed.

The endSession function is called when the Timer fires and it is where the session should be invalidated.

The stopSession function ends the current session by invalidating the Timer.

The vulnerability here is that the session duration is set to 60 minutes. This means that if a user becomes inactive, their session will still remain active for up to an hour. This can be a security risk as an attacker could potentially use this time to hijack the user's session.

Steps

  • Reduce the session duration to 5 minutes (300 seconds) to enforce the expiration time.
  • Modify the `endSession` method to invalidate the session when called.
  • Update the `startSession` method to reset the timer whenever there is user activity.
  • Implement a mechanism to track user activity and reset the session timer accordingly.

Compliant code

        import UIKit

class SessionManager {
    static let shared = SessionManager()
    var timer: Timer?
    var sessionDuration: TimeInterval = 300 // 5 minutes

    private init() {}

    func startSession() {
        stopSession()
        timer = Timer.scheduledTimer(timeInterval: sessionDuration, target: self, selector: #selector(endSession), userInfo: nil, repeats: false)
        NotificationCenter.default.addObserver(self, selector: #selector(resetSession), name: UIApplication.didBecomeActiveNotification, object: nil)
    }

    @objc func endSession() {
        // Invalidate session here
        stopSession()
    }

    func stopSession() {
        timer?.invalidate()
        timer = nil
    }

    @objc func resetSession() {
        startSession()
    }
}
        
        

The updated code now sets the session duration to 5 minutes (300 seconds) instead of 1 hour. This change enforces the session to expire after 5 minutes of inactivity.

The startSession method has been updated to reset the session timer whenever the application becomes active. This is achieved by adding an observer for the UIApplication.didBecomeActiveNotification notification. When this notification is received, the resetSession method is called, which stops the current session and starts a new one.

The endSession method is called when the timer expires. This method should be updated to invalidate the session as per your application's requirements.

The stopSession method is used to invalidate the timer. This method is called when the session ends or when a new session is started.

By implementing these changes, the session will now expire after 5 minutes of inactivity, thus fixing the vulnerability.

References