> 백엔드 개발 > Golang > Go의 명령 주입 취약점 이해

Go의 명령 주입 취약점 이해

DDD
풀어 주다: 2024-11-26 00:49:14
원래의
644명이 탐색했습니다.

Go 개발자는 이미지 조작과 같은 다양한 시나리오에 대해 시스템 명령을 사용해야 할 수 있습니다. 여기서는 이미지를 처리하거나 크기를 조정하거나 시스템 명령을 실행하여 리소스를 관리하거나 메트릭 또는 로그를 수집해야 합니다.

다른 경우에는 기존 레거시 시스템과 인터페이스해야 하는 새로운 시스템을 Go로 구축하고 있을 수도 있습니다. 이 인터페이스는 시스템 명령 실행 및 출력 처리에 의존합니다.

두 경우 모두 시스템 명령을 생성할 때 보안 코딩 규칙을 따르는 것이 중요합니다. 그렇게 하면 명령 삽입이라는 보안 취약점이 발생할 수 있습니다.

명령 주입이란 무엇입니까?

명령 주입은 애플리케이션이 안전하지 않은 사용자 제공 데이터(예: 웹 양식의 입력)를 시스템 셸로 전달할 때 발생하는 보안 취약성입니다. 이 취약점을 통해 공격자는 동일한 애플리케이션 사용자로 호스트 운영 체제에서 임의의 명령을 실행할 수 있습니다.

Go에서 명령 주입에는 시스템 명령을 생성하기 위해 os/exec 패키지를 사용하는 경우가 많습니다.

다음 Go 코드 예제를 고려하세요.

func handler(req *http.Request) {
  cmdName := req.URL.Query()["cmd"][0]
  cmd := exec.Command(cmdName)
  cmd.Run()
}
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사

이 코드 조각에서 cmdName은 요청 쿼리 매개변수에서 직접 추출되어 서버에서 실행되는 명령을 구성하는 데 사용됩니다. 이는 공격자가 cmd 쿼리 문자열 값을 조작하여 자신이 선택한 명령을 실행하여 잠재적으로 서버를 손상시킬 수 있기 때문에 명령 주입 취약점의 전형적인 예입니다.

공격자는 다음과 같은 악의적인 명령을 사용하여 요청을 조작할 수 있습니다.

http://example.com/execute?cmd=rm%20-rf%20/
로그인 후 복사
로그인 후 복사
로그인 후 복사

명령어 주입이 위험한 이유는 무엇인가요? 명령 주입은 공격자가 서버에서 임의의 명령을 실행할 수 있게 하여 다음과 같은 심각한 결과를 초래할 수 있으므로 위험합니다.

  • 데이터 침해: 공격자는 서버에 저장된 민감한 데이터에 접근할 수 있습니다. config.toml 및 리소스와 자격 증명을 나열하는 기타 구성 파일에 액세스한다고 상상해 보세요.
  • 시스템 손상: 공격자가 서버에 대한 제어권을 획득하여 추가 악용으로 이어질 수 있습니다. 이는 손상된 시스템 내의 측면 이동 및 손상될 수 있는 다른 서버에 대한 검색 작업의 형태를 취하는 경우가 많습니다.
  • 서비스 중단: 공격자는 서비스를 중단시키는 명령을 실행하여 다운타임을 일으킬 수 있습니다. 사실상 이는 서비스 거부 공격으로 인한 금전적 손실 및 비즈니스 위험으로 직접적으로 이어질 수 있습니다.

성공적인 명령 주입 공격의 영향은 파괴적일 수 있으며 손상된 시스템뿐만 아니라 조직의 평판과 고객 신뢰에도 영향을 미칠 수 있습니다.

Go에서 취약한 프로세스 실행 및 명령 주입

단순성과 성능을 선호하는 Go 개발자는 이러한 유틸리티의 기능을 활용하기 위해 시스템 명령을 통합하기로 선택할 수 있습니다. 이 접근 방식을 통해 그들은 바퀴를 재발명하지 않고도 강력한 애플리케이션을 구축하는 데 집중할 수 있습니다. 그러나 이러한 통합에는 특히 보안 측면에서 그 자체의 과제가 따릅니다.

더 현실적인 시나리오를 설명하려면 변환과 같은 명령줄 유틸리티를 사용하여 이미지 파일을 처리하는 Go 애플리케이션을 고려해 보세요.

이미지 크기 조정 요청을 처리하도록 설계된 Go 애플리케이션을 살펴봅니다. 애플리케이션은 Gin 웹 프레임워크를 사용하여 사용자 입력에 따라 이미지 크기 조정을 처리하는 POST 엔드포인트 /cloudpawnery/image를 정의합니다. 이 끝점은 쿼리 문자열에서 테넌트 ID, 파일 ID 및 파일 크기와 같은 매개 변수를 허용합니다. fileSize 매개변수는 선택사항이며 제공되지 않은 경우 기본값은 "200"입니다.

