학사 나부랭이
iOS - Sandbox, Container Directory 본문
Sandbox - 어린이가 안전을 위해 모래통 안에서만 놀게 하는 것에서 유래
서드파티 앱은 샌드박스 처리 즉, 격리되어 있기에 자신의 폴더에 있는 데이터 외에는 접근할 수 없어요. 즉, 다른 앱에서 저장한 파일, 시스템 파일 및 자원 등을 수정 및 접근할 수 없고, 접근하려면 샌드박스 정책에 따라 접근 권한을 부여받아야 해요. 각 앱은 설치 시 랜덤으로 지정되는 파일 저장용 고유 디렉터리가 할당되고 거기가 해당 앱의 홈 디렉터리가 되어요.
샌드박스가 없다면?
앱에 모든 접근 권한을 줄 경우, 편의성과 수행의 자유도가 높지만 해당 앱이나 프레임워크에 취약점이 있을 경우 공격자가 해당 취약점을 이용해 접근, 공격자가 모든 데이터나 자원에 접근해 악용할 수 있죠. 하지만 샌드박스를 적용할 경우, 공격자는 해당 앱과 공간을 제외한 다른 앱 및 시스템에 영향을 줄 수 없어요.
그럼, 추가적인 권한이나 데이터는?
이런 샌드박스는 개발자가 앱이 시스템과 어떤 상호작용을 거치며 작업을 수행할 건지 설정할 수 있게 해줘요. 그럼 시스템은 앱의 작업을 수행하는데 필요한 권한과 데이터만 부여하죠. 그런데 프로그램이 실행되다 보면 방금 외부에서 다운로드한 파일을 수정해야 하든지 여러 이유로 추가적인 액세스 권한이 필요할 때도 있죠. 샌드박스는 아래 그림처럼 사용자의 드래그&드롭, 대화 상자 등의 인터렉션을 통해 앱에게 추가적인 권한을 부여할 수 있게 해요.
그리고 앱끼리 문서나 음악, 사진 등을 전송하는 것을 시스템 API에서 기능을 제공하는 경우에만 사용 가능하죠.
그러나... iOS 11에서 서드파티 앱도 연동해 사용할 수 있고, 검색, 정렬 등 다양한 기능을 갖고 있는 Files 앱이 등장했어요. 그리고 iCloud와 연동되어서 휴대폰으로 Mac의 파일을 볼 수도 있게 되었죠.
아니면 public API가 아니라 private API의 기능을 사용해 전원 종료 같은 보통의 앱이 할 수 없는 동작을 하게끔 만들 수도 있어요. 스토어에 등록이 안 될 뿐이지만ㅋㅋㅋ
이렇게 불편해도 샌드박스는 무적이 아니며 앱은 언제든 크랙될 위험이 있어요. 하지만 이로 인해 줄어든 잠재적 피해 범위는 크게 줄어들죠. 그래서 제가 아이폰용 시스템 보호 앱을 만들 생각을 접었어요.ㅋ
샌드박스의 발악(?)
만약 공격자가 앱의 취약점을 찾아 접근에 성공했을 경우, 샌드박스는 사용자의 데이터 도난, 오염, 하드웨어 접근에 대한 마지막 방어선을 구축해요.
하드웨어 - 카메라, 마이크, USB 포트, 프린터(출력장치) 등
네트워크 통신 - 인바운드와 아웃바운드
앱 데이터 - 캘린더, 위치, 연락처 등
유저 파일 - 다운로드된 파일, 사진, 음악 등
이러한 자원을 사용하려면 그 의도를 명시해야 해요. 그리고 명시적으로 요청되지 않은 자원에 대한 접근은 런타임 때 시스템에 의해 거절되어요.
Container
전술했듯이 앱과 파일 시스템의 상호 작용은 앱의 샌드박스 디렉터리 내로 제한되어요. 새 앱을 설치할 때 설치 관리자는 샌드박스 디렉터리(앱의 홈 디렉터리) 내에 앱용 컨테이너 디렉터리를 만드는데 이 컨테이너 디렉터리에는 각각 역할이 있어요.
1. Bundle Container - path: Bundle.main.bundlePath
- 하나의 디렉터리
- 실행 가능한 파일, info.plist, 리소스(이미지, 사운드, 문자열, ...) 등을 함께 그룹화
- 읽기 전용으로, 수정이 필요한 경우 데이터 컨테이너로 옮겨 작업
- iTunes나 iCloud에 백업 X
ⓐ Compile Sources들은 바이너리 형태의 실행 파일로 변해요.
ⓑ 라이브러리는 프레임워크에 들어가요.
ⓒ Assets에 들어있는 리소스 파일들이 들어가요.
ⓓ Assets에 넣지 않은 리소스 파일들은 이미지 관리를 못하니까 Assets에 넣어서 관리하는게 좋아요.
2. Data Container - path: NSHomeDirectory()
기본 디렉터리는 Document, Library, tmp, System Data가 있어요.
사용자가 직접 디렉터리나 파일을 추가할 수 없고, Documents 같은 서브 디렉터리를 통해 관리할 수 있어요.
2.1. Documents 폴더
- 유저가 앱을 통해 생성하거나 외부 앱에서 받은 데이터를 저장
- 설정에 따라 유저가 직접 파일 추가나 삭제가 가능
- 디렉터리 자체는 삭제 불가, 삭제 시도 시 내용물만 삭제
- iTunes, iCloud에 백업
- UIFileSharingEnabled 설정으로 iCloud에서 접근, 파일 추가 및 삭제 가능
2.1.1. Documents/Inbox 폴더
- 외부 앱에서 받은 파일이 저장되는 디렉터리
- 파일을 읽거나 삭제할 수 있으나 새 파일을 추가하거나 기존 파일 수정 불가
- 동일한 이름의 파일을 받을 시, file-1.txt, file-2.txt 처럼 자동으로 번호 부여
- iOS 9.0부터는 디렉터리가 한 번 만들어지면 삭제 불가
- 유저가 직접 생성 불가
- Documents와 동일하게 디렉터리 삭제 시도 시 내용물만 삭제
2.2. Library 폴더
- 유저 데이터 파일과 임시 파일을 제외한 모든 파일 관리
- 유저에게 노출되는 것을 피하고 앱의 기능이나 관리에 필요한 파일 저장
- 주로 서브 디렉터리인 Application Support와 Caches를 이용하지만, 커스템 디렉터리도 사용 가능
- Preference, Cookies, Saved Application State, WebKit 등 필요할 때 시스템에서 자동 생성
- iTunes, iCloud에 백업
2.2.1. Library/Application Support 폴더
- 앱의 기능이나 관리에 필요한 파일 저장
- Dovuments와 거의 동일한 속성이지만 유저에게 노출하지 않을 데이터 저장
- BundleID, 회사명 등 서브 디렉터리를 만들어 관리
- CoreData 기본 저장 경로
- iTunes, iCloud에 백업
CoreData는 Library/Application Support 폴더가 기본 경로이기에 노출되지 않지만, realm은 기본적으로 Documents 폴더를 사용하기에 노출되죠. 이로 인해, 중요한 정보들이 저장되어 있다면 Application Support 폴더로 변경해서 사용하는 것이 좋겠죠?
2.2.2. Library/Caches 폴더
- 잘 알고 있는 그 개념
- 앱의 수행 속도, 통신 데이터 절약 등을 위해 사용
- 지도 정보, json 파일처럼 재생성 및 다운로드 용이한 파일
- 저장공간 부족, 시스템 복원 등으로 인해 자동으로 삭제 가능
- 없어도 정상적인 동작에는 영향 전무
- 백업하지 않음
2.2.3. Library/Caches/Snapshots 폴더
- applicationDidEnterBackground(_:) 메서드 호출 후 현재 뷰에 대한 스냅샷 생성
- 백그라운드에서 포어그라운드로 넘어올 때 저장된 스냅샷 이미지를 사용
- Reastore Application State 기능 사용 시, Suspend 된 앱이 다시 Activate-Dispatch 될 때, 사용자에게 앱이 종료되지 않고 계속 실행된 것처럼 하기 위해 사용
2.2.4. Library/Preferences 폴더
- 앱의 설정 정보 저장
- 별도의 파일을 저장할 수 있으나 직접 조작하지 않는 것을 권장
- 대신 UserDefaults, Settings.bundle, CFPreferences API 등을 이용 권장
- iTunes, iCloud에 백업
3. tmp - path: NSTemporaryDirectory()
- 실행 중에 사용하지만 다음에 다시 런칭할 때까지 필요 없는 임시 파일 저장
- 사용 후 필요없어진 파일은 시스템이 주기적으로 삭제하나, 직접 삭제하는 것을 권장
- 앱이 실행되고 있는 동안에는 삭제되지 않음
- 백업하지 않음
이미지 캐싱 라이브러리인 SDWebImage 라이브러리를 봐서 폴더의 사용 형태를 알 수 있는데,
1. queryDiskCacheForKey() 매소드로 저장된 Cache를 찾고
2. Library/Caches 폴더에 캐시된 이미지가 없으면 downloadImage(url, ..., completed) 메서드로
3. 다운받고 앱 시작 중에는 데이터를 유지할 필요가 없으니 tmp 폴더에 잠시 저장
4. Library/Caches 폴더에 저장
3.1. tmp/"BundleID"-Inbox 폴더
- LSSupportsOpeningDocumentsInPlace키의 값이 NO일 때 iCloud 드라이브 관련, Files 앱, DocumentsPicker 등에서 공유된 파일이 저장
- Documents/Inbox와 달리 디렉터리 및 파일을 다루는데 제약 없음
- tmp 디렉터리의 속성을 따르므로, 백업되지 않으며, 시스템에 의해 삭제될 수 있음
'自習 > iOS' 카테고리의 다른 글
iOS - How to Break the Sandbox (0) | 2021.06.03 |
---|---|
iOS - Code Signing, Certification, Provisioning Profile (0) | 2021.06.03 |
iOS - Multitasking (0) | 2021.06.03 |