Security Best Practices

Overview

This guide provides actionable security practices for mobile and desktop applications, focusing on protecting sensitive data, preventing unauthorized access, and maintaining application integrity across platforms.

General Security Best Practices (Cross-Platform)

Runtime Protection and Hooking Prevention

Protecting your application during runtime is essential to prevent malicious actors from manipulating application behavior or extracting sensitive information.

  • Implement runtime hooking protection mechanisms in both iOS and Android applications

  • Detect and prevent manipulation of application behavior during execution

  • Monitor for debugging attempts and suspicious runtime modifications

  • Implement integrity checks for critical application components

Code Obfuscation

Making reverse engineering difficult protects your intellectual property and security implementations from analysis by potential attackers. Focus obfuscation efforts on security-critical code paths, API keys, and business logic

Note: We don't obfuscate the SDK on any platform

Logging

Remove sensitive information such as access tokens, credentials, and personal data from application logs.

For SDK Logging Levels, different platforms require careful configuration of logging levels to prevent sensitive data exposure.

Implementation Checklist

To ensure comprehensive security coverage, use this checklist when developing or auditing applications:

  • Data backup restrictions configured

  • Root/jailbreak detection active

  • Runtime protection mechanisms deployed

  • Code obfuscation applied to sensitive components

  • Tapjacking protections implemented (mobile)

  • Sensitive data handling procedures followed

  • Platform-specific security features utilized

  • Security testing completed across all target platforms

  • Regular security updates scheduled

iOS-Specific Security

Beyond the core principles, iOS applications require platform-specific security measures:

  • Integrate jailbreak detection mechanisms to identify compromised devices and restrict access accordingly. Consider using iOS Jailbreak detection libraries.

  • Use proper Keychain access control attributes

  • Clear sensitive data from memory proactively

  • Implement anti-debugging techniques

  • While native iOS code is compiled, consider obfuscating sensitive logic and string literals

  • Implement appropriate responses when compromise is detected (e.g., limiting functionality, warning users, or blocking access)

See iOS Keychain Services.

Sensitive Information Management

In iOS, proper handling of sensitive data throughout its lifecycle is fundamental to application security.

  • Memory Management: Clear sensitive data from memory immediately after use, especially in iOS applications

  • Storage: Avoid storing sensitive data in the iOS Keychain without proper encryption and access control attributes

Android-Specific Security

Android's open ecosystem requires additional security considerations:

  • Implement root detection mechanisms. Add root detection to prevent execution on rooted devices, reducing the risk of tampering and sensitive data exposure

  • Disable application backups for sensitive data

  • Apply code obfuscation consistently

  • Implement tapjacking protection on all sensitive screens

  • Use Android-specific security features like SafetyNet

  • Obfuscate application code using tools like ProGuard or R8

  • Implement appropriate responses when compromise is detected (e.g., limiting functionality, warning users, or blocking access)

See Play Integrity API Overview.

Data Backup Protection

In Android, preventing unauthorized data backups is crucial for maintaining data confidentiality, especially on mobile platforms where users may unknowingly expose sensitive information through device backups.

  • Set android:allowBackup="false" in the Android manifest to prevent unauthorized backups

  • This protects application data from being extracted through ADB backup commands or cloud backup services

  • For data that must be backed up, implement encryption before allowing backup operations

Tapjacking Protection

In Android, overlay attacks can trick users into performing unintended actions. Implementing tapjacking protection ensures user interactions are intentional and secure.

  • Use filterTouchesWhenObscured="true" in sensitive UI components

  • Check for obscured windows before processing input events

  • Implement runtime checks to detect potential overlay attacks

  • Warn users when suspicious overlay activity is detected

Desktop-Specific Security (Windows/Mac)

DLL Hijacking Prevention

In Windows:

  • Use fully qualified paths when loading binaries

  • Remove the current working directory from the binary search path

  • Secure access permissions on local directories

  • Validate binary signatures before loading

See Microsoft secure loading of libraries to prevent DLL preloading attacks.

Logging

In Windows, when using SDK logging, note that Trace and Debug levels will log all requests and responses without any encryption. All keys and tokens will be logged to the log file. Therefore, we recommend using default option settings (only error logging), Warning or Information (only general data logging) in production environments

Cross-Platform Desktop Security:

  • Prevent sensitive information from being written to application logs: This addresses a critical issue where sensitive data received from SDKs could be exposed in app logs. Sensitive information encompasses all data received from the SDK, with access tokens from login processes being particularly critical.

    While we cannot completely omit storing access tokens in application memory (as they are essential for authentication), you must ensure they are never written to logs in plaintext. It's important to understand that even when using encryption, there are moments when tokens must exist in their decrypted form: initially when receiving them from the SDK, and subsequently for each API request where the token is required as a parameter. During these operations, the application must decrypt and use the real token value.

    Given these technical constraints, implement robust security measures: use encryption for tokens at rest, implement careful logging practices that exclude sensitive fields, and ensure that decrypted values exist in memory only for the minimum time necessary to complete their intended operations.

  • Understand practical limitations of memory protection: Access tokens and other sensitive information cannot be entirely eliminated from application memory. Even when using encryption, the application must temporarily decrypt these values when:

    • Initially receiving tokens from the SDK

    • Preparing tokens as parameters for API requests

    • Processing authentication workflows

    • The goal is to minimize the exposure window and ensure sensitive data exists in plaintext form only for the briefest necessary duration.

  • Implement proper memory clearing for sensitive data

  • Avoid storing sensitive data in registry

  • Implement obfuscation for critical security components

Conclusion

Security is not a one-time implementation but an ongoing process. By following these best practices and regularly updating your security measures, you can significantly reduce the attack surface of your applications and protect your users' data. Remember that security measures should be layered. No single protection is foolproof, but combined defenses create a robust security posture.

Last updated

Was this helpful?