Skip to main content

mobile-security

Security practices and implementations for mobile applications

Jump to install

Source facts

Repository
NeuralBlitz/Agent-Gateway
Last source activity
April 9, 2026 at 10:58
Detected SKILL.md language
English
Stars
1
Forks
0

Install options

The review-first prompt is selected by default. You can switch to a direct command or download a local copy.

Review the source files

Read SKILL.md and any companion files shown by SkillsMP before deciding whether to install.

Showing SKILL.md

SKILL.md
Source instructions · Read-only preview
name
mobile-security
description
Security practices and implementations for mobile applications
category
mobile-development
difficulty
advanced
tags
["mobile","security","encryption","authentication"]
author
OpenCode Community
version
1
last_updated
2024-01-15T00:00:00.000Z
# Mobile Security ## What I Do I am Mobile Security, the discipline of protecting mobile applications and their data from unauthorized access, tampering, and reverse engineering. I encompass secure coding practices, encryption implementation, authentication mechanisms, secure storage, network security, and platform-specific security features. I address the unique vulnerabilities of mobile environments including rooted/jailbroken devices, insecure data storage, man-in-the-middle attacks, and code injection. I implement platform security features like Keychain on iOS and Keystore on Android. I protect sensitive data at rest and in transit, implement proper authentication flows, and detect tampering indicators. I help developers follow OWASP Mobile Top 10 guidelines and achieve compliance requirements like SOC 2, HIPAA, and PCI-DSS. ## When to Use Me - Building applications handling sensitive user data - Financial and healthcare applications - Enterprise mobility solutions - Applications requiring authentication and authorization - Compliance-driven development environments - Protecting intellectual property in apps - Securing API communications - Anti-tampering and fraud prevention - Biometric authentication integration ## Core Concepts **Data Encryption**: Protecting data at rest using platform keychain/keystore and secure enclaves. **Certificate Pinning**: Preventing man-in-the-middle attacks by validating server certificates. **Root/Jailbreak Detection**: Identifying compromised devices and applying security mitigations. **Secure Storage**: Platform-specific secure storage mechanisms (Keychain, EncryptedSharedPreferences). **OAuth 2.0/OpenID Connect**: Secure authentication and authorization protocols. **Code Obfuscation**: Protecting application logic from reverse engineering. **Input Validation**: Preventing injection attacks and malicious input processing. **Runtime Application Self-Protection (RASP)**: Runtime security monitoring and protection. ## Code Examples ### Example 1: Secure Storage Implementation (Android) ```kotlin // SecurePreferences.kt import android.content.Context import android.content.SharedPreferences import android.security.keystore.KeyGenParameterSpec import android.security.keystore.KeyProperties import androidx.security.crypto.EncryptedSharedPreferences import androidx.security.crypto.MasterKey import java.security.KeyStore import javax.crypto.Cipher import javax.crypto.KeyGenerator import javax.crypto.SecretKey import javax.crypto.spec.GCMParameterSpec class SecurePreferences(context: Context) { companion object { private const val PREFS_NAME = "secure_prefs" private const val KEYSTORE_ALIAS = "mobile_app_key" private const val ANDROID_KEYSTORE = "AndroidKeyStore" private const val TRANSFORMATION = "AES/GCM/NoPadding" private const val IV_SIZE = 12 private const val TAG_SIZE = 128 } private val masterKey: MasterKey = MasterKey.Builder(context) .setKeyScheme(MasterKey.KeyScheme.AES256_GCM) .setUserAuthenticationRequired(false) .build() private val encryptedPrefs: SharedPreferences = EncryptedSharedPreferences.create( context, PREFS_NAME, masterKey, EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV, EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM ) fun putString(key: String, value: String) { encryptedPrefs.edit().putString(key, value).apply() } fun getString(key: String, default: String? = null): String? { return encryptedPrefs.getString(key, default) } fun putInt(key: String, value: Int) { encryptedPrefs.edit().putInt(key, value).apply() } fun getInt(key: String, default: Int = 0): Int { return encryptedPrefs.getInt(key, default) } fun putLong(key: String, value: Long) { encryptedPrefs.edit().putLong(key, value).apply() } fun getLong(key: String, default: Long = 0L): Long { return encryptedPrefs.getLong(key, default) } fun remove(key: String) { encryptedPrefs.edit().remove(key).apply() } fun clear() { encryptedPrefs.edit().clear().apply() } } // Encryption Service class EncryptionService(context: Context) { private val keyStore: KeyStore = KeyStore.getInstance(ANDROID_KEYSTORE).apply { load(null) } init { if (!keyStore.containsAlias(KEYSTORE_ALIAS)) { generateKey() } } private fun generateKey() { val keyGenerator = KeyGenerator.getInstance( KeyProperties.KEY_ALGORITHM_AES, ANDROID_KEYSTORE ) val keyGenSpec = KeyGenParameterSpec.Builder( KEYSTORE_ALIAS, KeyProperties.PURPOSE_ENCRYPT or KeyProperties.PURPOSE_DECRYPT ) .setBlockModes(KeyProperties.BLOCK_MODE_GCM) .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE) .setKeySize(256) .setUserAuthenticationRequired(false) .build() keyGenerator.init(keyGenSpec) keyGenerator.generateKey() } private fun getSecretKey(): SecretKey { return (keyStore.getEntry(KEYSTORE_ALIAS, null) as KeyStore.SecretKeyEntry).secretKey } fun encrypt(data: String): Pair<ByteArray, ByteArray> { val cipher = Cipher.getInstance(TRANSFORMATION) cipher.init(Cipher.ENCRYPT_MODE, getSecretKey()) val iv = cipher.iv val encryptedData = cipher.doFinal(data.toByteArray(Charsets.UTF_8)) return Pair(iv, encryptedData) } fun decrypt(iv: ByteArray, encryptedData: ByteArray): String { val cipher = Cipher.getInstance(TRANSFORMATION) val spec = GCMParameterSpec(TAG_SIZE, iv) cipher.init(Cipher.DECRYPT_MODE, getSecretKey(), spec) val decryptedData = cipher.doFinal(encryptedData) return String(decryptedData, Charsets.UTF_8) } fun encryptBytes(data: ByteArray): Pair<ByteArray, ByteArray> { val cipher = Cipher.getInstance(TRANSFORMATION) cipher.init(Cipher.ENCRYPT_MODE, getSecretKey()) return Pair(cipher.iv, cipher.doFinal(data)) } fun decryptBytes(iv: ByteArray, encryptedData: ByteArray): ByteArray { val cipher = Cipher.getInstance(TRANSFORMATION) val spec = GCMParameterSpec(TAG_SIZE, iv) cipher.init(Cipher.DECRYPT_MODE, getSecretKey(), spec) return cipher.doFinal(encryptedData) } } ``` ### Example 2: Certificate Pinning (React Native) ```typescript // certificate-pinning.ts import axios, { AxiosInstance } from 'axios' import { Platform } from 'react-native' import RNFetchBlob from 'rn-fetch-blob' interface SSLConfig { keyHash: string certPinning?: string[] } class SecureNetworkClient { private client: AxiosInstance private config: SSLConfig constructor(config: SSLConfig) { this.config = config this.client = axios.create({ baseURL: 'https://api.example.com', timeout: 30000, validateStatus: (status) => status >= 200 && status < 300, }) this.setupCertificatePinning() this.setupInterceptors() } private setupCertificatePinning(): void { if (Platform.OS === 'ios') { this.setupIOSPinning() } else { this.setupAndroidPinning() } } private async setupIOSPinning(): Promise<void> { // Load pinned certificates from assets const certPath = Platform.OS === 'ios' ? RNFetchBlob.fs.dirs.MainBundlePath : RNFetchBlob.fs.dirs.AssetDirDir // iOS uses ATS with embedded certificates // Configure in Info.plist: // <key>NSAppTransportSecurity</key> // <dict> // <key>NSExceptionDomains</key> // <dict> // <key>example.com</key> // <dict> // <key>IncludesSubdomains</key> // <true/> // <key>ExceptionRequiresForwardSecrecy</key> // <true/> // </dict> // </dict> // </dict> } private setupAndroidPinning(): void { // Android uses Network Security Config // Create res/xml/network_security_config.xml: /* <?xml version="1.0" encoding="utf-8"?> <network-security-config> <domain-config cleartextTrafficPermitted="false"> <domain includeSubdomains="true">api.example.com</domain> <pin-set expiration="2025-01-01"> <pin digest="SHA-256">base64EncodedPublicKeyHash=</pin> </pin-set> </domain-config> </network-security-config> */ } private setupInterceptors(): void { // Request interceptor for adding auth headers this.client.interceptors.request.use( async (config) => { const token = await SecureStore.getItemAsync('accessToken') if (token) { config.headers.Authorization = `Bearer ${token}` } // Add security headers config.headers['X-Client-Version'] = '1.0.0' config.headers['X-Platform'] = Platform.OS return config }, (error) => Promise.reject(error) ) // Response interceptor for error handling this.client.interceptors.response.use( (response) => response, async (error) => { if (error.response?.status === 401) { // Token expired - attempt refresh try { await this.refreshAccessToken() // Retry original request return this.client.request(error.config) } catch (refreshError) { // Force logout await this.handleLogout() return Promise.reject(refreshError) } } return Promise.reject(error) } ) } private async refreshAccessToken(): Promise<void> { const refreshToken = await SecureStore.getItemAsync('refreshToken') const response = await axios.post('https://api.example.com/auth/refresh', { refresh_token: refreshToken }) const { access_token, refresh_token } = response.data await SecureStore.setItemAsync('accessToken', access_token) await SecureStore.setItemAsync('refreshToken', refresh_token) } private async handleLogout(): Promise<void> { await SecureStore.deleteItemAsync('accessToken') await SecureStore.deleteItemAsync('refreshToken') // Navigate to login screen } async get<T>(url: string, params?: object): Promise<T> { const response = await this.client.get<T>(url, { params }) return response.data } async post<T>(url: string, data?: object): Promise<T> { const response = await this.client.post<T>(url, data) return response.data } async put<T>(url: string, data?: object): Promise<T> { const response = await this.client.put<T>(url, data) return response.data } async delete<T>(url: string): Promise<T> { const response = await this.client.delete<T>(url) return response.data } } ``` ### Example 3: Root/Jailbreak Detection ```typescript // security-check.ts import { Platform } from 'react-native' import RNFetchBlob from 'rn-fetch-blob' import fs from 'react-native-fs' interface SecurityCheck { isRooted: boolean isJailbroken: boolean isEmulator: boolean isDebuggerAttached: boolean isTampered: boolean threatLevel: 'low' | 'medium' | 'high' } class SecurityChecker { async performSecurityCheck(): Promise<SecurityCheck> { const [ isRooted, isJailbroken, isEmulator, isDebuggerAttached, isTampered ] = await Promise.all([ this.checkRooting(), this.checkJailbreak(), this.checkEmulator(), this.checkDebugger(), this.checkTampering() ]) const threatLevel = this.calculateThreatLevel({ isRooted, isJailbroken, isEmulator, isDebuggerAttached, isTampered }) return { isRooted, isJailbroken, isEmulator, isDebuggerAttached, isTampered, threatLevel } } private async checkRooting(): Promise<boolean> { if (Platform.OS !== 'android') return false // Check for root access binaries const rootPaths = [ '/system/bin/su', '/system/xbin/su', '/sbin/su', '/data/local/xbin/su', '/data/local/bin/su', '/system/app/Superuser.apk', '/system/app/SuperSU.apk', '/system/bin/failsafe/su' ] for (const path of rootPaths) { try { const exists = await this.fileExists(path) if (exists) return true } catch { continue } } // Check for root management apps const rootApps = [ 'com.noshufu.android.customizersa', 'com.koushikdutta.superuser', 'com.chainfire.supersu', 'com.topjohnwu.magisk' ] for (const packageName of rootApps) { if (await this.isPackageInstalled(packageName)) { return true } } return false } private async checkJailbreak(): Promise<boolean> { if (Platform.OS !== 'ios') return false const jailbreakPaths = [ '/Applications/Cydia.app', '/Library/MobileSubstrate/MobileSubstrate.dylib', '/bin/bash', '/usr/sbin/sshd', '/etc/apt', '/private/var/lib/apt' ] for (const path of jailbreakPaths) { try { const exists = await this.fileExists(path) if (exists) return true } catch { continue } } // Check for jailbreak detection bypass tools const bypassTools = [ 'com.iOSOnDevice.Anti', 'com.jailbreak.anch0r', 'libhooker' ] for (const packageName of bypassTools) { if (await this.isPackageInstalled(packageName)) { return true } } return false } private async checkEmulator(): Promise<boolean> { if (Platform.OS === 'android') { const emulatorIndicators = [ 'ro.kernel.qemu', 'ro.hardware', 'generic', 'sdk' ] for (const indicator of emulatorIndicators) { const value = await this.getSystemProperty(indicator) if (value?.includes(indicator)) return true } } if (Platform.OS === 'ios') { const simulator = await this.getDeviceModel() if (simulator.includes('Simulator')) return true } return false }
View on GitHub
This SKILL.md is very large, so SkillsMP previews the first section here. View on GitHub