Protect against path traversal in the content provider to protect app internal data, make SearchResults accessible from the app only to protect agains attacks trying to extract information by sending Search intents (even though the starting app would not directly be able to access the found data), make sure plugins cannot upgrade their scopes without the user noticing it

This commit is contained in:
Philipp Crocoll
2017-09-18 10:03:31 +02:00
parent 55bea71ec2
commit d4bbde1691
8 changed files with 23 additions and 6 deletions

View File

@@ -38,6 +38,10 @@ namespace keepass2android
// E.g. // E.g.
// 'content://keepass2android.provider/Test.txt' // 'content://keepass2android.provider/Test.txt'
// Take this and build the path to the file // Take this and build the path to the file
//Protect against path traversal with an uri like content://keepass2android.keepass2android.provider/..%2F..%2Fshared_prefs%2FKP2A.Plugin.keepass2android.plugin.qr.xml
if (uri.LastPathSegment.Contains("/"))
throw new Exception("invalid path ");
String fileLocation = Context.CacheDir + File.Separator + AttachmentCacheSubDir + File.Separator String fileLocation = Context.CacheDir + File.Separator + AttachmentCacheSubDir + File.Separator
+ uri.LastPathSegment; + uri.LastPathSegment;

View File

@@ -1,7 +1,8 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="46" android:versionName="0.9.3-release-3" package="keepass2android.keepass2android_debug" android:installLocation="auto"> <manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="46" android:versionName="0.9.3-release-3" package="keepass2android.keepass2android_debug" android:installLocation="auto">
<uses-sdk android:minSdkVersion="14" android:targetSdkVersion="23" /> <uses-sdk android:minSdkVersion="14" android:targetSdkVersion="23" />
<permission android:description="@string/permission_desc" android:icon="@drawable/ic_launcher" android:label="KP2A internal file browsing" android:name="keepass2android.keepass2android_debug.permission.KP2aInternalFileBrowsing" android:protectionLevel="signature" /> <permission android:description="@string/permission_desc" android:icon="@drawable/ic_notify_locked" android:label="KP2A internal file browsing" android:name="keepass2android.keepass2android_debug.permission.KP2aInternalFileBrowsing" android:protectionLevel="signature" />
<permission android:description="@string/permission_desc2" android:icon="@drawable/ic_notify_locked" android:label="KP2A entry search" android:name="keepass2android.keepass2android_debug.permission.KP2aInternalSearch" android:protectionLevel="signature" />
<application android:label="keepass2android" android:icon="@drawable/ic_launcher"> <application android:label="keepass2android" android:icon="@drawable/ic_launcher">
<activity android:name="com.dropbox.core.android.AuthActivity" android:launchMode="singleTask" android:configChanges="orientation|keyboard"> <activity android:name="com.dropbox.core.android.AuthActivity" android:launchMode="singleTask" android:configChanges="orientation|keyboard">

View File

