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
Insecure Code Example
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.
Secure Code Example
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
Last updated
2023/09/18