https://fingerprintjs.com/blog/how-android-wallpaper-images-threaten-privacy/ BlogCase StudiesDocsSupportLogin Why Us Use Cases Account SharingAccount TakeoverPayment FraudPaywallEcommerceGaming Cryptocurrency DemoPricing Star Contact SalesFree Trial Blog>>How android wallpaper images threaten privacy * Fingerprinting * Vulnerability * Privacy * Android How Android Wallpaper Images Can Threaten Your Privacy October 5, 2021 [Z]Alexey Verkhovsky photo Alexey VerkhovskyAndroid Researcher [AhUvNfZiOM]Android Wallpaper Identifcation Android 12's highly anticipated Material You design system features wallpaper-based color theming and advanced customizations powered by color extraction. These UI enhancements allow users to select a wallpaper (i.e., a personal background image) from which an optimal palette of colors is automatically generated and applied to the device's look and feel globally. Unfortunately, such personalization can carry a high price in compromised privacy. In this article, we'll demonstrate how Android wallpapers can be used to track users and explore ways to prevent your device from being exploited. Skip to the good stuff - try it yourself You can download the demo app that generates a unique ID per user on Google Play (for Android 5.0 and above, no permissions are required); the source code is available on GitHub. Android wallpaper images vs. user privacy The WallpaperManager class was introduced in 2009 as part of the release of Android 2, API version 5. The class provides methods for interacting with wallpapers, including getDrawable() for retrieving the current system wallpaper as a drawable resource. Using the following code, a drawable resource can be represented as a byte array: private fun calculateWallpaperBytes(): ByteArray { val imageBitmap = wallpaperManager.drawable.toBitmap() val stream = ByteArrayOutputStream() imageBitmap.compress (Bitmap.CompressFormat.PNG, 100, stream) return stream.toByteArray() } Byte arrays can be used to restore original images from Android wallpapers, which are highly likely to contain personal information or details uniquely important to the user. Every app on your device can view and download photos of your family, pets, favorite bands or movies, and anything else you may have set as a wallpaper. Moreover, you couldn't prevent them from doing so before Android 8.1. As it stands, a large percentage of devices are running Android 8.1 or earlier (almost 44.6% at the time of this writing, per Google Analytics) and still vulnerable to this exploit. A new color extraction method Starting with Android 8.1, the getDrawable() method requires the use of READ_EXTERNAL_STORAGE, a less insecure but nonetheless risky permission as it enables access to all media on a device (and more privileged data). To compensate for the limited functionality, an easier way to extract colors was also introduced in Android 8.1: getWallpaperColors(int which), which returns 3 main colors from a wallpaper image. Like iOS, Android allows users to determine which specific screens to use wallpaper images, and the integer argument "which" sets which exact wallpaper image to use for color extraction. There are two options: the constant values WallpaperManager.FLAG_SYSTEM or WallpaperManager.FLAG_LOCK. Wallpaper setting in Android // WallpaperManager.FLAG_LOCK for the the lock screen val colors = WallpaperManager .getInstance(context).getWallpaperColors (WallpaperManager.FLAG_SYSTEM) val primaryColor: Int = colors.primaryColor.toArgb() val secondaryColor: Int = colors.secondaryColor.toArgb() val tertiaryColor: Int = colors.tertiaryColor.toArgb() The above code illustrates how to extract colors using a context object with primary, secondary and tertiary colors corresponding to the most popular colors in the picture (primary being the most popular). Note that no special permissions are required to use this new method. The following is an example of color extraction using the new method with a real picture: Color extraction example The methods may return null in some scenarios (e.g., when custom launchers redefine wallpaper management logic without using the WallpaperManager class). However, if a wallpaper was set once by WallpaperManager, the method will return a not-null value. The science of color extraction Since Android is open source, we can readily determine how the method actually works. According to the code, colors are the result of work of Variational K-means quantizer. Every image pixel is represented by a color and every color is a 3-dimensional point in space (e.g., RGB color space). All pixels form a set in space, and the algorithm performs clustering of the set on K parts with finding K points, which are equidistant from others in the set. [wZzelSbxnR] Above is a visualization of how the K-means method works, courtesy of vas3k. This particular case is 3-means in a 2-dimensional space. In the case of Android, colors are represented in the HSL color space and distance is calculated using classical measures of euclidean distance. The results are three shades of an image that are equidistant (in the color space) from every pixel of the image. A universe of combinations This color extraction algorithm is basically a map from the set of all possible images to the RGB color space. The set is infinite and the RGB color space is limited by 224 combinations. Theoretically, this means every RGB combination is possible. Every color is represented by 32 bits, but only 24 matter. Alpha channels will always be equal to 1 (according to sources), while every component of the colors R, G and B have 256 possible combinations, or 28. Since each component is independent, we can directly multiply the number of combinations together. This comes out to: 28 * 28 * 28 = 224 combinations for every color. We have 3 colors for a image, and 224 * 224 * 224 = 272 combinations per image. The same logic applies to the second wallpaper image, and they can be set up independently of each other. From one wallpaper image we have 72 bits and 144 bits using system wallpaper and lock screen wallpaper -- 144 bits and 2144 combinations. The more combinations possible, the higher probability of generating a unique value suitable for use as an ID. And hence, it's likely you can easily be tracked. 2144 = 22,300,745,198,530,623,141,535,718,272,648,361,505,980,416 How large is this number, exactly? For context, the universe is made up of around 1080 atoms. And 2144 is approximately equal to 1043. So the squared value of combinations is larger than the number of atoms in the universe! It's safe to say that this outnumbers all devices on the Earth, for the foreseeable future. The identification algorithm As you may recall, developers can use byte arrays to restore wallpaper images prior to Android 8.1. After version 8.1, 144 bits can be extracted from wallpaper colors. Both can be used as an ID, but let's use them instead as inputs for the SHA-256 hash function (for unification). We have an ID that contains 256 bits, is unique across all applications, and only changes when the device wallpaper changes. The code for getting the ID is: val id = hasher.hash( if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O_MR1) { extractWallpaperBytes() } else extractColorsBytes()) The ID remains the same even after reinstalling the application and only changes when the wallpaper changes. Try it yourself For demonstration purposes, we've created an open source application that calculates the ID and checks its uniqueness. You can download the app on Google Play (for Android 5.0 and above, no permissions are required); the source code is available on GitHub. Note: the method does not work on custom launchers that redefine logic of wallpaper management without using WallpaperManager class. Android wallpaper demo How to prevent wallpaper tracking on your Android device The following measures can help prevent wallpaper tracking on your Android device: 1. Never use private or personal images for wallpapers, especially on devices running Android 8.1 and earlier. 2. Use a default wallpaper and don't change it. By using a custom image, you inadvertently add entropy and uniqueness for distinguishing your device from others. 3. Check if your launcher has redefined the logic of the device's wallpaper management (you can do this with our demo application). 4. Don't install suspicious applications. 5. Be sure to keep your device operating system continuously updated. 6. Use anti-malware software to ensure your installed applications are behaving as expected. Conclusion As you can see, signals generated from wallpaper color extraction can be used to create a single identifier available to all applications, no additional permissions required. That said, extracting colors from device wallpapers is just one way mobile developers can uniquely profile Android devices, and it's not the most dependable at that. For some examples of more stable and reliable methods, please view our fingerprint-android library source code. Google has not restricted these for a number of years now, and it is unlikely that it ever will. At the end of the day, doing so would impact Android's efficacy as an advertising platform -- and for the world's largest tech firm, it's a constant juggle between balancing these interests with protecting user privacy. Get in touch * Star, follow, or fork our production-grade library for Android device fingerprinting * Email any questions you have to oss@fingerprintJS.com * Join our team and work on exciting research in device security: work@fingerprintjs.com Related Articles [svg] Phishing Email September 30, 2021 How to Outsmart Fraudsters and Recognize Phishing Emails Phishing emails targeting businesses are increasingly difficult to detect. Learn how to train your employees to spot common signs of a phishing attack. * Account takeover * Payment fraud * Ecommerce fraud * Privacy [svg] iCloud Private Relay Leak September 20, 2021 iOS 15 iCloud Private Relay Vulnerability Identified Learn more about this vulnerability in Apple's new iCloud Private Relay service and how you can prevent your data from being leaked. * Web * Apple * Leak * Ios * Vulnerability [svg] Account Takeover Fraud September 16, 2021 Account Takeover Indicators That Businesses Should Know to Prevent Digital Identity Fraud Learn more about these tell-tale signs that your customers' accounts have been hijacked by cyber criminals. * Fingerprinting * Account takeover * Payment fraud * Ecommerce fraud [svg] 6 Types of Ecommerce Fraud September 15, 2021 6 Types of Ecommerce Fraud and How To Prevent Them From Harming Your Customers Today's ecommerce fraud is sophisticated, automated, and hard to detect. Learn about these 6 leading types and how to recognize them before it's too late. * Fingerprinting * Bot attacks * Payment fraud * Ecommerce fraud [svg] Phishing Email September 30, 2021 How to Outsmart Fraudsters and Recognize Phishing Emails Phishing emails targeting businesses are increasingly difficult to detect. Learn how to train your employees to spot common signs of a phishing attack. * Account takeover * Payment fraud * Ecommerce fraud * Privacy [svg] iCloud Private Relay Leak September 20, 2021 iOS 15 iCloud Private Relay Vulnerability Identified Learn more about this vulnerability in Apple's new iCloud Private Relay service and how you can prevent your data from being leaked. * Web * Apple * Leak * Ios * Vulnerability [svg] Account Takeover Fraud September 16, 2021 Account Takeover Indicators That Businesses Should Know to Prevent Digital Identity Fraud Learn more about these tell-tale signs that your customers' accounts have been hijacked by cyber criminals. * Fingerprinting * Account takeover * Payment fraud * Ecommerce fraud [svg] 6 Types of Ecommerce Fraud September 15, 2021 6 Types of Ecommerce Fraud and How To Prevent Them From Harming Your Customers Today's ecommerce fraud is sophisticated, automated, and hard to detect. Learn about these 6 leading types and how to recognize them before it's too late. * Fingerprinting * Bot attacks * Payment fraud * Ecommerce fraud General Technical DemoWhy UsOpen SourcePricingSupportTerms of UsePrivacy PolicyCareersLoginSystem Status Use Cases Account SharingAccount TakeoverPayment FraudPaywallEcommerceGaming Cryptocurrency Docs Get StartedPro vs Open SourceBrowser FingerprintingIncognito Mode DetectionServer APILegal FingerprintJS 1440 W. Taylor St #735, Chicago, IL 60607, USA support@fingerprintjs.com Star Find us on social * * (c) 2021 FingerprintJS, Inc