Swift 로컬 데이터베이스 민감 정보 평문 저장

Swift 로컬 데이터베이스에 민감 정보 평문 저장

설명

Core Data 또는 Realm 로컬 데이터베이스에 비밀번호, 토큰, API 키 같은 민감 값을 평문으로 저장하면 백업, 디버그 추출, 탈옥된 기기에서 값이 노출될 수 있습니다.

잠재적 영향

  • 인증 토큰 또는 세션 탈취
  • 로컬 백업과 디버그 추출을 통한 민감 정보 노출
  • 탈취한 값 재사용을 통한 계정 접근

해결 방법

  1. 민감 값은 가능한 한 로컬 데이터베이스에 저장하지 않습니다.
  2. 저장이 필요하면 Keychain, SQLCipher, Realm encryption key 등 검증된 암호화 저장소를 사용합니다.
  3. 데이터베이스에 저장하기 전 값 단위 암호화를 적용하고 키는 Keychain에서 관리합니다.

예시

변경 후 예시는 Core Data의 access_token 속성이 Binary Data 형식이라고 가정합니다. 키 조회와 컨텍스트 저장 코드는 생략했습니다.

변경 전

swift
let user = NSEntityDescription.insertNewObject(forEntityName: "User", into: context)
user.setValue(accessToken, forKey: "access_token")

변경 후

swift
import CoreData
import CryptoKit

enum StorageEncryptionError: Error {
    case missingCombinedRepresentation
}

func storeToken(
    context: NSManagedObjectContext,
    accessToken: Data,
    databaseKey: SymmetricKey
) throws {
    let sealedBox = try AES.GCM.seal(accessToken, using: databaseKey)
    guard let encryptedToken = sealedBox.combined else {
        throw StorageEncryptionError.missingCombinedRepresentation
    }

    let user = NSEntityDescription.insertNewObject(
        forEntityName: "User", into: context)
    user.setValue(encryptedToken, forKey: "access_token")
}

설명:

  • 변경 전: 인증 토큰을 로컬 데이터베이스에 평문으로 저장합니다.
  • 변경 후: CryptoKit의 AES-GCM으로 인증 암호화를 적용한 결합 표현만 저장합니다. databaseKey는 데이터베이스나 소스 코드가 아니라 Keychain 같은 별도 보안 저장소에서 관리해야 합니다.

참조