
C언어는 강력한 성능과 높은 이식성 덕분에 운영체제, 임베디드 시스템 등 시스템 프로그래밍의 근간을 이루는 언어이다. 하지만 개발자에게 많은 자유를 주는 만큼, 메모리 관리의 허점이나 잘못된 코딩 습관으로 인해 치명적인 보안 취약점이 발생하기 가장 쉬운 언어이기도 하다. 버퍼 오버플로우, 포맷 스트링 버그와 같은 고전적이지만 여전히 강력한 해킹 공격의 대부분이 바로 이 C언어의 취약점에서 비롯된다. 그렇다면 이러한 위험을 최소화하고 안전한 C 코드를 작성할 방법은 없을까? 그 해답을 제시하는 것이 바로 'CERT C 코딩 표준'이다.

CERT C 코딩 표준(CERT C Coding Standard)은 미국 카네기 멜런 대학의 소프트웨어 공학 연구소(SEI) 부설 CERT에서 만든 C언어를 위한 시큐어 코딩(Secure Coding) 가이드라인이다. 이 표준의 목표는 간단하다.
C언어로 프로그래밍할 때 발생할 수 있는 보안 취약점과 버그를 유발하는 코딩 오류를 예방하기 위한 구체적인 규칙(Rule)과 권고(Recommendation)를 제공하는 것이다. 이는 개발자가 '하지 말아야 할 것'과 '해야 할 것'을 명확히 알려주는 안전 운전 설명서와 같다.
그렇다면 왜 수많은 프로그래밍 언어 중에서도 유독 C언어에 이토록 상세하고 엄격한 코딩 표준이 강조되는 것일까? 그 이유는 C언어가 가진 본질적인 특징에서 찾을 수 있다.

- 직접적인 메모리 제어의 양날의 검: C언어의 가장 큰 특징은 포인터를 통해 메모리에 직접 접근하고 제어할 수 있다는 점이다. 이는 하드웨어를 최대한 활용하여 성능을 극한으로 끌어올릴 수 있는 강력한 장점이지만, 동시에 개발자의 작은 실수가 메모리 침범, 데이터 손상, 시스템 다운과 같은 치명적인 결과로 이어질 수 있는 위험을 내포한다. malloc과 free를 통한 수동 메모리 관리는 메모리 누수(Memory Leak)나 이중 해제(Double Free)와 같은 문제를 야기하기 쉽다.
- 경계를 확인하지 않는 위험한 자유: C언어의 배열은 경계 검사(Bounds Checking)를 자동으로 수행하지 않는다. 예를 들어, 크기가 10인 배열의 11번째 공간에 데이터를 쓰려고 할 때, 대부분의 최신 언어들은 오류를 발생시켜 프로그램을 중단시킨다. 하지만 C언어는 이를 막지 않고 그냥 데이터를 써버려 인접한 메모리를 오염시키는 '버퍼 오버플로우'를 유발한다. 이는 공격자가 가장 선호하는 대표적인 침투 경로이다.
- '정의되지 않은 동작'이라는 시한폭탄: C언어 표준에는 일부 연산의 결과를 '정의되지 않은 동작(Undefined Behavior)'으로 규정하는 부분이 많다. 예를 들어, 부호 있는 정수의 오버플로우나 널 포인터 역참조 등이 여기에 해당한다. 이런 코드는 컴파일러나 실행 환경에 따라 전혀 다른 방식으로 동작하거나 아예 오작동할 수 있어, 예측 불가능한 버그와 보안 구멍을 만들어내는 시한폭탄과 같다.
이처럼 C언어의 특징인 높은 자유도와 직접적인 시스템 제어 능력은 성능이라는 장점을 주지만, 그 이면에는 항상 보안 취약점이라는 그림자가 따라다닌다. CERT C 코딩 표준은 바로 이러한 C언어의 태생적 위험을 개발자가 명확히 인지하고, 안전한 방향으로 코드를 작성하도록 이끄는 필수적인 나침반 역할을 한다.
CERT C 코딩 표준은 수많은 규칙으로 구성되어 있으며, 각 규칙은 고유 식별자와 함께 상세한 설명, 그리고 안전하지 않은 코드 예제와 안전한 코드 예제를 함께 제공한다. 이해를 돕기 위해 대표적인 규칙 몇 가지를 살펴보자.