@@ -6,6 +6,8 @@
android:installLocation="auto"> android:installLocation="auto">
<uses-sdk android:minSdkVersion="14" android:targetSdkVersion="23" /> <uses-sdk android:minSdkVersion="14" android:targetSdkVersion="23" />
<permission android:description="@string/permission_desc" android:icon="@drawable/ic_launcher_online" android:label="KP2A internal file browsing" android:name="keepass2android.keepass2android.permission.KP2aInternalFileBrowsing" android:protectionLevel="signature" /> <permission android:description="@string/permission_desc" android:icon="@drawable/ic_launcher_online" android:label="KP2A internal file browsing" android:name="keepass2android.keepass2android.permission.KP2aInternalFileBrowsing" android:protectionLevel="signature" />
<permission android:description="@string/permission_desc2" android:icon="@drawable/ic_launcher_online" android:label="KP2A entry search" android:name="keepass2android.keepass2android.permission.KP2aInternalSearch" android:protectionLevel="signature" />
<application android:label="keepass2android" android:icon="@drawable/ic_launcher_online"> <application android:label="keepass2android" android:icon="@drawable/ic_launcher_online">
<activity android:name="com.dropbox.core.android.AuthActivity" android:launchMode="singleTask" android:configChanges="orientation|keyboard"> <activity android:name="com.dropbox.core.android.AuthActivity" android:launchMode="singleTask" android:configChanges="orientation|keyboard">
<intent-filter> <intent-filter>
@@ -146,6 +148,7 @@
<uses-permission android:name="android.permission.USE_CREDENTIALS" /> <uses-permission android:name="android.permission.USE_CREDENTIALS" />
<uses-permission android:name="android.permission.MANAGE_ACCOUNTS" /> <uses-permission android:name="android.permission.MANAGE_ACCOUNTS" />
<uses-permission android:name="keepass2android.keepass2android.permission.KP2aInternalFileBrowsing" /> <uses-permission android:name="keepass2android.keepass2android.permission.KP2aInternalFileBrowsing" />
<uses-permission android:name="keepass2android.keepass2android_debug.permission.KP2aInternalSearch" />
<uses-permission android:name="android.permission.USE_FINGERPRINT" /> <uses-permission android:name="android.permission.USE_FINGERPRINT" />
<uses-permission android:name="android.permission.BIND_ACCESSIBILITY_SERVICE" /> <uses-permission android:name="android.permission.BIND_ACCESSIBILITY_SERVICE" />

View File

@@ -5,6 +5,7 @@
package="keepass2android.keepass2android_nonet" package="keepass2android.keepass2android_nonet"
android:installLocation="auto"> android:installLocation="auto">
<uses-sdk android:minSdkVersion="14" android:targetSdkVersion="23" /> <uses-sdk android:minSdkVersion="14" android:targetSdkVersion="23" />
<permission android:description="@string/permission_desc2" android:icon="@drawable/ic_launcher_online" android:label="KP2A entry search" android:name="keepass2android.keepass2android_nonet.permission.KP2aInternalSearch" android:protectionLevel="signature" />
<application android:label="keepass2android" android:icon="@drawable/ic_launcher_offline"> <application android:label="keepass2android" android:icon="@drawable/ic_launcher_offline">
<provider android:name="group.pals.android.lib.ui.filechooser.providers.localfile.LocalFileProvider" android:authorities="keepass2android.keepass2android_nonet.android-filechooser.localfile" android:exported="false" /> <provider android:name="group.pals.android.lib.ui.filechooser.providers.localfile.LocalFileProvider" android:authorities="keepass2android.keepass2android_nonet.android-filechooser.localfile" android:exported="false" />
<provider android:name="group.pals.android.lib.ui.filechooser.providers.history.HistoryProvider" android:authorities="keepass2android.keepass2android_nonet.android-filechooser.history" android:exported="false" /> <provider android:name="group.pals.android.lib.ui.filechooser.providers.history.HistoryProvider" android:authorities="keepass2android.keepass2android_nonet.android-filechooser.history" android:exported="false" />
@@ -126,6 +127,8 @@
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.USE_FINGERPRINT" /> <uses-permission android:name="android.permission.USE_FINGERPRINT" />
<uses-permission android:name="android.permission.BIND_ACCESSIBILITY_SERVICE" /> <uses-permission android:name="android.permission.BIND_ACCESSIBILITY_SERVICE" />
<uses-permission android:name="keepass2android.keepass2android.permission.KP2aInternalFileBrowsing" />
<uses-permission android:name="keepass2android.keepass2android_debug.permission.KP2aInternalSearch" />
<!-- Samsung Pass permission --> <!-- Samsung Pass permission -->
<uses-permission android:name="com.samsung.android.providers.context.permission.WRITE_USE_APP_FEATURE_SURVEY" /> <uses-permission android:name="com.samsung.android.providers.context.permission.WRITE_USE_APP_FEATURE_SURVEY" />
</manifest> </manifest>

View File

