Android 플랫폼은 Linux 사용자 기반 보호 기능을 활용하여 앱 리소스를 식별하고 분리합니다. 이러한 방법으로 앱을 서로 분리하고 앱과 시스템을 악성 앱으로부터 보호합니다. 이를 위해 Android는 각 Android 애플리케이션에 고유한 사용자 ID(UID)를 할당하여 자체 프로세스에서 실행합니다.
Android는 UID를 사용하여 커널 수준의 애플리케이션 샌드박스를 설정합니다. 커널은 앱에 할당된 사용자 및 그룹 ID와 같은 표준 Linux 시설을 통해 프로세스 수준에서 앱과 시스템 간의 보안을 강화합니다. 기본적으로 앱은 서로 상호작용할 수 없으며 OS 액세스가 제한됩니다. 앱 A가 애플리케이션 B의 데이터를 읽거나 권한 없이 전화를 거는 등 악의적인 작업을 시도하는 경우 앱 A는 적절한 기본 사용자 권한이 없으므로 이러한 작업은 허용되지 않습니다. 샌드박스는 단순하고 감사가 가능하며 프로세스 및 파일 권한에 관한 수십 년 된 UNIX 스타일의 사용자 구분을 기반으로 합니다.
애플리케이션 샌드박스는 커널에 있으므로 이 보안 모델은 네이티브 코드와 OS 애플리케이션 모두로 확장됩니다. OS 라이브러리, 애플리케이션 프레임워크, 애플리케이션 런타임 및 모든 애플리케이션과 같은 커널 상위에 있는 모든 소프트웨어는 애플리케이션 샌드박스 내에서 실행됩니다. 일부 플랫폼에서는 개발자가 특정 개발 프레임워크, API 세트 또는 언어로 제한됩니다. Android에서는 보안을 강화하기 위해 애플리케이션을 작성하는 방법에 제한이 없습니다. 이러한 점에서 네이티브 코드에는 해독된 코드처럼 샌드박스가 설정됩니다.
보호
일반적으로 올바르게 구성된 기기에서는 Linux 커널의 보안을 침해해야 애플리케이션 샌드박스를 벗어날 수 있습니다. 하지만 다른 보안 기능과 마찬가지로 애플리케이션 샌드박스에 시행되는 개별 보호는 취약할 수 있으므로 단일 취약점이 OS 또는 다른 앱의 보안을 침해하지 않도록 심층 방어가 중요합니다.
Android는 여러 가지 보호 수단을 기반으로 애플리케이션 샌드박스를 시행합니다. 이러한 시행 기능은 시간이 지남에 따라 도입되었으며 원래 UID 기반 임의 액세스 제어(DAC) 샌드박스를 한층 강화했습니다. 이전 Android 버전에는 다음과 같은 보호 기능이 포함되었습니다.
- Android 5.0에서 SELinux는 시스템과 앱 사이에 강제 액세스 제어(MAC) 분리를 제공했습니다. 그러나 동일한 SELinux 컨텍스트 내에서 모든 타사 앱이 실행되었으므로 앱 간 격리는 주로 UID DAC에 의해 시행되었습니다.
- Android 6.0에서는 SELinux 샌드박스를 확장하여 실제 사용자별로 앱을 분리했습니다. 또한 Android는 애플리케이션 데이터에 더 안전한 기본값을 설정했습니다.
targetSdkVersion >= 24
를 가진 앱에서는 앱의 홈 디렉터리에 관한 기본 DAC 권한이 751에서 700으로 변경되었습니다. 이는 비공개 앱 데이터에 더 안전한 기본값을 제공합니다. 단 앱은 이러한 기본값을 재정의할 수 있습니다. - Android 8.0에서는 앱이 사용할 수 있는 syscall을 제한하는
seccomp-bpf
필터로 모든 앱이 실행되도록 설정하여 앱과 커널 사이의 경계를 강화했습니다. - Android 9에서 권한이 없으며
targetSdkVersion >= 28
을 가진 모든 앱은 개별 SELinux 샌드박스에서 실행해야 하며, MAC은 앱별로 제공해야 합니다. 이러한 보호 수단은 앱 분리를 개선하고 안전한 기본 설정을 재정의하지 않으며 앱이 데이터에 액세스할 수 없도록 합니다. - Android 10에서 앱은 파일 시스템의 제한된 원시 보기를 가지며 /sdcard/DCIM과 같은 경로에 직접 액세스할 수 없습니다. 하지만 앱은 Context.getExternalFilesDir()과 같은 적용 가능한 메서드에서 반환되는 패키지 전용 경로에 원시 전체 액세스를 유지합니다.
파일 공유 가이드라인
앱 데이터를 어디서든 액세스할 수 있도록 보안 수준을 설정하는 것은 좋은 방법이 아닙니다. 액세스 권한은 모든 사용자에게 부여되며 의도된 수신자만 액세스하도록 제한할 수는 없습니다. 이러한 설정으로 인해 정보 유출 및 혼동으로 인한 대리인 취약점이 발생했으며 민감한 정보를 사용하는 앱(예: 이메일 클라이언트)을 대상으로 하는 멀웨어의 공격 타겟이 만들어집니다. Android 9 이상 버전에서는 이 방법으로 파일을 공유하는 작업은 targetSdkVersion>=28
을 사용하는 앱에서 명시적으로 허용되지 않습니다.
파일을 공유할 때 앱 데이터를 어디서든 액세스할 수 있도록 설정하는 대신 다음 가이드라인을 따르세요.
- 앱이 다른 앱과 파일을 공유해야 하는 경우 콘텐츠 제공업체를 사용합니다. 콘텐츠 제공업체는 어디서든 액세스 가능한 Unix 권한의 여러 가지 단점 없이 적절한 수준의 세부정보를 통해 데이터를 공유합니다. 자세한 내용은 콘텐츠 제공업체 기본 사항을 참조하세요.
- 앱에 전체 공개해야 하는 파일(예: 사진)이 있다면 파일이 미디어 파일(사진, 동영상, 오디오 파일만 해당)이어야 하며 MediaStore 클래스를 사용하여 저장되어야 합니다. 미디어 항목을 추가하는 방법에 관한 자세한 내용은 공유 저장소의 미디어 파일에 액세스를 참고하세요.
저장소 런타임 권한은 MediaStore를 통해 강력한 유형의 컬렉션 액세스를 제어합니다. PDF 및 MediaStore.Downloads 클래스와 같이 약한 유형의 파일에 액세스하려면 앱은 ACTION_OPEN_DOCUMENT 인텐트와 같은 인텐트를 사용해야 합니다.
Android 10 동작을 사용 설정하려면 requestLegacyExternalStorage
매니페스트 속성을 사용하고 앱 권한 권장사항을 따르세요.
- Android 9 이하를 타겟팅하는 앱의 경우 매니페스트 플래그 기본값은
true
입니다. - Android 10을 타겟팅하는 앱의 경우 기본값은 false입니다. Android 10을 타겟팅하는 앱에서 필터링된 저장소 보기를 일시적으로 선택 해제하려면 매니페스트 플래그 값을
true
로 설정하세요. - 설치 프로그램은 제한된 권한을 사용하여 샌드박스가 설정되지 않은 저장소에 허용된 앱을 허용 목록에 추가합니다. 허용되지 않은 앱에는 샌드박스가 설정됩니다.