- STR31-C: 문자열을 위한 저장 공간은 반드시 널 종단 문자를 포함해야 한다. C언어에서 문자열의 끝은 항상 널 문자('\0')로 표시된다. 만약 문자열을 저장할 메모리 공간을 할당할 때 이 널 문자를 위한 공간을 확보하지 않으면, 의도치 않은 메모리 영역을 침범하는 버퍼 오버플로우의 직접적인 원인이 된다. 예를 들어, "hello"라는 5글자 문자열을 저장하려면 널 문자 공간을 포함하여 최소 6바이트의 공간이 필요하다.
- MEM35-C: 동적 할당된 메모리에 충분한 공간을 확보해야 한다. malloc이나 calloc 함수로 메모리를 동적 할당할 때, 객체의 크기나 개수를 잘못 계산하여 필요한 것보다 작은 메모리를 할당하는 경우가 있다. 이 경우, 할당된 메모리 경계를 넘어 데이터를 쓰게 되는 힙 오버플로우(Heap Overflow)가 발생하여 프로그램의 비정상적인 종료나 보안 공격의 빌미를 제공한다.
- INT32-C: 정수 오버플로우나 랩어라운드가 발생하지 않도록 보장해야 한다. 정수형 변수가 표현할 수 있는 최댓값보다 큰 결과가 발생하는 연산을 수행하면 오버플로우가 발생한다. 부호 있는 정수의 오버플로우는 '정의되지 않은 동작(Undefined Behavior)'을 유발하여 예측 불가능한 결과를 낳고, 이는 종종 보안 취약점으로 이어진다. 따라서 정수 연산 전후에는 항상 오버플로우 발생 가능성을 검사해야 한다.
사이버 공격이 점점 더 지능화되는 오늘날, 시큐어 코딩은 더 이상 선택이 아닌 필수이다. CERT C 코딩 표준을 준수하면 다음과 같은 중요한 이점을 얻을 수 있다.

1. 보안성 향상
이미 알려진 수많은 보안 취약점의 근본 원인을 코드 레벨에서 제거하여 해킹의 위협으로부터 소프트웨어를 보호한다.
2. 소프트웨어 신뢰성 및 안정성 증가
정의되지 않은 동작이나 시스템 충돌을 유발할 수 있는 위험한 코드를 배제하여 프로그램이 예측 가능하고 안정적으로 동작하도록 만든다.
3. 코드 품질 및 유지보수성 향상
잘 정의된 표준을 따름으로써 코드의 가독성이 높아지고, 여러 개발자가 협업하는 프로젝트에서 일관된 코딩 스타일을 유지하는 데 큰 도움이 된다.

CERT C 코딩 표준은 단순한 규칙 목록을 넘어, 수십 년간 축적된 C언어의 취약점과 오류 사례를 집대성한 지식의 보고이다. 안전하고 견고한 소프트웨어를 만들고자 하는 개발자라면 반드시 학습하고 프로젝트에 적용해야 할 핵심적인 지침서라고 할 수 있다.

#CERT #CERTC #코딩표준 #시큐어코딩 #SecureCoding #C언어 #정보보안 #프로그래밍 #개발자 #C언어보안
'IT 정보 > 용어' 카테고리의 다른 글
| SDLC란?소프트웨어 개발의 교과서 (feat. 애자일, 워터폴) (1) | 2025.11.09 |
|---|---|
| QA란? 품질보증(Quality Assurance) 소프트웨어 품질의 수호자 (0) | 2025.11.08 |
| CWE란? 모든 개발자가 알아야 할 시큐어 코딩의 첫걸음 (0) | 2025.11.06 |
| XSS란? 크로스 사이트 스크립팅, 웹 보안의 첫걸음 (1) | 2025.11.05 |
| JNDI란? 이름으로 객체를 찾는 마법, 자바를 위한 전화번호부 (0) | 2025.11.03 |