본문으로 건너뛰기
CodeAuditAgent
전체 글

CodeAuditAgent 리포트를 읽고 조치하는 법

CodeAuditAgent 리포트 읽는 법: 위험 점수, 심각도, 신뢰도, CWE, 근거와 패치, 트리아지와 재감사.

· 6분 분량 · Lina Source LLC

보안 리포트는 병합된 수정으로 이어질 때만 쓸모가 있습니다. CodeAuditAgent 리포트는 바로 그 점을 중심으로 설계되었습니다. 각 발견 사항은 빠르게 검증할 수 있을 만큼 구체적이며, 상황에 맞게 다듬을 수 있는 패치가 함께 제공됩니다. 이 가이드는 리포트의 모든 구성 요소와, 전담 보안 엔지니어가 없을 때 트리아지하는 방법, 그리고 수정이 제대로 됐는지 확인하는 방법을 설명합니다.

무엇을 감사하는가

감사는 공개 GitHub 저장소 또는 여러분이 붙여넣은 코드 스니펫을 대상으로 실행됩니다. 저장소의 경우 CodeAuditAgent는 기본 브랜치를 읽습니다. 비공개 저장소는 URL로 감사할 수 없고, 아직 풀 리퀘스트 댓글 기능도 없습니다. 결과는 대시보드와 내보내기에 남습니다.

저장소를 얼마나 많이 읽는지는 플랜에 따라 다릅니다. 무료 플랜은 저장소 1개, 월 3회 감사, 감사당 최대 20개 파일을 지원합니다. 월 $49의 Starter는 저장소 5개, 감사 50회, 감사당 40개 파일을 지원합니다. 월 $199의 Pro는 저장소 무제한, 감사 500회, 감사당 80개 파일을 지원합니다. 60 KB를 넘는 개별 파일은 건너뜁니다. 월간 감사 횟수는 매월 초(UTC 기준)에 초기화됩니다. 붙여넣은 스니펫은 저장소 전체를 감사하기 전에 걱정되는 파일 하나를 빠르게 확인하는 방법이기도 합니다.

이 한도 때문에 일부 파일이 제외되면 리포트에 부분 스냅샷이라고 표시됩니다. 이 표시를 진지하게 받아들이세요. 깨끗한 부분 스냅샷은 읽은 파일이 깨끗해 보인다는 뜻이지 저장소가 깨끗하다는 뜻이 아닙니다. 가장 신경 쓰이는 코드가 빠졌다면 그 코드를 스니펫으로 붙여넣어 감사하거나, 더 많은 파일을 다루는 플랜에서 감사하세요.

위험 점수

모든 리포트 상단에는 0에서 100까지의 위험 점수가 있으며, Markdown 내보내기에는 그 옆에 종합 심각도도 표시됩니다. 높을수록 위험이 큽니다. 이 점수는 해당 감사의 발견 사항을 요약한 값으로, 두 가지에 유용합니다. 저장소를 얼마나 급하게 살펴봐야 할지 판단하는 것과, 시간이 지나며 나아지고 있는지 추적하는 것입니다.

서로 무관한 저장소 사이의 작은 점수 차이에 지나치게 의미를 두지 마세요. 점수는 언제나 감사한 대상을 기준으로 한 상대적인 값이고, 부분 스냅샷은 더 적은 코드를 봅니다. 같은 저장소의 수정 전후를 비교할 때 이 숫자가 가장 의미 있습니다.

심각도와 신뢰도

모든 발견 사항에는 심각도와 신뢰도가 있습니다. 둘은 서로 다른 질문에 답합니다. 심각도는 그 발견 사항이 사실일 경우 얼마나 나쁜가이고, 신뢰도는 그것이 사실이라고 리뷰어가 얼마나 확신하는가입니다.

  • 치명: 공개 엔드포인트의 인젝션, 인증 우회, 노출된 프로덕션 자격 증명처럼 곧바로 악용 가능하며 영향이 심각한 경우.
  • 높음: 어느 정도 전제 조건이 필요하거나, 크지만 제한된 영향을 가지는 실제 취약점.
  • 중간: 다른 버그와 결합될 때 의미가 있거나 영향이 중간 정도인 약점.
  • 낮음: 보안 강화 사항과 심층 방어의 공백.
  • 정보: 그 자체로는 취약점이 아니지만 알아 둘 만한 관찰 사항.

