3. 시큐어 코딩¶
본 자료는 하단의 참조 및 해킹 방어를 위한 JAVA 시큐어코딩을 참고하여 재구성한 내용입니다.
3.1. OWASP Top 10¶
OWASP는 웹 애플리케이션의 보안 향상을 위해 표준, 도구를 제공하는 개방 커뮤니티이다. OWASP Top 10 애플리케이션 보안 위험은 다음과 같다.
3.1.1. Injection(인젝션)¶
- 정의. 프로그램에 신뢰할 수 없는 데이터를 전송하여 시스템의 데이터를 조작하거나 장애를 일으키는 위험
- 예방. 질의 또는 명령어를 신뢰할 수 없는 데이터와 분리한다.
- 예시. 변수 바인딩을 사용 / 특수문자 이스케이핑
3.1.2. Broken Authentication and Session Management(잘못된 인증 및 세션 관리)¶
- 정의. 관리되지 않는 인증 정보와 관리 취약점을 바탕으로 다른 사용자로 가장하고 시스템을 제어하는 위험
- 예방. OWASP에서 제공하는 가이드라인에 따라 세션을 관리한다.
- 예시. XSS 취약점 제거 / 세션 타임아웃 추가 / 인증 정보 URL 노출 제거 / 인증 정보 암호화 전송
3.1.3. XSS(크로스 사이트 스크립팅)¶
- 정의. 다른 사용자의 브라우저에 신뢰할 수 없는 데이터를 전송하여 다른 취약점을 유발하는 위험 (세션 하이재킹, 사이트 변조, 악성 사이트 리다이렉션 등)
- 예방. 브라우저 명령어와 신뢰할 수 없는 데이터를 분리한다.
- 예시. 모든 신뢰할 수 없는 데이터를 이스케이핑 / sanitizer 라이브러리 적용
3.1.4. Insecure Direct Object References(안전하지 않는 직접 객체 참조)¶
- 정의. 참조값을 변경하여 권한이 없는 객체에 접근할 수 있는 위험
- 예방. DB키 대신 간접 참조를 사용하거나 직접 참조시 접근을 통제한다.
- 예시. 자원에 접근 권한이 있는지 확인
3.1.5. Security Misconfiguration(보안 설정 오류)¶
- 정의. 샘플 페이지 또는 기본 설정을 활용 하여 시스템에 침투하는 위험 (관리 콘솔, 디렉토링 리스팅, 스택 추적 허용)
- 예방. 불필요한 기능을 제거한다.
- 예시. 기본 관리 콘솔 제거 또는 기본 패스워드 변경 / 샘플 페이지 제거
3.1.6. Sensitive Data Exposure(민감 데이터 노출)¶
- 정의. 민감 데이터를 탈취하여 보호해야할 모든 데이터를 탈취하는 위험
- 예방. 민감한 정보를 암호화 하고 강력한 알고리즘을 적용한다.
- 예시. bcrypt와 같은 특별한 알고리즘으로 패스워드 보호 / SSL 사용
3.1.7. Missing Function Level Access Control(기능 수준의 접근 통제 누락)¶
- 정의. URL 조작을 통해 권한이 없는 기능에 접근할 수 있는 위험
- 예방. 서버 쪽에서 인증 및 권한을 검증한다. 단, 룰 갱신이 쉬워야 한다.
- 예시. 권한 관리 컴포넌트 개발
3.1.8. CSRF(크로스 사이트 요청 변조)¶
- 정의. 위조된 HTTP를 요청하여 사용자의 권한으로 명령을 실행하는 위험
- 예방. 예측 불가능한 CSRF 토큰을 포함시켜서 자원을 요청하도록 한다.
- 예시. CSRF 토큰 포함 / 재인증 요구
3.1.9. Components with Known Vulnerabilities(알려진 취약점이 있는 컴포넌트 사용)¶
- 정의. 스캐닝을 통해 취약한 컴포넌트를 찾아서 관련 취약점을 발동시키는 위험
- 예방. 공개된 데이터베이스 확인하고 버전을 최신 상태로 유지한다.
- 예시. 메일링 리스트, 공개된 데이터베이스 모니터링
3.1.10. Unvalidated Redirects and Forwards(타당하지 않은 리다이렉트 및 포워딩)¶
- 정의. 신뢰할 수 없는 링크로 리다이렉트 하거나 포워딩 시켜 사용자를 위험에 빠뜨리거나 시스템의 정보를 노출 시키는 위험
- 예방. 사용자 파라미터로 링크를 전송할 수 없도록 한다.
- 예시. 파라미터를 사용해야 한다면 서버에서 검증해야 함
3.2. Concept¶
시큐어 코딩 이란 보안 취약점에 의한 사고를 방지하기 위한 소프트웨어 개발 방법이다. (예를들어 각 프로젝트 단계별로 시큐어 코딩을 적용할 수 있다. ) 결함, 버그, 결점이 있는 로직( 소프트웨어의 약점 )은 소프트웨어 취약점의 주요한 원인이다. 알려진 취약점을 기반으로 보안 전문가들은 대부분의 취약점이 소프트웨어 프로그래밍에서 발견한다는 사실을 알게 되었다. 시큐어코딩 전문가들은 안전하지 않은 코딩 습관을 발견하고 대안책들을 개발자에게 교육함으로써 개발자들이 소프트웨어 개발전에 취약점을 제거하거나 줄이게된다.
3.3. 안전한 소프트웨어 개발 방법론¶
3.3.1. 흔한 웹 기반 공격 시나리오¶
웹 기반 공격은 2가지 패턴을 가지고 있다 첫번재는 DMZ에 놓여있는 웹서버를 공격하는 방법이다. 웹 서버에 웹쉘을 올려서 서버의 임의코드를 실행할 수 있는 권한을 얻는 것이다. 두번째 방법은 내부 사용자를 통해 내부망을 공격하는 방식이다.
웹 어플리케이션 보안이 중요한 이유는 웹을 통해 개개인의 민간한 정보가 전송되기 때문이다. 요즘의 모바일, 데스크탑의 어플리케이션은 주로 HTTP를 통해 서비스된다.
3.3.2. 계층별 보안 솔루션의 한계¶
어플리케이션 보안/ 시스템 보안/ 네트워크 보안/ DB 보안으로 나눠서 솔루션을 통해 보안을 강화할 수 있다. 하지만 네트워크 보안이나 웹 방화벽(어플리케이션 보안)에 의한 보안은 룰/시그니처 기반 정책을 가지고 있으므로 코드 레벨의 보안이 중요하다.
3.3.3. 소프트웨어 보안의 중요성¶
CMS나 오픈소스, 플랫폼에서 발생한 취약점은 그 소프트웨어를 적용하는 모든 서비스나 소프트웨어의 취약점이 된다. 이러한 소프트웨어 수준의 취약점은 큰 파급력을 갖는다.
3.3.4. 소프트웨어 해킹 사례¶
- KT의 요금명세서 조회 기능에서 파라미터 조작을 통해 다른 사용자의 요금명세서를 조회하는 사례가 있었다.(파라미터의 고객번호를 A에서 B로 바꾼뒤 쿼리를 실행하여 해킹, 이를 해결하기 위해 로그인한 사용자의 세션값에 맞는 고객정보만 조회되도록 수정 해야함)
- 현대캐피탈 - SSL을 이용해 종단간 암화화를 했더라도 소프트웨어 자체에서 암호화되지 않은 로깅을 쌓아서 원본데이터가 노출될 수 있다.
- OpenSSL HeartBleed 취약점은 서버와 연결상태를 체크하는 HeartBeat 프로토콜에서 문제가 발생한 경우이다. TLS HeartBeat Request에서 Length를 조작할 경우 서버의 메모리를 읽어들일 수 있었다. 라이브러리에서 길이와 실제 데이터를 비교했다면 이런 문제가 발생하지 않았을 것이다.
3.4. 소프트웨어 보안 약점/취약점(CWE, CVE, OWASP)¶
CWE이란 일반적으로 침해사고를 일으킬 수 있는 소프트웨어의 분류체계를 정의한다. CVE란 이미 침해사고가 발생한 소프트웨어의 결함의 히스토리이다. 미국 국토안보부에서 만든 CWE 에서 일반적인 소프트웨어 약점을 검색할 수 있다. CVE 에서 소프트웨어 취약점(이미 침해사고가 발생한)을 검색할 수 있다. SANS TOP 25 에서 가장 위험한 소프트웨어 약점 25개를 확인할 수 있다.
시큐어 코딩 방법은 https://www.securecoding.cert.org/ 과 행자부 소프트웨어 개발 보안 가이드(7개의 카테고리 47개의 항목 - CERT LEVEL1 + SANS 25)에서 확인할 수 있다. SANS 25를 이용해서 스코어링해서 순서대로 제거해라.
25개의 CWE를 적용하기 어렵다면 OWASP TOP 10 을 사용하여 시큐어 코딩을 적용하자.
3.5. 소프트웨어 개발보안 방법론¶
SW 개발 보안이란 잠재적인 보안약점을 제거하고 보안을 고려하여 설계, 구현하는 방법이다. 소프트웨어 개발 프로세스는 요구사항 분석 -> 설계 -> 구현 -> 테스트 으로 이루어진다. 개발 단계별 시큐어 코딩 적용은 다음과 같다.
- 테스트 단계에서 약점을 진단하지말고 설계단계에서 기능단위로 보안 약점을 도출하면서 설계해야한다.
- 구현 단계에서 보안 코딩 컨벤션을 정하고 제약을 걸어라. (JSP에서 태그 마크업을 필터링하거나 사용자의 파라미터를 체크하거나, 실전에서는 소스코드 보안약점 진단 도구를 활용하면 됨)
- 테스트 단계에서는 스캐닝 및 퍼징을 통해 취약점을 찾거나 모의해킹을 통해 취약점을 찾는다.
3.5.1. 레퍼런스¶
- Microsoft SDL은 표준처럼 사용되고 있다. 이를 적용하여 개발하면 보안 약점을 줄이는데 도움이 될 것이다.
- CLASP 은 각 활동에 대해 누가 맡을지에 대한 내용을 참조할 때 좋다.
- Seven Touch Point는 가장 심플하게 접근할 수 있는 개발보안 방법론이다.
소프트웨어 개발 보안 방법론을 적용하면 유지보수 비용이 절감된다. 이제는 시큐어 코딩은 선택이 아니라 필수같다.
3.5.2. 위협모델링¶
위협모델은 요구사항 분석 단계에서( 유즈케이스 다이어그램, 액티비티 다이어그램, DFD ) 기능 단위로 공격자가 어떻게 공격할 수 있는지 정의한 것이다. 이에 대한 위협분석의 목적은 대응해야할 위협을 파악하고, 어떻게 대응할 수 있는지를 결정하기 위한 체계적인 방법을 제공하는 것이다. 이를 조사하여 설계자에게 전달하는 것은 개발보안에서 중요하다.
단계는 다음과 같다. (실제로 7단계로 구성되어 있음) MS가 제시한 모델링 방법 OPENEG 예시
- 배경 정보 수집 (DFD를 사용하여 어플리케이션을 분해한다.)
- 위협 모델 만들기 및 분석 (각 기능별 보안 약점을 도출하고 이를 7가지로 분류한다. SPRIDE를 사용한다.)
- 위협 검토 (DREAD의 각 항목에 점수를 매겨 높은 순서대로 제거한다.)
- 완화 방법 및 기술 식별
3.6. 안전한 소프트웨어를 만드는 시큐어 코딩 기법¶
3.6.1. SQL 인젝션 기본¶
사용자가 쿼리를 조작할 수 있으면 SQL 인젝션이 가능하다.
String query = 《SELECT * FROM WHERE ID = 〈 《+ id + 》 〈 and bPass = 〈 《+ bPass + 》 〈 《
공격 쿼리는 다음고 같다. 아이디/ 비밀번호
- admin〉– / 아무거나
- admin〉# / 아무거나
- 〈 or 〈a〉 = 〈a / 〈 or 〈a〉 = 〈a
String query = 《SELECT * FROM WHERE ID = 〈 《+ id + 》 〈 《
Mysql DB 정보를 보는 방법은 다음과 같다.
- 〈 union select schema_name,2,3,4,5,6 from information_schema.schemata#
OWASP의 ESAPI를 이용하여 위험한 문자열을 필터링하거나 동적SQL 대신 정적SQL을 사용하자. 또한 pangolin으로 SQL 인젝션 점검을 할 수 있다.
3.6.2. 운영체제 명령어 삽입¶
서버에서 명령어로 실행되는 경우 침해사고가 발생한다. 꼭 필요한 기능이라면 철저한 유효성 검사 및 명령어를 인덱스화 하여 서버에 전달할 필요가 있다.
3.6.3. 세션 공격¶
- 세션 ID 분석을 통해 예측 - 서버에서 난수를 사용해서 세션 ID를 생성하므로 일반적으로 어렵다.
- 셰션 ID 훔치기 - XSS와 같은 취약점이 있다면 위험할 수 있다.
- 세션 ID 고정 - 브라우저에 세션 ID를 고정시킬 수 있는 기능이 있다면 문제가 발생한다.
3.6.4. XSS (크로스 사이트 스크립트)¶
- Reflective XSS : 악성스크립트를 GET 파라미터에 포함 시킨 하이퍼 링크를 다른 사용자가 클릭하게 만들어서 악성 스크립트를 실행하는 해킹 방법
- Stored XSS : 악성스크립트를 DB에 저장하는 기능을 이용하여 저장하고 다른 사용자가 그 정보를 이용할때 공격이 일어나는 해킹 방법
- DOM XSS : AJAX 요청에 대한 브라우저에 수신된 데이터를 다시 잘라서 Document에 write하는 작업을 수행하는 경우 사용하는 해킹 방법
3.6.5. CSRF (크로스사이트 요청위조)¶
상대방이 잘못된 요청을 보내도록 하는 사회공학적 해킹 기법이다. 이를 방어하기 위해서 write.html에서 CSRF Token(난수) 을 미리 발급하고 실제 요청할때 토큰을 포함시켜서 보내도록 한다. 여러가지 재인증 기법을 사용하여 막을 수 있다. 이를 WAS의 CSRFInterceptor를 통해 검사하고 비지니스 로직을 수행한다.
아래는 CSRF 공격 코드의 예시이다. XSS 취약점이 있는 게시판에 삽입하여 CSRF공격을 수행할 수 있다.
<body>
<form style="display:none" method="post" action="write.do" ENCTYPE="multipart/form-data">
<input type="hidden" name="subject" value="회비 계좌 확인 요합니다">
<input type="hidden" name="writer" value="관리자">
<input type="hidden" name="writerId" value="admin">
<input type="hidden" name="content" value="이번 모임의 회비 납부 안내입니다<br>국민은행 010 최창원">
<input type="hidden" name="submit" id="send">
</form>
<script>document.forms[0].send.click();</script>
</body>
3.6.6. 파일 업로드/다운로드 취약점¶
업로드
- 업로드되는 파일의 타입/크기/개수를 제한하지 않고 외부로 부터 접근이 되는 경우
- 업로드된 파일이름과 저장된 파일이름이 같은 경우
- 파일의 타입체크/사이즈체크/외부에서 접근하지 않는 경로에 저장되도록/파일명 랜덤생성/실행권한을 가지지 않도록
다운로드
- 권한이 없는 사용자가 파일을 다운로드 받을 수 있는 취약점
- 악성코드에 감염된 파일을 다운로드 허용하는 경우
- 파일의 타입체크/사이즈체크/외부에서 접근하지 않는 경로에 저장되도록/파일명 랜덤생성/실행권한을 가지지 않도록