[C/C++] C언어 gets() 함수가 위험한 이유와 안전한 대안

[C/C++] C언어 gets() 함수가 위험한 이유와 안전한 대안

C
민호이 민호이 2025. 1. 13. 18:43
목차
  1. 1. gets() 함수가 위험한 이유
  2. 2. gets()의 대안
  3. 3. 권장 대안
  4. 4. 결론
  5. Reference

C언어에서 gets() 함수는 입력을 처리하는 데 사용되었지만, 심각한 보안 문제로 인해 더 이상 사용되지 않습니다. 실제로, 최신 C 표준(C11)에서는 gets() 함수가 완전히 제거되었습니다. 아래에서는 gets() 함수의 위험성과 그에 대한 안전한 대안을 살펴보겠습니다.


1. gets() 함수가 위험한 이유

1.1. 버퍼 오버플로우 문제

  • gets() 함수는 입력 버퍼의 크기를 확인하지 않고 무제한으로 입력을 읽습니다.
  • 만약 사용자 입력이 버퍼 크기를 초과하면, 메모리의 다른 영역을 덮어쓰게 됩니다.
  • 결과: 프로그램이 비정상적으로 종료되거나, 공격자가 임의의 코드를 실행할 수 있는 취약점(버퍼 오버플로우 공격)이 발생합니다.

예제 코드:

char buffer[10];
gets(buffer); // 버퍼 크기를 확인하지 않고 입력을 읽음

문제 시나리오:

  • 입력값: 123456789012345
  • 결과: 메모리 오버플로우로 인해 프로그램 동작이 예측 불가능하게 됩니다.

1.2. 보안 사고 사례

  • 1988년 모리스 웜(Morris Worm):
    • 인터넷 웜의 초기 사례 중 하나로, gets() 함수의 버퍼 오버플로우 취약점을 악용해 시스템 간에 웜이 퍼졌습니다.
    • 이 사건 이후 gets() 함수는 대표적인 보안 취약점으로 주목받았습니다.

2. gets()의 대안

2.1. fgets() 함수

  • fgets()는 입력 크기를 제한하며, 지정된 버퍼 크기만큼만 읽습니다.
  • 사용 예:
char buffer[10];
fgets(buffer, sizeof(buffer), stdin); // 안전하게 입력 처리
  • 특징:
    • 버퍼 크기를 초과하는 입력은 자동으로 잘립니다.
    • 개행 문자(\n)가 포함되므로 필요시 제거해야 합니다:
buffer[strcspn(buffer, "\n")] = '\0'; // 개행 문자 제거

2.2. POSIX getline() 함수

  • getline() 함수는 동적으로 메모리를 할당하여 무제한 입력을 안전하게 처리할 수 있습니다.
  • 사용 예:
char *line = NULL;
size_t len = 0;
getline(&line, &len, stdin);
printf("입력값: %s", line);
free(line); // 동적 메모리 해제
  • 특징:
    • 동적으로 메모리를 관리하므로 입력 크기에 제한이 없습니다.
    • 사용 후 **free()**를 호출해 메모리를 해제해야 합니다.

2.3. C11 gets_s() 함수

  • C11 표준에서는 gets()의 대체로 gets_s() 함수를 제안합니다.
  • **gets_s()**는 버퍼 크기를 명시적으로 전달하며, 크기를 초과하는 입력은 읽지 않습니다.
  • 사용 예:
#define __STDC_WANT_LIB_EXT1__ 1
#include <stdio.h>
char buffer[10];
gets_s(buffer, sizeof(buffer)); // 안전한 입력 처리
  • 한계:
    • 대부분의 컴파일러와 표준 라이브러리에서 지원하지 않습니다.
    • 주로 Windows 환경에서 사용 가능합니다.

3. 권장 대안

  • 일반적인 입력 처리: fgets() 함수 사용
  • 큰 데이터 입력 처리: POSIX의 getline() 함수 사용
  • 특정 플랫폼: gets_s() 사용(C11 지원 환경)

4. 결론

gets() 함수는 버퍼 크기를 확인하지 않아 심각한 보안 취약점을 초래합니다. 이러한 문제로 인해 C11 표준에서 공식적으로 제거되었으며, 더 이상 사용하지 않는 것이 좋습니다. fgets()나 getline()과 같은 안전한 대체 함수를 사용하는 것이 현대적인 C 프로그래밍의 필수적인 보안 습관입니다.

 

Reference

https://stackoverflow.com/questions/1694036/why-is-the-gets-function-so-dangerous-that-it-should-not-be-used

 

Why is the gets function so dangerous that it should not be used?

When I try to compile C code that uses the gets() function with GCC, I get this warning: (.text+0x34): warning: the `gets' function is dangerous and should not be used. I remember this has som...

stackoverflow.com

 

저작자표시 비영리 변경금지 (새창열림)
  1. 1. gets() 함수가 위험한 이유
  2. 2. gets()의 대안
  3. 3. 권장 대안
  4. 4. 결론
  5. Reference
'C' 카테고리의 다른 글
  • [C/C++] 배열 범위를 초과하면 안되는 이유: 위험과 좋은 코딩하기
  • [C/C++] 포인터 별 위치에 따른 차이점: 완전 분석, const까지
  • [C/C++] 초기화되지 않은 포인터 사용으로 인한 Segmentation Fault 해결하기
  • [C/C++] C에서 포인터로 배열 크기를 알 수 없는 이유와 해결책
민호이
민호이
민호이
ChungCODE
민호이
전체
오늘
어제
  • Categories (128)
    • 스포츠 (6)
    • 인공지능 (5)
    • 주식 (6)
      • 경제 주식 전망 (5)
      • ETF (9)
    • CSAPP (4)
      • Lab Session (4)
      • Concepts (0)
    • C (19)
    • Java (24)
    • Rust (44)
      • Concepts (27)
      • Libraries (17)
    • PS (2)
    • 국내 소식 (3)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • 알고리즘
  • 코드업
  • 수학
  • c++
  • 최소공배수
  • C
  • 최대공약수
  • 유클리드 호제법

최근 댓글

최근 글

반응형
hELLO · Designed By 정상우.v4.2.1
민호이
[C/C++] C언어 gets() 함수가 위험한 이유와 안전한 대안
상단으로

티스토리툴바

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.