다음 코드 조각은 Go의 취약한 구현을 보여줍니다.

func handler(req *http.Request) {
  cmdName := req.URL.Query()["cmd"][0]
  cmd := exec.Command(cmdName)
  cmd.Run()
}
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사

downloadAndResize 함수는 변환을 사용하여 이미지 크기를 조정하는 명령 문자열을 구성하고 exec.CommandContext를 사용하여 실행합니다.

downloadAndResize 함수는 명령 문자열을 어떻게 구성하나요? 사용자가 제공한 fileSize를 사용하여 이 입력을 받습니다. 그런 다음 이 문자열이 실행되어 잠재적으로 공격자가 악성 명령을 주입할 수 있습니다. 이러한 위험을 완화하려면 Go 개발자는 모든 사용자 입력을 검증 및 삭제하고, 매개변수화된 명령을 사용하고, 명령 실행을 안전하게 처리하는 보안 방식을 활용해야 합니다.

명령 주입 취약점 완화

Go 개발에서는 다른 언어와 마찬가지로 명령 삽입 취약점으로부터 코드를 보호하는 것이 무엇보다 중요합니다. 명령 주입은 공격자가 호스트에서 임의의 명령을 실행할 수 있을 때 발생하며, 이로 인해 무단 액세스, 데이터 침해 및 기타 심각한 보안 문제가 발생할 수 있습니다.

이러한 위험을 완화하기 위한 몇 가지 모범 사례를 살펴보겠습니다.

입력 검증 및 위생

명령 삽입을 방지하기 위한 기본 단계 중 하나는 엄격한 입력 검증 및 삭제입니다. 제공된 예에서 downloadAndResize 함수는 fileSize와 같은 사용자 제공 입력을 사용하여 명령 문자열을 구성합니다. 이러한 입력이 제대로 검증되지 않으면 공격자가 악성 명령을 주입할 수 있습니다.

입력 유효성 검사를 개선할 수 있는 방법은 다음과 같습니다.

  1. 허용 목록 입력: fileSize와 같은 입력에 허용되는 값 집합을 정의합니다. 예를 들어, 합리적인 범위에 속하는 숫자 값만 허용합니다.
  2. 입력 삭제: 사용자 입력에서 잠재적으로 위험한 문자를 제거하거나 이스케이프 처리합니다. 여기에는 ;, |, & 등과 같은 셸 메타 문자가 포함될 수 있습니다. 명령을 하드 코딩하고 사용자 입력으로 제어할 수 없도록 하는 것이 가장 좋습니다.
  3. 엄격한 유형 사용: 가능한 한 빨리 입력을 예상되는 데이터 유형으로 변환합니다. 예를 들어 fileSize를 정수로 변환하고 해당 범위의 유효성을 검사합니다.

다음은 이러한 관행을 구현할 수 있는 방법의 예입니다.

func handler(req *http.Request) {
  cmdName := req.URL.Query()["cmd"][0]
  cmd := exec.Command(cmdName)
  cmd.Run()
}
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사

그럼에도 불구하고 우리는 명령 삽입으로부터 Go 코드를 보호하기 위해 훨씬 더 나은 조치를 취할 수 있습니다. 계속 읽어보세요!

시스템 명령 대신 안전한 API 또는 라이브러리 사용

또 다른 효과적인 전략은 가능하면 시스템 명령을 직접 실행하지 않는 것입니다. 대신 애플리케이션을 명령 삽입 위험에 노출시키지 않으면서 필요한 기능을 제공하는 안전한 API 또는 라이브러리를 활용하세요.

예를 들어 애플리케이션이 이미지를 조작해야 하는 경우 ImageMagick 소프트웨어 라이브러리에서 변환과 같은 외부 명령을 호출하는 대신 github.com/disintegration/imaging과 같은 Go 라이브러리를 사용하는 것이 좋습니다. 이 접근 방식은 Go의 유형 안전 환경 내 기능을 캡슐화하여 공격 표면을 줄입니다.

http://example.com/execute?cmd=rm%20-rf%20/
로그인 후 복사
로그인 후 복사
로그인 후 복사

Go에서 이미징과 같은 라이브러리를 사용하면 셸 명령을 구성하고 실행할 필요가 없으므로 명령 삽입 위험이 완화됩니다. 그러나 일부 라이브러리 및 언어 생태계에서는 타사 패키지가 명령 실행을 둘러싼 간단한 래퍼일 가능성이 있으므로 민감한 작업에 대한 코드를 검토하는 것이 필수입니다.

