BLOG
Tracefield · 02
Tracefield · 01
블로그 · 14
Vibe Audit · 04
Vibe Audit · 03
Vibe Audit · 02
Vibe Audit · 01
출판편집자 · 01
StudyTree · 01
SecurityOps · 02
SecurityOps · 01
AI챗봇 · 04
AI챗봇 · 03
AI챗봇 · 02
AI챗봇 · 01
퍼플심 · 04
퍼플심 · 03
퍼플심 · 02
퍼플심 · 01
블로그 · 13
rootscan · 07
rootscan · 06
블로그 · 12
블로그 · 11
블로그 · 10
블로그 · 09
블로그 · 08
블로그 · 07
블로그 · 06
블로그 · 05
블로그 · 04
블로그 · 03
블로그 · 02
블로그 · 01
rootscan · 05
rootscan · 04
rootscan · 03
asmspeak · 03
asmspeak · 02
rootscan · 02
asmspeak · 01
rootscan · 01
웹보안도구 · 02
웹보안도구 · 01
루트캠프 · 02
루트캠프 · 01
All notes 167
SAST의 동작 원리와 AST(추상 구문 트리)
SAST는 코드를 실행하지 않고 소스 코드 자체를 읽어 취약점을 찾는 방식이다. 겉으로 보면 Ctrl+F나 grep과 비슷해 보일 수 있지만, 실제로는 훨씬 더 구조적인 분석을 한다. 핵심 차이는 문자열을 찾느냐, 코드를 이해하느냐에 있다.
1. 텍스트 매칭의 한계
가장 단순한 방법은 위험한 함수 이름을 문자열로 찾는 것이다. 예를 들어 eval()을 찾는 상황을 생각해보면 한계가 바로 보인다.
# 단순 검색으로 탐지 가능 (True Positive)
eval(user_input)
# 주석인데도 탐지됨 (False Positive)
# Don't use eval() here
# 변수명이 같아서 탐지됨 (False Positive)
eval_score = 100
문자열 기반 탐지는 주석, 문자열 리터럴, 변수명까지 코드처럼 오인한다. 그러면 오탐이 급격히 늘어난다. 오탐이 쌓이면 개발자는 결국 경고를 무시하거나 꺼버린다.
2. AST: 코드를 구조로 이해하기
이 문제를 줄이기 위해 SAST는 코드를 텍스트가 아니라 AST라는 구조로 바꿔서 본다. 파서가 코드를 읽고 문법 구조를 해석한 뒤, 그 구조를 기준으로 분석하는 방식이다.
AST를 쓰면 아래처럼 문맥을 구분할 수 있다.
eval(input)은 함수 호출(Call Expression) 노드이다. -> 탐지 대상# eval은 주석(Comment) 노드이다. -> 무시eval_score는 변수 선언(Assignment) 노드이다. -> 무시
2.1. 의미론적 패턴 매칭(Semantic Matching)
Semgrep 같은 도구는 이 AST 위에서 패턴을 맞춘다. 그래서 줄바꿈이나 공백보다 코드 구조 자체가 중요해진다.
patterns:
- pattern: eval($X)
이 규칙은 단순히 eval이라는 문자열을 찾는 게 아니다. 함수 이름이 eval이고, 인자 $X를 받는 호출 노드를 AST에서 찾는다. 그래서 띄어쓰기나 줄바꿈이 달라도 구조가 같으면 정확히 잡힌다.
3. Taint Analysis (오염 분석)
AST만으로 충분하지 않은 경우도 있다. 같은 위험 함수라도, 그 안에 들어가는 값이 어디서 왔는지에 따라 실제 위험도는 달라지기 때문이다.
# Case A: 안전함 (상수 전달)
eval("1 + 1")
# Case B: 위험함 (사용자 입력 전달)
eval(request.GET['cmd'])
이를 구분하려고 Taint Analysis를 쓴다. 외부 입력이 Source에서 들어와, 검증 없이 Sink로 흘러가는 경로를 따라가는 방식이다. 결국 중요한 건 위험한 함수 이름이 아니라, 위험한 데이터 흐름이 실제로 존재하느냐는 점이다.

