Insufficient data authenticity validation - Front bypass - Swift

Insufficient data authenticity validation - Front bypass - Swift

Need

Enhanced data authenticity validation and enforcement

Context

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

Description

Non compliant code

        import UIKit

class ChangePasswordViewController: UIViewController {
    @IBOutlet weak var newPasswordTextField: UITextField!
    
    @IBAction func changePasswordButtonTapped(_ sender: UIButton) {
        let newPassword = newPasswordTextField.text
        // Password validation only in frontend
        if isValidPassword(password: newPassword) {
            // API call to change password
            changePasswordAPI(newPassword: newPassword)
        } else {
            // Show error message
            showError("Password must not be consecutive and/or repeated numbers")
        }
    }
    
    func isValidPassword(password: String?) -> Bool {
        // Check if password is not consecutive and/or repeated numbers
        // This is the validation that should also be done in the backend
        let regex = "^(?!.*?(\\\\d)\\\\1{2,})[0-9]*$"
        let passwordTest = NSPredicate(format: "SELF MATCHES %@", regex)
        return passwordTest.evaluate(with: password)
    }
    
    func changePasswordAPI(newPassword: String?) {
        // API call to change password
    }
    
    func showError(_ message: String) {
        // Show error message
    }
}
        
        

The above Swift code for an iOS mobile application represents a ChangePasswordViewController, where users can change their passwords. The password policy in the system is checked in the isValidPassword(password: String?) -> Bool function, which uses a regular expression to ensure that the password does not contain consecutive and/or repeated numbers.

However, this validation is only performed in the frontend of the application (inside the changePasswordButtonTapped(_ sender: UIButton) function), making the system vulnerable. An attacker can bypass this frontend validation by directly making an API call to the changePasswordAPI(newPassword: String?) function with a password that violates the system's password policy.

To fix this vulnerability, the same password validation should also be performed in the backend of the application, not just the frontend. This ensures that even if the frontend validation is bypassed, the backend validation will still prevent the use of a password that violates the system's password policy.

Steps

  • Move the password validation logic to the backend.
  • Implement a secure API endpoint for changing the password.
  • Validate the password on the backend using the same validation logic as in the frontend.
  • Return appropriate error messages from the backend if the password does not meet the validation criteria.
  • Update the frontend code to call the secure API endpoint for changing the password.

Compliant code

        import UIKit

class ChangePasswordViewController: UIViewController {
    @IBOutlet weak var newPasswordTextField: UITextField!
    
    @IBAction func changePasswordButtonTapped(_ sender: UIButton) {
        let newPassword = newPasswordTextField.text
        // API call to change password
        changePasswordAPI(newPassword: newPassword)
    }
    
    func changePasswordAPI(newPassword: String?) {
        // API call to change password
        // The password validation is now done in the backend
    }
    
    func showError(_ message: String) {
        // Show error message
    }
}
        
        

The updated code removes the password validation logic from the frontend and moves it to the backend. This is done to prevent a front bypass vulnerability where a malicious user could potentially modify the password from the same request and assign a key that goes against the policies.

The changePasswordButtonTapped function now directly calls the changePasswordAPI function without performing any password validation. The password validation is now expected to be done in the backend.

The changePasswordAPI function is expected to call a secure API endpoint that changes the user's password. This function should validate the new password using the same validation logic as before (i.e., the password must not be consecutive and/or repeated numbers). If the password does not meet the validation criteria, the backend should return an appropriate error message.

The showError function is used to display error messages to the user. This function can be used to display the error messages returned by the backend if the password does not meet the validation criteria.

By moving the password validation logic to the backend, we ensure that the password validation is always performed, even if a malicious user tries to bypass the frontend validation. This significantly improves the security of the application.

References