주입을 방지하기 위해 취약한 downloadAndResize 함수를 리팩터링

이전 예에서는 exec.CommandContext 함수를 사용하여 셸 명령을 실행하는 잠재적으로 취약한 Go 애플리케이션을 시연했습니다. 이 접근 방식은 앞서 언급한 것처럼 명령 주입 취약점으로 이어질 수 있습니다.

사용자 입력으로 인해 임의의 명령이 실행되지 않도록 downloadAndResize 함수를 리팩터링해 보겠습니다.

명령 주입을 방지하는 효과적인 방법 중 하나는 사용자 입력에서 직접 셸 명령 문자열을 구성하지 않는 것입니다. 대신 별도의 인수와 함께 exec.Command 함수를 사용할 수 있습니다. 이는 셸을 호출하지 않고 사용자가 실제 명령을 제어할 수 없도록 허용하지 않고도 사용자 입력을 명령에 대한 매개변수로 안전하게 전달하는 데 도움이 됩니다.

다음은 명령 삽입 취약점을 해결하는 downloadAndResize 함수의 리팩터링 버전입니다.

func handler(req *http.Request) {
  cmdName := req.URL.Query()["cmd"][0]
  cmd := exec.Command(cmdName)
  cmd.Run()
}
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사

이 리팩터링에서는 명령과 인수를 분리했습니다. 별도의 인수와 함께 exec.CommandContext를 사용하면 쉘 명령 문자열을 구성할 필요가 없습니다. 이 방법을 사용하면 사용자 입력이 실행 코드가 아닌 데이터로 처리되어 명령 삽입 위험이 크게 줄어듭니다.

또한 셸 호출의 필요성도 제거되었습니다. 리팩터링된 코드는 명령 주입을 위한 공통 벡터인 셸(sh -c)을 호출하지 않습니다. 대신 지정된 인수를 사용하여 변환 유틸리티를 직접 호출합니다.

코드 보안을 위해 Snyk 활용

Snyk Code는 개발자가 코드베이스의 취약점을 식별하고 수정하는 데 도움이 되는 강력한 정적 분석 도구입니다. IDE 및 개발 워크플로에 원활하게 통합되어 잠재적인 보안 문제에 대한 실시간 피드백을 제공합니다.

Snyk가 Go의 명령 주입 취약점을 식별하는 데 어떻게 도움이 됩니까?

제공된 Go 예제에서 downloadAndResize 함수는 사용자 제공 입력을 사용하여 셸 명령을 구성합니다.

http://example.com/execute?cmd=rm%20-rf%20/
로그인 후 복사
로그인 후 복사
로그인 후 복사

이 코드는 사용자 입력을 명령 문자열에 직접 통합하기 때문에 명령 주입에 취약합니다.

팀에 명령 주입 취약점을 인식하지 못하는 개발자가 있다면 어떨까요?

이 명령 주입 취약점을 찾기 위해 코드 검토에서 파일 간 정적 분석 호출 흐름을 쉽게 찾아낼 수 있습니까?

여기서 Snyk이 등장합니다.

VS Code 편집기 내에서 실시간으로 취약한 코드를 강조 표시하는 Snyk Code 확장 프로그램을 통해 애플리케이션 보안이 어떻게 쉬워지는지 살펴보세요.

Understanding command injection vulnerabilities in Go
Snyk는 Go 코드를 스캔하고 셸 명령에서 사용자 입력이 안전하지 않게 사용되는 인스턴스에 플래그를 지정하여 이러한 취약점을 식별하는 데 도움을 줄 수 있습니다. Snyk는 이 특정 취약점을 완화한 다른 오픈 소스 프로젝트의 실제 커밋을 보여 주므로 "좋은 모습"의 예로서 여러 코드 참조를 얻을 수 있습니다.

더욱이 문제 개요 탭을 클릭하면 명령 삽입 방지에 대한 자세한 내용과 모범 사례를 드릴다운할 수 있습니다. 이 탭은 이러한 위험을 완화하는 방법에 대한 자세한 통찰력과 권장 사항을 제공하며 코딩하는 동안 IDE 보기에서 바로 사용할 수 있으며 비용이 많이 드는 컨텍스트 전환 없이 다음 작업을 수행할 수 있습니다.

Understanding command injection vulnerabilities in Go
이러한 취약점으로부터 코드를 보호하는 방법에 대해 자세히 알아보려면 Snyk Code IDE 확장을 설치하고 Git 프로젝트를 연결하여 Go 애플리케이션의 보안 문제를 식별하고 수정하는 것을 고려해 보세요. 코드의 취약점 스캔을 시작하려면 가입하면 무료로 쉽게 수행할 수 있습니다.

위 내용은 Go의 명령 주입 취약점 이해의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

원천:dev.to
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