Python의 CWE 예측을 위한 LLM과 SAST 도구의 적응적 계층 평가

읽는 시간: 9 분
...

📝 원문 정보

- Title: Adaptive Hierarchical Evaluation of LLMs and SAST tools for CWE Prediction in Python
- ArXiv ID: 2601.01320
- 발행일: 2026-01-04
- 저자: Muntasir Adnan, Carlos C. N. Kuhn

📝 초록

본 연구는 대형 언어 모델(LLMs)이 생성한 코드에서 취약점을 감지하는 데 있어 정적 분석 도구(SAST)와 LLMs의 성능을 비교하고, 이를 기반으로 반복적인 피드백 루프를 설계하기 위한 벤치마크인 **ALPHA**를 제시합니다. 이 연구는 취약점 탐지를 위해 사용되는 도구 선택에 대한 실질적인 근거를 제공하며, Python 함수 수준에서 CWE 분류의 정확성을 평가합니다.

💡 논문 해설

1. **첫 번째 기여**: 본 연구에서는 LLMs와 SAST 도구 사이의 성능을 비교하는 첫 번째 벤치마크인 **ALPHA**를 제시하고 있습니다. 이는 취약점 탐지에서 LLMs가 SAST보다 우수한지 여부를 결정할 수 있는 중요한 기준이 됩니다. 2. **두 번째 기여**: 함수 단위로 분석하여 LLM의 컨텍스트 윈도우 제한을 고려하고, 이는 코드 생성 시 더 세밀한 디버깅을 가능하게 합니다. 이를 통해 취약점 수정에 필요한 정확한 피드백을 제공할 수 있습니다. 3. **세 번째 기여**: 본 연구에서는 LLMs와 SAST 도구의 일관성을 여러 실행에서 평가하여 반복적인 피드백 시스템에 적합한 도구를 선택하는 데 중요한 정보를 제공합니다.

📄 논문 발췌 (ArXiv Source)

취약점 감지, 대형 언어 모델, 정적 분석, CWE 분류, 계층평가

서론

대형 언어 모델(LLMs)은 소프트웨어 개발 프랙티스를 근본적으로 변화시켰으며, 코드 생성 능력이 GitHub Copilot, Amazon CodeWhisperer 및 ChatGPT와 같은 도구를 통해 주류 개발 워크플로에 통합되었습니다. 이 패러다임 전환은 개발자의 생산성을 크게 향상시켜 프로토타입 구현을 빠르게 수행하고 개발 사이클을 가속화하는 것이 가능하게 하였습니다. 그러나 최근 연구는 LLMs이 생성한 코드에 악용 가능한 취약점이 포함되는 경우가 많다는 점을 보여주며, 보안 결함은 모델 복잡성과 작업에 따라 40-60%의 생성된 코드 조각에서 나타납니다. 연구 커뮤니티는 이 취약점 문제를 두 가지 주요 방향으로 접근했습니다: 프롬프트 엔지니어링과 감독 학습 세분화.

보안에 초점을 맞춘 프롬프트 기법은 잠재력을 보여주며, GPT-4와 같은 모델에서 취약점 생성을 최대 61%까지 줄였습니다. 자가 반성 접근 방식에서는 모델이 이전에 생성한 코드의 취약점을 감지하고 수정하여 특정 프롬프트로 41.9-68.7%의 취약점 해결을 달성했습니다. 그러나 이러한 기법은 실용적인 한계를 보입니다. 해당 기법들은 중요한 향상을 이루려면 취약점에 대한 지시가 필요하고, 또한 우려할 만큼 불안정한 결과를 보여줍니다. 프롬프트의 작은 수정으로도 결과가 크게 달라지고 연구 내외에서 일관성이 부족합니다.

세분화 접근 방식은 개선을 보였지만, 헤이저포르팅, 일반화 문제 및 취약점 경로가 변화함에 따라 자주 재훈련하는 데 필요한 계산 비용의 제한 사항 등 여러 중대한 한계를 가지고 있습니다. 최근 증거는 현대적 소형 언어 모델(SLMs)이 개선된 훈련 방식을 통해 이전보다 큰 모델의 성능을 능가하거나 동등하게 할 수 있음을 시사하며, 이를 통해 취약점에 대한 세분화 학습이 불필요해질 수도 있습니다.

