Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Jon Markoff - Best practice for apps

Jon Markoff - Best practice for apps

droidcon Berlin

July 17, 2018
Tweet

More Decks by droidcon Berlin

Other Decks in Programming

Transcript

  1. British Gas boolean switchOnTorch() { CameraManager manager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);

    // Find the camera device with flash (if it exists) String[] cameraIds = manager.getCameraIdList(); for (String cameraId : cameraIds) { CameraCharateristics cc = manager.getCameraCharacteristics(cameraId); if(cc.get(CameraCharacteristics.FLASH_INFO_AVAILABLE )) { manager.setTorchMode(cameraId, true); return true; } } return false; } OR set screen brightness to the max <uses-permission android:name="android.permission.WRITE_SETTINGS"/> Settings.System.putInt(context.getContentResolver(), Settings.System.SCREEN_BRIGHTNESS, 255 ); Thoughtful use of peripherals
  2. Marine traffic private SensorManager mSensorManager; private Sensor mGravitySensor; private SensorEventCallback

    mGravityEventCallback; ... mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); mGravitySensor = mSensorManager.getDefaultSensor(Sensor.TYPE_GRAVITY); mGravityEventCallback = new SensorEventCallback() { @Override public void onSensorChanged(SensorEvent event) { float axisX = event.values[0]; float axisY = event.values[1]; float axisZ = event.values[2]; // Do work } }; mSensorManager.registerListener( registerListener, mGravitySensor, SensorManager.SENSOR_DELAY_NORMAL); Augmented reality
  3. Google FixIt (internal app) Location - quick (but not necessarily

    accurate) String locationProvider = LocationManager.NETWORK_PROVIDER; Location lastKnownLocation = locationManager.getLastKnownLocation(locationProvider); Location - accurate (but takes some time) String locationProvider = LocationManager.GPS_PROVIDER; LocationListener locationListener = new LocationListener() { public void onLocationChanged(Location location) { makeUseOfNewLocation(location); } locationManager.requestLocationUpdates(locationProvider, 0, 0, locationListener); // Make a best estimate of location … // Remove the listener you previously added locationManager.removeUpdates(locationListener); Enter it for me
  4. Target API Level 26 • All apps are affected EXCEPT:

    ◦ Apps uploaded for Managed Play via the API • New apps - August 2018 • App updates - November 2018 • TONS of documentation • NEW! Google Play API Level Requirement
  5. Secure network protocols <?xml version="1.0" encoding="utf-8"?> <network-security-config> <domain-config cleartextTrafficPermitted="false"> <domain

    includeSubdomains="true"> secure.example.com </domain> </domain-config> </network-security-config>
  6. SSL proxy? <network-security-config> <domain-config> <domain includeSubdomains="true">userCa.com</domain> <domain includeSubdomains="true">otherUserCa.com</domain> <trust-anchors> <!--

    Trust preinstalled CAs --> <certificates src="system" /> <!-- Additionally trust user added CAs --> <certificates src="user" /> </trust-anchors> </domain-config> </network-security-config> Be conscious of support for user-added CAs Android 7.0+
  7. Use default storage External storage UID Y App B UID

    X Only app A can interact with its own home directory unless it decides otherwise! App A
  8. Attestation Generate single-use token (nonce) Call attest() with nonce Send

    result to your server Validate JWS A. Validate SSL cert chain B. Verify signature of JWS Check nonce, timestamp and APK information fields. Use basicIntegrity & ctsProfileMatch 1. 2. 3. 4. 5. 6. byte[] nonce = getRequestNonce(); SafetyNetApi.attest(mGoogleApiClient, nonce) .setResultCallback( new ResultCallback<AttestationResult>() { @Override public void onResult( AttestationResult result) { ... // JSON Web Signature response. String jws = result.getJwsResult(); // Send result to server and validate. sendSignInRequest(..., jws); } }); CLIENT SIDE Sample code on Github: googlesamples / android-play-safetynet
  9. Attestation Generate single-use token (nonce) Call attest() with nonce Send

    result to your server Validate JWS A. Validate SSL cert chain B. Verify signature of JWS Check nonce, timestamp and APK information fields. Use basicIntegrity & ctsProfileMatch 1. 2. 3. 4. 5. 6. JSON Web Signature message: { "nonce": "R2Rra24fVm5xa2Mg", "timestampMs": 9860437986543, "apkPackageName": "com.mycompany.example", "apkCertificateDigestSha256": ["SHA-256 hash of signing certificate"], "apkDigestSha256": "SHA-256 hash of the APK", "ctsProfileMatch": true, "basicIntegrity": true } SERVER SIDE Sample code on Github: googlesamples / android-play-safetynet
  10. APIs Verify Apps isVerifyAppsEnabled() enableVerifyApps() listHarmfulApps() DevicePolicyManager.addUserRestriction (..., UserManager.ENSURE_VERIFY_APPS) Available

    through Google Play Services (SafetyNetApi) and Platform APIs. Providing transparency and control to developers:
  11. List PHAs listHarmfulApps API returns any known PHAs that are

    currently installed. Use the Google API client classes to connect to the SafetyNet API. PendingResult<HarmfulAppsResult> result = SafetyNetApi.listHarmfulApps(mGoogleApiClient); result.setResultCallback( new ResultCallback<HarmfulAppsResult>() { @Override public void onResult( HarmfulAppsResult harmfulResult) { // Last time all apps were scanned. long lastScanTimeMs = harmfulResult.getLastScanTimeMs(); // List of any PHAs installed. List<HarmfulAppsData> appList = harmfulResult.getHarmfulAppsList(); } });
  12. SaaS backend Android app EMM SaaS backend Android app OAuth

    request (via AppAuth) Managed configuration Enterprise authorization server (login_hint) (login_hint) OAuth response (via AppAuth) Enterprise authentication Enterprise authentication response EMM Enterprise authorization server
  13. B Secure context, host app cannot inspect contents Shared cookie

    state across apps Custom tabs are a system browser activity presented in app context
  14. In 2016, Chrome OS launched a new framework for running

    Android apps • Runs a full, CTS-compatible Android image • Access to the full Play Store • Apps “just work” without code changes (including native code!) Android apps on ChromeOS More on this topic at 2:05PM!
  15. Work Profile Fully Managed Device BYOD Data separation User privacy

    sensitive Corp liable Admin full visibility Deep inspection Developing for managed Android
  16. Work Profile Compatibility Handle cross-profile intents Check intents resolve with:

    Intent.resolveActivity() - result should be non null. Share data with other apps Use content URIs for sharing data between apps Grant other apps in same profile with Context.grantUriPermission() Don’t use file URIs
  17. Declare schema restrictions.xml <?xml version="1.0" encoding="utf-8"?> <restrictions xmlns:android="http://schemas.android.com/apk/res/android"> <restriction android:key="login_hint"

    android:title="@string/login_hint_title" android:restrictionType="string" android:description="@string/login_hint_description" / </restrictions>
  18. Get the values MainActivity.java // Lookup configuration values RestrictionsManager myRestrictionsMgr

    = (RestrictionsManager) getSystemService(Context.RESTRICTIONS_SERVICE); Bundle appRestrictions = myRestrictionsMgr.getApplicationRestrictions(); // getApplicationRestrictions returns null if there are none. if (appRestrictions != null) { String loginHint = appRestrictions.getString("login_hint"); }
  19. Handle updates MainActivity.java BroadcastReceiver restrictionsReceiver = new BroadcastReceiver() { @Override

    public void onReceive(Context context, Intent intent) { // Get the current configuration bundle Bundle appRestrictions = myRestrictionsMgr.getApplicationRestrictions(); } }; this.registerReceiver( restrictionsReceiver, new IntentFilter( Intent.ACTION_APPLICATION_RESTRICTIONS_CHANGED));
  20. Enabling single use (Pre Android P) MainActivity.java void lockMe(){ string

    packageId = “com.google.myapp”; DevicePolicyManager dpm = (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE); if(dpm.isLockTaskPermitted(packageId)){ myMainActivity.startlockTask(); } } void unlockMe(){ myMainActivity.stopLockTask(); } AndroidManifest.xml <activity android:name=".MainActivity" android:lockTaskMode="if_whitelisted">
  21. Management benefits* Fully curated store: public and private apps Push

    installs Managed configuration No need for a Google Account Full set of APIs for EMM integration Google Play benefits Secure: authenticated and encrypted delivery of signed apps Global server footprint Patch updates APK scanning Publishing tools such as alpha/beta testing and rollout management Reporting tools Automatic updates *dependent on EMM support Why?
  22. Insecure Hostname Verification Fragment Injection Supersonic Ad SDK Libpng Libjpeg-turbo

    Vpon Ad SDK Airpush Ad SDK MoPub Ad SDK OpenSSL (“logjam” and CVE-2015-3194, CVE-2014-0224) TrustManager AdMarvel Libupup (CVE-2015-8540) Apache Cordova (CVE-2015-5256, CVE-2015-1835) Vitamio Ad SDK GnuTLS Webview SSLErrorHandler Vungle Ad SDK Apache Cordova (CVE-2014-3500, CVE-2014-3501, CVE-2014-3502) GPP helps scan your apps
  23. Beta testing Alpha tests Open betas Closed betas Manage app

    releases Staged rollout Controlled % rollout Ability to halt Full release Timed publishing Google Play rollout management
  24. Design Spend time on design! Don’t just port! Internal enterprise

    developers ISVs Agencies Build Security! Form factors Management Deploy Google Play Summary
  25. Q&A