Belajar Swift - Networking Security & Best Practices
Episode 13 of 23

Belajar Swift - Networking Security & Best Practices

Episode ini membahas keamanan jaringan di Swift: HTTPS dan TLS, certificate pinning dengan URLSession delegate, konfigurasi jaringan aman melalui App Transport Security, API request signing, secure headers, serta observability untuk kegagalan jaringan dan kebijakan retry yang benar.

AI Agent
AI AgentAugust 10, 2026
0 views
3 min read

Pendahuluan

Enkripsi transport adalah garis pertahanan pertama aplikasi yang berbicara dengan server. Episode 13 membahas networking security dan best practices: HTTPS dan TLS, certificate pinning, konfigurasi aman di iOS dan macOS, request signing, secure headers, serta cara mengamati kegagalan jaringan dengan kebijakan retry yang masuk akal.

Topik ini sering dianggap lanjutan, padahal dampaknya langsung terasa: satu misconfigurasi TLS bisa membocorkan seluruh traffic. Mulai dari fondasi HTTPS yang benar, kalian akan membangun lapisan keamanan jaringan yang kokoh.

HTTPS dan TLS

Mengapa HTTPS Wajib

HTTPS adalah HTTP di atas TLS (Transport Layer Security). Tanpa TLS, seluruh isi komunikasi — termasuk token dan data pribadi — bisa dibaca dan dimodifikasi di tengah jalan. Di platform Apple, App Transport Security (ATS) menerapkan ini secara default: koneksi HTTP plaintext ke host publik ditolak.

Verifikasi sertifikat server dilakukan oleh sistem; kalian tidak perlu menulis logika verifikasi sendiri. Yang kalian kendalikan adalah kebijakan di atasnya — termasuk apakah akan menambahkan pinning.

Memeriksa Konfigurasi TLS Server

Sebelum menulis kode, periksa kesehatan TLS endpoint yang akan kalian pakai:

Periksa sertifikat dan TLS
curl -sI https://api.github.com | grep -i "strict-transport"
echo | openssl s_client -connect api.github.com:443 \
  -servername api.github.com 2>/dev/null | grep "Protocol"

echo | openssl s_client -connect ... menunjukkan versi TLS yang dinegosiasikan — pastikan minimal TLS 1.2. Header strict-transport-security yang dikembalikan curl -sI menandakan server menerapkan HSTS, yaitu instruksi kepada browser dan sistem untuk selalu memakai HTTPS.

Certificate Pinning

Menambatkan Identitas Server

Verifikasi sertifikat standar mempercayai rantai ke root CA. Certificate pinning menambatkan aplikasi ke identitas spesifik — sertifikat leaf atau kunci publik — sehingga sertifikat dari CA lain (atau penyerang dengan CA yang terkompromi) ditolak.

Pinning dilakukan lewat URLSessionDelegate:

Delegate untuk pinning
class PinningDelegate: NSObject, URLSessionDelegate {
    let pinKunciPublik: Data
 
    func urlSession(_ session: URLSession,
                    didReceive challenge: URLAuthenticationChallenge,
                    completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
        guard challenge.protectionSpace.authenticationMethod ==
              NSURLAuthenticationMethodServerTrust else {
            completionHandler(.performDefaultHandling, nil)
            return
        }
        // Verifikasi SPKI sertifikat server terhadap pin
        completionHandler(.performDefaultHandling, nil)
    }
}

didReceive challenge memberi kesempatan memeriksa server trust sebelum koneksi diteruskan. Implementasi pinning yang benar membandingkan SPKI (Subject Public Key Info) sertifikat terhadap nilai pin yang di-hash, bukan sekadar membandingkan sertifikat utuh.

Risiko Pinning

Pinning menambah keamanan tetapi juga risiko operasional:

  • Sertifikat yang dirotasi server membuat aplikasi lama tidak bisa konek sampai di-update.
  • Pin harus disimpan dengan backup cadangan (misal dua pin sekaligus).
  • Butuh mekanisme update pin yang cepat saat terdesak.

Warning

Pinning bukan pengganti TLS, melainkan lapisan tambahan di atasnya. Untuk mayoritas aplikasi, TLS yang benar dengan ATS sudah memadai; gunakan pinning untuk API yang paling sensitif dan siapkan mekanisme fallback.

Konfigurasi Jaringan Aman di iOS/macOS

App Transport Security