@@ -45,8 +45,10 @@
<string name="oi_filemanager_market">market://details?id=org.openintents.filemanager</string> <string name="oi_filemanager_market">market://details?id=org.openintents.filemanager</string>
<string name="oi_filemanager_web">https://openintents.googlecode.com/files/FileManager-2.0.2.apk</string> <string name="oi_filemanager_web">https://openintents.googlecode.com/files/FileManager-2.0.2.apk</string>
<string name="permission_desc">KP2A Internal File Browsing Permission</string> <string name="permission_desc">KP2A Internal File Browsing Permission</string>
<string name="permission_desc2">KP2A Search</string>
<!-- Preference settings -->
<!-- Preference settings -->
<string name="algorithm_key">algorithm</string> <string name="algorithm_key">algorithm</string>
<string name="app_key">app</string> <string name="app_key">app</string>
<string name="app_timeout_key">app_timeout_key</string> <string name="app_timeout_key">app_timeout_key</string>

View File

@@ -132,7 +132,7 @@ namespace keepass2android
i.PutExtra(Strings.ExtraSender, _ctx.PackageName); i.PutExtra(Strings.ExtraSender, _ctx.PackageName);
i.PutExtra(Strings.ExtraRequestToken, GetPreferencesForPlugin(pluginPackage).GetString(_requesttoken, null)); i.PutExtra(Strings.ExtraRequestToken, GetPreferencesForPlugin(pluginPackage).GetString(_requesttoken, null));
_ctx.SendBroadcast(i); _ctx.SendBroadcast(i);
StorePlugin(pluginPackage, null, GetPluginScopes(pluginPackage)); StorePlugin(pluginPackage, null, new List<string>());
} }
} }

View File

@@ -70,7 +70,7 @@ namespace keepass2android
PluginHost.TriggerRequest(this, _pluginPackageName, new PluginDatabase(this)); PluginHost.TriggerRequest(this, _pluginPackageName, new PluginDatabase(this));
//show the buttons instead of the checkbox //show the buttons instead of the checkbox
_checkbox.Visibility = ViewStates.Invisible; _checkbox.Visibility = ViewStates.Invisible;
FindViewById(Resource.Id.accept_button).Visibility = ViewStates.Visible; FindViewById(Resource.Id.accept_button).Visibility = ViewStates.Invisible; //show them only after access is requested
FindViewById(Resource.Id.deny_button).Visibility = ViewStates.Visible; FindViewById(Resource.Id.deny_button).Visibility = ViewStates.Visible;
FindViewById(Resource.Id.accept_button).Click += delegate(object sender, EventArgs args) FindViewById(Resource.Id.accept_button).Click += delegate(object sender, EventArgs args)
@@ -86,6 +86,9 @@ namespace keepass2android
SetResult(Result.Canceled); SetResult(Result.Canceled);
Finish(); Finish();
}; };
//in case the plugin requested scopes previously, make sure we display them
UpdateView();
} }
else else
{ {
@@ -100,6 +103,7 @@ namespace keepass2android
{ {
if (args.Package == _pluginPackageName) if (args.Package == _pluginPackageName)
{ {
FindViewById(Resource.Id.accept_button).Visibility = ViewStates.Visible;
UpdateView(); UpdateView();
} }
} }

View File

@@ -29,7 +29,7 @@ namespace keepass2android.search
/// <summary> /// <summary>
/// Activity to show search results /// Activity to show search results
/// </summary> /// </summary>
[Activity(Label = "@string/app_name", Theme = "@style/MyTheme_ActionBar", LaunchMode = Android.Content.PM.LaunchMode.SingleTop)] [Activity(Label = "@string/app_name", Theme = "@style/MyTheme_ActionBar", LaunchMode = Android.Content.PM.LaunchMode.SingleTop, Permission="keepass2android."+AppNames.PackagePart+".permission.KP2aInternalSearch")]
#if NoNet #if NoNet
[MetaData("android.app.searchable", Resource = "@xml/searchable_offline")] [MetaData("android.app.searchable", Resource = "@xml/searchable_offline")]
#else #else