이러한 한계를 고려할 때 반복적인 피드백 루프는 유망한 대안으로 부상하고 있으며 이미 코드 생성의 기능 정확성을 향상시키는 데 효과를 보여주고 있습니다. 이러한 시스템은 생성된 코드를 반복적으로 분석하고 특정 문제점을 식별하여 모델이 이를 해결하도록 프롬프트합니다. 그러나 아직 답변되지 않은 중요한 질문이 하나 남아 있습니다: 취약점 감지를 위한 피드백을 제공하는 도구는 무엇일까요? 두 가지 후보 접근 방법이 있으며, 현재의 관행은 대부분 SAST 도구를 피드백 생성에 사용하지만 이 선택은 경험적으로 이루어진 것보다 체계적인 검증이 부족한 측면이 있습니다. 최근 비교 연구는 LLMs가 취약점 감지에서 SAST 도구보다 우수할 수 있음을 시사하지만, 결과는 제한적이고 혼합적이며 맥락에 따라 달라집니다.

연구 격차 및 기여

기존의 SAST-LLM 비교는 기본적인 방법론적 한계를 가지고 있습니다: 대부분 이진 분류(취약점/취약점 없음)를 사용하여 반복적인 수정에 필요한 충분한 구체성을 제공하지 않습니다. 효과적인 피드백 메커니즘은 취약점의 종류, 위치 및 특성(CWE 유형)을 정확하게 식별해야 합니다. 이러한 세부 정보 없이는 모델이 프롬프트 엔지니어링 연구에서 제시한 취약점에 대한 명확한 지침을 받을 수 없습니다.

일부 연구는 SAST와 LLMs을 비교하였지만, Python의 함수 단위 분석을 위한 피드백 메커니즘 설계에 필요한 벤치마크를 제공하지 않습니다. 이 세분화는 필수적입니다; 함수 단위 분석은 LLM 컨텍스트 윈도우 제한을 고려하고 세밀한 디버깅이 가능하게 합니다. Python은 개발 워크플로에서 가장 널리 사용되는 언어이며 여기서 LLM 코드 생성이 가장 많이 이루어지므로 이 연구는 이러한 격차를 직접적으로 해결합니다.

본 연구에서는 여러 LLMs(현대 SLMs 포함)과 SAST 도구를 다양한 Python 취약점 데이터셋에 대해 CWE 수준의 세분화로 비교하는 첫 번째 종합 벤치마크 ALPHA(계층 평가를 통한 적응 학습)를 제시합니다. 우리의 기여는 다음과 같습니다:

  • 함수 단위 파이썬 취약점 감지 벤치마크인 ALPHA - LLMs와 SAST 도구 모두에 대한 CWE 특정 식별을 평가하여 피드백 메커니즘 선택의 실질적인 근거를 제공합니다.
  • 각 LLM에 대해 여러 실행에서 검출 일관성 분석, 반복적 수정 시스템에서 일관된 피드백이 중요하기 때문에.

관련 연구

초기 보안 개선 노력은 취약점 토큰 분류 및 적대적 학습을 사용하여 LLMs를 안전한 코드 생성으로 세분화하는 데 집중했습니다. 이러한 연구는 30-32%의 정확도 향상을 보고하였지만, 세분화된 모델은 일반화 능력이 부족하고 과적합 문제가 있습니다. 세분화된 모델에서 지식 대칭성이 반전되는 역주행 현상이 문서화되었으며, 재학습에 따른 급격한 잊어버림과 세분화의 상당한 계산 비용은 자주 재훈련하기 어렵게 합니다. 특히 취약점 증강 프롬프트 프레임워크 DLAP은 프롬프트 엔지니어링이 세분화보다 취약점 감지 정확도와 비용 효과성이 우수함을 발견하여 프롬프트 기반 접근 방식을 검토하게 되었습니다.