신뢰도는 높음, 중간, 낮음입니다. 신뢰도가 높은 발견 사항은 읽은 코드에 명확한 근거가 있습니다. 신뢰도가 낮은 발견 사항은 보통 감사가 볼 수 없었던 것에 의존합니다. 다른 파일의 미들웨어, 데이터베이스 정책, 배포 시점에 설정되는 구성 값 같은 것들이죠. 신뢰도가 낮다는 것은 무시해도 된다는 뜻이 아니라, 수정하기 전에 사람이 빠진 맥락을 확인해야 한다는 뜻입니다.

발견 사항의 구조

모든 발견 사항은 같은 구조를 따르므로 일정한 순서로 검증할 수 있습니다.

  • 제목과 CWE: 사용자가 제어하는 키를 통한 인가 우회를 가리키는 CWE-639처럼 약점의 분류입니다. CWE를 보면 어떤 종류의 수정이 필요할지 짐작할 수 있습니다.
  • 위치: 파일과 줄 번호로, 코드를 바로 열어 볼 수 있습니다.
  • 근거: 해당 파일에서 인용한 관련 코드입니다. 인용문이 현재 코드와 일치하는지 확인하세요. 그 줄이 이미 바뀌었다면 발견 사항이 오래된 것일 수 있습니다.
  • 공격 시나리오: 공격자가 그 약점을 실제로 어떻게 이용할지 단계별로 설명합니다. 여러분의 맥락에서 이것이 실제 문제인지 판단하는 가장 빠른 방법입니다.
  • 해결 방법: 주변 코드 스타일에 맞춰 제안된 변경입니다.

패치는 바로 병합할 수 있는 커밋이 아니라 든든한 출발점으로 여기세요. 감사가 읽은 코드를 바탕으로 작성되므로 여러분의 헬퍼 함수나 ORM 관례, 코드베이스 다른 곳의 호출자를 모를 수 있습니다. 일반적인 패치는 작고 목표가 분명합니다.

--- a/app/api/invoices/[id]/route.ts
+++ b/app/api/invoices/[id]/route.ts
@@
-  const invoice = await db.invoice.findUnique({ where: { id } });
+  const invoice = await db.invoice.findFirst({
+    where: { id, userId: session.user.id },
+  });
   if (!invoice) return Response.json({ error: 'not_found' }, { status: 404 });

잘된 점과 다음 단계

리포트에는 잘하고 있는 점도 함께 담깁니다. 매개변수화 쿼리를 일관되게 사용하는 것, 시크릿을 환경에서 읽는 것, 엄격한 쿠키 설정 같은 것들이죠. 이 부분도 읽어 볼 가치가 있습니다. 어떤 패턴을 유지하고 새 코드에 복사해야 하는지 알려 주며, 코드베이스의 상태를 다른 사람에게 설명할 때도 유용합니다.

권장 다음 단계 섹션은 발견 사항을 순서가 있는 계획으로 바꿔 줍니다. 관련된 발견 사항을 묶어 주는 경우가 많습니다. 예를 들어 소유권 검사가 빠진 여러 건은 다섯 개의 개별 패치보다 공용 헬퍼 하나로 함께 고치는 편이 낫습니다.

작은 팀을 위한 트리아지 절차

