ionic-team / capacitor-plugins

Official plugins for Capacitor ⚡️

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

feat(@capacitor/device) Request to update device plugin to remove privacy-impacting APIs

Kevin-Hamilton opened this issue · comments

Feature Request

Plugin

device

Description

Starting May 1st 2024 Apple requires a PrivacyInfo.xcprivacy file to be added when specific functionality is used. The device plugin is using privacy impacting disk space APIs.

APIs for accessing the available disk space require reasons for use. For a detailed list of restricted APIs see here.

There are 4 allowed reasons for accessing the available disk space, as summarized below:

  1. (Reason Code 85F4.1) Declare this reason to display disk space information to the person using the device.
  2. (Reason Code E174.1) Declare this reason to check whether there is sufficient disk space to write files, or to check whether the disk space is low so that the app can delete files when the disk space is low.
  3. (Reason Code 7D9E.1) Declare this reason to include disk space information in an optional bug report that the person using the device chooses to submit.
  4. (Reason Code B728.1) Declare this reason if your app is a health research app

According to Apple policy:

[Your app] must declare one or more approved reasons that accurately reflect your use of each of these APIs and the data derived from their use. You may use these APIs and the data derived from their use for the declared reasons only. These declared reasons must be consistent with your app’s functionality as presented to users, and you may not use the APIs or derived data for tracking.

Currently, the device plugin accesses the restricted volumeAvailableCapacityForImportantUsageKey API within the getRealFreeDiskSize function here:

public func getRealFreeDiskSize() -> Int64? {
do {
let values = try URL(fileURLWithPath: NSHomeDirectory() as String).resourceValues(forKeys: [URLResourceKey.volumeAvailableCapacityForImportantUsageKey])
if let available = values.volumeAvailableCapacityForImportantUsage {
return available

And the restricted systemFreeSize API within the getFreeDiskSize function here:

public func getFreeDiskSize() -> Int64? {
let paths = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)
if let dictionary = try? FileManager.default.attributesOfFileSystem(forPath: paths.last!) {
if let freeSize = dictionary[FileAttributeKey.systemFreeSize] as? NSNumber {
return freeSize.int64Value
}

And the restricted systemSize API within the getTotalDiskSize function here:

public func getTotalDiskSize() -> Int64? {
let paths = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)
if let dictionary = try? FileManager.default.attributesOfFileSystem(forPath: paths.last!) {
if let freeSize = dictionary[FileAttributeKey.systemSize] as? NSNumber {
return freeSize.int64Value
}

These functions are all called from the getInfo function of the device plugin. If an app attempts to use the device plugin to access information such as model, platform, manufacturer, or isVirtual it also receives the restricted disk information, triggering the responsibility to declare one of the required reasons for accessing that disk information.

Platform(s)

iOS

Preferred Solution

I would prefer to have the restricted API calls moved to a separate function call, or new methods created to more granularly select what data the device plugin will return, so the app can avoid calling restricted APIs when trying to get non-restricted data.

Alternatives

I am not 100% clear on whether this is the case, but I am concerned about the possibility that an app could be flagged for the privacy-impacting APIs being compiled into the app, even if the API does not get called. This probably warrants testing to verify. If an app can be flagged for the disk space APIs just on the basis of the device plugin being installed even if the getInfo function is not called, then I would request an alternate plugin be made available which does not include these disk space APIs.

We've discussed this a bit internally for a better long term solution to this. Unfortunately, based on prior experience with rules such as these, it's likely just a static automated scanner looking for specific references in the code that doesn't account for if the API is in use, only that the code to use it exists. We'll be looking into this to see if there are any changes we can make for Capacitor 7, but for the time being, if you use a flagged plugin, you'll need to declare the privacy manifest for it, even if you're not actively using it (or fork the plugin yourself to remove the specific references).

We are adding to our docs what you could use by default to help know what to put as well. #2076