시큐어 코딩 가이드 · · 8 min read
2. 보안 기능
2.1. 적절한 인증 없는 중요 기능 허용
정의
적절한 인증과정이 없이 중요정보(계좌이체 정보, 개인정보 등)를 열람(또는 변경)할 때 발생하는 보안 약점
안전한 코딩 기법
- 클라이언트의 보안검사를 우회하여 서버에 접근하지 못하도록 설계한다.
- 중요한 정보가 있는 페이지는 재인증을 적용한다.
- 안전하다고 검증된 라이브러리나 프레임워크를 사용한다.
2.2. 부적절한 인가
정의
프로그램이 모든 가능한 실행 경로에 대해서 접근 제어를 검사하지 않거나 불완전하게 검사하는 경우, 공격자는 접근 가능한 실행 경로로 정보를 유출할 수 있다.
안전한 코딩 기법
- 응용프로그램이 제공하는 정보와 기능을 역할에 따라 배분함으로써 공격자에게 노출되는 공격 노출면(Attack Surface)을 최소화하고 사용자의 권한에 따른 ACL(Access Control List)을 관리한다.
- JAAS Authorization Framework나 OWASP ESAPI Access Control 등 인증 프레임워크 사용
2.3. 중요한 자원에 대한 잘못된 권한 설정
정의
SW가 중요한 보안 관련 자원에 대하여 읽기 또는 수정하기 권한을 의도하지 않게 허가할 경우, 권한을 갖지 않은 사용자가 해당 자원을 사용하게 된다.
안전한 코딩 기법
- 설정 파일, 실행 파일, 라이브러리 등은 SW 관리자에 의해서만 읽고 쓰기가 가능하도록 설정
- 설정 파일과 같은 중요한 자원을 사용하는 경우, 허가 받지 않은 사용자가 중요한 자원에 접근 가능한지 검사한다.
2.4. 취약한 암호화 알고리즘 사용
정의
환경 설정 파일에 저장된 패스워드를 보호하기 위하여 간단한 인코딩 함수를 이용하여 패스워드를 감추는 방법을 사용한다. base64와 같은 지나치게 간단한 인코딩 함수로는 패스워드를 제대로 보호할 수 없다.
정보 보호 측면에서 취약하거나 위험한 암호화 알고리즘을 사용해서는 안 된다.
RC2, RC4, RC5, RC6, MD4, MD5, SHA1, DES 알고리즘과 같은 오래된 알고리즘은 취약해져 사용해서는 안 된다.
안전한 코딩 기법
- 자신만의 암호화 알고리즘을 개발하는 것은 위험
- 3DES, AES, SEED 등 안전한 알고리즘으로 대체 사용
- 업무관련 내용, 개인정보 등에 대한 암호 알고리즘 적용 시, IT보안인증 사무국이 안전성을 확인한 검증필 암호모듈을 사용해야 한다.
참고: 안전한 암호알고리즘 및 키 길이 (원문의 이미지를 표로 옮김)
| 분류 | 구분 | 보호함수 목록 |
|---|---|---|
| 최소 안전성 수준 | 112비트 | |
| 블록암호 | ARIA(키 길이: 128/192/256), SEED(키 길이: 128) | |
| 블록암호 운영모드 | 기밀성 | ECB, CBC, CFB, OFB, CTR |
| 블록암호 운영모드 | 기밀성/인증 | CCM, GCM |
| 해쉬함수 | SHA-224/256/384/512 | |
| 메시지 인증코드 | 해쉬함수기반 | HMAC |
| 메시지 인증코드 | 블록기반 | CMAC, GMAC |
| 분류 | 구분 | 보호함수 목록 |
|---|---|---|
| 난수발생기 | 해쉬함수/HMAC 기반 | HASH_DRBG, HMAC_DRBG |
| 난수발생기 | 블록기반 | CTR_DRBG |
| 공개키 암호 | RSAES(공개키 길이: 2048, 3072). RSA-OAEP에서 사용되는 해쉬함수: SHA-224/256 | |
| 전자서명 | RSA-PSS, KCDSA, ECDSA, EC-KCDSA | |
| 키 설정 방식 | DH, ECDH |
| 보호함수 | 보호함수 파라미터 |
|---|---|
| RSA-PSS | 공개키 길이: 2048, 3072 |
| KCDSA, DH | (공개키 길이, 개인키 길이) = (2048, 224), (2048, 256) |
| ECDSA, EC-KCDSA, ECDH | FIPS 곡선 B-233, B-283 / K-233, K-283 / P-224, P-256 |
2.5. 암호화되지 않은 중요 정보
정의
사용자 또는 시스템의 중요 정보가 포함된 데이터를 평문으로 송/수신 또는 저장할 때 인가되지 않은 사용자에게 민감한 정보가 노출될 수 있는 보안 약점
안전한 코딩 기법
- 개인정보(주민등록번호, 여권번호 등), 금융정보(카드번호, 계좌번호 등), 패스워드 등 중요 정보를 통신 채널로 전송하거나 저장할 때는 반드시 암호화 과정을 거쳐야 한다.
- 필요한 경우 SSL 또는 HTTPS 등과 같은 암호채널을 사용해야 하며, HTTPS와 같은 보안 채널을 사용하여 브라우저 쿠키에 중요 데이터를 저장하는 경우, 쿠키객체에 보안속성을 반드시 설정하여 중요정보의 노출을 방지한다.
- 중요 정보를 읽거나 쓸 경우 권한 인증 등으로 적합한 사용자가 중요 정보에 접근하도록 해야한다.
2.6. 하드코드된 중요정보
정의
프로그램 코드 내부에 하드 코딩된 패스워드 또는 암호화키를 포함하여 내부 인증에 사용하거나 암호화를 수행하면 중요 정보(관리자 정보, 암호화된 정보 등)가 유출될 수 있는 보안 약점이다.
안전한 코딩 기법
- 패스워드는 암호화 하여 별도의 파일에 저장하여 사용
- 중요 정보를 암호화하면, 상수가 아닌 암호화 키를 사용하도록 하며, 소스 코드 내부에 상수 형태의 암호화 키를 저장해서 사용하지 않도록 한다.
2.7. 충분하지 않은 키 길이 사용
정의
길이가 짧은 키를 사용하는 것은 암호화 알고리즘을 취약하게 만들 수 있다. 키는 암호화 및 복호화에 사용되는데, 검증된 암호화 알고리즘을 사용하더라도 키 길이가 충분히 길지 않으면 짧은 시간 안에 키를 찾아낼 수 있고 이를 이용해 공격자가 암호화된 데이터나 패스워드를 복호화 할 수 있게 된다.
안전한 코딩 기법
- RSA 알고리즘은 적어도 2048 비트 이상의 길이를 가진 키와 함께 사용해야 하고, 대칭 암호화 알고리즘(Symmetric Encryption Algorithm)의 경우에는 적어도 128 비트 이상의 키를 사용한다.
2.8. 적절하지 않은 난수 값 사용
정의
예측 가능한 난수를 사용하는 것은 시스템에 보안약점을 유발한다. 예측 불가능한 숫자가 필요한 상황에서 예측 가능한 난수를 사용한다면, 공격자는 SW에 생성되는 다음 숫자를 예상하여 시스템을 공격하는 것이 가능하다.
안전한 코딩 기법
- 컴퓨터의 난수 발생기는 난수 값을 결정하는 시드(Seed)값이 고정될 경우, 매번 동일한 난수값이 발생한다. 이를 최대한 피하기 위해 Java에서는 Random()과 Math.random() 사용 시 java.util.Random 클래스에서 기본값으로 현재 시간을 기반으로 조합하여 매번 변경되는 시드(Seed)값을 사용하며, C 에서는 rand() 함수 사용 시 매번 변경되는 기본 시드(Seed)값이 없으므로, srand()로 매번 변경되는 현재시간 기반 등으로 시드(Seed)값을 설정해야 한다.
- 세션 ID, 암호화키 등 보안결정을 위한 값을 생성하고 보안결정을 수행하는 경우, 예측이 거의 불가능하게 암호학적으로 보호된 것을 사용하는 것이 안전하다.
2.9. 취약한 비밀번호 허용
정의
사용자에게 강한 비밀번호 조합 규칙을 요구하지 않으면, 사용자 계정이 취약하게 된다. 안전한 비밀번호를 생성하기 위해서는 [패스워드 선택 및 이용 안내서]의 안전한 패스워드 설정 규칙을 적용해야 한다.
안전한 코딩 기법
- 비밀번호 생성 시 강한 조건 검증을 수행한다. 비밀번호는 숫자와 영문자, 특수문자 등을 혼합하여 정해진 자릿수를 사용하여 생성되도록 하고, 주기적으로 변경하도록 해야 한다.
2.10. 부적절한 전자서명 확인
정의
전자서명이란 서명자의 신원을 확인하고 서명된 파일의 무결성을 보장할 수 있는 디지털 정보이다. 전자서명이 사용된 경우, 전자서명을 검증하지 않거나 검증절차가 부적절하면 위변조된 파일로 악성코드에 감염될 수 있으므로 전자서명을 확인하여 위변조 여부를 판별하고 사용해야 한다.
안전한 코딩 기법
- 전자서명을 포함하는 파일을 사용할 때는 항상 전자서명을 확인하여야 한다.
- 이때, 전자서명 파일의 출처 등을 확인하여 신뢰할 수 없는 곳에서 생성된 파일을 사용하지 않도록 한다.
2.11. 부적절한 인증서 유효성 검증
정의
인증서를 확인하지 않거나 인증서 확인 절차를 적절하게 수행하지 않아, 악의적인 호스트에 연결되거나 신뢰할 수 없는 호스트에서 생성된 데이터를 수신하게 되는 보안약점이다.
안전한 코딩 기법
- 인증서를 사용하기 전에 인증서의 유효성을 확인한다.
- 유효한 인증서인지 검증하는 절차를 구현하여야 한다.
- 인증서의 CN(Common Name)과 실제 호스트가 일치하는지
- 신뢰된 발급기관(CA, RootCA)의 서명 여부
- 인증서의 유효기간
- 인증서의 해지여부
- 안전한 암호화 알고리즘 사용 여부 확인
2.12. 사용자 하드디스크에 저장되는 쿠키를 통한 정보 노출
정의
대부분의 웹 응용프로그램에서 쿠키는 메모리에 상주하며, 브라우저의 실행이 종료되면 사라진다. 프로그래머가 원하는 경우, 브라우저 세션에 관계없이 지속적으로 저장되도록 설정할 수 있으며, 이것은 디스크에 기록되고, 다음 브라우저 세션이 시작되었을 때 메모리에 로드된다.
개인정보, 인증 정보 등이 이와 같은 영속성 쿠키에 저장된다면, 공격자는 쿠키에 접근할 수 있는 보다 많은 기회를 가지게 되며, 이는 시스템을 취약하게 만든다.
안전한 코딩 기법
- 쿠키의 만료시간은 세션이 지속되는 시간을 고려하여 최소한으로 설정하고 영속적인 쿠키에는 사용자 권한 등급, 세션ID 등 중요정보가 포함되지 않도록 한다.
2.13. 주석문 안에 포함된 시스템 주요정보
정의
패스워드를 주석문에 넣어두면 시스템 보안이 훼손될 수 있다.
소프트웨어 개발자가 편의를 위해서 주석문에 패스워드를 적어둔 경우, 소프트웨어가 완성된 후에는 그것을 제거하는 것이 매우 어렵게 된다.
공격자가 소스코드에 접근할 수 있다면, 아주 쉽게 시스템에 침입할 수 있다.
안전한 코딩 기법
- 주석에는 ID, 패스워드 등 보안과 관련된 내용을 기입하지 않는다.
2.14. 솔트 없이 일방향 해쉬함수 사용
정의
패스워드를 저장 시 일방향 해쉬함수의 성질을 이용하여 패스워드 해쉬값을 저장한다.
패스워드를 솔트(Salt) 없이 해쉬하여 저장한다면, 공격자는 레인보우 테이블과 같이 해쉬값을 미리 계산하여 패스워드를 찾을 수 있게 된다.
안전한 코딩 기법
- 패스워드를 저장 시 패스워드와 솔트를 해쉬함수의 입력으로 하여 얻은 해쉬값을 저장한다.
2.15. 무결성 검사없는 코드 다운로드
정의
원격으로부터 소스코드 또는 실행 파일을 무결성 검사 없이 다운로드 받고, 이를 실행하는 제품은 호스트 서버의 변조, DNS 스푸핑 또는 전송 시의 코드 변조 등의 방법을 이용하여 공격자가 악의적인 코드를 실행할 수 있도록 한다.
안전한 코딩 기법
- DNS 스푸핑을 방어할 수 있는 DNS lookup을 수행하고 코드 전송 시 신뢰할 수 있는 암호 기법을 이용하여 코드를 암호화한다.
- 다운로드한 코드는 작업 수행을 위해 필요한 최소한의 권한을 실행하도록 한다.
2.16. 반복된 인증시도 제한 기능 부재
정의
일정 시간 내에 여러 번의 인증을 시도하여도 계정잠금 또는 추가 인증 방법 등의 충분한 조치가 수행되지 않는 경우, 공격자는 성공할법한 ID와 비밀번호들을 사전(Dictionary)으로 만들고 무차별 대입하여 로그인 성공 및 권한 획득이 가능하다.
안전한 코딩 기법
- 인증시도 횟수를 적절한 횟수로 제한한다.
- 설정된 인증실패 횟수를 초과했을 경우 계정을 잠그거나 추가적인 인증과정을 거쳐서 시스템에 접근이 가능하도록 한다.