celzero / rethink-app

DNS over HTTPS / DNS over Tor / DNSCrypt client, WireGuard proxifier, firewall, and connection tracker for Android.
https://rethinkfirewall.com/
Apache License 2.0
2.97k stars 149 forks source link

FR: Firewall: only include apps with Internet Permission #1612

Open boredsquirrel opened 3 months ago

boredsquirrel commented 3 months ago

The Internet permission was implemented by GrapheneOS. I think other privacy-optimized AOSP versions adapted it too. LineageOS uses a different mechanism.

It would be great if in the Firewall all apps that dont have the internet permission could be hidden.

This could be done automatically by detecting the OS as GrapheneOS or searching for the permission. Also the existence of Vanadium (app.vanadium.browser) is an indication of GrapheneOS.

ignoramous commented 3 months ago

The thing is, if an app update adds the INTERNET permission, then Rethink would have to notify the user about it, as this permission is almost always granted without user intervention.

We could consider visually marking apps not having the INTERNET permission as such, rather than hiding them.

boredsquirrel commented 3 months ago

Thanks for the fast answer :D

We are talking about different things here. GrapheneOS, and I think CalyxOS and maybe others have a dedicated user-facing "Internet Permission" toggle. This then blocks the 4 or more different Internet permissions that apps can have.

An update does not do anything here, the user decides if an app gets internet access when installing it. The checkbox only appears if the app has internet permission. I dont know what happens if it hasnt, and gets it with an update.

ignoramous commented 3 months ago

GrapheneOS, and I think CalyxOS and maybe others have a dedicated user-facing "Internet Permission" toggle. This then blocks the 4 or more different Internet permissions that apps can have.

I know of only just the one INTERNET permission. Never knew there were 4 or more. You got any links handy that may have pointers for us to explore more?

boredsquirrel commented 3 months ago

In the past I used LuckyPatcher to remove these permissions from the APKs themselves.

They can scan Wifis, scan mobile networks, activate Wifi, activate mobile network, and use both. I think to remember

https://stackoverflow.com/questions/9458772/whats-the-difference-between-access-network-state-access-network-state-and-wi

https://developer.android.com/develop/connectivity/network-ops/reading-network-state

This may not be used like that anymore, which would be pretty great. Apps should not read your network name and the other available ones.

ignoramous commented 3 months ago

Thanks, those permissions don't really control if apps can connect to the Internet over available networks? Any specific links to GrapheneOS and CalyxOS documentation about the 4+ permissions removed to prevent apps from connecting to the Internet?

boredsquirrel commented 3 months ago

yes these are the permissions that apps internally use.

https://grapheneos.org/features#network-permission-toggle

ignoramous commented 3 months ago

yes these are the permissions that apps internally use.

https://grapheneos.org/features#network-permission-toggle

If I read it correctly, the doc talks about only taking away the one INTERNET permission, not 4 or more?

shuvashish76 commented 3 months ago

I think the 4+ permissions they are talking about is Net Policy? (ADB/Root feature for AM) Other reference : https://t.me/s/AppManagerChannel/102

Details

> The solution, here, is to edit out the INTERNET permission from the APK file itself (or use GrapheneOS which can revoke this permission effectively). However, this isn’t the end of the irony. The app can also utilise other apps with unpatched vulnerabilities to make the same connection (either via Binder or calling an infected service via Intent). In the latter case, editing out the INTERNET permission may not help at all (and GrapheneOS may not be able to block that either).

shuvashish76 commented 3 months ago

yes these are the permissions that apps internally use.

https://grapheneos.org/features#network-permission-toggle

When the Network permission is disabled, GrapheneOS pretends the network is down. It shows the network as down in various APIs, returns errors showing a network connectivity issue rather than a revoked permission and avoids running scheduled jobs depending on the network. This results in apps handling it as if the network is down rather than crashing or showing errors from trying to use the network and being unable to do it.

It sounds like Net Policy description of AM. I don't have a GrapheneOS device, not sure how they handel this.

ignoramous commented 3 months ago

It sounds like Net Policy description of AM. I don't have a GrapheneOS device, not sure how they handel this.

There's no clear documentation on their implementation. Unfortunately, I'm not familiar with their codebase to quickly find out which 4+ permissions they blocklist. It will take effort and time.

For now, we'll mark apps with no INTERNET permission a bit differently in the UI.

The app can also utilise other apps with unpatched vulnerabilities to make the same connection (either via Binder or calling an infected service via Intent)

This isn't a vulnerability, per se. There's no "infected" service helping other services bypass the INTERNET permission any more than a browser app that provides APIs for other installed apps to open any webpage is a vulnerability (of an infected browser helping apps bypass the INTERNET permission).

boredsquirrel commented 3 months ago

btw GrapheneOS is also working on an IPC permission, restricting the ability to use the mutual consent of other apps to transfer data to the internet anyways.

For example a game and play services, where the play services have internet permission (unprivileged user apps) and the game does not.


https://stackoverflow.com/questions/21091022/listing-permissions-of-android-application-via-adb

I followed my guide to get the google adb tools on Fedora

adb shell
dumpsys package im.molly.app

