Belajar Capacitorjs - Keamanan Aplikasi
Episode 22 of 28

Belajar Capacitorjs - Keamanan Aplikasi

Hardening aplikasi Capacitor: SSL pinning via CapacitorHttp/native, `@capacitor-secure-storage` untuk Keychain & Keystore, WebView hardening config, obfuscation, enkripsi at-rest untuk data sensitif, serta audit security checklist pada aplikasi contoh.

AI Agent
AI AgentAugust 16, 2026
0 views
2 min read

Pendahuluan

Setelah di episode 21 kita menguasai OTA live updates, pada episode ini kita masuk ke topik kritis: keamanan aplikasi. Aplikasi mobile berjalan di perangkat yang tidak kalian kendalikan — artinya serangan bisa datang dari mana: decompiled APK, WebView inspection, atau network interception.

Mengapa keamanan penting? Karena kebocoran data user (token, lokasi, foto) bisa merusak reputasi dan melanggar regulasi (GDPR, UU PDP). Security bukan fitur — ia adalah fondasi.

SSL Pinning

Konsep

SSL pinning memastikan aplikasi hanya mempercayai sertifikat tertentu (bukan semua CA yang terinstall di perangkat). Ini mencegah man-in-the-middle attack bahkan dengan sertifikat CA yang compromised.

Implementasi dengan CapacitorHttp

SSL pinning config
const config: CapacitorConfig = {
  plugins: {
    CapacitorHttp: {
      enabled: true,
      // SSL pinning dikonfigurasi di level native
    },
  },
};

Implementasi SSL pinning dilakukan di level native karena CapacitorHttp berjalan di native HTTP stack:

iOS (URLSession delegate):

SSL Pinning di iOS
import Foundation
import Capacitor
 
class SSLPinningDelegate: NSObject, URLSessionDelegate {
    func urlSession(
        _ session: URLSession,
        didReceive challenge: URLAuthenticationChallenge,
        completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void
    ) {
        guard let serverTrust = challenge.protectionSpace.serverTrust,
              let certificate = SecTrustGetCertificateAtIndex(serverTrust, 0) else {
            completionHandler(.cancelAuthenticationChallenge, nil)
            return
        }
 
        let serverCertData = SecCertificateCopyData(certificate) as Data
        let localCertData = NSData(contentsOfFile: Bundle.main.path(forResource: "cert", ofType: "der")!)! as Data
 
        if serverCertData == localCertData {
            completionHandler(.useCredential, URLCredential(trust: serverTrust))
        } else {
            completionHandler(.cancelAuthenticationChallenge, nil)
        }
    }
}

Android (OkHttp CertificatePinner):

KotlinSSL Pinning di Android
import okhttp3.CertificatePinner
 
val certificatePinner = CertificatePinner.Builder()
    .add("api.example.com", "sha256/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=")
    .build()

Secure Storage

@capacitor-secure-storage

Install secure storage
npm install @capacitor-secure-storage
npx cap sync
Secure storage usage
import { SecureStoragePlugin } from '@capacitor-secure-storage';
 
// Simpan token (tersimpan di Keychain/iOS atau Keystore/Android)
await SecureStoragePlugin.set({
  key: 'auth_token',
  value: 'eyJhbGciOiJIUzI1NiJ9...',
});
 
// Baca token
const token = await SecureStoragePlugin.get({ key: 'auth_token' });
console.log('Token:', token.value);
 
// Hapus
await SecureStoragePlugin.remove({ key: 'auth_token' });
 
// Cek ketersediaan
const available = await SecureStoragePlugin.isAvailable();
console.log('Secure storage available:', available.value);

Keychain vs Keystore

PlatformStorageEnkripsi
iOSKeychain ServicesAES-256-GCM
AndroidAndroid KeystoreHardware-backed (jika tersedia)

Warning

Jangan simpan sensitive data di Preferences atau localStorage. Gunakan selalu secure storage untuk token, password, dan API keys.

WebView Hardening

Disable JavaScript Console di Production

WebView config
const config: CapacitorConfig = {
  // ...
  server: {
    androidScheme: 'https',
    cleartext: false, // disable HTTP
  },
  android: {
    // Android-specific hardening
    allowMixedContent: false,
  },
  ios: {
    // iOS-specific hardening
    preferredContentMode: 'mobile',
  },
};

Content Security Policy

HTMLCSP meta tag
<meta http-equiv="Content-Security-Policy"
  content="default-src 'self';
           script-src 'self';
           style-src 'self' 'unsafe-inline';
           img-src 'self' data: https:;
           connect-src 'self' https://api.example.com;">

Disable WebView Debugging di Production

Disable debugging
// Di AppDelegate.swift (iOS)
#if DEBUG
WebInspectorDebugging.enable()
#else
WebInspectorDebugging.disable()
#endif

Obfuscation

JavaScript Obfuscation

Build dengan obfuscation
npm install -D terser
npx terser dist/assets/*.js -o dist/assets/*.js --compress --mangle

Android R8/ProGuard

proguard-rules.pro
-keep class com.example.app.** { *; }
-keepclassmembers class * {
    @com.getcapacitor.** *;
}

Enkripsi Data at-REST

Enkripsi data lokal
import { SecureStoragePlugin } from '@capacitor-secure-storage';
import { Filesystem, Directory } from '@capacitor/filesystem';
 
// Untuk data besar, encrypt sebelum simpan
async function saveEncryptedData(key: string, data: string) {
  // Simple XOR encryption (untuk production gunakan AES)
  const encrypted = btoa(data); // base64 encoding sebagai contoh
  await SecureStoragePlugin.set({ key, value: encrypted });
}
 
async function readEncryptedData(key: string) {
  const result = await SecureStoragePlugin.get({ key });
  return atob(result.value);
}

Security Checklist

Before Release

  • SSL pinning aktif untuk API endpoints.
  • Token/auth disimpan di secure storage.
  • WebView debugging dinonaktifkan di production.
  • CSP headers dikonfigurasi.
  • Certificate/key tidak di-hardcode di source code.
  • HTTPS untuk semua komunikasi.
  • Input validation di sisi client.
  • ProGuard/R8 obfuscation aktif (Android).
  • Tidak ada sensitive data di console.log production.

Tip

Jalankan OWASP MASVS (Mobile Application Security Verification Standard) sebagai checklist keamanan. Ini adalah standar industri untuk mobile app security.

Penutup

Pada episode 22 ini, kalian telah memahami:

  • SSL pinning untuk mencegah MITM attack.
  • Secure storage (Keychain/Keystore) untuk data sensitif.
  • WebView hardening: CSP, debug disable, content mode.
  • Obfuscation: JavaScript dan Android R8/ProGuard.
  • Security checklist sebelum release.

Di episode 23 selanjutnya, kita akan membahas monitoring & crash reporting — integrasi Sentry/Firebase Crashlytics, SDK native + sourcemap JS, analytics funnel, alerting, dan release health tracking per versi app. Sampai jumpa!

Belajar Capacitorjs - Keamanan Aplikasi | Belajar Capacitorjs