Saltar al contenido principal
CNIT 128
Hacking Mobile Devices
9. Writing Secure
Android Apps
Updated 11-14-22
Common Vulnerabilities
• Code injection
• Logic flaws
• Insecure storage
• Application configuration
• Insecure communication
• Logging
Topics
• Principle of Least Exposure
• Essential Security Mechanisms
• Advanced Security Mechanisms
• Slowing Down a Reverse Engineer
Principle of Least Exposure
Minimizing Attack Surface
• Find all entry points
• Code exposed to inputs from outside
sources
• Remove unnecessary entry points
• Perform security checks at necessary entry
points
App Components
• Don't export more components than required
• The safest case is shown below
• Most apps require some integration with other apps
Data Storage
• Avoid storing unnecessary data
• Such as passwords!
• Private directory is protected somewhat by the
sandboxing
• SD card is less protected
Untrusted Sources
• Inputs from SD card, Internet, Wi-Fi,
Bluetooth, etc.
• Verify authenticity with signature, encryption,
or some other validation
• Be careful loading classes or running
executables from untrusted locations
• Cryptographic protections are the best
Minimal Permissions
• Request the fewest permissions needed for
your app
• This is safer, and also avoids worrying careful
users
• Avoid risky permissions
• INSTALL_PACKAGES
• Using powerful shared users such as
android.uid.system
Bundling Files in the APK
• APK can contain extra files by accident
• May contain SSH credentials or other
secrets
Essential Security
Mechanisms
Review Entry Points
• Trace these functions
Permission Protection
• Exported components should be limited with
permissions
• Only available to apps with the same
signature
• If you really want to offer a component for
public use
• Great care is required in the implementation
Securing Activities
Task Manager Snooping
• Remove your app from the recent app list
• To avoid exposing private information on that image
• Put this code in OnCreate() to show a blank screen in
the list
getWindow().addFlags(WindowManager.LayoutParams.FLAG_SE
CURE)
;

• Set this attribute in an activity to remove it entirely
from the list
intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_
FROM_RECENTS);
Tapjacking
• Prevent touches from being sent through
elements with this attribute:
android:filterTouchesWhenObscured="true
"

• Or by using this method:
view.setFilterTouchesWhenObscured(true);
Dictionary
• Disable additions to the dictionary to keep
passwords and other secrets out
• Add this attribute to an EditText box:
android:inputType="textVisiblePassword"
Fragment Injection
• https://securityintelligence.com/new-vulnerability-
android-framework-fragment-injection/
Fragment Attacks
• Fragments are small UI elements that customize activities
• But fragment injection vulnerabilities were found
• Since Android 4.4, fragments are blocked by default
• Use this code to allow a whitelist of fragments:
@Override
 

protected boolean isValidFragment(String fragmentName)
{

String[] validFragments =
 

{"com.myapp.pref.frag1",
"com.myapp.pref.frag2"};
 

return Arrays.asList(validFragments).
contains(fragmentName);
 

}
Secure Trust Boundaries
• Make sure there's no way to open an
authenticated activity from unauthenticated
areas of the app
• One way: implement an app-wide
authentication variable
Masking Password Displays
• Add this attribute to an EditText box:
android:inputType="textPassword"
Browsable Activities
• Can be used directly from a web browser
• High-value targets for attackers
• Avoid using BROWSABLE
• If you use it, consider all possible intents that
could cause actions in your app
Securing Content Providers
Default Export Behavior
• Prior to API 17, content providers were
exported by default
• To prevent this, put this code in the manifest:
<provider
 

android:name=".ContentProvider"
android:authorities="com.myapp.ContentProvider"
android:exported="false" >
 

</provider>
SQL Injection
• Use prepared statements, like this:
String[] userInput = new String[] {"book",
"wiley"};
 

