- Sun 22 March 2015
- Misc
- #development, #coding, #android, #security
In a recent working session, some of the best practices for a secure Android application development were discussed. Following were some of the important aspects of the discussion. Other the usual standards of securing the APK and securing the server-side components, some of the development and secure coding practices are listed in this post. Its the responsibility of every Android app developer to keep themselves appraised about new threats using OWASP Mobile Top 10 Risks.
Data classification and Handling Standards
- All data persisted should be encrypted - sqlliteDB, files, dataprovider etc.,
- Don’t transmit sensitive data to unapproved 3rd party.
- Don’t put sensitive data into Intents
Mobile privacy
- Respect user’s privacy by collecting minimum amount of data
- GPS & location data - fine grain vs. coarse grain GPS data
- Contact Info
- Microphone and Camera use
- Tracking and Analytics IDs
Attack Surface Analysis
- Third party code automatically inherits app permissions. Treat new versions of library as a new version of your app.
- Use Google Alerts for any security disclosures regarding the 3rd party library.
Securing logs
- Do not enable crash logs by default. Get user consent before logging.
- Do not store crash logs for too long
- Do not send plain-text logs over HTTP
- Mask sensitive user information in the logs - starbucks usecase
- Minimize the number of permissions - dont ask for what you dont need - Incoming SMS messages -
Securing Intents
- Use PendingIntents as delayed callbacks to private Broadcast receivers
- Use Explicit intents as much as possible
.sendBroadcast(intent,"custom-permission");
context.startActivity(intent); context
Permissions and Intents
- Use custom permission for 3rd party or other apps to subscribe for notifications
- For sensitive activities, set FLAG_SECURE constant flag in WindowManager.LayoutParams
- Perform intent data validation
- For private activities, use explicit intent
- Seperate services in AndroidManifest with explicit and seperate permissions
- Use explicit intent to call Service
- Use
checkCallingPermission()
to verify if permission is available to the caller
Data Security
- Use record level delegation feature to share a specific record or file without sharing the entire database to provide minimum access.
- Never trust the parameters passed to content providers. Sanatize for injection attacks.
- Securing ContentProviders. Always set
exported=false
in your AndroidManifest.xml - Ppecify explicit permissions for reading and writing.
- Use dynamic
grantUriPermissions
attribute to true to grant permission for certain portion for certain amount of time.
WebView Security
- Disable JS and Plugin support if not needed
- No local file access
- Do not load 3rd party hosts unless validated
- Do not follow redirect requests in the server response unless validated
- If possible, use only https
- Disable form auto-fill feature by using
WebView.WebSettings.setSaveFormData()
as false - Reject unexpected content - only allow HTML for main page (reject PDFs etc.,)
- Secure Page Rendering in WebView - shouldOverrideUrlLoading
- Access Modifiers should not be trusted for sensitivity.
- Clear the cache after Webview of a Sensitive page.
onPageFinished(Webview view, String Url){
.clearCache(true);
view}
- Ensure that UI Redressing (a.k.a) Tap jacking protection is setup to
prevent click jacking Use
setFilterTouchesWhenObscured(true)
orandroid:setFilterTouchesWhenObscured
for activity declaration.
Development practices
- Keep sensitive data in RAM no longer than required such as Encryption keys, Authn, Authz tokens, passwords.
- Variables should be nullified after use
- Use byte[] and char[] for sensitive data rather than Strings which helps in cleaning easier.
Internal Storage
- Accessible only to your app
- clean the cache using deleteFile()
External Storage
- Globally readable and writable
- Can be physically removed
- Avoid using this storage for sensitive apps in general. Use
preferInternal
to prevent app being installed in external storage. - Use Keychain API for system wide credentials
- Use Keystore to stores its own credentials
file.delete()
does not securely delete.- Always delete cache files when user logs out
- Do not keep files with any sensitive data any longer than absolutely needed.
- Do not create files with MODE_WORLD_READABLE or writeable
- Do not use modes such as 0666, 0777, 0663 with chmod binary or syscalls accepting a file modes
- Only share info using content providers instead of file system
Cryptography
- Dont store plain-text secret key
- Never roll your own CRYPTO libraries. use the approved ones
- Never store secrets using string - only char[] and byte[]
- Never seed SecureRandom
Camera feed
- Use default CAmera app/services
- Or, create SurfaceView to display a Camera Preview and click button to convert to Picture
URL Connections
- Use TLS instead of SSLv3.
- Use only https
- SSLSocket class can be used but with caution. It does not do hostname verification.
- If overriding, check
getDefaultHostNameVerifier()
orHostNameVerifier.verify()
returns boolean true.