Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to verify installed application in runtime to prevent phishing attack?

I have a payment application in my device, my application connect to that application's service to get a pending-intent for launch payment activity and then listen to result in onActivityResult() method.(similar to In-App-Purchase scenario)

I set package name for payment intent. but you know, it's not guarantee payment application is trusted. if some one install fake application through unknown source with same package name and same aidl-service implementation then it can give me pending-intent and phishing my user info.

I verify payment result with some mechanism and that only safe my application from fake payment result but my application user enter their data in phisher application. (this paragraph say my problem is not trusting response of payment application, my problem is trusting payment application before launch their activity)

I know some approach that i can check other application signature and public key. if Android OS guarantee that public key and signature is read-only and matched for installed application, i can rely on that and check public key of payment application before sending intent to that.but i guess those is not ready-only and check match only in installing.

any suggestion (similar or different approach) for prevent phishing attack ?

Updated: about 50% of application's user install application from my corporation website directly (Unknown-Source).

like image 637
Mojtaba Asg Avatar asked Apr 06 '16 07:04

Mojtaba Asg


1 Answers

What you are looking for is a combination of app signatures and permissions. To clarify, this will only work if you own both applications and can sign them with the same key.

According to the docs:

"signature": A permission that the system grants only if the requesting application is signed with the same certificate as the application that declared the permission. If the certificates match, the system automatically grants the permission without notifying the user or asking for the user's explicit approval.

This means that the Android OS itself enforces that the signatures of the two applications must match in order for the permission to be granted. This is what you want, since the permission will not be granted if someone tries to spoof your app. Since they cannot possibly sign their app with your private key, there is no way they can forge your signature.

To create a permission, in your Manifest for the application providing the payment service, you should declare it like this:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.myapp.paymentservice" >

    <permission android:name="com.example.myapp.paymentservice.permission.PAYMENT"
        android:label="@string/permission_payment_label"
        android:description="@string/permission_payment_description"
        android:protectionLevel="signature" />
    ...

Then, when you declare your service, protect it with the android:permission that you declared:

    ...
    <service android:name=".BillingService"
        android:permission="com.example.myapp.paymentservice.permission.PAYMENT" />
</manifest>

Finally, you declare in your client application(s) that you use that permission:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.myapp.clientapp" >

    <uses-permission android:name="com.example.myapp.paymentservice.permission.PAYMENT" />
    ...
</manifest>

As long as the two applications are signed with the same signing key, the OS will grant the permission. For more information, check out http://developer.android.com/guide/topics/security/permissions.html#defining and http://developer.android.com/guide/topics/manifest/permission-element.html

like image 54
Jschools Avatar answered Oct 12 '22 22:10

Jschools