반응형

참조 : https://toss.im/slash-21/sessions/3-6

 

메모리에 남지 않는 문자열

메모리에 남지 않는 문자열을 통해 민감한 정보를 안전하게 사용하는 방법을 공유합니다.

toss.im

 

보안 관련된 프로젝트에서 문자열 사용후에 메모리는 해제 되지만 메모리 덤프를 했을때
원본 문자열이 메모리에 남아 있을때의 문제를 해결하는 방법

특정 객체가 메모리 해제시 handler를 호출하도록 하기위한 클래스 선언

final class DeallocHooker {
    typealias Handler = () -> Void
    private struct AssociatedKey {
        static var deallocHooker = "deallocHooker"
    }
    private let handler: Handler
    private init(_ handler: @escaping Handler) {
        self.handler = handler
    }
    deinit { handler() }
    static func install(to object: AnyObject, _ handler: @escaping Handler){
        objc_setAssociatedObject(object, &AssociatedKey.deallocHooker, DeallocHooker(handler), .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
    }
}

 

Swift의 String은 struct 타입이기 때문에
class인 NSMutableString을 사용해서 UTF8 문자열 메모리 할당하고,
메모리 해제시 직접 메모리 영역을 모두 0으로 설정함으로써
해당 문자열 사용 후 메모리에 원본 문자열이 남아있지 않게 해준다.

func safeString(string: NSMutableString) -> NSMutableString {
    let encoding = String.Encoding.utf8.rawValue
    let bufferSize = string.maximumLengthOfBytes(using: encoding) + 1
    let buffer = UnsafeMutablePointer<Int8>.allocate(capacity: bufferSize)
    string.getCString(buffer, maxLength: bufferSize - 1, encoding: encoding)
    
    let newString = NSMutableString(bytesNoCopy: buffer, length: strlen(buffer), encoding: encoding, freeWhenDone: false) ?? NSMutableString()
    
    DeallocHooker.install(to: newString) {
        memset(buffer, 0, bufferSize)
        buffer.deallocate()
    }
    return newString
}

 

반응형
Posted by 까칠코더
,