Taint Tracking 실증실험으로 확인한 semgrep CE(오픈소스 버전)의 기능적 한계와 도입 시 주의사항
1. 오픈소스 SAST 도입, 무엇을 확인해야 할까?
소프트웨어 개발 과정에서 보안취약점을 사전에 발견하기 위해 SAST(Static Application Security Testing, 정적 애플리케이션 보안 테스트) 도구 사용은 이미 의무화된지 오래되어 다양한 인증 제품들이 시장에서 사용되고 있다.
특히 Shift Left 보안전략의 일환으로써 SAST 도구를 CI/CD 파이프라인에 Plugin으로 연동하는 구성으로 가다보니 별도의 상용 라이선스 비용 없이 도입할 수 있는 오픈소스 SAST도 인기가 있어 여러 기업에서 사용되고 있다.
대표적인 오픈소스 SAST 도구 중 하나인 Semgrep은 다양한 프로그래밍 언어를 지원하며, 보안취약점 탐지를 위한 Rule을 제공한다. OWASP, CWE 등과 연관된 보안 규칙을 활용할 수 있고, 사용자가 직접 Rule을 개발하거나 수정할 수도 있다.
Semgrep은 단순히 개인 개발자가 공개한 소규모 프로젝트가 아니다. 초기 기술은 Facebook에서 2009년 시작된 오픈소스 정적 분석 프로젝트에서 출발했으며, 이후 보안 전문기업 r2c(현 Semgrep)가 개발을 이어받아 오픈소스 커뮤니티와 함께 발전시켜 왔다.
다양한 개발 조직에서 활용할 수 있는 규칙 기반 분석 도구로 자리 잡았으며, 오픈소스 기반 보안진단 도구를 검토할 때 자주 거론되는 프로젝트 중 하나다.
다만 Semgrep의 제품 구성은 초기와 달라졌다.
초기에는 오픈소스 엔진을 중심으로 개발되었으나, 이후 상용 제품이 확대되면서 현재는 Semgrep Community Edition(오픈소스)과 Pro Engine·Pro Rules 등을 포함하는 상용 기능이 구분되어 제공되고 있다.
특히 심층적인 함수 간·파일 간 데이터 흐름 분석 기능은 상용 Pro Engine의 주요 차별화 기능으로 소개되고 있다.
따라서 Semgrep을 평가할 때는 단순히 ‘Semgrep이 어떤 기능을 지원하는가’가 아니라, ‘오픈소스로 공개된 Community Edition에서 실제로 어떤 기능을 사용할 수 있는가’를 구분해야 한다.
또한 SAST 도구를 선택할 때는 지원 언어와 Rule 개수뿐 아니라 프로그램 내부의 데이터 흐름을 실제로 어디까지 분석할 수 있는지 확인해야 한다.
WIKI SECURITY는 Semgrep Community Edition의 Taint Analysis 기능이 일반적인 애플리케이션 구조에서 어느 범위까지 동작하는지 확인하기 위해 Python 기반 실증실험을 수행했다.
이번 게시물에서는 실험 방법과 결과를 소개하고, 오픈소스 SAST를 실무에 도입할 때 고려해야 할 사항을 정리한다.
2. SAST에서 Taint Analysis가 중요한 이유
Taint Analysis는 외부에서 입력된 데이터가 프로그램 내부에서 어떻게 전달되고 사용되는지를 추적하는 정적 분석 기술이다.
일반적으로 다음 세 가지 요소를 중심으로 동작한다.
- Source: 사용자 입력, HTTP 요청 파라미터, 외부 파일 등 신뢰할 수 없는 데이터가 유입되는 지점
- Sink: SQL 실행, 운영체제 명령 실행, 파일 접근 등 오염된 데이터가 달될 경우 보안 위험이 발생할 수 있는 지점
- Sanitizer: 입력 데이터의 위험 요소를 제거하거나 안전하게 처리하는 기능
예를 들어 웹 애플리케이션에서 사용자가 입력한 문자열이 적절한 검증 없이 SQL 실행 함수에 전달되면 SQL Injection 취약점이 발생할 수 있다.
문제는 실제 프로그램이 하나의 함수로 구성되지 않는다는 점이다.
일반적인 웹 애플리케이션은 Controller, Service, Repository 등 여러 계층으로 구성되며, 사용자 입력은 여러 함수와 소스코드 파일을 거쳐 최종적으로 사용된다.
이러한 모듈화 구조는 대규모 애플리케이션에서만 나타나는 것이 아니다. 비교적 작은 프로그램이라도 유지보수성과 재사용성을 고려하여 기능을 여러 함수와 파일로 분리하는 것이 일반적이다.
따라서 실무 수준의 Taint Analysis에서는 다음 분석 기능이 중요하다.
- Intraprocedural Analysis(함수 내부 분석): 동일 함수 내부에서 Source와 Sink 사이의 데이터 흐름을 추적하는 기능
- Interprocedural Analysis(함수 간 분석): 서로 다른 함수의 호출과 반환값을 경유하는 데이터 흐름을 추적하는 기능
- Interfile Analysis(파일 간 분석): 서로 다른 소스코드 파일 또는 모듈을 경유하는 데이터 흐름을 추적하는 기능
특히 함수 간·파일 간 추적 기능이 제한될 경우, 프로그램 규모에 관계없이 실제 데이터 흐름에 기반한 보안취약점을 발견하지 못할 가능성이 있다.
3. Semgrep Taint Tracking 실증실험 환경
이번 실험에서는 Semgrep Community Edition의 분석 범위를 확인하기 위해 Python 테스트 프로그램을 직접 작성했다.
3.1 실험 환경
- SAST 도구: Semgrep
- 버전: 1.184.0
- 분석 엔진: Community Edition의 OSS Engine
- 프로그래밍 언어: Python
- 탐지 방식: Taint Analysis
- Rule: 사용자 정의 YAML Rule
- 실험 범위: 함수 내부, 함수 간, 파일 간 데이터 흐름
- 결과 형식: JSON
테스트에서는 untrusted_source()를 Source로, dangerous_sink()를 Sink로 정의했다.
이 함수들은 실제 위험 명령을 실행하지 않는 실험용 함수이며, 오염된 데이터가 Source에서 Sink까지 도달하는지를 검증하기 위해 사용했다.
3.2 테스트 시나리오
총 6개의 테스트 시나리오를 구성했다.
- Case 01 — 동일 함수 내부 Taint 전파: 기본적인 Taint 추적 기능을 확인한다.
- Case 02 — 동일 파일 내 서로 다른 함수 간 전달: 함수 간 데이터 흐름 추적 기능을 확인한다.
- Case 03 — 다른 파일의 Sink로 데이터 전달: 파일 간 전달 과정의 Taint 추적 기능을 확인한다.
- Case 04 — 다른 파일의 Source에서 데이터 반환: 외부 모듈의 함수 반환값에 대한 Taint 추적 기능을 확인한다.
- Case 05 — 3개 파일을 경유하는 데이터 전달: 여러 모듈에 걸친 다단계 Taint 추적 기능을 확인한다.
- Case 06 — 오염되지 않은 데이터 전달: 안전한 코드가 잘못 탐지되는지 확인하는 대조 실험이다.
모든 테스트에 동일한 사용자 정의 Rule을 적용해 결과를 비교했다.
4. 1차 실험: 기본 Taint Tracking 기능 확인
1차 실험에서는 6개 시나리오를 대상으로 Semgrep의 취약점 탐지 결과를 확인했다.
4.1 실험 결과
- Case 01 — 동일 함수 내부: 1건 탐지
- Case 02 — 동일 파일 내 함수 간: 0건, 미탐
- Case 03 — 파일 간 Sink 전달: 0건, 미탐
- Case 04 — 파일 간 Source 전달: 0건, 미탐
- Case 05 — 다단계 파일 간 전달: 0건, 미탐
- Case 06 — 안전한 코드: 0건, 예상대로 탐지 없음
동일 함수 내부에서는 Source에서 Sink까지 전달되는 데이터 흐름이 정상적으로 탐지되었다.
Semgrep의 JSON 결과에서도 Source, 중간 변수 및 Sink에 대한 dataflow_trace가 확인되었다.
반면 서로 다른 함수 또는 파일을 경유하는 사례에서는 취약점이 탐지되지 않았다.
이 결과는 이번 실험에서 Semgrep OSS 엔진과 적용한 Rule이 함수 간·파일 간 데이터 흐름을 충분히 추적하지 못했음을 보여준다.
다만 여기서 한 가지 추가로 확인할 부분이 발견되었다.
파일 간 데이터 전달을 시험한 Case 03~05에서는 단순히 탐지 결과가 0건인 것뿐 아니라, 내부 프로파일링 정보에서 Rule 선택 비율이 0%로 나타났다.
이는 실제 Taint 분석 기능의 한계와 별도로, Semgrep의 분석 전 최적화 과정이 결과에 영향을 주었을 가능성을 의미한다.
5. 2차 실험: 사전 필터링의 영향 검증
Semgrep는 본격적인 데이터 흐름 분석을 수행하기 전에 Rule과 소스코드의 특징을 확인하여 불필요한 분석을 줄이는 사전 필터링(Prefiltering) 기능을 사용한다.
1차 실험에서는 Source와 Sink가 서로 다른 파일에 존재할 경우 Rule이 분석 대상으로 선택되지 않는 현상이 관찰되었다.
이에 따라 미탐 원인을 보다 명확하게 구분하기 위해 2차 실험을 수행했다.
5.1 Baseline과 Probe 구성
2차 실험은 다음 두 가지 환경으로 구성했다.
Baseline(기준 실험)
1차 실험과 동일한 원본 소스코드를 사용했다. 소스코드의 변경 없이 각 시나리오에 대한 Rule 선택률과 탐지 결과를 측정했다.
Probe(변경 실험)
기존의 데이터 전달 흐름은 유지하면서 각 파일에 다음 테스트 함수를 추가했다.
def prefilter_probe():
untrusted_source()
dangerous_sink("safe")
이 함수에는 Source와 Sink 패턴이 함께 존재하지만 오염된 데이터가 Sink로 전달되지는 않는다.
따라서 Probe 자체는 Taint 취약점으로 탐지되지 않아야 한다.
이와 같은 변경을 통해 Semgrep의 사전 필터링 결과가 달라지는지, 그리고 분석이 수행된 후에는 파일 간 데이터 흐름을 탐지할 수 있는지 확인했다.
5.2 Baseline과 Probe의 결과 비교
Case 01 — 동일 함수 내부
- Baseline Rule 선택률: 100%
- Probe Rule 선택률: 100%
- Baseline 탐지: 1건
- Probe 탐지: 1건
Case 02 — 동일 파일 내 함수 간
- Baseline Rule 선택률: 100%
- Probe Rule 선택률: 100%
- Baseline 탐지: 0건
- Probe 탐지: 0건
Case 03~05 — 파일 간 데이터 흐름
각 시나리오에서 동일한 결과가 확인되었다.
- Baseline Rule 선택률: 0%
- Probe Rule 선택률: 100%
- Baseline 탐지: 0건
- Probe 탐지: 0건
Case 06 — 안전한 코드
- Baseline Rule 선택률: 100%
- Probe Rule 선택률: 100%
- Baseline 탐지: 0건
- Probe 탐지: 0건
5.3 실험 결과 분석
실험 결과, Case 03~05에서 Rule 선택률이 0%에서 100%로 증가했다.
또한 기존에 0으로 기록되었던 Taint 분석 시간이 Probe 적용 이후에는 양수로 나타났다.
이는 사전 필터링을 통과해 규칙에 대한 분석 작업이 수행되었음을 보여준다. 다만 분석 작업이 수행되었다는 사실만으로 파일 간 데이터 흐름이 완전히 분석되었다고 볼 수는 없다.
파일 간 데이터 흐름에 대한 취약점 탐지는 여전히 0건이었다.
따라서 이번 실험의 미탐 현상은 사전 필터링만으로 설명할 수 없다.
Semgrep OSS 엔진의 분석 범위와 해당 Rule의 데이터 흐름 모델링 방식이 중요한 제약으로 작용할 수 있음을 보여주는 결과다.
다만 사전 필터링의 정확한 내부 조건과 모든 유형의 함수 간 분석 가능 여부까지 규명한 것은 아니므로, 결론은 이번 실험 환경과 테스트 사례로 한정해야 한다.
6. 실험 결과가 실무 보안진단에 주는 의미
이번 실험은 오픈소스 SAST를 도입할 때 고려해야 할 중요한 문제를 보여준다.
Taint Analysis 지원 여부와 분석 범위는 다르다
SAST 도구에서 Taint Analysis를 지원한다고 해서 모든 함수 간·파일 간 데이터 흐름이 자동으로 추적되는 것은 아니다.
특히 여러 함수와 파일로 분리된 일반적인 업무 애플리케이션을 분석할 때는 분석 엔진이 해당 구조를 지원하는지 확인해야 한다.
탐지 결과가 0건이라고 안전한 것은 아니다
SAST 진단에서 발견된 취약점이 없다는 것은 적용된 Rule과 분석 엔진이 취약점을 탐지하지 못했다는 의미일 수도 있다.
따라서 분석 결과를 해석할 때는 탐지된 취약점뿐 아니라 탐지하지 못할 수 있는 취약점의 범위도 고려해야 한다.
이는 보안진단 결과를 고객에게 제공하거나 보안성 평가에 활용할 때 특히 중요하다.
Rule의 개수만으로 SAST 도구를 평가해서는 안 된다
Semgrep는 다양한 보안 Rule을 제공하며 사용자가 직접 Rule을 개발할 수도 있다.
그러나 Rule이 많다고 해서 반드시 실제 취약점 탐지율이 높아지는 것은 아니다.
취약점 탐지 성능은 Rule의 정확성과 함께 분석 엔진의 데이터 흐름 추적 능력, 프로그래밍 언어 및 프레임워크 지원 범위에 의해 결정된다.
Community Edition과 Pro Engine을 구분해야 한다
Semgrep은 초기 오픈소스 프로젝트에서 출발했으나, 현재는 오픈소스와 상용 기능을 구분하여 개발·제공하고 있다.
대표적인 차이는 다음과 같다.
Semgrep Community Edition(OSS)
- 오픈소스 기반의 정적 분석 엔진을 제공한다.
- 구문 패턴 탐지와 함수 내부 중심의 Taint Analysis를 수행할 수 있다.
- Community Rules와 사용자 정의 Rule을 사용할 수 있다.
- 로컬 환경과 CI/CD 환경에서 실행할 수 있다.
Semgrep 상용 제품 및 Pro Engine
- 함수 간·파일 간 데이터 흐름을 분석하는 고급 기능을 제공한다.
- 추가 언어 지원과 고급 분석 기능을 제공한다.
- 별도의 Pro Rules를 제공한다.
- AppSec Platform을 통해 중앙 관리, 분석 결과 검토 및 보안 운영 기능을 제공한다.
단, 상용 Pro Engine의 함수 간 분석 기능 역시 언어와 분석 유형에 따른 지원 범위가 있으며, 공식 문서에서는 함수 간 분석을 실험적 기능으로 설명하고 있다.
이번 실험은 Community Edition의 OSS 엔진을 대상으로 수행했으며, Pro Engine의 탐지 성능을 검증한 것은 아니다.
따라서 이번 실험 결과를 Semgrep 전체 제품군의 기능적 한계로 일반화하는 것은 적절하지 않다.
또한 Community Edition의 엔진이 오픈소스라는 사실과 함께 제공되는 모든 Rule이 동일한 오픈소스 라이선스를 따른다는 것은 별개의 문제다.
Semgrep은 2024년 12월 Community Edition의 공개 정책을 정비하면서 Semgrep이 관리하는 Community Rules에 별도 라이선스를 적용했다.
공식 발표에서는 일반적인 내부 사용과 보안 컨설팅 목적의 사용을 허용되는 활용 사례로 설명한다. 반면 Rule을 다른 제품에 재배포하거나 서비스로 제공하는 행위에는 별도 제한이 있으므로, 실제 사업 모델이 라이선스 조건에 부합하는지 확인해야 한다.
따라서 오픈소스 기반 보안진단 서비스를 구축하려는 기업은 엔진의 기능뿐 아니라 Rule 라이선스와 상용 기능 의존성까지 함께 검토해야 한다.
7. Semgrep의 한계성과 실무 도입 시 고려사항
이번 실증실험에서는 Semgrep Community Edition 1.184.0의 Taint Analysis 기능을 대상으로 총 6개의 Python 시나리오를 구성하고, 사전 필터링의 영향을 확인하기 위한 추가 비교 실험을 수행했다.
그 결과 동일 함수 내부의 Taint 추적은 정상적으로 확인되었지만, 서로 다른 함수와 파일을 경유하는 데이터 흐름에서는 취약점이 탐지되지 않았다.
또한 사전 필터링을 통과하도록 테스트 조건을 변경한 후에도 파일 간 Taint 탐지 결과는 달라지지 않았다.
이러한 결과는 Semgrep Community Edition을 실무 보안진단에 도입할 때 고려해야 할 중요한 제약을 보여준다.
함수 간·파일 간 데이터 흐름 분석의 한계
현대적인 소프트웨어 개발에서는 프로그램의 규모와 관계없이 유지보수성, 재사용성, 확장성 등을 고려하여 기능을 여러 함수와 모듈로 분리하는 것이 일반적이다.
예를 들어 웹 애플리케이션에서는 사용자 입력을 처리하는 Controller, 업무 로직을 수행하는 Service, 데이터베이스에 접근하는 Repository 등이 각각 다른 함수나 파일로 구성된다.
이러한 구조에서는 외부 입력이 유입되는 Source와 실제 위험한 작업이 수행되는 Sink가 서로 다른 함수 또는 파일에 위치하는 경우가 흔하다.
따라서 함수 간·파일 간 데이터 흐름 추적은 대규모 또는 복잡한 애플리케이션에만 필요한 고급 분석 기능이 아니라, 일반적인 소프트웨어의 보안취약점을 분석하기 위한 중요한 기본 요건이라고 볼 수 있다.
이번 실험에서 Semgrep Community Edition은 동일 함수 내부의 Taint 전파를 탐지했지만, 함수 간·파일 간 데이터 흐름을 경유하는 테스트 사례에서는 취약점을 탐지하지 못했다.
이는 SQL Injection, Command Injection, Path Traversal 등 외부 입력이 여러 처리 단계를 거쳐 취약한 함수에 전달되는 유형의 취약점을 진단할 때 중요한 제약으로 작용할 수 있다.
다만 이번 실험은 특정 Python 테스트 코드와 사용자 정의 Rule을 대상으로 수행되었으므로, 모든 함수 간 데이터 흐름이 탐지되지 않는다고 일반화할 수는 없다.
Semgrep Community Edition의 활용 범위
Semgrep Community Edition이 실무에서 활용 가치가 없는 것은 아니다.
특히 다음과 같이 데이터 흐름의 심층 분석보다 특정 코드 패턴이나 보안 규칙의 준수 여부를 확인하는 작업에 활용할 수 있다.
- 위험한 API 또는 함수의 사용 여부 탐지
- 하드코딩된 인증정보 및 민감정보 관련 코드 패턴 점검
- 취약하거나 권장되지 않는 함수 및 라이브러리 사용 탐지
- 사용자 정의 Rule을 이용한 보안 코딩 규칙 점검
- CI/CD 파이프라인에서 반복적인 코드 검사 자동화
- 보안 담당자의 수작업 코드 리뷰를 지원하는 보조 도구
그러나 이러한 활용 가능성이 실제 보안취약점에 대한 충분한 탐지 성능을 보장하는 것은 아니다.
특히 함수 간·파일 간 데이터 흐름을 분석하지 못하는 경우, 개별 코드 패턴은 식별하더라도 외부 입력이 해당 코드까지 전달되어 실제 취약점으로 이어지는지를 판단하는 데 한계가 발생할 수 있다.
따라서 Semgrep Community Edition은 보안 코딩 규칙 점검과 패턴 기반 정적 분석을 위한 도구로 활용하되, 이를 일반적인 애플리케이션 보안취약점 진단의 단독 수단으로 사용하는 것은 신중하게 검토해야 한다.
실무 도입 시 확인해야 할 사항
Semgrep Community Edition을 실제 보안진단 업무에 도입하려는 경우 다음 사항을 사전에 검증할 필요가 있다.
- 분석 엔진: Community Edition의 OSS Engine과 상용 Pro Engine의 기능적 차이를 확인한다.
- 데이터 흐름 분석: 함수 내부뿐 아니라 함수 간·파일 간 Source-to-Sink 추적 기능이 실제 진단 대상에서 동작하는지 확인한다.
- 프로그래밍 언어 및 프레임워크: 대상 애플리케이션의 개발 언어, 프레임워크, 모듈 구성에 대한 분석 지원 범위를 검증한다.
- Rule의 적합성: OWASP, CWE 및 사용자 정의 Rule이 실제 취약점 탐지 목적에 적합한지 확인한다.
- 탐지 정확도: 알려진 취약 코드와 안전한 코드를 대상으로 오탐(False Positive) 및 미탐(False Negative) 가능성을 검증한다.
- 운영환경: 폐쇄망 환경에서의 설치, 로컬 Rule 관리 및 분석 결과 활용 가능 여부를 확인한다.
- 라이선스: Community Rules의 사용 조건과 상용 기능에 대한 의존성을 검토한다.
- 교차 검증: 필요한 경우 다른 SAST 분석 엔진이나 수작업 코드 리뷰를 통해 탐지 결과를 보완한다.
특히 실제 고객사의 프로그램 구조를 대표하는 테스트 코드를 이용하여 도입 전에 탐지 성능을 검증하는 것이 중요하다.
단순한 예제에서 취약점이 정상적으로 탐지되더라도, 실제 업무 프로그램의 함수 호출과 모듈 구조에서는 동일한 탐지 결과가 보장되지 않기 때문이다.
종합 의견
이번 실험에서 얻은 가장 중요한 교훈은 SAST 도구가 Taint Analysis 기능을 제공한다는 사실과 실제 프로그램의 데이터 흐름을 충분히 추적할 수 있다는 것은 별개의 문제라는 점이다.
Semgrep은 오픈소스 생태계와 다양한 보안 Rule을 갖춘 정적 분석 도구이며, 보안 코딩 규칙 점검과 반복적인 코드 검사 자동화에 활용할 수 있다.
그러나 이번 실험에서는 Community Edition의 함수 간·파일 간 Taint Tracking에 중요한 제약이 확인되었다.
더욱이 함수와 모듈의 분리는 프로그램 규모와 관계없이 일반적으로 적용되는 소프트웨어 설계 방식이라는 점에서, 이러한 분석 제약은 실무 보안진단에서 가볍게 볼 수 없는 문제다.
따라서 Semgrep Community Edition을 도입할 때는 제공되는 Rule의 개수나 지원 언어만을 기준으로 평가하기보다 실제 프로그램 구조에서 취약점 탐지가 가능한 범위와 미탐 가능성을 우선적으로 검증해야 한다.
특히 고객에게 보안취약점 진단 서비스를 제공하는 경우에는 분석 도구의 기능적 한계를 명확히 이해하고, 필요한 경우 다른 분석 기술을 보완적으로 활용해야 한다.
이번 실험 결과는 Semgrep의 상용 Pro Engine이나 다른 버전의 성능을 평가한 것이 아니며, Community Edition 1.184.0과 해당 사용자 정의 Rule에 한정된 결과다.
WIKI SECURITY는 앞으로도 다양한 오픈소스 보안 도구에 대한 실증실험을 통해 실제 업무에서 활용 가능한 기술과 적용 시 주의해야 할 사항을 지속적으로 공유하고 있다.
실험 결과는 WIKI SECURITY 자체 테스트 환경의 Semgrep 1.184.0 OSS 엔진과 사용자 정의 Rule을 대상으로 측정한 것이다. 결과는 다른 Semgrep 버전, Rule 및 분석 엔진의 성능을 대표하지 않는다.

