メルカリとソウゾウアプリの アプリ間連携の仕組み in 2017 summer

E77b6a5f919f7366d94f21eee9a014f5?s=47 operandoOS
August 25, 2017

メルカリとソウゾウアプリの アプリ間連携の仕組み in 2017 summer

メルカリとソウゾウアプリの
アプリ間連携の仕組み
in 2017 summer

Souzoh Android Talk
https://mercari.connpass.com/event/63552/

Application Interoperability Sample
https://github.com/operando/Application-Interoperability-Sample

Android アプリのセキュア設計・セキュアコーディングガイド
https://www.jssec.org/dl/android_securecoding.pdf

「メルカリとソウゾウアプリのアプリ間連携の仕組み in 2017 summer」のセキュアコーディングガイドに関する補足
http://hack-it-iron.hatenablog.com/entry/2017/08/28/101615

E77b6a5f919f7366d94f21eee9a014f5?s=128

operandoOS

August 25, 2017
Tweet

Transcript

  1. ϝϧΧϦͱι΢κ΢ΞϓϦͷ
 ΞϓϦؒ࿈ܞͷ࢓૊Έ
 in 2017 summer Souzoh Android Talk #1

  2. About Me Shinobu Okano @operandoOS Mercari, Inc. Souzoh, Inc.

  3. Compassͷࣗݾ঺հ • Ͳ͏΋ɺAndroidνʔϜͷ΍͍͖ͬͯʂͰ͢ • ਏͦ͏ͳਓΛॿ͚Δ܎Ͱ͢ • ϓϩμΫτͷ੒ՌΛউखʹOSSʹ͢Δͷ͕ಘҙͰ͢ʂ • ౔೔͸ळ༿ݪͷελόʹ͍·͢(ݟ͚ͭͨΒ࿩͔͚ͯ͠΍͍ͬͯͩ͘͞...) •

    ϛελʔυʔφπɺήʔϜɺຊ େ޷͖Ͱ͢ʂ • ϝϧΧϦ → ϝϧΧϦ Ξος → ϝϧΧϦ Χ΢ϧ
  4. ΞϓϦؒ࿈ܞͱ͸ʁ • ΞϓϦA͔ΒΞϓϦBͷػೳΛݺͼग़͢ • ͸͍ɺΘ͔Γ·͢ɻIntentͰ͢Ͷ • ϝϧΧϦ Χ΢ϧ͔ΒϝϧΧϦͷग़඼Ұཡը໘
 ʹભҠ͢Δ

  5. ΞϓϦؒ࿈ܞͱ͸ʁ

  6. ΞϓϦؒ࿈ܞͱ͸ʁ • AΞϓϦ͔Βऔಘͨ͠৘ใΛΞϓϦBͰ࢖༻ͯ͠
 ϢʔβʹػೳΛఏڙ͢Δ • ϝϧΧϦ͕อ࣋ͯ͠Δͷ৘ใΛϝϧΧϦ Χ΢ϧ͕
 औಘͯ͠γʔϜϨεʹϩάΠϯ • ΞΧ΢ϯτ࿈ܞɺID࿈ܞ

  7. ΞϓϦؒ࿈ܞͱ͸ʁ

  8. ϝϧΧϦͱι΢κ΢ΞϓϦͷΞϓϦؒ࿈ܞ • ηΧϯυύʔςΟʔ(ࣗࣾΞϓϦؒ)Ͱͷ࿈ܞ͕ϝΠϯ • αʔυύʔςΟʔ޲͚ͷ࿈ܞ͸·ͣ͸΍Βͳ͍લఏ

  9. ͜Ε͔Β࿩͢͜ͱ • ͜ʔΏʔ࢓૊ΈΛ࡞ΔͨΊͷ࢓૊Έ͸Androidʹෳ਺͋Δ • ͦͷதͰ͍͔ͭ͘ݕ౼ͨ͠΋ͷͱ࣮ࡍʹ
 ࢖͍ͬͯΔ΋ͷΛ͝঺հ͢Δ͍ͧʂ • ଞʹ΋৭ʑ͋Γͦ͏͔ͩΒɺ஌ݟ͋Ε͹
 ڭ͍͑ͯͩ͘͞ʂ

  10. ࿩͞ͳ͍͜ͱ • ओʹAndroidΞϓϦଆͷ࢓૊Έͷ঺հͳͷͰ
 όοΫΤϯυͷ࢓૊Έ͸࿩͠·ͤΜ • mercari Tech Conf 2017ʹظ଴ʂ •

    https://techconf.mercari.com/2017/
  11. ஫ҙ఺ • ࿈ܞͷͨΊͷ࣮૷Λ͍͔ͭ͘ͷͤͯ·͕͢ɺ
 ηΩϡϦςΟతͳͱ͜Ζ͸࣌ؒͷؔ܎্୺ં͍ͬͯ·͢ • ঺հ͢Δํ๏౳ͰΞϓϦؒ࿈ܞΛ࣮૷͢Δ৔߹͸ɺ
 ඞͣAndroid ηΩϡΞίʔσΟϯάΨΠυΛ͓ಡΈ͍ͩ͘͞ʂ • https://www.jssec.org/dl/

    android_securecoding.pdf
  12. ΞϓϦ͕อ࣋ͯ͠Δ৘ใΛ
 ΞϓϦؒ࿈ܞͰ΍ΓͱΓ͢Δ

  13. sharedUserId

  14. sharedUserId • AndroidͰ͸ΞϓϦຖʹϢʔβ ID(uid)ׂ͕Γ౰ͯΒΕΔ • sharedUserIdͷػೳΛ࢖༻͢ΔͱҟͳΔΞϓϦʹಉ͡ uidΛׂΓ౰ͯΔ͜ͱ͕Ͱ͖Δ • ಉ͡uidʹ͢Δͱޓ͍ͷΞϓϦͰ࡞੒ͨϑΝΠϧͷ
 Φʔφʔ͕ಉ͡ʹͳΔ

    • Αͬͯɺ࡞੒ͨ͠ϑΝΠϧ͸͓ޓ͍ʹಡΈॻ͖ՄೳʹͳΔ
  15. sharedUserId • ಉ͡uidΛׂΓ౰ͯΔʹ͸͓ޓ͍ͷΞϓϦʹ
 ҎԼͷ৚͕݅ඞཁ 1. ಉҰͷূ໌ॻͰॺ໊͍ͯ͠Δ 2. AndroidManaifest.xml಺Ͱಉ͡ android:sharedUserIdΛࢦఆ͍ͯ͠Δ

  16. <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.os.operando.application.interoperability.sample" android:sharedUserId="app.shareduserid"> .... </manifest> <?xml

    version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.shareduserid_app" android:sharedUserId="app.shareduserid"> .... </manifest> AndroidManifest.xml
  17. sharedUserId Demo AΞϓϦͰ࡞੒ͨ͠SharedPreferencesΛ BΞϓϦͰಡΈࠐΈ஋Λऔಘ͢Δ

  18. sharedUserId // AΞϓϦ(com.os.operando.application.interoperability.sample) getSharedPreferences("master_app", MODE_PRIVATE).edit().putInt("int", 1).apply(); // BΞϓϦ(com.example.shareduserid_app) // ஋͕औಘͰ͖Δ

    try { Context c = createPackageContext(“com.os.operando.application.interoperability.sample", CONTEXT_RESTRICTED); int i = c.getSharedPreferences(“master_app”, MODE_PRIVATE).getInt("int", 0); Log.d(TAG, i + ""); // 1 } catch (PackageManager.NameNotFoundException e) { e.printStackTrace(); }
  19. sharedUserIdΛ࢖ͬͯΞϓϦؒͰ
 ৘ใΛڞ༗͢Δ • ࣮૷͸؆୯ • ޓ͍ͷΞϓϦ͕࡞੒ͨ͠ϑΝΠϧಡΈॻ͖͠์୊

  20. ͕͔ͩ͠͠... • ࡞੒ͨ͠ϑΝΠϧͳΒͳΜͰ΋ڞ༗Ͱ͖ΔͷͰɺ৭ΜͳϑΝΠϧ ΛಡΈॻ͖࢝͠ΊΔةݥੑ͕͋Δ • ϝϧΧϦͱι΢κ΢ΞϓϦಉ࢜ͷ༻్ͱͯ͠͸ڞ༗͗ͯ͢͠Δ • ڞ༗Ͱ͖Δ৘ใ͸੍ݶ͢Δ΄͏͕؅ཧ͠΍͍͢ • ยํͷΞϓϦʹ੬ऑੑ͕͋Δͱޓ͍ʹ΍ΒΕͯ·͏ةݥੑ΋͋Δ

    • ݱঢ়Ͱ͸࢖༻͠ͳ͍͜ͱʹͨ͠
  21. AccountManager

  22. AccountManager • αʔϏε͝ͱͷϢʔβʔ৘ใʢΞΧ΢ϯτʣ Λ؅ཧ͢Δ࢓૊Έ • ઃఆͷΞΧ΢ϯτͷͱ͜ΖͰ؅ཧ͞ΕͯΔ͋Ε • ෳ਺ΞϓϦͰೝূ৘ใΛڞ༗͢Δ͜ͱ΋Ͱ͖Δ • ͪΌΜͱཧղ͢Ε͹ͱͯ΋ศརͳ࢓૊Έ

  23. ͕͔ͩ͠͠ • ΅͘ʹ͸ͪΐͬͱ೉͍͠Ͱ͢ɺAndroidઌੜ... • ݸਓతʹ͸ͪΌΜͱཧղͯ͠࢖͏ͷ͕ͪΐͬͱ೉͍͠࢓૊Έͳҹ৅ • ϝϧΧϦͱι΢κ΢ΞϓϦಉ࢜ͷ࿈ܞʹͯ͠͸ɺ΍Γ͍ͨ͜ͱʹ
 ରͯ͠ϋΠεϖοΫ͗͢Δ • த్൒୺ʹ࣮૷͢Δͱ੬ऑੑʹͳΔ͠ɺෛ࠴ʹ΋ͳΔ

    • αʔυύʔςΟʔͱͷ࿈ܞ·Ͱߟ͑ΔͳΒAccountManager͕ྑͦ͞͏
  24. AccountManagerͷࢀߟࢿྉ • Android ʹ͓͚ΔΞΧ΢ϯτ؅ཧ • http://tech.gunosy.io/entry/android-accounts • Android ͷΞΧ΢ϯτϚωʔδϟ (AccountManager)

    ͷ֓આ • http://vividcode.hatenablog.com/entry/ android/account-manager
  25. ContentProvider

  26. ContentProvider • ͬ͘͟Γ͍͏ͱΞϓϦؒͰσʔλΛڞ༗͢ΔͨΊͷίϯϙʔωϯτ • DBΛ࢖༻͢ΔΑ͏ͳઃܭʹͳͬͯΔ • ੲͳʹ͔ͱηΩϡϦςΟपΓͰΑ͘ొ৔ͨ͠ίϯϙʔωϯτ • ઃఆ࣍ୈͰͲΜͳΞϓϦ͔ΒͰ΋ಡΈॻ͖Ͱ͖Δ •

    ઃఆ࣍ୈͰಛఆͷΞϓϦ͚ͩಡΈॻ͖Ͱ͖ΔΑ͏ʹ͢Δ͜ͱ΋Ͱ͖Δ
  27. Permission • ΞϓϦ͝ͱʹಠࣗͷPermissionΛ࡞Δ͜ͱ͕Ͱ͖Δ • AndroidManifest.xmlʹఆٛ͢Δ • protectionLevelΛsignatureʹ͢Δ͜ͱͰɺಉ͡ॺ໊Λ࣋ͭΞϓϦ ʹͷΈPermissionͷ࢖༻ΛڐՄ͢Δ͜ͱ͕Ͱ͖Δ • ຊࢿྉ಺ͰͷSignature

    Permission͸͜ΕΛҙຯ͢Δ • https://developer.android.com/guide/topics/manifest/ permission-element.html#plevel
  28. Signature Permissionͷఆٛ <manifest xmlns:android="http://schemas.android.com/apk/res/ android"> <permission android:name="com.kouzoh.mercari.id.permission.READ" android:protectionLevel="signature" /> ...

    </manifest>
  29. Android Component + Permission • Androidͷίϯϙʔωϯτʹ͸PermissionΛࢦఆͰ͖Δ • ίϯϙʔωϯτΛར༻͢ΔΞϓϦʹPermissionͷఆٛΛཁٻͰ͖Δ • ίϯϙʔωϯτͷఏڙଆ͕ΞϓϦಠࣗͷSignature

    PermissionΛ
 ఆٛ͢Δ • ίϯϙʔωϯτͷఏڙଆ͸ٻΊΔPermission͕ར༻ଆʹ
 ఆٛ͞Ε͍ͯͳ͚Ε͹ίϯϙʔωϯτͷ࢖༻ΛෆՄೳʹͰ͖Δ
  30. ContentProvider + Permission • ContentProvider΋ίϯϙʔωϯτͳͷͰPermission͕ࢦఆͰ͖Δ • readPermissionଐੑͱwritePermissionଐੑ͕ଘࡏ͢Δ • ಡΈॻ͖ͲͪΒͱ΋ಉ͡Permissionͷ͍ͨ͠৔߹͸permissionଐੑΛ࢖͏ •

    permissionଐੑʹΞϓϦಠࣗͷSignature PermissionΛࢦఆ͢Ε͹
 ಉ͡ॺ໊Λ࣋ͭΞϓϦͰ͔͠ಡΈग़ͤͳ͍ContentProvider͕࡞ΕΔ • ଞͷίϯϙʔωϯτ(ActivityͳͲ)΋ಉ༷ͷखॱͰಉ͜͡ͱ͕Ͱ͖Δ
  31. <!-- ίϯϙʔωϯτ(ContentProvider)Λఏڙ͢Δଆ ྫ͑͹ɺϝϧΧϦ --> <provider android:name=".auth.IdContentProvider" android:authorities="com.kouzoh.mercari.id" android:exported="true" android:permission="com.kouzoh.mercari.id.permission.READ" />

    ContentProvider + Permission
  32. Uses Signature Permission <!-- ίϯϙʔωϯτ(ContentProvider)Λར༻͢Δଆ ྫ͑͹ɺϝϧΧϦ Χ΢ϧ --> <manifest xmlns:android="http://schemas.android.com/apk/res/

    android"> <uses-permission android:name="com.kouzoh.mercari.id.permission.READ" /> </manifest>
  33. ContentProvider + Permission • ͜ͷ࢓૊ΈͰηΩϡΞʹΞϓϦؒͰσʔλΛ
 ڞ༗͢Δ͜ͱ͕Ͱ͖Δ • ΍ͬͨͧʂ • ϝϧΧϦͱι΢κ΢ΞϓϦͷΞΧ΢ϯτ࿈ܞ͸

    ͜ͷ࢓૊ΈΛ࠾༻ͯ͠·͢
  34. ͕͔ͩ͠͠ • Signature PermissionʹҰ෦ ࠔͬͨ໰୊͕ଘࡏ͢Δ • Android 5.0ະຬͩͱɺPermission ఆٛઌউͪ໰୊͕͋Δ •

    ͔֬5.0ະຬͩͬͨؾ͕͢Δ͚Ͳιʔε͕ݟ͔ͭΒͳ͔ͬͨͷͰόʔδϣϯ
 ҙࣝ͠ͳ͍΄͏͕͍͍ • protectionLevel͕signatureͷPermissionΛఆٛ͢ΔલʹɺprotectionLevel͕ ऑ͍(normalͱ͔)ಉ໊ͷPermission͕ఆٛ͞Εͯ͠·͏ͱɺಉ͡ॺ໊Λ࣋ͨͳ͍ ΞϓϦ͔ΒͰ΋ίϯϙʔωϯτ͕ݺͼग़ͤΔ • ୺຤಺ʹطʹಉ໊ͷpermissionͷఆ͕ٛ͋Δ৔߹ɺޙ͔Βఆٛ͞ΕΔ৘ใ͕
 ্ॻ͖͞Εͳ͍໰୊͕͋Δ
  35. ಠࣗఆٛ Signature PermissionΛճආ Ͱ͖ΔAndroid OSͷಛੑͱͦͷରࡦ • ৄࡉ͸ηΩϡΞίʔσΟϯάΨΠυͷ ʮ5.2.3.1. ಠࣗఆٛ Signature

    PermissionΛճ ආͰ͖ΔAndroid OSͷಛੑͱͦͷରࡦʯΛࢀর • https://www.jssec.org/report/ securecoding.html • ରࡦ΋ͪΌΜͱಡΜͰͶʂ
  36. ઈରηΩϡΞίʔσΟϯά ΨΠυಡΜͰ͍ͩ͘͞ʂ
 ͓ئ͍͠·͢ʂ

  37. ΞϓϦؒ ػೳ࿈ܞ

  38. IntentͰ͠ΐʁ؆୯؆୯

  39. ͦ͏ࢥ͏Ͱ͠ΐʁ

  40. ผͷΞϓϦͷػೳΛݺͼग़͢ • ผΞϓϦͷίϯϙʔωϯτΛ໌ࣔతIntent͢Δͷ͸஍ຯʹ೉͍͠ • ݺͼग़͠ઌͷΞϓϦͷίϯϙʔωϯτ໊͕มΘͬͨΒݺͼग़ͤͳ͍ • ҉໧తIntent͸ԣऔΓ͞ΕΔةݥੑ͕͋Δ • Intent Filterఆٛ͢Ε͹୭Ͱ΋ϑοΫͰ͖Δ

    • Ϣʔβ͕ޡͬͯมͳΞϓϦʹIntentΛ౉ͯ͠͠·͏ةݥੑ͕͋Δ • ͦΕͧΕͷIntentͰΞϓϦؒ࿈ܞΛ͢Δ৔߹ʹͲ͏͢Δ͔
  41. ໌ࣔతIntentͰ࿈ܞ • ϝϧΧϦɾι΢κ΢ΞϓϦͷΑ͏ʹࣗࣾΞϓϦಉ࢜ͷݺͼग़͠
 ͳΒܾ·Γ͸࡞ΕΔ • ϝϧΧϦͷಛఆͷActivityΛ໌ࣔతʹݺͼग़͍ͨ͠ʂ • ݺͼग़͍ͨ͠Activity͸Activity AliasͰఆٛ͢Δͷ͕ྑͦ͞͏ •

    ࣮ࡍͷActivity໊͕มߋ͞Εͯ΋େৎ෉ʂ • ࣗࣾΞϓϦҎ֎͔Βݺͼग़͞Εͨ͘ͳ͔ͬͨΒίϯϙʔωϯτʹ Signature PermissionΛ͚ͭΔ
  42. ໌ࣔతIntentͰ࿈ܞ ػೳఏڙଆ <!-- ػೳఏڙଆ --> <activity android:name=".SettingActivity" android:label="@string/title_activity_setting" android:theme="@style/AppTheme.NoActionBar" />

    <activity-alias android:name="com.os.operando.application.interoperability.sample.S ettingAliasActivity" android:exported="true" android:permission="master.app.OPEN" android:targetActivity=".SettingActivity" />
  43. ໌ࣔతIntentͰ࿈ܞ ར༻ଆ // ར༻ଆ Intent i = new Intent(); i.setComponent(new

    ComponentName("com.os.operando.sample", “com.os.operando.sample.SettingAliasActivity")); startActivity(i);
  44. ҉໧తIntent??Ͱ࿈ܞ • URI = Deep LinkͰػೳΛݺͼग़͢ • Intent#setPackageϝιουͰ໌ࣔతʹͲͷΞϓϦʹରͯ͠ͷ Intentͳͷ͔Λࢦఆ͢Δ •

    ಉ͡Intent FilterΛఆٛͨ͠ΞϓϦ͕͋ͬͯ΋ϑοΫ͞Εͳ͍ • https://developer.android.com/reference/android/content/ Intent.html#setPackage(java.lang.String)
  45. ҉໧తIntent??Ͱ࿈ܞ ػೳఏڙଆ <activity android:name=".SampleActivity"> <intent-filter> <data android:host="sample" android:scheme="https" /> <action

    android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.BROWSABLE" /> </intent-filter> </activity>
  46. ҉໧తIntent??Ͱ࿈ܞ ར༻ଆ // ύοέʔδ໊Λ໌ࣔతʹઃఆ͢Δ Intent i = new Intent(Intent.ACTION_VIEW, Uri.parse("https://sample"));

    i.setPackage("com.os.operando.sample"); startActivity(i);
  47. ޾ͤ ☺

  48. ͕͔ͩ͠͠ • IntentઌͷΞϓϦ͕ύοέʔδ໊ಉ͡ͳِ෺ΞϓϦ ͩͱࠔΔ • ΋͠IntentʹηΩϡΞͳ৘ใΛͷͤͯͨ৔߹౪Έऔ ΒΕΔةݥੑ͕͋Δ • ͦ͏Ͱͳͯ͘΋ِ෺ΞϓϦ͕ಈ͍ͯ͠·͏ͷ͸ࠔΔ

  49. • ࿈ܞઌ͕ࣗࣾΞϓϦ + ಉҰॺ໊ͷΞϓϦΛର৅ͱͯ͠Δ͜ͱ͕લఏͷ৔߹ • ࿈ܞઌͷΞϓϦͷॺ໊͕ࣗࣾͷॺ໊͔Ͳ͏͔Λௐ΂Δ • PackageManager#getPackageInfoͷflagʹ PackageManager.GET_SIGNATURESΛࢦఆ͢Δͱॺ໊ͷ৘ใ͕खʹೖΔ •

    ΞϓϦ͕Πϯετʔϧ͞Ε͍ͯΔ͔Ͳ͏͔΋߹Θͤͯௐ΂Δ͜ͱ͕Ͱ͖Δ • https://developer.android.com/reference/android/content/pm/ PackageManager.html#getPackageInfo(java.lang.String, int) ࿈ܞઌͷͷΞϓϦ͕ຊ෺͔Ͳ͏͔Λௐ΂Δ
  50. ࿈ܞઌͷͷΞϓϦ͕ຊ෺͔Ͳ͏͔Λௐ΂Δ • ࣮૷ํ๏͸ηΩϡΞίʔσΟϯάΨΠυΛ
 ࢀর͍ͯͩ͘͠͞ʂ • https://www.jssec.org/dl/ android_securecoding.pdf

  51. αϯϓϧίʔυ https://github.com/operando/ Application-Interoperability-Sample

  52. ·ͱΊ • ΞϓϦؒ࿈ܞͱҰݴͰݴͬͯ΋࣮૷ํ๏͸৭ʑ͋ΔΑ • ͱʹ͔͘ηΩϡϦςΟ͸ؾΛ͚ͭͯͶʂ • มʹಠ࣮ࣗ૷Λ͠ͳ͍ͰɺAndroid͕ఏڙ͢ΔػೳΛ ࢖ͬͨ΄͏͕͍͍ • ৗʹ࠷ળͷ࣮૷ํ๏͸໛ࡧ͠ଓ͚Δ

  53. Thanks!!