gitlab

GitLab은 리팩터링과 코드 재서식을 통해 취약점을 추적하는 방법 (새 탭에서 열림)

GitLab은 코드 위치나 줄 번호가 바뀌어도 동일한 취약점을 안정적으로 추적하기 위해 Scope+Offset 핑거프린팅을 개선했습니다. 기존 방식은 주석과 빈 줄도 오프셋에 포함해 비기능적 수정만으로 중복 취약점을 만들 수 있었지만, 개선된 방식은 이를 무시합니다. 벤치마크에서 중복 핑거프린트를 제거하고 고유 핑거프린트를 43% 줄였으며, scope_offset_compressed 알고리즘으로 GitLab에 적용되었습니다.

코드 변경으로 발생하는 취약점 추적 문제

  • 개발자가 주석을 추가하거나 파일을 재포맷하거나 함수를 이동하면 코드 줄 번호가 달라질 수 있습니다.
  • 줄 번호만으로 취약점을 식별하면 기존 취약점이 새로운 문제로 오인됩니다.
  • 그 결과 보안 팀은 이미 검토한 취약점을 다시 분류해야 하고, 스캔 결과에 대한 신뢰도도 낮아집니다.

기존 Scope+Offset 핑거프린팅

  • 2022년에 도입된 방식으로, 취약점을 다음 두 요소의 조합으로 식별합니다.
    • 취약점을 포함하는 가장 좁은 코드 범위: 모듈, 클래스, 함수 등
    • 해당 범위 내부에서 취약점까지의 줄 오프셋
  • 파일 전체의 절대 줄 번호 대신 범위 내부 위치를 사용해 코드 이동에 더 강합니다.
  • 기존 줄 기반 추적보다 불필요한 재감사를 약 30% 줄였습니다.
  • 그러나 범위 시작점부터 취약점까지의 모든 줄을 계산했기 때문에 주석과 빈 줄 추가에는 취약했습니다.

비기능적 코드 무시를 통한 개선

  • 개선된 알고리즘은 핑거프린트를 계산할 때 다음 요소를 제외합니다.
    • 주석
    • 빈 줄
  • 프로그램 동작에 영향을 주지 않는 코드가 취약점의 정체성에 영향을 주지 않아야 한다는 원칙을 적용했습니다.
  • 따라서 취약점 앞에 주석을 추가하거나 파일을 재포맷해도 동일한 핑거프린트가 유지됩니다.
  • 기존 방식의 추적 정밀도는 유지하면서 비기능적 수정에 대한 안정성만 높였습니다.
  • 스캐너가 이미 생성하는 파스 트리를 재사용하므로 스캔 시간은 증가하지 않습니다.

벤치마크 결과

  • C/C++, C#, Go, Java, JavaScript, Python, Ruby의 소스 파일 439개를 대상으로 평가했습니다.
  • 취약점 바로 앞에 주석 또는 빈 줄 하나를 추가하는 커밋 2,247개를 생성했습니다.
  • 기존 Scope+Offset 방식:
    • 중복 핑거프린트 1,361개 발생
    • 기준 대비 77% 증가
  • 정규화된 방식:
    • 중복 핑거프린트 0개
    • 고유 핑거프린트 43% 감소
  • 모든 커밋이 취약점 인근의 비기능적 수정이라는 최악의 조건에서도 효과를 확인했습니다.

GitLab 적용 방식

  • 개선된 알고리즘 이름은 scope_offset_compressed입니다.
  • 다음 언어를 지원합니다.
    • C#
    • C/C++
    • Go
    • Java
    • JavaScript
    • Python
    • Ruby
    • PHP
  • 기존 보안 보고서 형식은 변경되지 않았습니다.
  • 따라서 여러 SAST 도구를 함께 사용하는 환경에서도 기존 통합 구조와 호환됩니다.
  • 관련 연구는 “Vulnerability Tracking using Normalized Scope+Offset”라는 제목으로 ASE 2026 Industry Showcase에서 발표될 예정입니다.

실용적인 결론

SAST 도구는 줄 번호가 아니라 코드의 논리적 범위와 의미 있는 위치를 기준으로 취약점을 추적해야 합니다. 특히 주석, 빈 줄, 포맷 변경처럼 동작에 영향을 주지 않는 수정은 핑거프린트에서 제외하는 것이 중복 경고와 불필요한 재감사를 줄이는 효과적인 방법입니다.