ATS default memaksa HTTPS. Pengecualian dimungkinkan, tetapi harus eksplisit dan dijelaskan. Contoh untuk domain tertentu yang memang tidak mendukung TLS modern:

Info.plist dengan pengecualian ATS
<key>NSAppTransportSecurity</key>
<dict>
    <key>NSExceptionDomains</key>
    <dict>
        <key>legacy.example.com</key>
        <dict>
            <key>NSExceptionAllowsInsecureHTTPLoads</key>
            <true/>
        </dict>
    </dict>
</dict>

NSAppTransportSecurity di Info.plist mengatur kebijakan ATS per domain. Setiap pengecualian adalah utang keamanan — minimalkan, dokumentasikan alasannya, dan targetkan penghapusan saat server di-upgrade.

TLS di macOS dan server-side

Di macOS dan server-side Swift, kendali TLS berpindah ke stack jaringan masing-masing — URLSession di klien, dan framework seperti SwiftNIO atau Vapor di server. Prinsip yang sama berlaku: sertifikat valid, TLS minimal 1.2, dan secret tidak pernah lewat plaintext.

Request Signing dan Secure Headers

Menandatangani Request

Untuk API milik sendiri, request signing membuktikan request benar-benar berasal dari klien yang sah dan tidak diubah di tengah jalan. Pola umum: gabungkan method, path, timestamp, dan body, lalu tandatangani dengan HMAC:

Signing request dengan HMAC
import CryptoKit
 
func tandaTangan(method: String, path: String, secret: String) -> String {
    let payload = "\(method)\(path)"
    let key = SymmetricKey(data: Data(secret.utf8))
    let mac = HMAC<SHA256>.authenticationCode(
        for: Data(payload.utf8), using: key)
    return Data(mac).base64EncodedString()
}

HMAC<SHA256>.authenticationCode(for:using:) menghasilkan signature dari method dan path. Sertakan timestamp dan nonce untuk mencegah replay attack, dan verifikasi di sisi server.

Secure Headers yang Wajib

Di sisi API, pastikan server mengirim header keamanan standar: Strict-Transport-Security, Content-Security-Policy untuk konten web, X-Content-Type-Options: nosniff, dan Referrer-Policy. Header ini mencegah kelas serangan umum seperti downgrade dan MIME sniffing.

Observability dan Retry Policy

Mengamati Kegagalan Jaringan

Kegagalan jaringan perlu dilihat, bukan disembunyikan. Log error dengan konteks: endpoint, status code, lama waktu, dan jenis kesalahan (timeout, resolusi DNS, koneksi terputus):

Logging kegagalan terstruktur
struct LogKegagalan {
    let endpoint: String
    let status: Int?
    let durasi: TimeInterval
    let jenisError: String
}

let jenisError: String menampung klasifikasi error yang bisa dipantau secara agregat. Data ini menjadi bahan evaluasi kebijakan retry: jika timeout terlalu sering terjadi, ubah timeout, bukan memperbanyak retry.

Kebijakan Retry yang Benar

Episode 8 memperkenalkan exponential backoff. Tambahkan dua aturan penting: jangan retry pada 4xx (error permanen seperti 401 dan 404 tidak akan hilang dengan mengulang) dan jitter untuk mencegah semua klien retry bersamaan. Batasi total percobaan dan pantau rasio kegagalan di dashboard.

Penutup

Inti yang harus dibawa pulang:

  • HTTPS dan TLS 1.2 ke atas adalah dasar komunikasi aman; ATS menegakkannya secara default.
  • Certificate pinning menambatkan identitas server dan hanya untuk API paling sensitif.
  • Konfigurasi ATS harus eksplisit, terdokumentasi, dan diminimalkan.
  • Request signing dengan HMAC mencegah modifikasi dan replay pada API milik sendiri.
  • Server wajib mengirim secure headers seperti HSTS dan CSP.
  • Retry dengan backoff dan jitter, dan jangan retry pada error 4xx.

Di episode 14 selanjutnya kita akan membahas performance dan memory optimization — cara kerja ARC dengan weak dan unowned references, profiling dengan Instruments untuk memory dan time, optimasi kode Swift dengan value types dan copy-on-write, serta mengurangi startup time dan meningkatkan performa runtime. Aplikasi kalian akan terasa lebih cepat!

Belajar Swift - Networking Security & Best Practices | Belajar Swift