프롬프트 엔지니어링은 계산적으로 효율적인 대안을 제공하며, 반영 기법이 특히 유망합니다. 최근 연구는 GPT 모델에서 재귀적 비판과 개선(RCI)으로 61%의 향상을 보고하였으며, 이 방식에서는 모델이 출력을 반복적으로 비판하고 정교화합니다. 그러나 프롬프트 기반 접근법은 우려할 만큼 불안정한 결과를 보여줍니다. 캐릭터 프롬프팅은 연구 간 일관성이 떨어지는 결과를 보였습니다. Kong과 Zhao는 60%의 정확도 향상을 보고하였지만, Bruni 등은 GPT 모델에서 43%의 개선을 보고했으며, Zheng 등은 네 가지 LLM 가족에 걸쳐 캐릭터 프롬프트가 무작위나 부정적인 효과를 나타냈습니다. 이러한 민감성은 단어 선택의 변동까지 확장되어 신뢰성을 저하시킵니다.

세분화 학습의 불실용성과 프롬프트 엔지니어링의 불안정성으로 인해, 반복 피드백 루프가 가장 유망한 접근 방식으로 부상하고 있으며 파이썬 코드 생성에서 15-35%의 향상을 보여줍니다. 피드백 루프는 프롬프트 엔지니어링의 효율성을 유지하면서 구조화된 외부 검증 및 피드백을 결합합니다. 이로 인해 중요한 질문이 제기됩니다: 취약점 수리를 위한 피드백은 어떤 도구가 생성해야 하나요? 주목할 만한 점은 현재 모든 반복 피드백 루프 구현에서 SAST 도구에 의존하고 LLMs는 주로 해석과 코드 수정을 위해 사용된다는 것입니다. 또한, SAST 도구는 평가 데이터셋의 기준 진실로 자주 사용되며 이는 이러한 도구를 취약점 감지에 적합한지 체계적으로 검증하지 않은 방법론적 순환성을 초래합니다. 따라서 피드백 루프에서 SAST 도구 선호는 경험적으로 이루어진 것보다 체계적인 검증이 부족한 측면이 있습니다.

SAST 도구와 LLMs을 취약점 감지에 대해 직접 비교하면 혼합되고 맥락에 따른 결과가 나타납니다. C 프로그램의 작은 코드베이스에서 Castle은 GPT-3.5-mini(977/1250)보다 SAST 도구(661/1250)보다 우수함을 보고하였지만, Gong 등은 GPT-4가 3.1%의 거짓 긍정으로 76%의 감지율을 달성했음에도 불구하고 여전히 정적 도구를 선호한다고 제안했습니다. 파이썬에 초점을 맞춘 연구는 유사한 혼합 결과를 보여줍니다: Li 등은 DeepSeek R1에서 67%의 정확도를 달성하였고, Zhou 등은 저장소 수준 분석에서 LLM 점수가 SAST의 44.4보다 100을 달성하였으며, PyVul은 커밋 수준 취약점 감지에서 CodeQL이 10.8%의 정확도를 달성한 반면 LLMs는 함수 단위에서 49.5-58.5%를 달성했습니다.

다수의 연구는 이진 분류(취약점/취약점 없음)를 수행하며, 저장소 또는 커밋 수준에서 평가하고, 특히 여러 실행에 대한 감지 일관성을 평가하지 않습니다. 반복 피드백 시스템에서는 이러한 한계가 치명적입니다: 이진 분류는 대상 수정을 안내할 수 없고 저장소 수준 분석은 LLM 컨텍스트 윈도우를 초과하며 불안정한 피드백은 반복적인 개선을 저해합니다.

기존 연구 중 SAST와 LLMs을 취약점 감지 피드백 도구로 직접 비교하여 Python 함수 단위에서 CWE 수준의 세분화를 평가하는 것은 없습니다. 이는 실용적인 반복 피드백 시스템에 필요한 정확한 요구 사항입니다. 파이썬이 LLM 코드 생성에서 우세하고 컨텍스트 윈도우 제약으로 인해 함수 단위 분석이 필요함을 고려할 때, 어떤 도구가 더 신뢰성 있고 행동 가능한 피드백을 제공하는지 여부는 여전히 개방적인 질문이며 직접적인 실용적 의미를 가지고 있습니다.