보안 엔지니어가 없을 때의 위험은 리포트를 무시하는 것이 아니라, 치명적인 항목이 기다리는 동안 낮은 항목에 하루를 쓰는 것입니다. 단순한 순서가 잘 통합니다.

  • 치명과 높음 발견 사항을 먼저 모두 읽으세요. 각각에 대해 공격 시나리오를 읽고 실제인지, 실제가 아닌지, 맥락이 더 필요한지 판단하세요.
  • 실제인 치명 발견 사항은 당일에 고치세요. 수정에 시간이 필요하다면 엔드포인트를 비활성화하거나 검사를 강화하는 임시 완화책을 두세요.
  • 맥락이 필요한 발견 사항은 빠진 조각을 확인하세요. 이미 그것을 막아 주는 미들웨어나 행 수준 정책, 설정이 있는지 확인하고 답을 기록해 두세요.
  • 높음은 현재 스프린트에, 중간은 백로그에 배치하고, 낮음과 정보는 모아서 보안 강화 작업으로 처리하세요.
  • 발견 사항이 실제가 아니라면 그 이유를 기록하세요. 그 메모가 다음 사람이 다시 조사하는 수고를 덜어 줍니다.

발견 사항마다 담당자를 한 명씩 지정하세요. 팀 전체가 공유하는 발견 사항은 결국 아무의 것도 되지 않는 경향이 있습니다.

발견 사항 탐색기와 내보내기

감사가 여러 건 쌓이면 개별 리포트보다 발견 사항 탐색기로 작업하는 편이 수월합니다. 탐색기는 여러 감사에 걸친 발견 사항을 나열하고 심각도와 CWE, 저장소로 필터링해 줍니다. CWE로 필터링하는 것이 특히 유용합니다. 같은 약점이 저장소 세 곳에 나타난다면 보통 공용 패턴이나 빠진 헬퍼를 가리키며, 각각을 고치는 것보다 패턴을 고치는 편이 비용이 적게 듭니다.

발견 사항은 탐색기에서 CSV로 내보낼 수 있어 이슈 트래커나 스프레드시트로 옮기기 좋습니다. 개별 리포트는 Markdown으로 내보낼 수 있으며, 풀 리퀘스트 설명이나 내부 위키, 수정을 맡은 외주 인력에게 보내는 메시지에 잘 어울립니다.

재감사로 수정 확인하기

확인하기 전까지 수정은 끝난 것이 아닙니다. 병합한 뒤 같은 저장소에 새 감사를 실행하세요. 각 리포트는 이전 감사와 비교할 수 있으므로 어떤 발견 사항이 사라졌고 무엇이 남았으며 새로 생긴 것이 있는지 볼 수 있습니다. 실제 문제가 고쳐졌다면 위험 점수가 떨어져야 합니다. 그렇지 않다면 비교 화면에서 이유를 확인하세요.

비교는 공정하게 유지하세요. 첫 감사가 부분 스냅샷이었고 두 번째가 다른 파일을 읽었다면, 차이는 수정뿐 아니라 감사 범위도 반영합니다. 감사는 월간 할당량에서 차감되므로, 커밋마다 다시 실행하기보다 여러 수정을 모아서 재감사하는 편이 대체로 낫습니다.

리포트가 다루지 않는 것

한계를 알면 빈틈을 메울 수 있습니다. 감사는 소스 코드를 읽으며, 알려진 취약 버전을 찾기 위해 의존성을 스캔하지는 않습니다. 따라서 패키지 매니저에 내장된 도구나 GitHub의 의존성 스캐너도 함께 돌리세요. 감사는 배포 시점의 설정과 저장소 밖의 인프라, 건너뛴 파일을 보지 못합니다. 그리고 사람이든 AI든 모든 리뷰어가 그렇듯 감사도 틀릴 수 있습니다. 근거와 신뢰도가 제공되는 이유는 그대로 믿기보다 빠르게 확인할 수 있게 하기 위해서입니다.

이렇게 활용하면 리포트는 근거가 붙은, 짧고 우선순위가 정해진 변경 목록이 됩니다. 치명적인 것을 고치고, 불확실한 것을 확인하고, 재감사해서 점수가 움직이는지 지켜보세요.