ページ

2013/05/04

[Android]パーミッションの改竄を検出する

アプリケーションの改竄でたまに聞くのが広告を消すために
INTERNET パーミッションを削るというもの。
広告が出るのはうざったいだろうけど削られてたらメシが食えないのでチェックします。
後は怪しいパーミッションを削って使うという用途もあるらしいけど
僕は怪しいパーミッションを取らないので関係ない話。
怪しいパーミッション入りのアプリなんか削る前に使うのやめた方が良いような。

参考
visible true: Androidアプリケーションのパーミッション改竄を検知するスニペット
/**
 * パーミッションが改竄されていないかチェックする
 * 
 * @param context
 * @param permissions
 *        想定するパーミッション
 * @return
 */
public static List<String> diffPermissions(Context context, String[] permissions){
    return diffPermissions(context, new ArrayList<String>(Arrays.asList(permissions)));
}

/**
 * パーミッションが改竄されていないかチェックする
 * 
 * @param context
 * @param permissions
 *        想定するパーミッション
 * @return
 */
private static List<String> diffPermissions(Context context, List<String> permissions){
    if(context == null || permissions == null){
        return new ArrayList<String>();
    }
    try{
        PackageManager pm = context.getPackageManager();
        PackageInfo packageInfo = pm.getPackageInfo(context.getPackageName(), PackageManager.GET_PERMISSIONS);
        String[] requestedPermissions = packageInfo.requestedPermissions;
        if(requestedPermissions != null){
            for(String permission : requestedPermissions){
                if(permissions.contains(permission)){
                    permissions.remove(permission);
                }else{
                    permissions.add(permission);
                }
            }
        }
        return permissions;
    }catch(NameNotFoundException e){
        e.printStackTrace();
    }
    return new ArrayList<String>();
}
メソッド名を diffPermissions に変更。
AndroidManifest.xml と呼び出しの差分をとるように変更。
null を返している部分で空の ArrayList を返すように変更。
String[] permissions = new String[]{ permission.INTERNET, permission.WRITE_EXTERNAL_STORAGE };
if(!diffPermissions(this, permissions).isEmpty()){
    // コードと AndroidManifest.xml に差分がある
}
nullチェックをなくすのと差分を取って将来のパーミッション追加による差分の検知をするように変更。
後から INTERNET パーミッションを追加してコード側に変更しないでリリースして、
そこから INTERNET パーミッションを削られたら検知できないので差分を検知できたほうが便利なはず。
add して差分を検出するのは主に開発者の変更漏れ防止のためなので別になくてもいいけど。