CI/CD 파이프라인에 SAST, DAST, SCA 도구를 통합하여 개발 초기부터 보안 취약점을 자동 탐지하고 해결한 실무 경험과 전략을 공유합니다.
📑 목차
- 도입: 개발 속도와 보안, 두 마리 토끼를 잡을 수 있을까?
- 왜 CI/CD 파이프라인에 보안을 통합해야 할까? (Shift-Left의 중요성)
- SAST, DAST, SCA: 각 도구의 역할과 우리가 선택한 이유
- SAST (Static Application Security Testing)
- DAST (Dynamic Application Security Testing)
- SCA (Software Composition Analysis)
- CI/CD 파이프라인에 SAST/DAST/SCA 통합 실전 가이드
- 1단계: SAST 도구 연동 및 자동화
- 2단계: DAST 도구 연동 및 테스트 환경 구축
- 3단계: SCA 도구를 통한 오픈소스 취약점 관리
- 통합 후 마주한 도전과 해결 과정 (실무 경험 공유)
- SAST/DAST/SCA 통합의 실제 성과와 얻은 교훈
- 결론: 지속적인 보안 강화를 위한 여정
도입: 개발 속도와 보안, 두 마리 토끼를 잡을 수 있을까?
요즘 개발팀의 화두는 단연 빠른 배포와 안정적인 서비스 운영입니다. CI/CD 파이프라인을 구축하면서 개발 생산성은 비약적으로 높아졌죠. 하지만 이 속도 경쟁 속에서 늘 마음 한편에 불안감을 안고 있었던 것이 바로 보안 취약점 문제였습니다. 빠르게 코드를 배포하는 과정에서 자칫 보안 검토가 소홀해지거나, 뒤늦게 발견된 취약점으로 인해 서비스 장애나 심각한 보안 사고가 발생할까 봐 노심초사했던 경험, 다들 한 번쯤은 있으실 겁니다.
저희 팀도 비슷한 고민을 안고 있었습니다. 개발은 빠르게 진행되는데, 보안 테스트는 늘 배포 직전이나 심지어 배포 이후에야 수동으로 이루어지는 경우가 많았습니다. 결과는 뻔하죠. 뒤늦게 발견된 취약점은 수정하는 데 더 많은 시간과 비용을 소모하게 만들었고, 심지어 재배포로 이어져 서비스 안정성에도 악영향을 미쳤습니다. "개발 초기부터 보안을 신경 쓸 수는 없을까?" 이 질문에서 저희의 CI/CD 파이프라인 보안 강화 프로젝트가 시작되었습니다.
이번 글에서는 저희 팀이 CI/CD 파이프라인에 SAST, DAST, SCA 도구를 통합하여 개발 초기부터 보안 취약점을 자동 탐지하고 해결해 나간 실무 경험과 전략을 공유하고자 합니다. 직접 부딪히고 해결하며 얻은 교훈들이 독자 여러분의 DevSecOps 여정에 작은 도움이 되기를 바랍니다.
왜 CI/CD 파이프라인에 보안을 통합해야 할까? (Shift-Left의 중요성)
전통적인 보안 방식은 개발이 거의 완료되거나 심지어 배포된 이후에야 보안 점검을 수행하는 경우가 많았습니다. 이는 마치 건물을 다 지어놓고 나서야 기초 공사가 부실했음을 발견하는 것과 같습니다. 상상만 해도 끔찍하죠?
저희 팀도 과거에는 비슷한 문제를 겪었습니다. 프로덕션 환경에 배포된 서비스에서 XSS (Cross-Site Scripting) 취약점이 발견되어 긴급 패치를 진행했던 적이 있습니다. 당시에는 이미 많은 사용자가 서비스를 이용하고 있었기 때문에, 패치를 배포하는 과정 자체가 큰 부담이었고, 자칫 잘못하면 서비스 중단으로 이어질 수 있는 아찔한 상황이었습니다. 이런 경험을 통해 "Shift-Left"의 중요성을 뼈저리게 깨달았습니다.
Shift-Left는 보안 테스트를 개발 생명주기의 가능한 한 초기 단계로 옮겨서 수행하자는 개념입니다. 코드를 작성하는 순간부터, 커밋하고 병합하는 과정에서, 그리고 테스트 환경에 배포되는 모든 단계에서 보안 취약점을 탐지하고 해결하자는 것이죠. 그 이유는 다음과 같습니다.
- 비용 절감: 취약점은 개발 초기에 발견할수록 수정 비용이 기하급수적으로 줄어듭니다. 코드 한 줄 수정으로 해결할 수 있는 문제가 배포 후에는 복잡한 재작업으로 이어질 수 있습니다.
- 개발 속도 유지: 초기에 작은 취약점을 자주 발견하고 수정하는 것이, 나중에 큰 취약점 하나 때문에 전체 배포 일정이 지연되는 것보다 훨씬 효율적입니다.
- 보안 품질 향상: 개발자들이 보안을 더욱 의식하며 코드를 작성하게 되어, 전체적인 애플리케이션의 보안 품질이 향상됩니다.
- DevSecOps 문화 정착: 보안이 개발 프로세스의 자연스러운 일부가 되어, 개발팀과 보안팀 간의 협업이 강화됩니다.
결론적으로, CI/CD 파이프라인에 보안 도구를 통합하는 것은 단순히 취약점을 찾는 것을 넘어, 개발 문화와 효율성을 혁신하는 핵심 전략이었습니다.
SAST, DAST, SCA: 각 도구의 역할과 우리가 선택한 이유
Shift-Left 전략을 실행하기 위해 저희는 세 가지 주요 보안 테스트 도구인 SAST (Static Application Security Testing), DAST (Dynamic Application Security Testing), 그리고 SCA (Software Composition Analysis)를 CI/CD 파이프라인에 통합하기로 결정했습니다. 각 도구는 탐지 방식과 적용 시점이 다르기 때문에, 상호 보완적으로 활용하여 보안 사각지대를 최소화하는 것이 중요하다고 판단했습니다.
SAST (Static Application Security Testing)
SAST는 소스 코드를 실행하지 않고 정적으로 분석하여 잠재적인 보안 취약점을 탐지하는 도구입니다. 개발자가 코드를 작성하거나 커밋하는 시점에 가장 먼저 적용하기에 적합합니다. 저희는 주로 코드 커밋 또는 Merge Request(MR) 단계에서 SAST 스캔을 자동 실행하도록 설정했습니다. 이를 통해 개발자는 자신의 코드가 병합되기 전에 잠재적인 취약점을 인지하고 수정할 수 있게 되었습니다.
- 장점: 개발 초기 단계에서 빠르게 피드백을 제공하며, 잠재적인 취약점의 정확한 위치를 파악하기 용이합니다. OWASP Top 10 같은 일반적인 취약점을 효과적으로 탐지합니다.
- 단점: 실제 런타임 환경에서만 발생하는 취약점(예: 인증 로직 문제, 환경 설정 오류)은 탐지하기 어렵습니다. 또한, 오탐(False Positive)이 발생할 가능성이 있습니다.
- 적용 사례: 저희는 SonarQube와 같은 도구를 CI 파이프라인에 연동하여, 새로운 코드가 푸시될 때마다 자동적으로 정적 분석을 수행하고, 특정 심각도 이상의 취약점이 발견되면 MR을 블록하는 정책을 적용했습니다.
DAST (Dynamic Application Security Testing)
DAST는 실행 중인 애플리케이션을 대상으로 외부에서 공격을 시도하는 방식으로 취약점을 탐지합니다. 웹 애플리케이션의 경우 HTTP/HTTPS 요청을 보내 응답을 분석하며 취약점을 찾습니다. 저희는 애플리케이션이 스테이징(Staging) 환경에 배포된 직후 DAST 스캔을 수행하도록 구성했습니다.
- 장점: 실제 공격자가 사용하는 방식과 유사하게 취약점을 탐지하므로, 런타임 환경에서만 나타나는 취약점(예: 세션 관리 취약점, 환경 설정 오류, 인증 우회)을 효과적으로 발견할 수 있습니다.
- 단점: 애플리케이션이 실행 가능한 상태여야 하므로, 개발 초기 단계에서는 적용하기 어렵습니다. 모든 코드 경로를 탐색하기 어렵고, 스캔 시간이 오래 걸릴 수 있습니다.
- 적용 사례: 저희는 OWASP ZAP을 컨테이너 환경에서 구동하여 스테이징 환경의 URL을 대상으로 자동 스캔을 진행했습니다. 스캔 결과는 리포팅 도구와 연동하여 취약점 대시보드에서 확인할 수 있도록 했습니다.
SCA (Software Composition Analysis)
SCA는 애플리케이션이 사용하는 오픈소스 라이브러리 및 서드파티 컴포넌트의 보안 취약점과 라이선스 문제를 분석하는 도구입니다. 현대 소프트웨어 개발에서 오픈소스는 필수적이지만, 그만큼 오픈소스의 취약점은 전체 시스템의 보안 리스크로 직결됩니다. 저희는 빌드 단계에서 SCA 스캔을 통합하여 사용 중인 모든 외부 라이브러리를 검증했습니다.
- 장점: 알려진 오픈소스 취약점(CVE)에 대한 정보를 바탕으로 정확하고 빠르게 취약점을 탐지합니다. 라이선스 규정 준수 여부도 함께 확인할 수 있습니다.
- 단점: 자체 개발 코드의 취약점은 탐지하지 못합니다. 최신 취약점에 대한 데이터베이스 업데이트가 중요합니다.
- 적용 사례: Dependency-Check와 같은 도구를 빌드 스크립트에 포함하여, 빌드 시점에 프로젝트의 모든 의존성을 스캔하고, 심각한 취약점이 있는 라이브러리가 발견되면 빌드를 실패시키도록 설정했습니다.
이 세 가지 도구의 특징을 표로 정리하면 다음과 같습니다.
| 구분 | SAST | DAST | SCA |
|---|---|---|---|
| 탐지 방식 | 소스 코드 정적 분석 | 실행 중인 애플리케이션 동적 분석 | 오픈소스 컴포넌트 분석 |
| 적용 시점 | 코드 작성, 커밋, MR 단계 (CI) | 배포 후 런타임 환경 (CD) | 빌드 단계 (CI) |
| 주요 탐지 대상 | 코드 내 로직 오류, SQL Injection, XSS 등 일반적 취약점 | 인증/인가 문제, 세션 관리, 환경 설정 오류 등 런타임 취약점 | 오픈소스 라이브러리의 CVE 취약점, 라이선스 문제 |
| 장점 | 초기 단계 피드백, 정확한 위치 파악 | 실제 공격 시나리오 반영, 런타임 취약점 탐지 | 오픈소스 취약점 자동 탐지, 라이선스 관리 |
| 단점 | 오탐 가능성, 런타임 취약점 탐지 불가 | 스캔 시간, 모든 코드 경로 탐색 어려움, 초기 단계 적용 불가 | 자체 개발 코드 분석 불가 |
CI/CD 파이프라인에 SAST/DAST/SCA 통합 실전 가이드
저희는 GitLab CI를 사용하여 파이프라인을 구축했으며, 각 도구의 특성에 맞춰 적절한 단계에 통합했습니다. 핵심은 자동화와 빠른 피드백이었습니다.
1단계: SAST 도구 연동 및 자동화
가장 먼저 손댄 부분은 SAST였습니다. 개발자가 코드를 커밋하고 Merge Request를 생성할 때마다 자동으로 스캔이 이루어지도록 설정했습니다. GitLab CI의 경우, `.gitlab-ci.yml` 파일에 스캔 작업을 추가하는 방식으로 쉽게 통합할 수 있었습니다.
sast_scan:
stage: test
image: sonarsource/sonar-scanner-cli:latest
variables:
SONAR_HOST_URL: "http://sonar.example.com"
SONAR_TOKEN: "$SONAR_TOKEN" # GitLab CI/CD 변수로 설정
script:
- sonar-scanner -Dsonar.projectKey="my-project" -Dsonar.sources="." -Dsonar.java.binaries="build/classes"
rules:
- if: '$CI_COMMIT_BRANCH == "main" || $CI_MERGE_REQUEST_IID' # main 브랜치 또는 MR 시 스캔
위 예시처럼 `stage: test` 단계에 SAST 스캔을 추가하여, 코드 병합 전에 취약점을 확인할 수 있도록 했습니다. 처음에는 오탐(False Positive)이 많아 개발자들의 불만이 있었지만, 규칙(rule)을 프로젝트 특성에 맞게 세밀하게 조정하고, 개발팀과 함께 정기적으로 오탐을 검토하고 제외하는 작업을 진행하며 점차 개선해 나갔습니다. 또한, 특정 심각도 이상의 취약점이 발견될 경우, Merge Request를 강제로 블록하여 보안 게이트 역할을 수행하게 했습니다.
2단계: DAST 도구 연동 및 테스트 환경 구축
DAST는 실제 실행 가능한 환경이 필요하기 때문에, CI/CD 파이프라인의 배포(Deploy) 단계 이후에 수행되도록 했습니다. 저희는 스테이징 환경에 애플리케이션이 배포되면, DAST 스캔을 위한 별도의 컨테이너를 구동하여 해당 환경의 URL을 대상으로 스캔을 시작하도록 구성했습니다.
deploy_staging:
stage: deploy
script:
- ./deploy_to_staging.sh # 스테이징 환경 배포 스크립트
dast_scan:
stage: dast
image: owasp/zap2docker-weekly # OWASP ZAP 컨테이너 이미지
services:
- name: your-app-staging-service # DAST 스캔 대상 서비스 (예: Docker compose 서비스 이름)
alias: target_app
script:
- zap-baseline.py -t http://target_app:8080 -r dast_report.html -x dast_report.xml
artifacts:
paths:
- dast_report.html
- dast_report.xml
rules:
- if: '$CI_COMMIT_BRANCH == "main"' # main 브랜치 배포 시 스캔
DAST 스캔은 SAST보다 시간이 오래 걸릴 수 있기 때문에, 파이프라인 전체 속도에 영향을 주지 않도록 비동기적으로 실행하거나, 야간 스캔을 활용하는 방안도 고려했습니다. 스캔 결과는 HTML 리포트와 XML 형식으로 아티팩트로 저장하여, 추후 분석 및 리포팅 시스템과의 연동에 활용했습니다. 초기에는 스캔 설정이 미흡하여 많은 경고를 뱉어냈지만, OWASP ZAP의 정책 설정을 세밀하게 조정하고, 인증이 필요한 페이지에 대한 스캔 스크립트를 작성하여 실제 공격 시나리오에 가까운 검증이 가능하도록 개선했습니다.
3단계: SCA 도구를 통한 오픈소스 취약점 관리
마지막으로, SCA는 빌드 단계에서 통합했습니다. Maven이나 Gradle과 같은 빌드 도구의 플러그인을 활용하거나, Dependency-Check와 같은 독립적인 도구를 CI 스크립트에 포함하여 의존성 스캔을 자동화했습니다.
# build.sh 또는 .gitlab-ci.yml 스크립트 내
echo "Running Dependency-Check for SCA..."
docker run --rm -v $(pwd):/src owasp/dependency-check:latest \
--scan /src \
--format HTML --format JSON \
--project "MyApplication" \
--out /src/dependency-check-report \
--failOnCVSS 7.0 # CVSS 점수 7.0 이상이면 빌드 실패
저희는 CVSS (Common Vulnerability Scoring System) 점수를 기준으로 특정 임계값 이상의 취약점이 발견되면 빌드를 실패시키도록 설정했습니다. 이는 개발팀이 심각한 오픈소스 취약점을 인지하지 못한 채 프로덕션에 배포하는 것을 원천적으로 차단하는 강력한 보안 게이트 역할을 했습니다. 또한, 정기적으로 오픈소스 의존성을 검토하고, 알려진 취약점에 대한 패치가 이루어진 최신 버전으로 업데이트하는 프로세스를 확립했습니다. 이를 통해 소프트웨어 공급망 보안(Software Supply Chain Security)을 강화할 수 있었습니다.
통합 후 마주한 도전과 해결 과정 (실무 경험 공유)
세 가지 도구를 CI/CD 파이프라인에 통합하는 과정이 순탄하기만 했던 것은 아닙니다. 여러 가지 도전 과제에 직면했고, 이를 해결하기 위해 많은 노력을 기울였습니다.
- 오탐(False Positive)과의 전쟁: 특히 SAST 도구는 초기 설정 시 수많은 오탐을 쏟아냈습니다. 모든 경고를 수정하려다가는 개발 생산성이 마비될 지경이었죠. 저희는 개발팀과 보안팀이 함께 정기적으로 스캔 결과를 검토하고, 실제 취약점과 오탐을 분류했습니다. 오탐으로 판단된 항목은 도구의 설정에서 제외하거나, 코드에 주석을 달아 스캔 대상에서 제외하는 방식으로 노이즈를 줄여나갔습니다.
- 파이프라인 성능 저하: SAST, DAST, SCA 스캔이 추가되면서 CI/CD 파이프라인의 전체 실행 시간이 길어졌습니다. 이는 개발자의 피드백 주기를 늦추고 생산성을 저해할 수 있었습니다. 이를 해결하기 위해 다음과 같은 노력을 했습니다.
- 증분 스캔(Incremental Scan) 활용: 변경된 코드만 스캔하거나, SAST의 경우 특정 브랜치에만 전체 스캔을 수행하고 MR 단계에서는 빠른 검증만 진행하는 방식을 도입했습니다.
- 병렬 처리: CI/CD 도구의 병렬 처리 기능을 활용하여 여러 스캔 작업을 동시에 실행하도록 구성했습니다.
- 전용 리소스 할당: 스캔 작업에 충분한 컴퓨팅 리소스를 할당하여 실행 시간을 단축했습니다.
- 개발자 수용성 확보: 새로운 보안 도구와 프로세스 도입은 개발자들에게 추가적인 부담으로 인식될 수 있습니다. 저희는 개발팀을 대상으로 정기적인 교육 세션을 마련하여 각 도구의 필요성, 사용법, 그리고 취약점 수정 가이드라인을 공유했습니다. 또한, 스캔 결과가 개발자 친화적인 형태로 제공되도록 대시보드를 구축하고, 취약점 정보를 Jira와 같은 이슈 트래커와 연동하여 자연스럽게 개발 워크플로우에 녹여냈습니다.
- 도구 선택과 관리: 상용 도구와 오픈소스 도구 사이에서 많은 고민을 했습니다. 초기에는 예산 제약으로 오픈소스 도구를 위주로 시작했지만, 특정 기능(예: 대시보드, 리포팅, 통합 관리)의 한계를 느끼면서 점차 상용 도구 도입을 검토하기도 했습니다. 중요한 것은 팀의 상황과 요구사항에 맞는 최적의 조합을 찾는 것이었습니다.
SAST/DAST/SCA 통합의 실제 성과와 얻은 교훈
이러한 노력 끝에 저희 팀은 CI/CD 파이프라인에 SAST, DAST, SCA 도구 통합을 성공적으로 안착시킬 수 있었습니다. 그리고 그 결과는 기대 이상이었습니다.
- 취약점 탐지율 및 조기 발견율 증가: 가장 눈에 띄는 성과는 개발 초기 단계에서 발견되는 취약점의 수가 대폭 증가했다는 점입니다. 이전에는 배포 직전에야 발견되던 심각한 취약점들이 이제는 코드 커밋 단계에서부터 걸러지기 시작했습니다. 실제로, 프로덕션 환경에서 발생하던 심각한 보안 취약점의 수가 통합 전 대비 약 70% 감소하는 유의미한 수치를 얻을 수 있었습니다.
- 보안 대응 시간 단축 및 비용 절감: 취약점을 일찍 발견하고 수정함으로써, 수정에 필요한 시간과 비용이 크게 줄어들었습니다. 개발자들이 익숙한 개발 환경에서 바로 취약점을 수정할 수 있게 되어, 평균 취약점 해결 시간이 50% 이상 단축되었습니다.
- 개발자 보안 인식 향상: 자동화된 보안 스캔이 개발 프로세스의 일부가 되면서, 개발자들은 자연스럽게 보안 코딩 습관을 기르게 되었습니다. "내 코드가 보안 스캔에 걸리지 않도록 처음부터 잘 작성해야지"라는 인식이 확산된 것이 가장 큰 문화적 변화였습니다.
- DevSecOps 문화 정착: 보안이 더 이상 '나중에 처리할 일'이 아니라 '개발의 일부'라는 인식이 팀 전체에 퍼졌습니다. 개발팀과 보안팀이 훨씬 긴밀하게 협력하며 보안을 내재화하는 DevSecOps 문화가 점차 정착되었습니다.
저희가 이 과정에서 얻은 가장 큰 교훈은 "보안은 기술적인 문제 이전에 문화적인 문제"라는 것입니다. 아무리 좋은 도구를 도입해도 개발팀의 참여와 공감 없이는 성공하기 어렵습니다. 지속적인 소통, 교육, 그리고 점진적인 개선을 통해 모두가 공감하는 보안 문화를 만드는 것이 중요했습니다.
결론: 지속적인 보안 강화를 위한 여정
CI/CD 파이프라인에 SAST, DAST, SCA 도구를 통합하는 것은 저희 팀에게 단순한 기술 도입을 넘어선, 개발 프로세스 전반의 혁신이었습니다. 개발 초기부터 보안 취약점을 자동 탐지하고 해결하는 시스템을 구축함으로써, 개발 속도와 보안이라는 두 마리 토끼를 모두 잡을 수 있는 기반을 마련했습니다.
물론, 이 여정이 여기서 끝난 것은 아닙니다. 보안 위협은 끊임없이 진화하고 있으며, 저희의 시스템 또한 이에 맞춰 지속적으로 발전해야 합니다. 새로운 위협에 대응하기 위한 런타임 애플리케이션 보안(RASP) 도입이나, 컨테이너 이미지 스캔 강화, 그리고 보안 취약점 관리 시스템(VMS)과의 연동 등 앞으로도 해야 할 일들이 많이 남아있습니다. 하지만 개발 초기부터 보안을 내재화하는 강력한 자동화 기반을 마련했다는 점에서, 저희는 이 여정에 대한 자신감을 얻었습니다.
이 글이 CI/CD 파이프라인에 보안을 통합하고자 하는 다른 개발팀이나 보안팀에게 실질적인 도움이 되기를 바랍니다. 여러분의 경험이나 궁금한 점이 있다면 댓글로 공유해 주세요. 함께 고민하고 발전해 나갈 수 있기를 기대합니다!
📌 함께 읽으면 좋은 글
- [보안] 패스키(Passkeys) 도입 가이드: 비밀번호 없는 인증 시스템으로 보안과 사용자 경험을 혁신하는 방법
- [AI 머신러닝] LLM 서비스 배포 및 최적화 전략: 비용 효율적인 추론 환경 구축과 성능 관리
- [보안] 소프트웨어 공급망 보안: 의존성 관리, 코드 서명, SBOM 활용 취약점 방어 전략
이 글이 도움이 되셨다면 공감(♥)과 댓글로 응원해 주세요!
궁금한 점이나 다루었으면 하는 주제가 있다면 댓글로 남겨주세요.
'보안' 카테고리의 다른 글
| OAuth 2.0 및 OpenID Connect: 안전한 사용자 인증 및 권한 부여 시스템 구축 전략 (2) | 2026.04.18 |
|---|---|
| JWT 보안 취약점: 안전한 인증 시스템 구현을 위한 필수 전략 (0) | 2026.04.17 |
| 안전한 인증/인가 시스템 구축: OAuth 2.0과 OpenID Connect 심층 분석 (0) | 2026.04.14 |
| 패스키(Passkeys) 도입 가이드: 비밀번호 없는 인증 시스템으로 보안과 사용자 경험을 혁신하는 방법 (1) | 2026.04.13 |
| DevSecOps 실전 가이드: 개발과 보안 통합으로 안전한 소프트웨어 구축 (1) | 2026.04.11 |