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.
// 'content://keepass2android.provider/Test.txt'
// 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
+ uri.LastPathSegment;

View File

@@ -1,7 +1,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">
<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">
<activity android:name="com.dropbox.core.android.AuthActivity" android:launchMode="singleTask" android:configChanges="orientation|keyboard">

View File

@@ -6,6 +6,8 @@
android:installLocation="auto">
<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_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">
<activity android:name="com.dropbox.core.android.AuthActivity" android:launchMode="singleTask" android:configChanges="orientation|keyboard">
<intent-filter>
@@ -146,6 +148,7 @@
<uses-permission android:name="android.permission.USE_CREDENTIALS" />
<uses-permission android:name="android.permission.MANAGE_ACCOUNTS" />
<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.BIND_ACCESSIBILITY_SERVICE" />

View File

@@ -5,6 +5,7 @@
package="keepass2android.keepass2android_nonet"
android:installLocation="auto">
<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">
<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" />
@@ -126,6 +127,8 @@
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.USE_FINGERPRINT" />
<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 -->
<uses-permission android:name="com.samsung.android.providers.context.permission.WRITE_USE_APP_FEATURE_SURVEY" />
</manifest>

View File

@@ -45,8 +45,10 @@
<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="permission_desc">KP2A Internal File Browsing Permission</string>
<!-- Preference settings -->
<string name="permission_desc2">KP2A Search</string>
<!-- Preference settings -->
<string name="algorithm_key">algorithm</string>
<string name="app_key">app</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.ExtraRequestToken, GetPreferencesForPlugin(pluginPackage).GetString(_requesttoken, null));
_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));
//show the buttons instead of the checkbox
_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.accept_button).Click += delegate(object sender, EventArgs args)
@@ -86,6 +86,9 @@ namespace keepass2android
SetResult(Result.Canceled);
Finish();
};
//in case the plugin requested scopes previously, make sure we display them
UpdateView();
}
else
{
@@ -100,6 +103,7 @@ namespace keepass2android
{
if (args.Package == _pluginPackageName)
{
FindViewById(Resource.Id.accept_button).Visibility = ViewStates.Visible;
UpdateView();
}
}

View File

@@ -29,7 +29,7 @@ namespace keepass2android.search
/// <summary>
/// Activity to show search results
/// </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
[MetaData("android.app.searchable", Resource = "@xml/searchable_offline")]
#else