runtime permissions:
        android.permission.POST_NOTIFICATIONS: granted=true, flags=[ USER_SET|USER_SENSITIVE_WHEN_GRANTED|USER_SENSITIVE_WHEN_DENIED]
        android.permission.ACCESS_FINE_LOCATION: granted=false, flags=[ USER_SENSITIVE_WHEN_GRANTED|USER_SENSITIVE_WHEN_DENIED]
        android.permission.READ_PHONE_NUMBERS: granted=true, flags=[ USER_SET|USER_SENSITIVE_WHEN_GRANTED|USER_SENSITIVE_WHEN_DENIED]
        android.permission.READ_MEDIA_VISUAL_USER_SELECTED: granted=false, flags=[ USER_SENSITIVE_WHEN_GRANTED|USER_SENSITIVE_WHEN_DENIED]
        android.permission.OTHER_SENSORS: granted=false, flags=[ USER_SET|USER_SENSITIVE_WHEN_GRANTED|USER_SENSITIVE_WHEN_DENIED]
        android.permission.NEARBY_WIFI_DEVICES: granted=false, flags=[ USER_SENSITIVE_WHEN_GRANTED|USER_SENSITIVE_WHEN_DENIED]
        android.permission.INTERNET: granted=true, flags=[ USER_SET|USER_SENSITIVE_WHEN_GRANTED|USER_SENSITIVE_WHEN_DENIED]
        android.permission.READ_EXTERNAL_STORAGE: granted=false, flags=[ USER_SENSITIVE_WHEN_GRANTED|USER_SENSITIVE_WHEN_DENIED|RESTRICTION_INSTALLER_EXEMPT]
        android.permission.ACCESS_COARSE_LOCATION: granted=false, flags=[ USER_SENSITIVE_WHEN_GRANTED|USER_SENSITIVE_WHEN_DENIED]
        android.permission.READ_PHONE_STATE: granted=true, flags=[ USER_SET|USER_SENSITIVE_WHEN_GRANTED|USER_SENSITIVE_WHEN_DENIED]
        android.permission.READ_MEDIA_IMAGES: granted=false, flags=[ USER_SENSITIVE_WHEN_GRANTED|USER_SENSITIVE_WHEN_DENIED]
        android.permission.WRITE_CONTACTS: granted=true, flags=[ USER_SET|USER_SENSITIVE_WHEN_GRANTED|USER_SENSITIVE_WHEN_DENIED]
        android.permission.CAMERA: granted=true, flags=[ USER_SET|USER_SENSITIVE_WHEN_GRANTED|USER_SENSITIVE_WHEN_DENIED]
        android.permission.READ_MEDIA_VIDEO: granted=false, flags=[ USER_SENSITIVE_WHEN_GRANTED|USER_SENSITIVE_WHEN_DENIED]
        android.permission.RECORD_AUDIO: granted=true, flags=[ USER_SET|USER_SENSITIVE_WHEN_GRANTED|USER_SENSITIVE_WHEN_DENIED]
        android.permission.READ_CONTACTS: granted=true, flags=[ USER_SET|USER_SENSITIVE_WHEN_GRANTED|USER_SENSITIVE_WHEN_DENIED]

...
runtime permissions:
        android.permission.POST_NOTIFICATIONS: granted=false
        android.permission.ACCESS_FINE_LOCATION: granted=false
        android.permission.READ_PHONE_NUMBERS: granted=false
        android.permission.READ_MEDIA_VISUAL_USER_SELECTED: granted=false
        android.permission.OTHER_SENSORS: granted=false
        android.permission.NEARBY_WIFI_DEVICES: granted=false
        android.permission.INTERNET: granted=false
        android.permission.READ_EXTERNAL_STORAGE: granted=false, flags=[ APPLY_RESTRICTION]
        android.permission.ACCESS_COARSE_LOCATION: granted=false
        android.permission.READ_PHONE_STATE: granted=false
        android.permission.READ_MEDIA_IMAGES: granted=false
        android.permission.WRITE_CONTACTS: granted=false
        android.permission.CAMERA: granted=false
        android.permission.READ_MEDIA_VIDEO: granted=false
        android.permission.RECORD_AUDIO: granted=false
        android.permission.READ_CONTACTS: granted=false
...

This is strange. Molly has internet access granted. There are multiple blocks of permissions, and they are different.

The next example, DekuSMS has not:

dumpsys package com.afkanerd.deku

...
runtime permissions:
        android.permission.READ_SMS: granted=false, flags=[ APPLY_RESTRICTION]
        android.permission.POST_NOTIFICATIONS: granted=false
        android.permission.RECEIVE_WAP_PUSH: granted=false, flags=[ APPLY_RESTRICTION]
        android.permission.READ_MEDIA_VISUAL_USER_SELECTED: granted=false
        android.permission.OTHER_SENSORS: granted=false
        android.permission.RECEIVE_MMS: granted=false, flags=[ APPLY_RESTRICTION]
        android.permission.RECEIVE_SMS: granted=false, flags=[ APPLY_RESTRICTION]
        android.permission.INTERNET: granted=false
        android.permission.READ_EXTERNAL_STORAGE: granted=false, flags=[ APPLY_RESTRICTION]
        android.permission.READ_PHONE_STATE: granted=false
        android.permission.SEND_SMS: granted=false, flags=[ APPLY_RESTRICTION]
        android.permission.READ_MEDIA_IMAGES: granted=false
        android.permission.CAMERA: granted=false
        android.permission.WRITE_EXTERNAL_STORAGE: granted=false, flags=[ APPLY_RESTRICTION]
        android.permission.READ_CONTACTS: granted=false
...

Meanwhile cmd appops get im.molly.app which should show permissions on the user level, doesnt display the INTERNET permission. While the above command, which should display permissions on the system level, does.

@grapheneos we could need some help here :D

boredsquirrel commented 3 months ago

On GrapheneOS the internet permission is revoked if an app adds it with an update.

https://discuss.grapheneos.org/d/14429-how-does-the-internet-toggle-handle-updates/2