tencent cloud

피드백

프런트엔드에서 COS로 다이렉트 업로드 시 임시 자격 증명 사용 보안 가이드

마지막 업데이트 시간:2024-06-24 16:44:04

    소개

    모바일 애플리케이션 및 Web에서 iOS/Android/JavaScript SDK를 통해 프런트 엔드에서 직접 Cloud Object Storage(COS)에 요청을 전달할 수 있습니다. 이 때 데이터의 업로드 및 다운로드는 사용자의 백엔드 서버를 통하지 않아 백엔드 서버 대역폭 및 부하를 절감할 수 있으며, COS 대역폭과 글로벌 가속 등의 능력을 충분히 이용할 수 있어 사용자의 애플리케이션 경험을 향상시켜 줍니다.
    실제 애플리케이션에서 임시 키를 프런트 엔드의 COS 요청 서명으로 사용하여 영구 키 노출 및 권한 없는 액세스 등의 문제를 방지할 수 있습니다. 그러나 임시 키를 사용한다 하더라도 임시 키 생성 시 너무 많은 권한 또는 경로를 지정하는 경우 마찬가지로 권한 없는 액세스 등의 문제가 발생할 수 있습니다. 이는 사용자의 애플리케이션에 일정의 리스크를 야기하며, 본 문서에서는 일부 리스크 사례에 대해 중점적으로 소개합니다. 사용자는 반드시 보안 규범을 준수하여 애플리케이션에서 안전하게 COS를 사용할 수 있도록 보장하십시오.

    전제 조건

    본 문서에서는 사용자가 임시 키와 관련한 개념을 충분히 이해하여 임시 키를 생성 및 사용할 수 있다는 전제하에 COS에 요청하는 방법을 설명합니다. 임시 키 생성 및 사용 가이드에 대한 자세한 내용은 임시 키 생성 및 사용 가이드 문서를 참고하십시오.
    주의:
    임시 키를 사용해 액세스 권한을 부여하는 경우, 반드시 업무 수요에 따라 최소 권한 부여를 원칙으로 권한을 부여해야 합니다. 직접 모든 리소스(resource:*) 또는 모든 작업(action:*)에 대한 권한을 부여하는 경우 권한 범위가 너무 커 데이터 보안에 대한 리스크가 발생할 수 있습니다.

    참고 사례 및 보안 규범

    참고 사례1: 리소스(resource)의 범위 제한 초과

    애플리케이션 A에서 가입 사용자가 업로드하는 프로필 사진에 COS를 사용하고 있으며, 모든 가입 사용자의 프로필 사진이 고정된 객체 키 app/avatar/<Username>.jpg를 가지고 있고 동시에 서로 다른 크기의 프로필 사진이 포함되어 있습니다. 여기에서 백그라운드에서 사용하기 편리하도록 해당 객체 키를 각각 app/avatar/<Username>_m.jpgapp/avatar/<Username>_s.jpg로 나누고, 임시 키 생성 시 직접 resource를 qcs::cos:<Region>:uid/<APPID>:<BucketName-APPID>/app/avatar/*로 설정했습니다. 이때 악성 사용자가 네트워크 패킷 캡쳐 등의 수단을 사용하여 생성된 임시 키를 획득하면 업로드된 임의의 사용자 프로필 사진을 덮어쓸 수 있으며 권한을 초과한 액세스가 발생해 사용자의 합법적 프로필 사진 데이터가 덮어쓰기 되어 손실될 수 있습니다.

    보안 규범

    resource 는 임시 키가 액세스를 허용하는 리소스 경로를 대표하며, 이때 해당 경로에서 커버하는 최종 사용자를 고려해야 합니다. 원칙적으로 resource에서 지정하는 리소스는 단일 사용자만 사용할 수 있도록 요구합니다. 해당 사례에서 지정한 qcs::cos:<Region>:uid/<APPID>:<BucketName-APPID>/app/avatar/*는 명백하게 모든 사용자를 커버하고 있어 보안 취약점이 존재하게 됩니다.
    해당 사례의 경우 사용자의 프로필 사진 경로를 app/avatar/<Username>/<size>.jpg로 수정하고, 이때 resource를 qcs::cos:<Region>:uid/<APPID>:<BucketName-APPID>/app/avatar/<Username>/*로 지정한다면 규범 요구를 만족할 수 있습니다. 이외에도 resource 필드는 숫자 조합 형식으로 여러 값을 전송할 수 있습니다. 따라서 명시적으로 여러 resource 값을 지정해 사용자가 액세스 권한을 가진 최종 리소스 경로를 완벽하게 한정할 수 있습니다. 예시는 다음과 같습니다.
    "resource": [
    "qcs::cos:<Region>:uid/<APPID>:<BucketName-APPID>/app/avatar/<Username>.jpg",
    "qcs::cos:<Region>:uid/<APPID>:<BucketName-APPID>/app/avatar/<Username>_m.jpg",
    "qcs::cos:<Region>:uid/<APPID>:<BucketName-APPID>/app/avatar/<Username>_s.jpg"
    ]

    참고 사례2: 작업(action)의 범위 제한 초과

    애플리케이션 B는 공유 포토월 기능을 제공하고 있으며, 모든 이미지는 app/photos/*에 저장됩니다. 클라이언트에서는 객체 조회(GET Bucket)와 객체 다운로드(GET Object) 작업이 동시에 필요하며, 백그라운드에서는 사용 편의를 위해 임시 키 생성 시 직접 action을 name/cos:*로 지정하였습니다. 이때 악성 사용자가 네트워크 패킷 캡쳐 등의 수단을 사용하여 생성된 임시 키를 획득하면 해당 리소스 경로 하의 모든 객체에 대해 모든 객체 작업(예: 업로드 및 삭제 등의 작업)을 실행할 수 있으며, 권한을 초과한 액세스가 발생해 데이터가 손실되고 온라인 비즈니스에 영향을 미칠 수 있습니다.

    보안 규범

    action은 임시 키가 요청을 허용하는 작업을 대표하며, 원칙적으로 name/cos:* 등을 사용한 모든 작업의 임시 키를 프런트 엔드에 전달하는 행위를 허용하지 않습니다. 반드시 모든 필요한 작업을 명확하게 나열해야 하며, 각 작업에 필요한 리소스 경로가 서로 다른 경우 병합 처리가 아닌 작업리소스 경로를 단독으로 매칭해야 합니다.
    해당 사례에서는 "action": [ "name/cos:GetBucket", "name/cos:GetObject" ]를 사용하여 구체적인 작업을 명확하게 지정해야 합니다. 권한 부여 작업 가이드에 대한 사항은 COS API 권한 부여 정책 사용 가이드를 참고하십시오.

    참고 사례3: 리소스와 작업의 범위 제한 초과

    애플리케이션 C는 관리 툴을 제공하고 있으며, 사용자에게 모든 사용자들의 파일(app/files/*)을 조회하고 다운로드할 수 있도록 허용하고, 업로드 및 삭제는 개인 디렉터리의 파일(app/files/<Username>/*)만 작업할 수 있도록 제공합니다. 백그라운드에서의 사용 편의를 위해 임시 키 생성 시 해당 두 권한에 대해 4가지 작업(action)을 함께 혼합하여 사용합니다. 두 권한의 해당 리소스 경로 또한 혼합하여 함께 사용하며, 이때의 임시 키는 리소스 경로에서 지정한 권한보다 더 큰 권한을 가지게 됩니다. 즉, 모든 사용자들의 파일에 대한 조회, 다운로드, 업로드, 삭제 권한을 가지게 됩니다. 악성 사용자가 이에 따라 타인의 파일을 조작하거나 삭제할 수 있으며 권한을 초과한 액세스가 발생하여 사용자의 합법적 데이터가 유출될 리스크가 있습니다.

    보안 규범

    여러 action과 resource의 조합은 간단하게 이들을 각각 병합하는 방법을 사용해서는 안 되며, 여러 statement 형식으로 조합해야 합니다. 간단하게 각각 병합하는 경우 권한이 커질 수 있습니다.
    해당 사례에서는 반드시 아래와 같이 사용해야 합니다.
    "statement": [
    {
    "effect": "allow",
    "action": [
    "name/cos:GetBucket",
    "name/cos:GetObject"
    ],
    "resource": "qcs::cos:<Region>:uid/<APPID>:<BucketName-APPID>/app/files/*"
    },
    {
    "effect": "allow",
    "action": [
    "name/cos:PutObject",
    "name/cos:DeleteObject"
    ],
    "resource": "qcs::cos:<Region>:uid/<APPID>:<BucketName-APPID>/app/files/<Username>/*"
    }
    ]

    참고 사례4: 권한을 초과한 임시 키 획득

    애플리케이션 D는 포럼 애플리케이션을 제공하고 있으며, 포럼의 포스팅 첨부파일이 COS에 저장됩니다. 해당 포럼 애플리케이션은 각 사용자 레벨별로 포스팅 수가 일정 임계값에 도달하여 활성화된 사용자만 특정 페이지 내의 포스팅과 첨부파일을 볼 수 있도록 제공하고, 일부 공개 페이지는 모든 사용자가 해당 페이지 내의 포스팅과 첨부 파일을 볼 수 있습니다. COS 사용 시, 백그라운드의 임시 키 생성 인터페이스는 프런트 엔드가 전송하는 페이지 ID에 따라 해당 페이지의 첨부파일에 대한 다운로드를 허용하는 임시 키를 생성합니다. 그러나 실현 과정에서 백그라운드에서 요청 사용자가 지정 페이지 ID 액세스 권한을 보유하고 있는지 여부를 판단할 수 없어 모든 사람이 해당 인터페이스를 요청하면 개인 페이지의 첨부파일에 대한 액세스 임시 키를 획득할 수 있게 됩니다. 이때 권한을 초과하는 액세스가 발생해 액세스를 제한하는 리소스에 대해 효과적으로 제한할 수 없게 되며 의도치 않은 데이터 유출 문제가 발생할 수 있습니다.

    보안 규범

    임시 키를 획득하는 인터페이스는 획득하는 임시 키 자체의 권한이 사전 설정된 범위 내여야 하며, 권한이 낮은 사용자가 높은 권한의 임시 키를 획득하지 못하도록 실제 업무 시나리오, 즉 권한이 정확한 사용자에 의해 요청되었는지 여부를 정확하게 판단해야 합니다.
    본 사례에서는 백그라운드 인터페이스에서 반드시 현재 요청하는 사용자가 특정 페이지에 액세스할 수 있는 권한이 있는지 여부를 판단하여 액세스 권한이 없는 사용자에게 임시 키 반환을 허용하지 않아야 합니다.

    결론

    이상의 사례로 예상 외로 임시 키의 권한이 확대되어 발생할 수 있는 보안 리스크를 설명하였습니다. 프런트 엔드에서 직접 COS에 전송하는 경우, 악성 사용자가 비교적 쉽게 임시 키 내용을 획득할 수 있습니다. 따라서 개발자는 해당 시나리오의 경우 백그라운드를 통한 COS 액세스에 비해 권한 제어에 대해 더욱 유의해야 합니다.
    본 문서에서의 보안 규범은 최소한의 권한 원칙으로, 실제 사용에서는 action과 resource에 따라 모든 가능한 권한을 나열할 수 있습니다. 예를 들어 action 3개, resource 2개가 있다면 액세스가 허용되는 리소스와 해당 작업을 3x2=6개로 산출할 수 있으며, 이에 따라 각 상황별로 예상에 부합하는지 여부를 평가하여 예상 권한 범위를 초과하는 경우 여러 statement를 나열하는 방식으로 권한을 분할하는 방법을 고려해야 합니다.
    이외에도 임시 키 생성에 사용하는 인터페이스는 자체적으로 자격 인증과 인증 처리를 충분히 고려해야 합니다. 임시 키를 획득하는 행위가 안전하다면, 해당 방법으로 획득한 임시 키에 대해 진정한 보안이 실현되는 것입니다. 보안이라는 연결 고리에는 어떠한 소홀함도 있어서는 안 됩니다!
    문의하기

    고객의 업무에 전용 서비스를 제공해드립니다.

    기술 지원

    더 많은 도움이 필요하시면, 티켓을 통해 연락 바랍니다. 티켓 서비스는 연중무휴 24시간 제공됩니다.

    연중무휴 24시간 전화 지원