회원가입을 하면 원하는 문장을
저장할 수 있어요!
다음
AWS 이용 중이라면 최대 700만 원 지원받으세요
시큐어 코딩(secure coding)은 소프트웨어 개발 시 안전한 코드를 제작한다는 의미입니다. 또한 해킹을 비롯한 사이버 공격의 대상이 될 수 있는 소프트웨어의 보안 약점을 출시 이후가 아닌, 개발 단계에서 사전에 제거하는 일련의 보안 활동을 말합니다.
회원가입을 하면 원하는 문장을
저장할 수 있어요!
다음
회원가입을 하면
성장에 도움이 되는 콘텐츠를
스크랩할 수 있어요!
확인
시큐어 코딩(secure coding)은 소프트웨어 개발 시 안전한 코드를 제작한다는 의미입니다. 또한 해킹을 비롯한 사이버 공격의 대상이 될 수 있는 소프트웨어의 보안 약점을 출시 이후가 아닌, 개발 단계에서 사전에 제거하는 일련의 보안 활동을 말합니다.
이는 개발 단계뿐만 아니라 소프트웨어 개발 생명 주기의 단계별로 정해진 보안 활동을 수행하여, 결과적으로 안전한 소프트웨어를 개발 및 운영하기 위한 것입니다. 이번 시리즈에서는 시큐어 코딩의 의미를 이해하고, 대표적인 7개 유형을 통해 어떻게 보안 측면에서 안전한 코드를 만들 수 있는지 알아보겠습니다.
시큐어 코딩은 사이버 공격에 대한 방어뿐만 아니라, 개발자의 실수나 코드상의 논리적 오류로 인해 발생할 수 있는 문제점을 사전에 차단 및 대응하는 내용도 포함되어 있습니다. 즉 소프트웨어의 가용성과 신뢰성이 위협받는 취약점은 모두 보안의 대상으로 정의한 것입니다. 정보 보호가 소프트웨어 개발의 중요한 주제인 만큼 이제 시큐어 코딩은 소프트웨어 개발 업체에겐 선택이 아닌 필수입니다.
소프트웨어 보안 취약점은 일반적으로 다음과 같은 경우에 자주 발생합니다. 이렇게 남겨진 보안 취약점으로 인해 시스템이 처리하는 중요 정보가 노출되거나, 정상적인 서비스가 불가능한 상황이 발생할 수 있습니다.
① 소프트웨어 요구 사항 정의 시에 아예 보안 요구사항을 고려하지 않았다.
② 소프트웨어가 논리적인 오류를 포함한 채로 설계되고 개발되었다.
③ 기술적 취약점을 보완하지 않은 코딩 규칙을 적용하여 코딩했다.
④ 발견된 취약점에 대해 적절한 관리 또는 패치를 제때 수행하지 않았다.
정부 기관의 경우 2021년 1월에 개정 및 고시된 ‘행정기관 및 공공기관 정보시스템 구축·운영 지침(행정안전부 고시 2021-3호)’을 통해 개발 보안과 관련하여 행정기관 및 공공기관이 정보화 사업을 추진 시, 준수해야 할 소프트웨어 개발 보안 활동 및 보안 약점 진단 기준을 제시했습니다.
구분 | 정의 |
목적 | 전자정부 서비스 보안을 강화하기 위해 정보시스템 개발 및 유지보수 시 SW 보안 약점(취약점) 점검 및 제거 |
대상 | 행정기관 및 공공기관의 정보시스템 감리 대상 정보화 사업 |
범위 | 소스 코드(신규 개발 전체 또는 유지보수로 변경된 부분) |
기준 | 소프트웨어 보안 약점(SQL 인젝션 등 47개 항목) |
사업자/개발자 | -개발 인력 대상, 소프트웨어 개발 보안 관련 교육 실시 -소프트웨어 개발 보안 가이드를 참조하여 개발 -자체적으로 SW 보안 약점 진단 및 제거 |
이 지침이 중요한 것은 정부 사업을 수행하는 소프트웨어 개발사뿐만 아니라, 시큐어 코딩의 사내 기준이 없는 기업에 일종의 지침서 혹은 표준 기준이 되었다는 부분입니다. 행안부 고시 행정기관 및 공공기관 정보시스템 구축·운영 지침 내용을 바탕으로, 소프트웨어 개발 보안 적용 대상 및 범위와 기준 등을 요약하면 위 표와 같습니다.
유형 | 보안 약점 | 항목 개수 |
입력 데이터 검증 및 표현 | 프로그램 입력값에 대한 부적절한 검증으로 발생 가능한 보안 약점(예시: SQL 삽입, 자원 삽입, 크로스 사이트 스크립트 등) | 15 |
보안 기능 | 인증, 접근제어, 권한 관리 등을 적절하지 않게 구현할 경우 발생 가능한 보안 약점 (예시: 부적절한 인가 허용, 중요 정보 평문 저장, 하드 코딩된 패스워드 등) | 16 |
시간 및 상태 | 멀티 프로세스 동작 환경에서 부적절한 시간 및 상태 관리로 발생 가능한 보안 약점 (예시: 경쟁 조건(TOCTOU), 제어문을 사용하지 않는 재귀함수 등) | 2 |
에러 처리 | 불충분한 에러 처리로 중요 정보가 에러 정보에 포함되어 발생 가능한 보안 약점 (예시: 오류상황 대응 부재, 오류 메시지를 통한 정보 노출 등) | 3 |
코드 오류 | 개발자가 범할 수 있는 코딩 오류로 인해 유발되는 보안 약점 (예시: Null 포인터 역참조, 부적절한 자원 해제 등) | 4 |
캡슐화 | 불충분한 캡슐화로 인가되지 않는 사용자에게 데이터가 노출될 수 있는 보안 정책 (예시: 제거되지 않고 남은 디버거 코드, 시스템 데이터 정보 노출 등) | 5 |
API 오용 | 부적절하거나 보안에 취약한 API 사용으로 발생할 수 있는 보안 약점 (예시: DNS 조회에 의존한 보안 결정 등) | 2 |
행안부가 발표한 소프트웨어 개발 보안 가이드에선 소프트웨어의 보안 약점 항목을 2021년 상반기 기준 47개의 소프트웨어 보안 취약점으로 정의했습니다.
2021년 11월을 기준으로 기존 47개 항목에서 일부 항목이 통폐합되고, 2개 항목이 증가했는데요. 현재 22년을 기준으로 49개의 보안 취약점 항목을 정의하고 있습니다.
시큐어 코딩을 어떻게 수행해야 하는지에 대한 부분은 기업보다 정부 기관이 더 앞장서고 있습니다. 기업은 자사의 시큐어 코딩 기준을 외부에 공개하는 것이 오히려 보안상 불리할 수 있습니다. 이번 글에서도 한국인터넷진흥원과 행안부가 발표한 시큐어 코딩의 유형과 샘플 예제 코드를 참고하여 작성했습니다.
폼(form) 양식의 입력란에 입력되는 데이터로 인해 발생하는 문제를 예방하기 위한 보안 항목입니다. 비정상적인 데이터를 입력하여 시스템에 손상을 주거나, 정보를 수정 및 탈취하지 못하도록 방지합니다. 대표적으로 SQL 인젝션(SQL Injection) 공격을 막기 위한 코딩을 예로 들 수 있습니다. SQL(Structured Query Language)은 DB 관리에서 가장 중요한 핵심 요소로, 실제 저장된 데이터를 수정, 삭제, 삽입할 수 있는 기능이 있습니다. 이에 사용자가 입력한 데이터를 확인하여, 공격 시도로 의심되는 단어를 치환하거나 차단하는 방식을 이용합니다.
또한 입력되는 데이터의 검증을 제대로 수행하지 않아, SQL 인젝션 공격에 취약한 파이썬 코드 예제를 보여줍니다. 데이터베이스와 연동된 웹 응용프로그램에서 입력된 데이터에 대한 유효성 검증을 하지 않는다면, 공격자가 입력한 SQL 구문을 코드가 걸러내지 못합니다. 이는 데이터베이스로부터 정보를 열람하거나 조작할 수 있는 보안 취약점을 만들 수 있습니다.
from django.shortcuts import render
def update_board(request):
......
with dbconn.cursor() as curs:
# 외부로부터 입력받은 값을 검증 없이 사용할 경우 안전하지 않다.
name = request.POST.get('name', '')
content_id = request.POST.get('content_id', '')
# 사용자의 검증되지 않은 입력으로 부터 동적으로 쿼리문 생성
sql_query = "update board set name='" + name + "' where content_id='“ + content_id + "'"
# 외부 입력값이 검증 없이 쿼리로 수행되어 안전하지 않다.
curs.execute(sql_query)
curs.commit()
return render(request, '/success.html')
예제 코드에서 content_id 값으로 ‘a’ or ‘a’ = ‘a와 같은 공격 문자열을 입력하면 조건절이 content_id = ‘a’ or ‘a’ = ‘a’로 바뀌고, 그 결과 board 테이블 전체 레코드의 name 칼럼이 공격자로부터 입력받은 name의 값으로 변경됩니다.
from django.shortcuts import render
def update_board(request):
......
with dbconn.cursor() as curs:
name = request.POST.get('name', '')
content_id = request.POST.get('content_id', '')
# 외부 입력값으로 부터 안전한 매개 변수화된 쿼리를 생성 한다.
sql_query = 'update board set name=%s where content_id=%s'
# 사용자의 입력 값을 매개변수로 지정된 쿼리에 바인딩하여 실행되므로 안전하다.
curs.execute(sql_query, (name, content_id))
curs.commit()
return render(request, '/success.html')
위는 이를 안전하게 변경한 예제입니다. 또한 SQL 인젝션 외에 데이터 입력의 보안 취약점을 이용하는 대표적인 공격 기법으로 크로스 사이트 스크립팅(XSS: Cross Site Scripting)이 있는데요. 이 공격은 인터넷상의 게시물 포스팅이나 파일 업로드 등의 기능에 내포된 보안 취약점을 이용합니다.
위 그림은 크로스 사이트 스크립팅의 일반적인 형태를 보여주고 있습니다. 공격자는 악성 스크립트가 포함된 글을 취약한 웹 사이트에 게시합니다. 이 게시물은 웹 서버를 통해 해당 게시물을 저장하는 데이터베이스에 저장됩니다. 선량한 일반 사용자는 동일한 웹 사이트의 게시물을 읽기 위해 접속하고, 악성코드가 포함된 글을 브라우저상에서 조회하면서 보안상 취약한 자바스크립트를 포함한 스크립트를 수행하게 됩니다. 이때 해당 브라우저의 정보를 공격자의 서버로 전송하거나, 브라우저 활동에서 예상하지 못한 악성 행위를 수행하곤 합니다.
<h1>XSS 취약점 예제</h1>
<%
String name = request.getParaemeter("name");
%>
<p> NAME: <% =name %> </p>
해당 코드는 크로스 사이트 스크립팅 취약점을 갖고 있는 JSP로 구현한 웹 페이지입니다. 파라미터 name 변수의 값을 그대로 페이지 변수로 사용하면서, 아무런 검증 없이 웹 페이지에 출력하고 있습니다.
<h1>XSS 취약점 예제</h1>
<%
String name = request.getParameter("name");
if (name != null)
{
name = name.replaceAll("<", "<");
name = name.replaceAll(">", ">");
name = name.replaceAll("&", "&");
name = name.replaceAll("\"", """);
}
else { return; }
%>
<p> NAME: <% =name %> </p>
위 코드를 보안 가이드에 따라 크로스 사이트 스크립팅 공격에 사용될 수 있는 의심 문자를 그대로 출력하는 것이 아니라, HTML 상의 코드로 변경하도록 수정한 내용입니다. 이로 인해 공격자가 입력한 자바스크립트 명령 등의 실행이 무력화될 수 있습니다.
이번 글에서는 시큐어 코딩의 중요성에 대해 다뤄봤는데요. 시큐어 코딩의 의미와 구체적인 가이드라인, 시큐어 코딩을 실천하기 위한 대표적인 유형 중 첫 번째 유형의 예제까지 살펴봤습니다. 다음 글에서는 시큐어 코딩의 유형들에 대해 좀 더 자세히 알아보겠습니다.
요즘IT의 모든 콘텐츠는 저작권법의 보호를 받는 바, 무단 전재와 복사, 배포 등을 금합니다.