apache / cordova-android

Apache Cordova Android
https://cordova.apache.org/
Apache License 2.0
3.65k stars 1.54k forks source link

Disabling WebView remote debugging doesn't work #1732

Open ghevge opened 1 month ago

ghevge commented 1 month ago

I am trying to disable WebView remote debugging on my cordova app, by setting in config.xml the entry:

According to the SystemWebViewEngine code, this should have worked, but practically I am still able to remotely debug the cordova app on my phone.

Any idea why is that?

I'm basically trying to lock my app so that users cannot get access to the app code.

What is expected to happen?

Should not be able to remote debug the app when InspectableWebview is set to false

What does actually happen?

I am able to remote debug the app when InspectableWebview is set to false

Environment, Platform, Device

Android on Samsung S7 .

Version information

cordova --version 12.0.0 (cordova-lib@12.0.1)

breautek commented 1 month ago

Can you provide which cordova-android version you're using (cordova platform ls will state this) and your config.xml?

ghevge commented 1 month ago

@breautek

cordova platform ls
Installed platforms:
  android 12.0.0
Available platforms:
  browser
  electron

and my config file:

<?xml version='1.0' encoding='utf-8'?>
<widget id="com.myapp" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0" xmlns:android="http://schemas.android.com/apk/res/android">
    <name>myapp</name>
    <description>myapp</description>
    <author email="admin@myapp.com" href="https://www.myapp.com">
        myapp
    </author>
    <content src="index.html" />
    <access origin="*" />
    <allow-intent href="*" />
    <allow-navigation href="*" />
    <preference name="scheme" value="https" />
    <preference name="hostname" value="www.myapp.com"/>
    <preference name="Debug" value="false" />
    <preference name="EnableMultiProcess" value="true" />
    <preference name="InspectableWebview" value="false" />
    <icon src="./www/p/img/logoCirclet.png" />

    <platform name="android">
        <preference name="Debug" value="false" />
        <preference name="EnableMultiProcess" value="true" />
        <preference name="android-minSdkVersion" value="21" />
        <preference name="android-targetSdkVersion" value="33" />
        <preference name="android-compileSdkVersion" value="33" />
        <preference name="AndroidWindowSplashScreenAnimatedIcon" value="res/drawable/logoCirclet.png" />
        <config-file target="AndroidManifest.xml" parent="/manifest">
            <uses-permission android:name="android.permission.CAMERA"/>
            <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
            <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
            <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
            <uses-permission android:name="android.permission.INTERNET"/>
        </config-file>
        <edit-config file="app/src/main/AndroidManifest.xml" mode="merge" target="/manifest/application">
            <application android:usesCleartextTraffic="true" />
        </edit-config>
    </platform>

    <!--<icon src="./www/p/img/oaklogb.png" platform="ios" width="57" height="57" density="mdpi" />-->
    <!-- <platform name="android">
      <icon src="./www/p/img/oaklogldpi.png" density="ldpi" />
      <icon src="./www/p/img/oaklogmdpi.png" density="mdpi" />
      <icon src="./www/p/img/oakloghdpi.png" density="hdpi" />
      <icon src="./www/p/img/oaklogxhdpi.png" density="xhdpi" />
      <icon src="./www/p/img/oaklogxxhdpi.png" density="xxhdpi" />
      <icon src="./www/p/img/oaklogxxxhdpi.png" density="xxxhdpi" />
    </platform>-->
</widget>
breautek commented 1 month ago

Thanks, the conifg looks fine and the feature was added in v12, so that should be fine as well.

Are you using any custom webview plugins, such as the ionic webview?

ghevge commented 1 month ago

These are the plugins I'm using:

"plugins": {
      "cordova-plugin-android-permissions": {},
      "cordova-plugin-geolocation": {
        "GPS_REQUIRED": "true"
      },
      "cordova-plugin-inappbrowser": {}
    }
"devDependencies": {
    "cordova-android": "^12.0.0",
    "cordova-plugin-android-permissions": "^1.1.5",
    "cordova-plugin-geolocation": "^4.1.0",
    "cordova-plugin-inappbrowser": "^6.0.0"
  }
ghevge commented 1 month ago

@breautek I've provided above the plugins I'm using. Thanks!

breautek commented 1 month ago

