시큐어코딩(SecureCoding)
#
Find similar titles
- 최초 작성자
- 최근 업데이트
Structured data
- Category
- Programming
- Description
- 소프트웨어 개발 과정의 일련의 보안활동
Table of Contents
시큐어 코딩 (Secure Coding) #
시큐어 코딩은 해킹 등 사이버 공격의 원인인 보안취약점을 제거해 안전한 소프트웨어를 개발하는 SW 개발 기법을 말한다. 개발자의 실수나 논리적 오류로 인해 발생할 수 있는 문제점을 사전에 차단하여 대응하고자 하는 것이다. 정보보호가 SW 개발의 중요한 주제로 떠오르는 지금 시큐어 코딩은 선택이 아닌 필수가 되었다.
시큐어 코딩 가이드 #
시큐어 코딩은 개발단계에서 적용되기 때문에 개발자의 코딩 작업이 핵심 대상이 된다. 그러나 개발자로서 취약점을 모두 고려하는 프로그래밍이란 어려운 일이다. 따라서 어떠한 규칙에 따라 코딩하면 되는지에 대한 기준이 있으면 좋을 것이다. 그리고 실제로 국내에서는 2012년 12월부터 행정안전부에 의해 시큐어 코딩에 대한 법규가 제정, 시행되어 그 기준을 제시하고 있다.
행정기관 및 공공기관 정보시스템 구축·운영 지침 (출처:행정안전부고시 제2021-3호, 2021.1.19.)
그리고 그 기준은 다음과 같이 49개의 소프트웨어 보안약점 항목으로 구성되어 있다.
소프트웨어 개발 보안 가이드 (한국인터넷진흥원, 2021.12.29.)
1. 입력데이터 검증 및 표현 #
입력데이터 검증 및 표현이란 폼 양식의 입력란에 입력되는 데이터로 인해 발생하는 문제를 예방하기 위해 점검하는 보안 항목을 의미한다. 쉽게 말해서 사용자가 비정상적인 데이터를 입력하여 시스템에 손상을 주거나 정보를 수정 및 탈취하지 못하도록 방지하는 것이다. 이는 주로 SQL 인젝션(SQL Injection) 공격을 막기 위한 코딩이라고 할 수 있다. SQL(Structured Query Language)은 DB 관리에서 가장 중요한 핵심 요소로 실제로 저장된 데이터를 수정, 삭제, 삽입할 수 있는 기능이 있다. 예를 들어 은행 업무 시스템에서는 SQL을 이용해 계좌의 잔액을 조절한다고 볼 수 있는 것이다. 이토록 중요한 SQL이 악의적인 해커 마음대로 실행될 수 있다면, 정말 치명적인 문제가 될 것이다. 이를 방어하기 위해 사용자가 입력한 데이터를 확인해 공격 시도로 의심되는 단어를 치환하거나 차단하는 방식을 이용한다. 이것이 바로 입력데이터 검증 및 표현의 가장 핵심 요소라고 말할 수 있다.
- SQL 삽입 : 데이터베이스(DB)와 연동된 웹 응용프로그램에서 입력된 데이터에 대한 유효성 검증을 하지 않을 경우, 공격자가 입력 폼 및 URL 입력란에 SQL 문을 삽입하여 DB로부터 정보를 열람하거나 조작할 수 있는 보안약점
- 코드 삽입 : 공격자가 소프트웨어의 의도된 동작을 변경하도록 임의 코드를 삽입하여 소프트웨어가 비정상적으로 동작하도록 하는 보안약점
- 경로 조작 및 자원 삽입 : 검증되지 않은 외부 입력값으로 파일 및 서버 등 시스템 자원에 대한 접근 혹은 식별을 허용할 경우, 입력값 조작으로 시스템이 보호하는 자원에 임의로 접근할 수 있는 보안약점
- 크로스사이트 스크립트 : 웹 페이지에 악의적인 스크립트를 포함시켜 사용자 측에서 실행되게 유도할 수 있는 보안약점
- 운영체제 명령어 삽입 : 적절한 검증절차를 거치지 않은 사용자 입력값이 운영체제 명령어의 일부 또는 전부로 구성되어 실행되는 경우, 의도하지 않은 시스템 명령어가 실행되어 부적절하게 권한이 변경되거나 시스템 동작 및 운영에 영향을 미치는 보안약점
- 위험한 형식 파일 업로드 : 서버 측에서 실행될 수 있는 스크립트 파일(asp, jsp, php 파일 등)이 업로드가능하고, 이 파일을 공격자가 웹으로 직접 실행시킬 수 있는 경우, 시스템 내부명령어를 실행하거나 외부와 연결하여 시스템을 제어할 수 있는 보안약점
- 신뢰 되지 않는 URL 주소로 자동접속 연결 : 사용자로부터 입력되는 값을 외부사이트의 주소로 사용하여 자동으로 연결하는 서버 프로그램은 피싱(Phishing) 공격에 노출되는 취약점
- 부적절한 XML 외부개체 참조 : XML 문서에는 DTD(Document Type Definition)를 포함할 수 있으며, DTD는 XML 엔티티(entitiy)*를 정의한다. 부적절한 XML 외부개체 참조 보안약점은 서버에서 XML 외부 엔티티를 처리할 수 있도록 설정된 경우에 발생
- XML 삽입 : 검증되지 않은 외부 입력 값이 XQuery 또는 XPath 쿼리문을 생성하는 문자열로 사용되어 공격자가 쿼리문의 구조로 임의로 변경하고 임의의 쿼리를 실행하여 허가되지 않은 데이터를 열람하거나 인증절차를 우회할 수 있는 보안약점
- LDAP 삽입 : 공격자가 외부 입력으로 의도하지 않은 LDAP(Lightweight Directory Access Protocol) 명령어를 수행할 수 있는 보안약점
- 크로스사이트 요청 위조 : 특정 웹사이트에 대해서 사용자가 인지하지 못한 상황에서 사용자의 의도와는 무관하게 공격자가 의도한 행위(수정, 삭제, 등록 등)를 요청하게 하는 보안약점
- 서버사이드 요청 위조 : 적절한 검증절차를 거치지 않은 사용자 입력 값을 서버간의 요청에 사용하여 악의적인 행위가 발생할 수 있는 보안약점
- HTTP 응답분할 : HTTP 요청에 들어 있는 파라미터(Parameter)가 HTTP 응답헤더에 포함되어 사용자에게 다시 전달될 때, 입력값에 CR(Carriage Return)이나 LF(Line Feed)와 같은 개행문자가 존재하면 HTTP 응답이 2개 이상으로 분리되는 보안약점
- 정수형 오버플로우 : 정수형 오버플로우는 정수형 크기는 고정되어 있는데 저장할 수 있는 범위를 넘어서, 크기보다 큰 값을 저장하려 할 때 실제 저장되는 값이 의도치 않게 아주 작은 수이거나 음수가 되어 프로그램이 예기치 않게 동작하는 보안약점
- 보안기능 결정에 사용되는 부적절한 입력값 : 응용프로그램이 외부 입력값에 대한 신뢰를 전제로 보호메커니즘을 사용하는 경우 공격자가 입력값을 조작할 수 있다면 보호메커니즘을 우회할 수 있는 보안약점
- 메모리 버퍼 오버플로우 : 메모리 버퍼 오버플로우 보안약점은 연속된 메모리 공간을 사용하는 프로그램에서 할당된 메모리의 범위를 넘어선 위치에 자료를 읽거나 쓰려고 할 때 발생하는 보안약점
- 포맷 스트링 삽입 : 외부로부터 입력된 값을 검증하지 않고 입·출력 함수의 포맷 문자열로 그대로 사용하는 경우 발생할 수 있는 보안약점
2. 보안 기능 #
보안 기능이란 소프트웨어 개발 구현단계에서 코딩하는 기능인 인증, 접근제어, 기밀성, 암호화 등을 올바르게 구현하기 위한 보안 항목을 의미한다. 주로 암호와 같이 중요한 정보를 암호화 없이 저장하거나 프로그램 내부에 하드 코딩되어 노출의 위험성이 있는 경우, 인증과 권한 관리를 부적절하게 구현할 시 발생하는 문제가 있다. 보안 기능은 비인가 접근을 방어하고 저장된 정보를 암호화하여 취약한 기능이 존재하지 않도록 하는 것이 중요하다.
3. 시간 및 상태 #
시간 및 상태는 동시 또는 거의 동시 수행을 지원하는 병렬 시스템이나 하나 이상의 프로세스가 동작하는 환경에서 시간 및 상태를 부적절하게 관리하여 발생할 수 있는 보안약점이다. 프로그래밍을 하다 보면 하나의 자원을 다수 개의 프로세스가 사용해야 하는 경우가 생긴다. 이때 자원 공유가 적절히 진행되지 않아 프로그램이 꼬일 수 있게 된다. 예를 들어, 프로세스 A는 ① 파일이 존재하는지 확인하고 ② 파일을 읽는 과정을 진행한다. 프로세스 B는 파일을 삭제한다. 만약 프로세스 A의 과정 ①이 진행되고, 과정 ②가 시작되기 전 프로세스 B가 파일을 삭제해버린다면 프로세스 A가 삭제된 파일 읽기를 시도하므로 레이스컨디션 이 발생한다. 이 밖에도 종료되지 않는 반복문이나 재귀문을 사용하여 무한루프에 빠지는 것도 시간 및 상태 점검 항목에 포함된다.
- 레이스컨디션(Race Condition): Race Condition은 두 개 이상의 프로세스가 공용 자원을 병행적으로(concurrently) 읽거나 쓸 때, 공용 데이터에 대한 접근이 어떤 순서에 따라 이루어졌는지에 따라 그 실행 결과가 달라지는 상황을 말한다.
4. 에러 처리 #
에러 처리는 이름 그대로 에러를 처리하는 방식이 부적절하거나 누락되어 발생하는 보안 항목을 의미한다. 종종 개발자가 디버깅의 편의성을 위해 에러 메시지를 화면에 출력하는 경우가 있다. 에러 메시지는 시스템과 관련된 중요 정보를 포함하는 경우가 많아 공격자의 악성 행위를 도울 수 있다. 또한, 오류가 발생할 상황을 적절하게 검사하지 않았거나 잘못된 처리를 한 경우도 에러 처리 항목에 포함된다. 에러 처리는 가능한 최소한의 정보만을 담고 있어야 하며, 광범위한 예외 처리보다는 구체적인 예외 처리를 통해 보안 공격을 사전에 방어하는 것이 중요하다.
5. 코드 오류 #
코드 오류는 구현단계에서 개발자의 실수나 지식 미달로 인한 오류를 예방하기 위한 점검 항목이다. 주로 형(Type) 변환 오류, 자원 반환, NullPointer 참조가 이에 해당한다. Null 값을 체크하지 않고 변수를 사용한다든가 실수로 스레드와 같은 자원을 무한하게 할당하여 시스템에 부하를 주는 경우가 있다. 개발자가 잘못된 코딩 습관을 들인다면 코드 오류 항목에서 번번이 보안 취약점에 걸리게 된다. 본인만의 보안 코딩 규칙을 만들어서 습관을 들이는 것을 추천한다.
6. 캡슐화 #
캡슐화란 객체 지향 방법론에 중요한 개념으로 객체와 필드의 은닉을 통해 외부의 잘못된 사용을 방지하는 것을 의미한다. 그런데 가끔 시스템의 데이터나 기능을 불충분하게 캡슐화하거나 잘못된 방법을 이용함으로써 보안 취약점으로 작용하는 경우가 있다. 부적절한 캡슐화는 정보은닉의 기능을 잃어버린다. 시스템의 중요 정보가 노출되어 공격자는 이 정보를 이용해 식별 과정을 우회할 수 있다. 변수 제어 함수가 노출된다면 공격자는 원하는 값으로 데이터를 외부에서 수정할 수 있게 된다.
7. API 오용 #
API(Application Programming Interface)란 응용프로그램에서 사용할 수 있도록 운영체제나 프로그래밍 언어가 제공하는 기능을 제어할 수 있게 만든 인터페이스를 뜻한다. 개발자는 편리하게 개발하고 유용한 정보를 얻기 위해 API를 활용한다. 그러나 의도된 사용에 반하는 방법으로 API를 이용하거나, 보안에 취약한 API를 이용한다면 심각한 보안 취약점이 될 수 있다. 예를 들어, 만약 공격자에 의해 로컬 DNS 캐시가 오염된 상황에서 DNS만 확인한다면 공격자의 네트워크로 경유하거나 공격자의 서버를 도착지로 인식할 수 있다. 이를 방지하기 위해 보안에 취약한 API 사용은 피해야 하며 DNS가 아닌 IP를 확인하는 것이 중요하다.