strcpy도 사용 금지

1 month ago 11

  • cURL 프로젝트가 기존에 strncpy()를 제거한 데 이어, 이제 strcpy()도 코드베이스에서 완전히 금지
  • strcpy()는 API가 단순하지만 버퍼 크기 검증이 분리될 위험이 있어, 장기 유지보수 시 안전하지 않음
  • 이를 대신해 curlx_strcopy() 라는 새 함수가 도입되어, 대상 버퍼 크기와 문자열 길이를 모두 인자로 받아 복사 가능 여부를 검사 후 수행
  • 이 함수는 내부적으로 memcpy()를 사용하며, 널 종료 문자 처리까지 보장
  • 이러한 변경으로 보안성과 코드 일관성을 높이고, AI가 잘못된 취약점 보고를 생성하는 문제도 줄일 수 있음

strcpy 제거 배경

  • cURL은 과거에 strncpy() 호출을 모두 제거했으며, 이 함수의 비직관적 API와 널 종료 보장 실패, 불필요한 0 패딩 문제를 지적함
    • 부분 문자열 복사가 필요한 경우 memcpy()를 사용하고 널 종료를 직접 처리하도록 변경
  • strcpy()는 API가 단순하지만 버퍼 크기를 명시하지 않아 유지보수 중 검증 코드와 복사 호출이 분리될 위험이 있음
    • 코드가 수십 년간 여러 개발자에 의해 수정될 경우, 버퍼 크기 검증이 무력화될 가능성이 존재

새로운 문자열 복사 함수 도입

  • 이러한 위험을 방지하기 위해 curlx_strcopy() 라는 대체 함수를 도입
    • 인자로 대상 버퍼, 버퍼 크기, 원본 버퍼, 원본 문자열 길이를 받음
    • 복사와 널 종료가 모두 가능한 경우에만 memcpy()로 수행
    • 실패 시 대상 버퍼를 빈 문자열로 초기화
  • 이 함수는 strcpy()보다 더 많은 인자와 코드량이 필요하지만, 버퍼 검증을 복사와 밀접하게 결합해 안전성을 확보
  • cURL 코드베이스에서 strcpy() 사용을 완전히 금지하고, strncpy()와 동일하게 제거

구현 세부

  • 함수 정의 예시는 다음과 같음 void curlx_strcopy(char *dest, size_t dsize, const char *src, size_t slen) { DEBUGASSERT(slen < dsize); if(slen < dsize) { memcpy(dest, src, slen); dest[slen] = 0; } else if(dsize) dest[0] = 0; }
  • DEBUGASSERT를 통해 개발 중 오류를 조기 탐지하며, 실제 배포 환경에서는 항상 성공하도록 설계
  • strcpy처럼 반환값이 없으며, 테스트 및 퍼징 단계에서 오류를 잡는 방식을 채택

커뮤니티 반응

  • 일부 개발자는 strcpy_s()(C11 Annex K) 와 유사하다고 지적했으나, cURL은 여전히 C89 표준을 사용 중
  • 다른 의견으로는 반환값 추가 필요성이나 버퍼 실패 시 처리 방식 개선 제안이 있었음
  • 이에 대해 cURL 측은 “항상 성공하는 함수로 설계되었기 때문에 반환값은 불필요하다”고 설명

AI 관련 부가 효과

  • 이번 변경으로 AI 챗봇이 cURL 코드에서 strcpy 사용을 잘못 탐지해 ‘취약하다’고 주장하는 문제를 방지할 수 있음
  • 다만, 작성자는 “AI가 다른 허위 보고를 만들어낼 가능성은 여전하다”며 AI 기반 코드 분석의 한계를 언급

Read Entire Article