Amazon Web Services 한국 블로그
Amazon CodeArtifact 패키지 그룹 기반 소프트웨어 공급망 보안 개선 하기
오늘부터 패키지 리포지토리 관리자는 새로운 AWS CodeArtifact 패키지 그룹 구성 기능을 사용하여 여러 패키지의 구성을 한 곳에서 관리할 수 있습니다. 패키지 그룹을 사용하면 내부 개발자가 패키지를 업데이트하거나 업스트림 리포지토리에서 패키지를 업데이트하는 방법을 정의할 수 있습니다. 이제 내부 개발자의 패키지 게시를 허용 또는 차단하거나, 패키지 그룹에 대한 업스트림 업데이트를 허용 또는 차단할 수 있습니다.
CodeArtifact는 완전 관리형 패키지 리포지토리 서비스로, 이 서비스를 사용하면 조직은 애플리케이션 개발에 사용하는 소프트웨어 패키지를 안전하게 저장하고 공유할 수 있습니다. CodeArtifact는 NuGet, Maven, Gradle, npm, yarn, pip, twine, Swift Package Manager 같은 대중적인 빌드 도구 및 패키지 관리자와 함께 사용할 수 있습니다.
CodeArtifact는 npmjs.com, maven.org, pypi.org 같은 퍼블릭 리포지토리에서 패키지를 온디맨드로 가져오는 기능을 지원합니다. 이 기능을 사용하면 조직의 개발자는 CodeArtifact 리포지토리라는 단일 소스에서 모든 패키지를 가져올 수 있습니다.
간단한 애플리케이션은 보통 수십 개의 패키지를 포함합니다. 대형 애플리케이션은 수백 개의 종속 항목을 포함할 수 있습니다. 이 패키지는 네트워크 액세스, 암호화 기능 또는 데이터 형식 조작 등의 일반적인 프로그래밍 문제를 해결하는 코드를 제공하기 때문에 개발자는 개발 및 테스트 프로세스의 속도를 높일 수 있습니다. 이러한 패키지는 조직의 다른 팀에서 제작하거나 오픈 소스 프로젝트와 같은 타사에서 유지 관리할 수 있습니다.
공급망 공격 위험을 최소화하기 위해, 일부 조직에서는 내부 리포지토리에서 사용할 수 있는 패키지와 이러한 패키지를 업데이트할 권한이 있는 개발자를 수동으로 검사합니다. 리포지토리에 있는 패키지는 세 가지 방법으로 업데이트할 수 있습니다. 조직에서 선정된 개발자가 패키지 업데이트를 푸시할 수 있습니다. 이 방법은 주로 조직의 내부 패키지에 적용됩니다. 업스트림 리포지토리에서 패키지를 가져올 수도 있습니다. 업스트림 리포지토리는 승인된 패키지의 전사적 소스인 포진해보리, 인기 있는 오픈 소스 패키지를 제공하는 외부 공개 리포지토리 같은 또 다른 CodeArtifact 리포지토리입니다.
다음은 개발자에게 패키지를 노출하는 다양한 방법을 보여주는 다이어그램입니다.리포지토리를 관리할 때는 패키지를 다운로드하고 업데이트할 수 있는 방법을 반드시 정의해야 합니다. 외부 업스트림 리포지토리에서의 패키지 설치 또는 업데이트를 허용하면 조직은 typosquatting이나 dependency confusion 같은 공격에 노출됩니다. 악의적인 공격자가 잘 알려진 패키지의 악성 버전을 이름만 조금 바꿔 게시한다고 상상해 보세요. 예를 들어 coffee-script
의 경우 ‘f’가 하나만 있는 악성 패키지 cofee-script
를 게시하는 식입니다. 업스트림 외부 리포지토리에서의 검색을 허용하도록 리포지토리를 구성하면, 주의가 산만한 개발자가 야근할 때 npm install coffee-script
대신 npm install cofee-script
를 입력하면 악성 코드가 시스템에 침투하게 됩니다.
CodeArtifact는 패키지를 업데이트하는 세 가지 방법에 대한 세 가지 권한을 정의합니다. 관리자는 내부 게시
명령, 내부 업스트림 리포지토리 또는 외부 업스트림 리포지토리에서 전달되는 설치와 업데이트를 허용
하거나 차단
할 수 있습니다.
지금까지는 저장소 관리자가 이러한 중요 보안 설정을 패키지별로 따로 관리해야 했습니다. 오늘 업데이트를 통해 리포지토리 관리자는 이러한 세 가지 보안 파라미터를 패키지 그룹을 대상으로 한 번에 정의할 수 있습니다. 패키지는 유형, 네임스페이스 및 이름을 기준으로 식별됩니다. 이 새로운 기능은 리포지토리 수준이 아닌 도메인 수준에서 적용됩니다. 이 기능을 사용하면 관리자는 도메인 내 모든 리포지토리의 패키지 그룹에 규칙을 적용할 수 있습니다. 모든 리포지토리에서 패키지 원본 제어 구성을 유지하지 않아도 됩니다.
작동 방식 자세히 살펴보기
CodeArtifact를 이용해 내부 패키지 리포지토리를 관리하고 있는 상황에서, 조직에서 검증한 (boto3라고도 하는) AWS SDK for Python 버전만 배포하고 싶다고 가정하겠습니다.
AWS Management Console의 CodeArtifact 페이지로 이동하여, 내부 개발자에게 검증된 패키지를 제공할 python-aws
리포지토리를 만듭니다.
이렇게 하면 내가 만든 리포지토리 외에 스테이징 리포지토리도 생성됩니다. pypi
의 외부 패키지는 먼저 pypi-store
내부 리포지토리에서 스테이징되며, 저는 이러한 패키지를 검증한 다음 python-aws
리포지토리에 제공합니다. 여기서는 개발자들이 연결하여 패키지를 다운로드합니다.
기본적으로 개발자가 CodeArtifact를 대상으로 인증하고 pip install boto3
를 입력하면, CodeArtifact는 퍼블릭 pypi
리포지토리에서 패키지를 다운로드하고 pypi-store
에서 스테이징한 다음 python-aws
에 복사합니다.
지금부터는 CodeArtifact가 어그러트림 외부 pypi
리포지토리에서 패키지를 가져오지 못 하게 하겠습니다. python-aws
가 제가 pypi-store
내부 리포지토리에서 승인한 패키지만 제공하게 해야 합니다.
오늘 출시한 새 기능을 사용하면 이제 이 구성을 패키지 그룹에 적용할 수 있습니다. 제 도메인으로 이동하여 Package Groups 탭을 선택합니다. 그런 다음 Create Package Group 버튼을 선택합니다.
Package group definition을 입력합니다. 이 표현식은 이 그룹에 포함되는 패키지를 정의합니다. 패키지는 패키지 형식, 선택적 네임스페이스와 이름이라는 세 가지 구성 요소의 조합을 사용하여 식별합니다.
다음은 허용된 각 조합에 사용할 수 있는 대표적인 패턴입니다.
- 모든 패키지 형식: /*
- 특정 패키지 형식: /npm/ *
- 패키지 형식 및 네임스페이스 접두사: /maven/com.amazon ~
- 패키지 형식 및 네임스페이스: /npm/aws-amplify/ *
- 패키지 형식, 네임스페이스 및 이름 접두사: /npm/aws-amplify/ui ~
- 패키지 형식, 네임스페이스 및 이름: /maven/org.apache.logging.log4j/log4j-core $
설명서를 읽어 모든 가능성을 확인해 보시기 바랍니다.
제가 든 예시에서는 Python 패키지용 네임스페이스라는 개념이 없으며, 저는 pypi
에서 제공하며 이름이 boto3
로 시작하는 모든 패키지를 그룹에 포함하려 합니다. 따라서 /pypi//boto3~
라고 입력해야 합니다.
그런 다음에는 패키지 그룹의 보안 파라미터를 정의합니다. 이 예시에서는 조직의 개발자가 업데이트를 게시해선 안 됩니다. 또한 CodeArtifact가 외부 업스트림 리포지토리에서 새 버전을 가져와서도 안 됩니다. 저는 내부 스테이징 디렉터리에 있는 패키지 업데이트만 승인해야 합니다.
Inherit from parent group 상자를 모두 선택 취소합니다. Publish와 External upstream에 Block을 선택합니다. Internal upstream은 그대로 Allow를 선택합니다. 그런 다음 Create Package Group을 선택합니다.
정의가 끝나면 개발자는 python-aws
리포지토에서 승인된 버전이 아닌 다른 패키지 버전은 설치할 수 없게 됩니다. 제가 개발자 자격으로 boto3
패키지의 다른 버전을 설치하려고 하면 오류 메시지가 표시됩니다. 이것은 자연스러운 현상인데, boto3
패키지 신규 버전을 업스트립 스테이징 리포지토리에서 사용할 수 없으며 외부 업스트립 리포지토리가 패키지나 패키지 업데이트를 가져오지 못하게 하는 차단
규칙이 있기 때문입니다.
마찬가지로, 관리자가 종속성 대체 공격으로부터 조직을 보호하려고 한다고 가정해 보겠습니다. 모든 내부 Python 패키지 이름은 회사 이름(mycompany
)으로 시작합니다. 관리자는 개발자가 이름이 mycompany
로 시작하는 pypi.org
패키지를 실수로 다운로드하는 일이 없게 해야 합니다.
관리자는 publish=allow
, external upstream=block
, internal upstream=block
을 적용한 /pypi//mycompany~
패턴이 있는 규칙을 만듭니다. 이 구성을 사용하면 내부 개발자나 CI/CD 파이프라인은 이러한 패키지를 게시할 수 있지만, CodeArtifact는 이름이 mycompany
로 시작하는 pypi.org
(예: mycompany.foo
또는 mycompany.bar
)에서 패키지를 가져오지 않습니다. 이렇게 하면 이러한 패키지에 대한 종속성 대체 공격을 방지할 수 있습니다.
CodeArtifact를 사용할 수 있는 모든 AWS 리전에서 패키지 그룹을 추가 비용 없이 사용할 수 있습니다. 따라서 패키지 및 패키지 업데이트가 내부 저장소에 저장되는 방식을 더 효과적으로 제어할 수 있습니다. typosquatting이나 dependency confusion 같은 다양한 공급망 공격을 방지하는 데도 도움이 됩니다. 이것은 코드형 인프라(IaC) 도구에 지금 바로 추가하여 CodeArtifact 리포지토리를 만들고 관리할 수 있는 추가 구성입니다.