Skip to content

Commit

Permalink
OWASP#1161: commited al recommended fixes/feedback
Browse files Browse the repository at this point in the history
  • Loading branch information
commjoen committed Aug 13, 2019
1 parent 4ecaca4 commit df28111
Show file tree
Hide file tree
Showing 4 changed files with 12 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -531,7 +531,7 @@ SEQUENCE (3 elem)
INTEGER 65537
```
To know what this means we can check the corresponding [RFC2313][]:
To know what this means we can check the corresponding [RFC2313](https://tools.ietf.org/html/rfc2313 "RSA Encryption Version 1.5"):
```shell
7.2 Private-key syntax
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -571,8 +571,9 @@ For applications which require L2 protection, the MASVS states that: "The app in
In all cases, you should verify whether different devices are detected correctly. Therefore, the binding of the application to the actual device should be tested.
In iOS, a developer can use `identifierForVendor`, which is related to the bundleID: the moment you change a bundle-ID, the method will return a different value. When the app is ran for the first time, make sure you store the String returned by `identifierForVendor` to the KeyChain, so that changes to it can be detected at an early stage.

In Android, the developer can use `Settings.Secure.ANDROID_ID` till Android 8.0 (API level 26) to identify an application instance. Note that starting at Android 8.0 (API level 26), `ANDROID_ID` is no longer a device unique ID. Instead it becomes scoped by the combination of app-signing key, user and device. So validating `ANDROID_ID` for device blocking could be tricky for these Android versions. Because if an app changes its signing key, the `ANDROID_ID` will change and it won't be able to recognize old users devices. Therefore it is better to store the `ANDROID_ID` encrypted with a randomly generated key from the `AndroidKeyStore` using AES_GCM encryption in the `SharedPreferences` (privately). The moment the app-signature changes, the application can check for a delta and register the new `ANDROID_ID`. The moment this changes without a new application signing key, it should indicate that something else is wrong.
Next the device binding can be extended by signing requests wih a key stored in the `Keychain` for iOS and in the `KeyStore` in Android can reassure strong device binding. Next, you should test if using different IPs, different locations and/or different time-slots will trigger the right type of information in all scenarios.
In Android, the developer can use `Settings.Secure.ANDROID_ID` till Android 8.0 (API level 26) to identify an application instance. Note that starting at Android 8.0 (API level 26), `ANDROID_ID` is no longer a device unique ID. Instead it becomes scoped by the combination of app-signing key, user and device. So validating `ANDROID_ID` for device blocking could be tricky for these Android versions. Because if an app changes its signing key, the `ANDROID_ID` will change and it won't be able to recognize old users devices. Therefore it is better to encrypt the `ANDROID_ID` with a randomly generated key from the `AndroidKeyStore` using `AES_GCM` encryption. The encrypted `ANDROID_ID` should then be stored in the `SharedPreferences` (privately). The moment the app-signature changes, the application can check for a delta and register the new `ANDROID_ID`. The moment this changes without a new application signing key, it should indicate that something else is wrong.
Next, the device binding can be extended by signing requests with a key stored in the `Keychain` for iOS and in the `KeyStore` in Android can reassure strong device binding.
You should also test if using different IPs, different locations and/or different time-slots will trigger the right type of information in all scenarios.

Lastly, the blocking of the devices should be tested, by blocking a registered instance of the app and see if it is then no longer allowed to authenticate.
Note: in case of an application which requires L2 protection, it can be a good idea to warn a user even before the first authentication on a new device. Instead: warn the user already when a second instance of the app is registered.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1325,7 +1325,13 @@ Before we describe the usable identifiers, let's quickly discuss how they can be

#### Static Analysis

In the past, Android developers often relied on the `Settings.Secure.ANDROID_ID` (SSAID) and MAC addresses. However, the behavior of the SSAID has changed since Android 8.0 (API level 26), and the behavior of MAC addresses [changed with the release of Android 7.0 (API level 25)](https://android-developers.googleblog.com/2017/04/changes-to-device-identifiers-in.html "Changes in the Android device identifiers"). In addition, there are new [recommendations for identifiers](https://developer.android.com/training/articles/user-data-ids.html "Developer Android documentation - User data IDs") in Google's SDK documentation. These last recommendations boil down to: either use the `Advertising ID` when it comes to advertising - so that a user can decline - or the `Instance ID` for device identification. Both are not stable accross device upgrades and device-resets, but `Instance ID` will at least allow to identify the current software installation on a device. The SSAID should only be used in case to detect fraud.
In the past, Android developers often relied on the `Settings.Secure.ANDROID_ID` (SSAID) and MAC addresses. However, the behavior of the SSAID has changed since Android 8.0 (API level 26), and the behavior of MAC addresses [changed with the release of Android 7.0 (API level 25)](https://android-developers.googleblog.com/2017/04/changes-to-device-identifiers-in.html "Changes in the Android device identifiers"). In addition, there are new [recommendations for identifiers](https://developer.android.com/training/articles/user-data-ids.html "Developer Android documentation - User data IDs") in Google's SDK documentation. Basically, Gooogle recommends to:

- use the Advertising ID (`AdvertisingIdClient.Info`) when it comes to advertising -so that a user can decline
- use the Instance ID (`FirebaseInstanceId`) for device identification.
- use the SSAID only in case to detect fraud.

Note that Instance ID and Advertising ID are not stable accross device upgrades and device-resets. However, Instance ID will at least allow to identify the current software installation on a device.

There are a few key terms you can look for when the source code is available:

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -575,11 +575,7 @@ Take the following steps when you want to verify app-binding with two jailbroken
Before we describe the usable identifiers, let's quickly discuss how they can be used for binding. There are three methods for device binding in iOS:
<<<<<<< HEAD
- You can use `[[UIDevice currentDevice] identifierForVendor]` (in Objective-C), `UIDevice.current.identifierForVendor?.uuidString` (in Swift3), or `UIDevice.currentDevice().identifierForVendor?.UUIDString` (in Swift2). These may not be available after you reinstall the application if no other applications from the same vendor are installed and it may change when you update your app-bundle's name. Therefore it is best to combine it with something in the Keychain.
=======
- You can use `[[UIDevice currentDevice] identifierForVendor]` (in Objective-C), `UIDevice.current.identifierForVendor?.uuidString` (in Swift3), or `UIDevice.currentDevice().identifierForVendor?.UUIDString` (in Swift2). These may not be available after you reinstall the application if no other applications from the same vendor are installed.
>>>>>>> master
- You can use `[[UIDevice currentDevice] identifierForVendor]` (in Objective-C), `UIDevice.current.identifierForVendor?.uuidString` (in Swift3), or `UIDevice.currentDevice().identifierForVendor?.UUIDString` (in Swift2). These may not be available after you reinstall the application if no other applications from the same vendor are installed and it may change when you update your app bundle's name. Therefore it is best to combine it with something in the Keychain.
- You can store something in the Keychain to identify the application's instance. To make sure that this data is not backed up, use `kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly` (if you want to secure the data and properly enforce a passcode or touch-id requirement), `kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly`, or `kSecAttrAccessibleWhenUnlockedThisDeviceOnly`.
- You can use Google and its Instance ID for [iOS](https://developers.google.com/instance-id/guides/ios-implementation "iOS implementation Google Instance ID").
Expand Down

0 comments on commit df28111

Please sign in to comment.