Cursor c = database.rawQuery("SELECT * FROM
Products WHERE type=?
 

AND brand=?", userInput);
Directory Traversal
• The getCanonicalPath() method removes ..
characters and provides the absolute path to a
file
• The code on the next page uses this to limit
paths to the /files/ subdirectory of the app's
private data directory
Pattern Matching
• Pattern-
matching
checks may
fail for
variations of
the path
• Link Ch 9a
Secret Codes
• Defined in Android Manifest
• http://blog.udinic.com/2013/05/17/create-a-
secret-doorway-to-your-app/
Securing Broadcast
Receivers
• Secret codes are
easily
enumerated
using apps on
the Play Store
• Don't trust them
CNIT 128 Ch 9a
Storing Files Securely
Creating Files and Folders
Securely
• Explicitly set permissions
Encryption
• Use AES for symmetric encryption, avoid ECB
• Use RSA-2048 for asymmetric encryption
• Password hashing advice in textbook is wrong
• You need salting and stretching; better to
avoid doing it yourself
Random Numbers
• Random() produces the same series of
numbers each time it's run from the same seed
• SecureRandom is better
• Java provides methods to seed it from a
source of entropy
Random()
import java.util.Random;
class Main {
public static void main(String[] args) {
// create instance of Random class
Random rand = new Random(1);
// Generate random integers in range 0 to 999
int rand_int1 = rand.nextInt(1000);
int rand_int2 = rand.nextInt(1000);
// Print random integers
System.out.println("Random Integers: "+rand_int1);
System.out.println("Random Integers: "+rand_int2);
}
}
• replit.com
• Every run produces the same numbers
Online Java Tester
Key Generation
• PBKDF2 uses many rounds of hashing to
derive a key from a password
• Key should be stored in Android Keystore
Exposing Files
• To allow specified other apps to see a file
• Those apps need com.myapp.docs.READWITE
permission
• They can only access the /document/ folder
Secure Communications
HTTPS
• HTTP is very unsafe
• HTTPS is much better, but depends on trusted
Certificate Authorities (CAs)
• Certificate pinning makes HTTPS even more
secure
• Requiring a specific certificate or CA
Local Communications
• Transferring data from one app to another
• Android API is the best method
• Activities with intent-filters
• In more recent Android versions
• ChooserTargets, Shortcuts, direct share
targets
• Using network sockets or the clipboard is less
safe
Securing WebViews
WebView
• Lets you display a Web page in an activity
• Often leads to security problems
• Use HTTPS
• Contemt loaded over HTTP is subject to
interception and modification
• Disable JavaScript
• If you aren't using it
WebView
• Don't Use JavaScriptInterface
• If you do use it, target an SDK >= 17
• Disable Plug-ins
• They're deprecated for Android 4.3 and higher
• Disable Filesystem Access
• Validate Web Content
Con
fi
guring the
Android Manifest
Backups and Debugging
• If android:allowBackup is false, an attacker
can't back up files with physical access to the
device
• android:debuggable allows debugging
API Version Targeting
• minSdkVersion should be as large as
possible
• Lower values remove new security fixes
• Values below 17 export content providers by
default
Android 9
• Targeting SDK 28+ gives you
• DNS over TLS
• Network TLS by default
• Cleartext traffic must be explicitly set
• Separate WebView directories for each
process
• Can't steal cookies
• https://blog.cloudflare.com/enable-private-dns-with-1-1-1-1-on-android-9-pie/
Logging
• Should be disabled in release builds
• Use a centralized logging class
• So it can be easily disabled
• ProGuard can remove logging code
Native Code
• Notoriously difficult to secure
• Limit its exposure to the outside world
• Enable exploit mitigations
• Use latest NDK version
Exploit Mitigations
• RELRO: Relocation Read-Only
• Prevents GOT rewrites
• RPATH / RUNPATH
• Allows attacker to load modified libraries
from a user-controlled path
• Link Ch 9f
Advanced Security
Mechanisms
Protection Level
Downgrade
• A malicious app can define a permission first
with an insecure protection level
• So your app inherits that level
• Your app can check to make sure the
protection levels are intact at each entry point
Protecting Non-Exported
Components
• Attacker with root permissions can interact
with them
• You can add a request token to prevent that
• Randomly generated
• Stored in a static variable in memory
• Intents must have this token to run
Slowing Down a Reverse
Engineer
Obfuscation
• ProGuard -- free
but very ineffective
• DexGuard -- paid
version of
ProGuard
• Dash-O is good but
expensive ($3000)
• Arxan is another
Root Detection
• Search for su
• See if default.prop allows ADB shell to run as
root
• See if adbd is running as root
• Look for packages with names like
• SuperSU or Superuser
Emulator Detection
• Check for emulator build properties
Debugger Detection
• Attacker may have modified your app or the
environment to allow debugging
Tamper Detection
• Check signature
CNIT 128 Ch 9b