시큐어코딩

시큐어 코딩 (1) - CH 00

vitamin3000 2025. 4. 13. 16:28

 

이번 포스트에서는 수업에서 제공해주신 ch00 자료를 바탕으로 중요하다고 생각되는 내용을 정리해보고자 한다.

 

 

1. 4차산업혁명 시대의 위협 : 소프트웨어 버그/에러/오류

 

  • (일반적인) 버그
    • 정상적 작동 중 설계/코딩 등의 잘못으로 발생하는 버그
    • SW 품질, 안전성, 신뢰성 등 저하
  • 취약점
    • 정상적 작동 중 공격자의 의도로 발생하는 보안 약점
    • 사이버 공격에 사용

2. 소프트웨어 안전성(safety) 사용

 

정의 : 시스템이 재앙(인명의 손상, 시스템의 파괴 등)과 같은 실패 없이 동작하는 능력

 

SW 신뢰성 != SW 안정성

 

문제 발생을 일으키는 것을 파악

 

예를들어, 어떠한 하드웨어의 내구성 문제로 유지보수 및 물품 교체가 필요하다고 가정해보자

 

물품 교체가 필요한 시기에 사고가 발생할 것으로 예상될 수 있다.

 

또는 운영시간이 특정 시간이 넘어가면서 발생하는 시간 오차에 대해서 

코드의 연산식과 숫자의 코드식은 다름을 인지하고 있다면,

 

즉 어느 조건에 따라 버그가 발생할 것이라 예상된다면, 미리 대응이 가능할 것이다.

 

 

하지만 위에서 설명한 정상적 작동 중 공격자의 의도로 발생하는 보안 약점에 해당하는 취약점 공격은 모든 경우의 수에 대해 대응이 불가하다

 

발생하는 사이버 사고의 예로, DDos, 해킹, 사이버 전쟁이 있다.

 

3. 소프트웨어 보안성(Security)

정의 : 실수 또는 고의의 외부 침입으로부터 시스템을 보호할 수 있는 능력

안전 필수, 고안전, 안전 중심

 

4. 소프트웨어 보안의 어려운 점

  • 프로그래밍 언어의 의미론이 명확하지 않아, 모르는 보안 약점이 존재
  • 제로데이 취약점을 줄여야 함
    • 제로데이 : 소유자, 개발자가 모르는 컴퓨터 시스템의 취약점 또는 보안
  • 취약점의 원인이 되는 보안 약점을 줄여야함
    • 사전에 약점을 제거한다
  • 명세에 정의된 영역의 입력이 아닌 정의가 안된 범위의 입력을 사용
    • SQL 삽입공격, 버퍼 오버플로 공격 등
  • 즉, 일반적인 테스트 방법과 다른 방법이 필요
    • 일반적인 테스트는 입력값이 정해져있다. 
    • 즉 기능의 동작만을 확인한다
  • 공격자는 새로운 보안 약점을 지속적으로 찾아내고, 이를 활용하여 제로데이 취약점 (사이버 무기)를 개발하고 있음

5. 소프트웨어중심 사회 소프트웨어 특징

  • 신뢰성/안전성/보안성 중 한 속성만 중요한 것이 아니다
  • 신뢰성 (정확성)과 안전성도 함께 중요하고
  • 또는 신뢰성 (정확성), 안전성, 보안성도 중요하다
  • 모두 신경써서 해커로부터 공격 받을 가능성이 낮은 소프트웨어를 만들자

6. High-Assurance(보증) Software

  • Correctness(기능 정확성)
  • Security(보안성)
  • Safety(안전성)

7. High-Confidence(신뢰) Software and Systems

시스템의 설계 및 구현에 있어 규모나 구성에 관계없이 그 속성을 평가할 수 있는 시스템 디자인 혁신 등이 시도

 

8. 소프트웨어를 왜 잘 만들어야 하는가?

  1. 소프트웨어 중심 사회도래
  2. 소프트웨어로 많은 사고 발생
  3. 문제가 뭐지?? 무엇이 필요하지??
  4. 소프트웨어 보안을 위한 공감대 형성, 프로세스 개발
  5. 소프트웨어를 잘 만들자!

9. 그러나 현실은 ....

  • SW 개발사 역량, 개발 비용
  • 제도적인 문제
  • 개발자와 해커의 관점이 다름
  • SW의 복잡도 증가

 

10. 코드로 예시를 살펴보자

 

아래와 같이 if와 else if, else 문을 통해 예외처리로 방어적 프로그래밍을 할 수 있다.

void printMsg(FILE *file, char* msg){
	if(file == NULL){
    	logError("attempt to print message to null file");
    } else if (msg == NULL) {
		logError("attempt to print null message");
    } else {
		fprintf(file, "%.128s", msg);
    }
}

 

또는, 아래와 같은 문자열 복사 함수가 있다고 가정해보자

 

void strcpy(char* _dst, const char* _src)
{
	while(*_dst++ = *_src++);
}

 

어때보이는가? 문제가 없어보이나?

 

바로 전의 코드를 살펴보고 아래의 문제점이 발생 여부를 확인해봐야 한다고 예상할 수 있다.

  1. _dst 또는 _src의 NULL 체크
  2. _src의 값이 너무나 긴 문자열로, _dst 메모리 영역을 침범 
  3. c언어에서는 문자열의 끝을 \0으로 판단하는데, \0의 유무 판단