룰과 패턴으로 운영하는 정적 분석 기반 결함 탐지

AST·데이터플로우·타인트 분석을 활용한 룰 기반 정적 분석의 설계, CI/CD 게이팅과 기준선 운영 방안을 정리한다.

2026-08-14 · 최초 발행 2025-12-22

실행 전에 코드 결함을 걸러내는 방식

정적 분석은 프로그램을 실행하기 전에 소스 코드, 바이트코드, IR을 분석해 결함·보안 취약점·규약 위반을 식별하는 기법이다. 룰과 패턴을 기반으로 한 탐지는 특정 코드 구조나 호출 순서를 DSL 또는 패턴으로 기술하고, 해당 사례를 코드에서 찾아낸다.

탐지 범위에는 CWE/SANS 관련 보안 취약점, null dereference와 자원 누수 같은 신뢰성 결함, 코드 스멜, MISRA와 CERT 등의 코딩 규약 검증이 포함된다. AST 매칭만으로 끝나는 방식도 있지만, 제어 흐름과 데이터 흐름의 제약, 타인트 추적까지 적용할 수 있다.

룰이 분석 결과로 이어지는 구성

룰 사양은 AST 노드 타입과 속성, 연산자 제약, 데이터 소스에서 싱크까지의 경로를 표현해야 한다. 위험 API 집합이나 보안상 중요한 영역처럼 반복되는 조건은 템플릿으로 관리하면 재사용성과 유지보수가 나아진다.

언어별 파서는 AST, CFG, SSA IR을 만든다. 전처리기와 매크로, 타입 해석의 정확도가 탐지 품질을 좌우한다. 코드베이스가 커지면 증분 파싱과 캐시를 통해 빌드 시간을 관리한다.

분석 엔진은 구문 패턴으로 빠르게 후보를 좁힌 뒤 데이터플로우와 타인트 해석으로 정밀도를 높인다. 이때 경로 폭발을 다루기 위해 요약 함수, 경로 제한, 취약 API 화이트리스트 같은 경량 추론을 적용한다.

경고 결과는 파일·라인·해시를 기준으로 중복을 제거하고, 경로 유사도로 클러스터링할 수 있다. 첫 스캔 결과를 기준선으로 고정하고 주석 또는 메타데이터 억제를 활용하면 오탐과 레거시 이슈를 분리해 다룰 수 있다.

PR 단위의 증분 분석, 심각도·개수 임계치 기반 빌드 게이트, SARIF·HTML 리포트 발행까지 연결하면 분석 결과가 개발 흐름 안으로 들어온다. 스캔 시간 예산, 병렬화, 캐시 정책은 개발자 경험을 지키는 운영 조건이다.

기법별 운영 특성

기법 성능 확장성 일관성 안정성 운영 편의
정규식/텍스트 패턴 매우 빠름, 초저비용 언어 추상화 한계 문맥 미반영으로 변동성 큼 오탐/미탐 높음 작성/도입 쉬움
AST 기반 룰 엔진 빠름, LOC 선형 멀티언어 지원 용이 구문 일관성 높음 중간 수준 오탐 DSL 학습 필요
데이터플로우/타인트 중간~느림 대형 모듈에 비용 증가 경로 모델 의존 정확도 높으나 경로 폭발 리스크 셋업/튜닝 비용 높음

분석 결과가 PR 피드백까지 도달하는 흐름

성공실패매치 있음매치 없음신규 이슈기존 이슈임계 초과임계 미만입력: 소스 코드/설정전처리 파싱(AST/IR 생성)룰/패턴 로딩(DSL 해석)에러 리포트 생성 파이프라인실패(옵션)패턴 매칭데이터플로우/타인트 해석결함 후보 생성(파일, 라인,증거 경로)결과 산출: 신규 이슈 없음결과 후처리: 디듀프/기준선비교심각도 스코어링 게이팅억제 또는 SLA 추적파이프라인 실패 피드백 루프리포트 발행 PR 코멘트피드백: 정밀도 튜닝

보안·품질·규약 검증에 적용하는 패턴

보안 취약점 탐지에서는 SQL Injection, Command Injection, XSS의 소스→싱크 경로를 타인트 기반 룰로 정의한다. exec, subprocess, eval 같은 조직 공통 위험 API와 안전한 래퍼를 정책으로 관리할 수도 있다.

신뢰성과 품질 측면에서는 null dereference, 파일·소켓 close 누락에 따른 자원 누수, 동시성 락 미해제 패턴을 탐지한다. PR 게이팅으로 심각도 High 이상인 신규 이슈를 릴리스 전에 차단하는 방식이 여기에 맞는다.

MISRA C와 CERT 룰셋은 자동차·금융 규제 대응에 사용할 수 있으며, 팀별 스타일 가이드 룰은 코드 일관성을 유지하는 수단이 된다.

Semgrep을 CI 파이프라인에 연결하기

Semgrep 1.60+ 설치, Python 3.10+ 권장, GitHub Actions 러너 Ubuntu 22.04를 전제로 한다.

아래 룰은 Python에서 subprocessshell=True와 함께 호출하는 패턴을 찾는다.

rules:
  - id: py-subprocess-shell-true
    languages: [python]
    severity: ERROR
    message: Avoid subprocess with shell=True; use list args or shlex.split.
    patterns:
      - pattern: subprocess.$FUNC(..., shell=True, ...)
    metadata:
      cwe: "CWE-78"
      category: "security"

루트의 .semgrep.yml을 사용하는 GitHub Actions 설정은 다음과 같다.

name: static-analysis
on:
  pull_request:
  push:
    branches: [main]
jobs:
  semgrep:
    runs-on: ubuntu-22.04
    steps:
      - uses: actions/checkout@v4
      - uses: returntocorp/semgrep-action@v1
        with:
          config: .semgrep.yml
          generateSarif: true
      - uses: github/codeql-action/upload-sarif@v3
        if: always()
        with:
          sarif_file: semgrep.sarif

main 브랜치 전체 스캔 결과를 baseline으로 고정하고 PR에서는 신규 항목만 평가한다. 오탐에는 억제 주석을 추가한 뒤, 같은 패턴을 룰의 예외 조건에 반영하는 튜닝 루프를 둔다.

측정 가능한 효과와 운영상 대가

CWE Top 25 관련 취약점은 사전 차단율 6080%, 보안 핫픽스 감소율 30% 수준을 목표로 둘 수 있다. AST 기반 증분 스캔은 100k LOC 기준 24분 내 완료해 PR 대기시간 영향을 최소화한다. 팀 규약 위반 감소율 70% 이상과 리뷰어 주관성 감소, 표준화 정착도 기대할 수 있다. 릴리스 후 결함 수정 비용과 비교하면 사전 탐지로 수정 비용을 3~10배 절감할 수 있다.

증분 분석·캐시·병렬화로 스캔 시간 예산을 관리하고, 기준선과 게이팅을 함께 운영하면 레거시 부담을 완화하면서 신규 이슈 유입을 막을 수 있다. 룰 변경에는 버전 태깅과 회귀 테스트 세트가 필요하다.

데이터플로우를 포함한 정밀 분석은 정확도를 높이는 대신 빌드 시간을 늘린다. 오탐을 줄이기 위해 예외를 넓히면 미탐 위험이 커질 수 있으며, 멀티언어 모노레포에서는 언어별 파서 정확도 차이로 커버리지가 불균형해질 수 있다.

정적 분석결함 탐지코드 품질CI/CD보안 취약점