Baseflow / Baseflow/flutter-permission-handler

[Bug]: Production Crash - SecurityException caused by unconditional canRequestPackageInstalls()call

Open
#1,502 1 comment 0 reactions 0 assignees View on GitHub
Dominant language
Dart
Stars
2.2k
Forks
970
Avg merge
14h 22m
Merged PRs (30d)
2

Description

### Please check the following before submitting a new issue.

- [x] I have searched the [existing issues](https://github.com/baseflow/flutter-permission-handler/issues).
- [x] I have carefully [read the documentation](https://github.com/Baseflow/flutter-permission-handler/blob/main/permission_handler/README.md) and verified I have added the required platform specific configuration.

### Please select affected platform(s)

- [x] Android
- [ ] iOS
- [ ] Windows

### Steps to reproduce

Our production app is experiencing crashes on live users due to the plugin calling canRequestPackageInstalls()inside PermissionManager.onActivityResult() without verifying whether the app declares the REQUEST_INSTALL_PACKAGES permission.

Our app does not request or use this permission, and cannot add it due to Google Play Store policy restrictions. As a result, this behavior is causing crashes that we cannot workaround safely.

This issue needs immediate attention because it directly impacts the stability of apps in production.

**Crash Log**

java.lang.SecurityException: Need to declare android.permission.REQUEST_INSTALL_PACKAGES to call this api at android.os.Parcel.createException(Parcel.java:2071) at Android.app.ApplicationPackageManager.canRequestPackageInstalls(ApplicationPackageManager.java:2963) at com.baseflow.permissionhandler.PermissionManager.onActivityResult(PermissionManager.java:120)

**Impact**

- This crash is happening in production on Android 10+ devices.
- Triggered during normal permission flows (camera, notifications, storage, etc).
- Users experience app termination even though the app never touches the install-packages functionality.
- We cannot declare REQUEST_INSTALL_PACKAGES because Google Play flags it as a high-risk permission and may reject the build.
- There is no safe app-side workaround available since the call originates inside plugin internals.
- This means the plugin is forcing apps into a position where they must either risk Play Store rejection or accept production crashes.

**Root Cause**

- In PermissionManager.java (around lines 120 and 534), the plugin executes:
- packageManager.canRequestPackageInstalls();

This API requires android.permission.REQUEST_INSTALL_PACKAGES.
If the permission is not declared (which is valid and expected in many apps), Android throws a SecurityException — causing the crash.

This call is made unconditionally during the onActivityResult() flow, even when the permission is never requested or used.

**Steps to Reproduce**

- Use this plugin on Android 10+
- Request any runtime permission (camera, storage, photos, notifications)
- When onActivityResult() is triggered, the plugin attempts to call canRequestPackageInstalls()
- Crash occurs if the app has not declared REQUEST_INSTALL_PACKAGES (which is the majority of apps)

Happy to provide additional logs if needed.

**Please prioritize this issue, as it is currently causing live production crashes and cannot be mitigated app-side due to Play Store restrictions.**

### Expected results

The plugin should not call canRequestPackageInstalls() unless the app:

- explicitly declares REQUEST_INSTALL_PACKAGES, or
- actually requests an install-packages permission, or
- needs to check install-package status based on app logic
- For normal permission flows, this check should be skipped.

### Actual results

` Caused by java.lang.SecurityException: Need to declare android.permission.REQUEST_INSTALL_PACKAGES to call this api
at android.os.Parcel.createException(Parcel.java:2071)
at android.os.Parcel.readException(Parcel.java:2039)
at android.os.Parcel.readException(Parcel.java:1987)
at android.content.pm.IPackageManager$Stub$Proxy.canRequestPackageInstalls(IPackageManager.java:9772)
at android.app.ApplicationPackageManager.canRequestPackageInstalls(ApplicationPackageManager.java:2963)
at com.baseflow.permissionhandler.PermissionManager.onActivityResult(PermissionManager.java:120)
at io.flutter.embedding.engine.FlutterEngineConnectionRegistry$FlutterEngineActivityPluginBinding.onActivityResult(FlutterEngineConnectionRegistry.java:774)
at io.flutter.embedding.engine.FlutterEngineConnectionRegistry.onActivityResult(FlutterEngineConnectionRegistry.java:422)
at io.flutter.embedding.android.FlutterActivityAndFragmentDelegate.onActivityResult(FlutterActivityAndFragmentDelegate.java:964)
at io.flutter.embedding.android.FlutterFragment.onActivityResult(FlutterFragment.java:1248)
at io.flutter.embedding.android.FlutterFragmentActivity.onActivityResult(FlutterFragmentActivity.java:645)
at android.app.Activity.dispatchActivityResult(Activity.java:8110)
at android.app.ActivityThread.deliverResults(ActivityThread.java:4896)
at android.app.ActivityThread.handleSendResult(ActivityThread.java:4944)
at android.app.servertransaction.ActivityResultItem.execute(ActivityResultItem.java:51)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2038)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7529)
at java.lang.reflect.Method.invoke(Method.java)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:935)`

### Code sample

Code sample

```dart














```

### Screenshots or video

Screenshots or video demonstration

[Upload media here]

Image
Image
Image

Image

### Version

11.3.1, 12.0.1

### Flutter Doctor output

Doctor output

```console
[!] Flutter (Channel [user-branch], 3.27.3, on macOS 15.3 24D60 darwin-arm64, locale en-IN)
! Flutter version 3.27.3 on channel [user-branch] at /Users/cygnet/FlutterSdk/3.27/flutter
Currently on an unknown channel. Run `flutter channel` to switch to an official channel.
If that doesn't fix the issue, reinstall Flutter by following instructions at https://flutter.dev/setup.
• Framework revision c519ee916e (10 months ago), 2025-01-21 10:32:23 -0800
• Engine revision e672b006cb
• Dart version 3.6.1
• DevTools version 2.40.2
• If those were intentional, you can disregard the above warnings; however it is recommended to use "git" directly to perform update checks and
upgrades.

[✓] Android toolchain - develop for Android devices (Android SDK version 36.0.0-rc4)
• Android SDK at /Users/cygnet/Library/Android/sdk
• Platform android-36, build-tools 36.0.0-rc4
• Java binary at: /Applications/Android Studio.app/Contents/jbr/Contents/Home/bin/java
• Java version OpenJDK Runtime Environment (build 21.0.5+-12932927-b750.29)
• All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS (Xcode 16.2)
• Xcode at /Applications/Xcode.app/Contents/Developer
• Build 16C5032a
• CocoaPods version 1.16.2

[✓] Chrome - develop for the web
• Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

[✓] Android Studio (version 2024.2)
• Android Studio at /Applications/Android Studio.app/Contents
• Flutter plugin can be installed from:
🔨 https://plugins.jetbrains.com/plugin/9212-flutter
• Dart plugin can be installed from:
🔨 https://plugins.jetbrains.com/plugin/6351-dart
• Java version OpenJDK Runtime Environment (build 21.0.5+-12932927-b750.29)

[✓] Android Studio (version 2022.2)
• Android Studio at /Applications/Android Studio 2.app/Contents
• Flutter plugin can be installed from:
🔨 https://plugins.jetbrains.com/plugin/9212-flutter
• Dart plugin can be installed from:
🔨 https://plugins.jetbrains.com/plugin/6351-dart
• Java version OpenJDK Runtime Environment (build 17.0.6+0-17.0.6b802.4-9586694)

[✓] VS Code (version 1.100.2)
• VS Code at /Users/cygnet/Downloads/Visual Studio Code.app/Contents
• Flutter extension version 3.122.0

[✓] Connected device (1 available)
• sdk gphone64 arm64 (mobile) • emulator-5554 • android-arm64 • Android 16 (API 36) (emulator)

[✓] Network resources
• All expected network resources are available.

```

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.