사용하는 PHP 패키지의 취약점 여부를 진단해 주는 Security Advisories Checker
개요
이제 보안은 "하면 좋고 아니면 그만" 에서 고객과 비즈니스를 보호하기 위한 핵심 컴포넌트라는 인식이 널리 퍼져 나고 있는 것 같습니다.
PHP 개발도 운영체제에 최신 패치 적용, PHP 엔진 보안 패치등 시스템 측면에서 보안 패치를 중요하게 생각하고 있고 SQL Injection, Cross Site Script 등 애플리케이션 측면의 취약점을 막고 견고한 웹 서비스를 개발하기 위한 시큐어 코딩의 중요성에 대해 공감대가 형성되고 있습니다.
공격도 마찬가지이지만 방어하는 입장에서도 어떤 취약점이 있고 해당 취약점의 위험도는 무엇인지를 알아야 중요도와 우선순위를 정할수 있고 이에 따라 적절한 방어 대책을 수립할 수 있습니다.
이때 주요 취약점을 식별하기 위한 좋은 방법중에 하나는 오픈소스 웹 애플리케이션 보안 취약점 프로젝트인 OWASP 에서는 주기적으로 발표하는 10대 웹 취약점입니다.
아직 RC1 버전이긴 하지만 2017년에 발표된 Top 10 에 드는 취약점중에 9번째인 "A9: Using Components with Known Vulnerabilities (알려진 취약점이 있는 컴포넌트 사용)" 는 사용하는 외부 컴포넌트가 취약성을 갖고 있음에 따라 발생하는 취약점으로 10위안에 들 정도로 중요한 취약점이며 2013년에도 포함되어 있는 중요한 취약점입니다.
대응 방안
혹시 외부 컴포넌트를 사용하는게 문제이므로 직접 만들어 써야 겠다고 생각하시지는 않는지요?
여러분이 직접 잘 만든 컴포넌트는 기능과 함께 보안을 고려해서 더 안전할 수도 있지만 프로그래밍의 도(Tao of Programming) 에 나오는 master 프로그래머가 아닌 이상 처음 버전에서 그러기는 쉽지 않고 오히려 보안 취약점이 있는지도 모르고 넘어갈 수 있는 위험이 있습니다.
이런 취약점에 대비하기 위한 기본은 composer 같은 패키지 매니저를 사용하여 외부 의존성을 손쉽게 교체할 수 있도록 하는 것이며 외부 컴포넌트를 교체할 때 어떤 위험이 있는지 알기 위해 유의적 버전(Semantic Versioning)을 익히는 것입니다.
컴포저를 사용하여 외부 패키지의 의존성을 관리하고 유의적 버전을 이해했다면 다음은 사용하는 외부 패키지가 어떤 취약점(Vulnerability)이 있는지를 확인하는 것이 필요합니다.
유명한 패키지에서 발견된 취약점은 CVE(Common Vulnerabilities and Exposure) 라는 방식을 이용하여 해당 취약점이 유일한 키를 갖도록 분류하고 있으므로 CVE Database(https://cve.mitre.org/find/) 에서 검색해서 나온 결과중에 사용하는 패키지가 있는지 확인하면 됩니다.
예로 라라벨에서도 내부적으로 사용하고 있는 유명한 PHP 메일 전송 라이브러리인 swiftmailer 의 취약점을 검색해 보면 아래와 같은 결과를 볼 수 있으며 해당 버전을 사용하고 있다면 composer.json 의 버전을 높여서 취약점이 해결된 버전을 사용하면 됩니다.
하지만 사용하는 패키지가 많고 패키지가 또 외부 패키지를 참조한다면 일일이 의존성을 확인해서 패키지를 입력해서 취약점과 버전을 확인하는 것은 너무 큰 일입니다.
Security Advisories Checker
이런 문제를 해결하기 위해 유명한 PHP 프레임워크인 Symfony 를 만든 SensioLabs 에서는 composer.lock 에 등록된 패키지의 취약점 점검을 자동으로 수행해 주는 Security Advisories checker 라는 제품을 내놓았습니다.
사용은 아주 간단하며 https://security.symfony.com/ 에 연결해서 프로젝트에서 사용하는 composer.lock 를 업로드하고 check 를 클릭하면 됩니다.
CI 와 연결하거나 커밋시마다 취약점 검사를 하는등의 자동화가 필요하다면 Command line 도구를 https://get.sensiolabs.org/security-checker.phar 에서 다운받아서 실행해도 됩니다.
$ php security-checker.phar security:check /path/to/composer.lock
현재는 라이센스가 바뀌어서 검사 건수 제한이 있으므로 무제한 검사를 하려면 subscription 을 가입해야 합니다.
subscription 에 가입하면 WEB API 기반으로 사용할 수가 있습니다. 예로 composer.lock 이 있는 프로젝트 폴더에서 아래 curl 명령으로 현재 사용하는 패키지의 취약점 여부를 점검할 수 있으며 취약점이 있는 패키지가 있을 경우 아래와 같이 취약점의 갯수와 함께 자세한 취약점 정보를 출력해 줍니다.
$ curl -H 'Content-Type: application/json' \ --url 'https://security.symfony.com/api/patch-lock?id=SUBSCRIPTION-UUID' \ --data '@composer.lock'
Security Report =============== The checker detected 1 package(s) that have known* vulnerabilities in your project. We recommend you to check the related security advisories and upgrade these dependencies. swiftmailer/swiftmailer (v5.4.1) -------------------------------- CVE-2016-10074: Remote Code Execution when using the mail transport https://legalhackers.com/advisories/SwiftMailer-Exploit-Remote-Code-Exec-CVE-2016-10074-Vuln.html * Disclaimer: This checker can only detect vulnerabilities that are referenced in the SensioLabs security advisories database.
만약 다른 형식의 결과를 보고 싶다면 Accept 헤더에 원하는 content 형식을 넣어주면 되며 예로 html 로 받을 경우 아래와 같이 입력하면 됩니다.
$ curl -H 'Content-Type: application/json' \ -H "Accept: text/html" \ --url 'https://security.symfony.com/api/patch-lock?id=SUBSCRIPTION-UUID' \ --data '@composer.lock'
결과를 재활용하기 위해 응답을 json 형식으로 요청할 수도 있습니다.
$ curl -H 'Content-Type: application/json' \ -H "Accept: application/json" \ --url 'https://security.symfony.com/api/patch-lock?id=SUBSCRIPTION-UUID' \ --data '@composer.lock'
현재 프로젝트에서 사용중인 패키지중 취약점이 있는 갯수는 X-Alerts HTTP 헤더에 포함되어 전송되므로 이 헤더의 값을 꺼내서 갯수를 파악하면 됩니다.
$ curl -v -H "Accept: application/json" 'https://security.symfony.com/api/patch-lock?id=SUBSCRIPTION-UUID' -F lock=@composer.lock * Connection state changed (MAX_CONCURRENT_STREAMS updated)! < HTTP/2 200 < cache-control: no-cache, private < content-type: application/json < date: Mon, 21 Aug 2017 15:06:53 GMT < x-alerts: 1 < x-correlation-id: iynedzgqah27xni6cjzgetsf < x-sensiocloud-cluster: vew2qlx3q3q5s-master-7rqtwti < x-sensiocloud-processor: lrulya64jw4swh4gabscug5fjq < x-sensiocloud-router: l3wvkn3gz2wprefxu3grtfrffi < content-length: 433 < { "swiftmailer\/swiftmailer": { "version": "v5.4.1", "advisories": { "swiftmailer\/swiftmailer\/CVE-2016-10074.yaml": { "title": "Remote Code Execution when using the mail transport", "link": "https:\/\/legalhackers.com\/advisories\/SwiftMailer-Exploit-Remote-Code-Exec-CVE-2016-10074-Vuln.html", "cve": "CVE-2016-10074" } } } }
아직 발표되지 않은 취약점이거나 취약점 DB 에 없는 패키지라면 검출할 수 없으니 주의하세요.
사용하는 패키지에서 취약점이 발견되었다면 해당 취약점이 패치된 버전이 있는지 확인해보고 composer.json 에 패치된 버전을 기술한 후에 composer update 를 실행하면 됩니다.
새로운 버전의 패키지 사용시 버전 향상에 따른 영향을 최소화하기 위해 유의적 버전에서 patch 버전만 올리는 것을 권장합니다.