---
title: Không hardcode thông tin nhạy cảm trong source code
impact: CRITICAL
impactDescription: Secret hardcode trong source sẽ bị lộ qua Git history, binary dump hay reverse engineering, gây rò rỉ toàn bộ hệ thống.
tags: swift, ios, secrets, security, api-keys, hardcoded
---

## Không hardcode thông tin nhạy cảm trong source code

API key, token, password, private key không được viết trực tiếp trong `.swift` file hay `.plist`. Dùng biến môi trường (CI/CD), `.xcconfig` file (không commit), hay Keychain để lưu runtime secrets.

**Incorrect (hardcode secrets):**

```swift
// !! API key visible trong source code
struct APIConfig {
    static let apiKey = "sk_live_AbC123XyZ789"
    static let secretToken = "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..."
    static let databasePassword = "MyS3cr3tPass!"
}

class AnalyticsService {
    private let firebaseKey = "AIzaSyC-abc123-real-key"  // hardcode
    private let mixpanelToken = "a1b2c3d4e5f6"            // hardcode
}
```

**Correct (lấy secret từ xcconfig hay environment):**

```swift
// Config.xcconfig (được thêm vào .gitignore)
// API_KEY = sk_live_AbC123XyZ789

// Info.plist (đọc giá trị từ xcconfig - không commit secret)
// <key>APIKey</key>
// <string>$(API_KEY)</string>

struct APIConfig {
    // Đọc từ Info.plist (value đến từ xcconfig không commit)
    static var apiKey: String {
        Bundle.main.infoDictionary?["APIKey"] as? String ?? ""
    }
}

// Secrets nhạy cảm hơn (user token, refresh token) - lưu Keychain
class TokenManager {
    func saveAccessToken(_ token: String) throws {
        try KeychainManager.save(key: "access_token", value: token)
    }

    func retrieveAccessToken() -> String? {
        return try? KeychainManager.load(key: "access_token")
    }
}
```

**Kiểm tra trước khi commit:**

```bash
# Dùng git-secrets hoặc truffleHog để scan
git secrets --scan
```

**Tools:** `git-secrets`, `truffleHog`, `.gitignore` cho `.xcconfig`, SwiftLint custom rule