방법론

데이터셋

우리는 두 가지 특성이 다른 Python 취약점 데이터셋에서 평가합니다. 데이터셋 선택은 세 가지 요구 사항에 제한되었습니다: 함수 단위의 세분화, 명시적인 CWE 진실 레이블, 그리고 SAST 도출된 진실 대신 인간 주석자 레이블. SecurityEval에는 CWE 계층에 분포되어 있는 취약함 121개가 포함되어 있습니다: 기본 약점 73개, 클래스 약점 26개, 변형 약점 16개, 기둥 약점 3개. SVEN은 원래의 다언어 데이터셋에서 필터링된 720개 중 342개의 Python 샘플로 구성되어 있으며 모두 기본 약점으로 레이블이 지정되었습니다. 이 수준 분포 차이는 중요합니다: SecurityEval의 계층적 다양성은 특정성 요구 사항이 다양한 더 어려운 탐지 작업을 생성하지만, SVEN의 균일한 기본 단계 레이블은 더 정확한 예측 대상을 제공합니다. 두 데이터셋 모두 계층적으로 인식된 탐지를 평가하기에 적합한 CWE 진실 레이블을 제공합니다.

CWE 그래프 구성

CWE는 소프트웨어 약점을 위한 계층적 분류체계를 제공합니다. MITRE CWE 데이터베이스에서 직접 그래프 $`G = (V, E)`$를 구성하였습니다.

  • 노드 ($`V`$): 기둥 약점, 클래스 약점, 기본 약점, 변형 약점, 복합 약점 및 체인 약점을 포함한 CWE 약점 유형
  • 엣지 ($`E`$): CWE 계층의 부모-자식 관계

“뷰"와 “카테고리” 두 가지 CWE 유형은 CWE 데이터베이스 내에서 조직 구조로서 제외되었습니다. 이는 총 49개 노드와 480개 엣지를 제거하지만 일반화를 잃지 않습니다. “뷰"는 약점을 다른 관점(예: 개발 단계나 대상)으로 제공하고, “카테고리"는 공유 특성(예: 인증 오류)에 따라 약점을 그룹화합니다. 이러한 구조들은 특정이고 탐지 가능한 취약점을 설명하지 않고 대신 분류 체계 내에서 길잡이 역할을 합니다. 결과 그래프에는 944개의 노드와 1,153개의 엣지가 포함되어 있으며 전체 그래프(모든 CWE를 포함)에는 각각 993개의 노드와 1,633개의 엣지가 포함됩니다.

ALPHA: 적응적 벌점 메트릭

주어진 코드 샘플에 대해 진실된 CWE $`c_{true}`$과 예측된 CWE $`c_{pred}`$, 벌점 점수 $`P`$는 다음과 같이 정의됩니다:

MATH
\begin{equation*}
    P(c_{\text{pred}}, c_{\text{true}}) = d(c_{\text{pred}}, c_{\text{true}}) \times \alpha(c_{\text{pred}}, c_{\text{true}})
\end{equation*}
클릭하여 더 보기

여기서 거리 구성 요소 $`d(c_{pred}, c_{true})`$는 그래프 $`G`$에서의 노드 간 최단 경로 길이를 나타냅니다. 이는 예측이 $`c_{true}`$로부터 얼마나 “멀리” 벗어났는지를 캡처합니다. 방향 곱셈자 $`\alpha(c_{pred}, c_{true})`$는 오류의 의미론적 유형을 인코딩합니다.

