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/
명령어 주입이 위험한 이유는 무엇인가요? 명령 주입은 공격자가 서버에서 임의의 명령을 실행할 수 있게 하여 다음과 같은 심각한 결과를 초래할 수 있으므로 위험합니다.
성공적인 명령 주입 공격의 영향은 파괴적일 수 있으며 손상된 시스템뿐만 아니라 조직의 평판과 고객 신뢰에도 영향을 미칠 수 있습니다.
단순성과 성능을 선호하는 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와 같은 사용자 제공 입력을 사용하여 명령 문자열을 구성합니다. 이러한 입력이 제대로 검증되지 않으면 공격자가 악성 명령을 주입할 수 있습니다.
입력 유효성 검사를 개선할 수 있는 방법은 다음과 같습니다.
다음은 이러한 관행을 구현할 수 있는 방법의 예입니다.
func handler(req *http.Request) { cmdName := req.URL.Query()["cmd"][0] cmd := exec.Command(cmdName) cmd.Run() }
그럼에도 불구하고 우리는 명령 삽입으로부터 Go 코드를 보호하기 위해 훨씬 더 나은 조치를 취할 수 있습니다. 계속 읽어보세요!
또 다른 효과적인 전략은 가능하면 시스템 명령을 직접 실행하지 않는 것입니다. 대신 애플리케이션을 명령 삽입 위험에 노출시키지 않으면서 필요한 기능을 제공하는 안전한 API 또는 라이브러리를 활용하세요.
예를 들어 애플리케이션이 이미지를 조작해야 하는 경우 ImageMagick 소프트웨어 라이브러리에서 변환과 같은 외부 명령을 호출하는 대신 github.com/disintegration/imaging과 같은 Go 라이브러리를 사용하는 것이 좋습니다. 이 접근 방식은 Go의 유형 안전 환경 내 기능을 캡슐화하여 공격 표면을 줄입니다.
http://example.com/execute?cmd=rm%20-rf%20/
Go에서 이미징과 같은 라이브러리를 사용하면 셸 명령을 구성하고 실행할 필요가 없으므로 명령 삽입 위험이 완화됩니다. 그러나 일부 라이브러리 및 언어 생태계에서는 타사 패키지가 명령 실행을 둘러싼 간단한 래퍼일 가능성이 있으므로 민감한 작업에 대한 코드를 검토하는 것이 필수입니다.
이전 예에서는 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 Code는 개발자가 코드베이스의 취약점을 식별하고 수정하는 데 도움이 되는 강력한 정적 분석 도구입니다. IDE 및 개발 워크플로에 원활하게 통합되어 잠재적인 보안 문제에 대한 실시간 피드백을 제공합니다.
제공된 Go 예제에서 downloadAndResize 함수는 사용자 제공 입력을 사용하여 셸 명령을 구성합니다.
http://example.com/execute?cmd=rm%20-rf%20/
이 코드는 사용자 입력을 명령 문자열에 직접 통합하기 때문에 명령 주입에 취약합니다.
팀에 명령 주입 취약점을 인식하지 못하는 개발자가 있다면 어떨까요?
이 명령 주입 취약점을 찾기 위해 코드 검토에서 파일 간 정적 분석 호출 흐름을 쉽게 찾아낼 수 있습니까?
여기서 Snyk이 등장합니다.
VS Code 편집기 내에서 실시간으로 취약한 코드를 강조 표시하는 Snyk Code 확장 프로그램을 통해 애플리케이션 보안이 어떻게 쉬워지는지 살펴보세요.
Snyk는 Go 코드를 스캔하고 셸 명령에서 사용자 입력이 안전하지 않게 사용되는 인스턴스에 플래그를 지정하여 이러한 취약점을 식별하는 데 도움을 줄 수 있습니다. Snyk는 이 특정 취약점을 완화한 다른 오픈 소스 프로젝트의 실제 커밋을 보여 주므로 "좋은 모습"의 예로서 여러 코드 참조를 얻을 수 있습니다.
더욱이 문제 개요 탭을 클릭하면 명령 삽입 방지에 대한 자세한 내용과 모범 사례를 드릴다운할 수 있습니다. 이 탭은 이러한 위험을 완화하는 방법에 대한 자세한 통찰력과 권장 사항을 제공하며 코딩하는 동안 IDE 보기에서 바로 사용할 수 있으며 비용이 많이 드는 컨텍스트 전환 없이 다음 작업을 수행할 수 있습니다.
이러한 취약점으로부터 코드를 보호하는 방법에 대해 자세히 알아보려면 Snyk Code IDE 확장을 설치하고 Git 프로젝트를 연결하여 Go 애플리케이션의 보안 문제를 식별하고 수정하는 것을 고려해 보세요. 코드의 취약점 스캔을 시작하려면 가입하면 무료로 쉽게 수행할 수 있습니다.
위 내용은 Go의 명령 주입 취약점 이해의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!