These are the plugins I'm using:

"plugins": {
      "cordova-plugin-android-permissions": {},
      "cordova-plugin-geolocation": {
        "GPS_REQUIRED": "true"
      },
      "cordova-plugin-inappbrowser": {}
    }
"devDependencies": {
    "cordova-android": "^12.0.0",
    "cordova-plugin-android-permissions": "^1.1.5",
    "cordova-plugin-geolocation": "^4.1.0",
    "cordova-plugin-inappbrowser": "^6.0.0"
  }

Can you run cordova plugin ls for reassurance? It should match the plugins as found in package.json but it is possible that plugins are being pulled elsewhere, say if they exists inside the plugins/ folder.

Can you clarify if you're attempting to prevent inspecting the cordova webview, or the in-app browser webview (or both)? Since you've referenced the SystemWebview I've assumed you're only concern about the main cordova webview.

For android in-app browser, it doesn't yet respond to the InspectableWebview preference so it results to the default behaviour, which depends on the browser mode. _blank I think is always disabled, while _system will be always enabled (since it's using the external browser app).

Lastly can you confirm if it works if you use the default option (e.g. do not set InspectableWebview at all). The default behaviour is enable in debug builds and disable in release builds. Therefore if you build and run with --release the app should not be debuggable.

I'm basically trying to lock my app so that users cannot get access to the app code.

Just in case you aren't aware. Users can still get access to your app code even without the inspector. The web assets is plaintext (as required to be read by the webview) and is extractable from the installable APK or AAB file. In otherwords it's not safe to store "secrets" on the client. This isn't exclusive to Cordova, but for any client-side development, but especially so for scripted environments where the code is interpreted like web environments. This is noted here.

ghevge commented 1 month ago

@breautek

cordova plugin ls
cordova-plugin-android-permissions 1.1.5 "Permissions"
cordova-plugin-geolocation 4.1.0 "Geolocation"
cordova-plugin-inappbrowser 6.0.0 "InAppBrowser"

I am trying to to prevent inspecting the cordova webview. Building the cordova app with --release doesn't work either (This is what I've initially tried ). In my current builds i'm setting both the --release and the config.xml param mentioned above.

Just in case you aren't aware. Users can still get access to your app code even without the inspector. The web assets (as required to be read by the webview) and is extractable from the installable APK or AAB file. In otherwords it's not safe to store "secrets" on the client. This isn't exclusive to Cordova, but for any client-side development, but especially so for scripted environments where the code is interpreted like web environments. This is noted here.

Well I was hoping to lock at least the medium knowledgeable users from getting access to the app code by disabling the remote debug. No secrets are stored in the cordova app code. I am aware that any client app can have its code exposed.

If I won't be able to find a solution, I can live with how it is too.

breautek commented 1 month ago

I am trying to to prevent inspecting the cordova webview. Building the cordova app with --release doesn't work either (This is what I've initially tried ). In my current builds i'm setting both the --release and the config.xml param mentioned above.

In my current builds i'm setting both the --release and the config.xml param mentioned above.

if the preference is set at all, it will override the default behaviour, which is to enable on debug. If the preference is set, then it should only enable debugging if it's specifically "true". Otherwise the webview setting is not called.... which I suppose leaves it to the SDK default. (Which I guess is enabled by default on Webview 113 and later if the app is a debug build).

So that might actually explain some situations because Cordova never explicitly sets the flag to false, but this should only affect debug builds that explicitly disable InspectableWebview.

A release build that uses a SDK default should produce a webview that isn't inspectable. For that case, is that something reproducible in a sample reproduction app?

breautek commented 1 month ago

An update, I just tested with my own apps so that I can build a release variant... and I've modified the framework code to easily test different scenarios.

It seems like WebView.setWebContentsDebuggingEnabled(false); is ignored on debug builds and the inspector is always enabled, which might be a bug in the android SDK.

For release builds, not setting setWebContentsDebuggingEnabled seems to correctly default to disable the inspector, or explicitly setting it to false correctly disables the inspector. The inspector is only enabled if WebView.setWebContentsDebuggingEnabled(true); is used. So I haven't reproduced your issue locally.

ghevge commented 1 month ago

I will see when I will find some free time to prune my app down so that I can share it with you. Thanks for now!