단점
이전 포스트에 설명한 안드로이드 앱 클라이언트의 IoT Publish에 대한 정책의 일부입니다.
{
"Effect": "Allow",
"Action": "iot:Publish",
"Resource": [
"arn:aws:iot:us-east-1:<account id>:topic/LEDButton*/command",
"arn:aws:iot:us-east-1:<account id>:topic/$aws/things/LEDButton*/shadow/get"
]
}
안드로이드 앱 클라이언트가 사물에 명령(command) 토픽을 발행(Publish)할 때 "LEDButton*/command" 토픽이 사용됩니다. * 는 와일드 카드를 의미하며 어떤 문자열도 허용된다는 의미입니다. 즉, 위와 같이 설정하면 "LEDButton12345670/command", "LEDButton00000000/command" 같이 "LEDButton"과 "/command"가 양 끝에 있으면 가운데는 어떤 문자열도 올 수 있습니다. 만약 클라이언트가 "LEDButt12345670/command" 토픽을 발행하면 AWS IoT는 비권한 접근으로 간주하고 해당 클라이언트의 연결을 끊어버립니다.
여기서 문제가 생깁니다. Cognito User Pool에 이메일 인증을 하고 로그인한 사용자는 모두 "LEDButton*/command" 토픽 발행에 대한 권한을 얻습니다. 와일트카드(*)를 제품 시리얼 넘버라고 가정해 봅시다. 자신의 사물이 아닌 제품의 시리얼 넘버를 알고 있거나, 시리얼 넘버 규칙을 찾아낸 공격자가 악의로 임의의 사용자의 사물(Thing)에게 의도하지 않은 명령을 내려 심각한 피해를 발생시킬 수도 있습니다.
물론 이것은 안드로이드 어플리케이션을 디컴파일 해서 User Pool ID, User Pool ID Secret key, ID Pool ID, IoT Custom Endpoint 등 AWS 정보를 모두 추출한 것을 가정한 것입니다. 안드로이드 앱 디컴파일은 난독화와 NDK를 이용하여 어느정도 방지할 수 있지만, 완전히 막을 수는 없습니다. 난독화를 해도 사용된 라이브러리를 알고 객체의 흐름을 추적한다면 얼마든지 AWS 정보를 추출할 수 있습니다. 또한 NDK로 문자열을 암호화하여 바이너리 형태로 저장했다고 하더라도, 어차피 String 객체에 다시 추출되기 때문에, 이 객체만 찾아낸다면 충분히 AWS 정보를 추출할 수 있습니다. 하지만 이런 과정은 상당한 실력을 요구하긴 합니다..
이것이 AWS LED Button 프로젝트에서 operation key를 사용한 이유입니다. 제품 시리얼 넘버는 사물마다 불변의 값을 가지지만, operation key는 사용자가 마음대로 바꿀 수 있기 때문에, 공격자가 대상 사물의 시리얼 넘버를 알더라도 사용자가 지정한 operation key가 없으면 사물에게 명령을 내릴 수 없습니다. 더 정확히 말하면, 공격자가 사물까지 메세지는 보낼 수 있지만 사물이 operation key를 검사하여 일치하지 않으면 무시해 버립니다. 해당 코드는 이전 포스트 맨 아래 예제 코드의 47번 라인에서 확인할 수 있습니다.
ESP32 (3) : C언어에서 JSON 문서 분석하기
장점
위에서 언급한 단점은 대량 생산한 어떤 IoT 제품을 불특정 다수 고객에게 판매한 경우를 가정한 것입니다. 만약 한정된 지역에서(비개방형) IoT 시스템을 구축하고, 특정 관리자에게만 관리 권한을 주는 시스템을 가정한다면 AWS 보안 시스템(특히 STS)은 보안상 매우 좋은 선택이라고 할 수 있습니다.
이전에 언급했다시피 "자격 인증"이 사용자 디바이스에 저장되지 않고, AWS STS에 저장됩니다. 사용자는 로그인시 부여받은 Identity ID를 사용하여 STS의 "임시 자격 증명"에 접근할 수 있고, 개발자는 사용자가 로그아웃하거나 앱이 비활성화됐을 때, Identity ID 등의 정보를 삭제할 수 있습니다. 즉, 사용자 디바이스가 해킹당한다고 하더라도 가져갈 정보가 없게 할 수 있습니다. AWS LED Button 프로젝트는 Cognito 예제를 수정하지 않았기 때문에 자동 로그인 기능 구현되어 있습니다. 따라서 위에 언급한 문제가 발생할 수 있지만, 만약 제가 실제 어떤 기관의 비개방형 IoT 시스템을 구현한다면 자동 로그인 기능은 넣지 않았을 것입니다.
또한 Cognito User Pool을 생성할 때 아래 그림과 같이 "Do you want to allow users to sign themselves up?" 항목에서 "Only allow administrators to create users"를 선택한다면 관리자가 허용하지 않은 사용자의 임의 가입을 막을 수 있습니다.
'AWS IoT > 안드로이드 앱' 카테고리의 다른 글
[AWS IoT] 어플리케이션 (5) : 소스 코드 (0) | 2018.02.05 |
---|---|
[AWS IoT] 어플리케이션 (3) : CognitoCachingCredentialsProvider 객체 (0) | 2018.02.05 |
[AWS LED Button] 어플리케이션 (2) : 정책 & 신뢰 관계 (0) | 2018.02.05 |
[AWS LED Button] 어플리케이션 (1) : 시스템 흐름 (0) | 2018.02.05 |