MATH
\alpha(c_{\text{pred}}, c_{\text{true}}) =
\left\{
\begin{array}{@{}l l@{}}
\alpha_{\text{up}}
& \makecell[l]{\text{if } c_{\text{pred}} \text{ is an ancestor of } c_{\text{true}}\\
(generalising)} \\[4pt]
\alpha_{\text{down}}
& \makecell[l]{\text{if } c_{\text{pred}} \text{ is a descendant of } c_{\text{true}}\\
(over-specifying)} \\[4pt]
% \alpha_{\text{oog}}
% & \makecell[l]{\text{if } c_{\text{pred}} \text{ does not exist in } G\\
% (out-of-graph)} \\[4pt]
\alpha_{\text{lateral}}
& \makecell[l]{\text{otherwise (lateral error)}}
\end{array}
\right.
클릭하여 더 보기

방향 결정은 방향 그래프를 사용하며, $`c_{pred}`$가 $`c_{true}`$의 조상이라면(일반화) $`c_{pred}`$에서 $`c_{true}`$로 연결된 경로가 존재하고, 반대라면 후손(과도한 구체화); 그렇지 않으면 횡단 오류입니다. 최단 경로 거리는 오류의 크기를 캡처하지만 모든 동일 거리의 오류를 동등하게 취급하여 실용적인 중요성을 포착하지 못합니다. 우리는 세 가지 오류 유형을 구분합니다:

  • 일반화 오류 ($`\alpha_{up} = 2.0`$): 예측이 계층 위로 이동하면 중요한 진단 정보가 손실됩니다. 예를 들어, 진정한 약점인 CWE-89(SQL 인젝션, 기본)을 예측하여 CWE-707(비적합 중화, 기둥)은 거의 행동 지침을 제공하지 않습니다. 우리는 이 심각한 유틸리티 손실을 반영하기 위해 가장 높은 고정 벌점 2.0을 부여합니다.

  • 횡단 오류 ($`\alpha_{lateral} = 1.8`$): 다른 분기에서 예측은 개념적 이해에 혼란이 있지만 약점들이 공통 부모 클래스를 가지고 있거나 관련 도메인에 속하는 경우 진단 가치가 일부 남아 있습니다. 우리는 중간적인 고정 벌점 1.8을 부여하여 일반화보다 낮고 과도한 구체화보다 높게 설정합니다.

  • 과도한 구체화 오류 ($`\alpha_{down},`$ 적응): 예측이 계층 아래로 이동하면 오류는 불필요하게 구체적이지만 일반적인 이해에는 맞습니다. 중요성은 진실된 CWE의 후손 계층에서 가능한 “구체화 여유 공간”에 크게 의존합니다.

    MATH
    \begin{equation*}
            \alpha_{down}(c_{true}) = \alpha_{max} - (\alpha_{max} - \alpha_{min}) \times \frac{\delta(c_{true})}{\Delta(type(c_{true}))}
    \end{equation*}
    클릭하여 더 보기

    여기서 $`\delta(c_{true})`$는 $`c_{true}`$에서 가족 서브트리의 모든 후손 리프까지의 최대 거리(깊이)이고, $`\Delta(type(c_{true}))`$는 해당 유형의 CWE 중 최대 $`\delta`$. 여기서 $`\alpha_{max} = \alpha_{lateral} = 1.8`$이고 $`\alpha_{min} = 1.1`$입니다.

    이러한 적응적 접근 방식의 이유는 다음과 같습니다:

    • 리프 노드($`\delta = 0`$): $`c_{true}`$가 자식이 없는 리프인 경우, 더 구체적인 것을 예측하는 것은 횡단 오류와 같기 때문에 부여된 벌점은 $`\alpha_{max} = \alpha_{lateral} = 1.8`$입니다.
    • 깊은 서브트리(높은 $`\delta`$): $`c_{true}`$가 많은 후손을 가진 Class 또는 Pillar인 경우, “구체화 여유 공간”이 많이 있습니다. 과도한 구체화는 경미한 오류로, 예측은 개념적으로 맞지만 특정 인스턴스를 가정합니다. 따라서 $`\alpha_{min} = 1.1`$ (1.0을 초과하여 벌점 효과가 유지되도록).

감사의 말씀

이 글의 저작권은 연구하신 과학자분들께 있으며, 인류 문명 발전에 공헌해주신 노고에 감사를 드립니다.

검색 시작

검색어를 입력하세요

↑↓
ESC
⌘K 단축키