SW개발보안가이드중 구현단계에서의 점검항목은 크게 7가지 이다. (입보시에코캡아)
1. 입력데이터 검증 및 표현
2. 보안기능
2-1. 적절한 인증없는 중요기능 허용
2-2. 부적절한 인가
2-3. 중요자원에 대한 잘못된 권한 설정
2-4. 취약한 암호화 알고리즘 사용
2-5. 중요정보 평문 저장
2-6. 중요정보 평문 전송
2-7. 하드코드된 비밀번호
2-8. 충분하지 않은 키 길이 사용
2-9. 적절하지 않은 난수값 사용
2-10. 하드코드된 암호화 키
2-11. 취약한 비밀번호 허용
2-12. 사용자 하드디스크에 저장되는 쿠기를 통한 정보노출
2-13. 주석문 안에 포함된 시스템 주요 정보
2-14. 솔트없이 일방향 해쉬 함수 사용
2-15. 무결성 검사 없는 코드 다운로드
2-16. 반복된 인증시도 제한 기능 부재
3. 시간 및 상태
4. 에러처리
5. 코드오류
6. 캡슐화
7. API 오용
이 장에서는 "2.보안기능" 에 대한 점검항목을 설명한다. (두번째)
2-10. 하드코드된 암호화 키
구분 | 설명 |
원인/영향 | 암호화에 사용되는 키를 소스코드에 하드코딩한 경우 실행파일을 역컴파일하면 키값이 유출될수있다. (예) String Key = "222##FFd:Fdrfdfs; <-- 하드코딩된 키값을 그대로 사용 sKeySpec = new.SecretKeySpec(Key.getBytes(), "AES"); String Key = getPassword("./password.ini"); <-- 키값을 안전한 곳에서 가져온다. Key = decrypt(Key); <-- 복호화해서 사용한다. |
대응 | ① 암호화 키는 암호화하여 별도 안전한 곳에 저장하여야 한다. |
2-11. 취약한 비밀번호 허용
구분 | 설명 |
원인/영향 | 비밀번호 조합규칙이 미흡한 경우 패스워드 사전공격이나 Brute Force 공격에 의해 노출될수 있다. (예) String id = request.getParameter("id"); String pwd = reqeust.getParameter("pwd"); registDAO.regist(id,pwd); <-- 조합규칙 체크없이 바로 등록 String id = request.getParameter("id"); String pwd = reqeust.getParameter("pwd"); Pattern pattern = Pattern.Compile("((?=.*[a-zA-Z])(?=.*[0-9]).{10,})"); Matcher matcher = pattern.matcher(pwd); <-- 패턴을 체크 if (!matchermatches()) { return "비밀번호 조합규칙 오류"; } |
대응 | ① 3가지 종류의 문자,숫자,특수문자로 8자리 이상 ② 2가지 종류의 문자,숫자,특수문자로 10자리 이상 ③ 한글,영어등 사전적 단어 포함 금지 ④ 널리 알려진 단어 사용 금지 ⑤ 사용자ID와 연관있는 단어 사용금지 ⑥ 3자가 쉽게 알수 있는 개인정보 포함 금지 ⑦ 패턴이 존재하는 비밀번호 사용금지 ⑧ 숫자와 영문자를 비숫한 문자로 치환한 형태를 포함한 구성의 비밀번호 사용 금지 ⑨ 이전 비밀번호와 연관성 있는 단어 사용 금지 |
2-12. 사용자 하드디스크에 저장되는 쿠기를 통한 정보노출
구분 | 설명 |
원인/영향 | 개인정보 등 중요한 정보를 영속적인 쿠키에 저장함으로써 유출의 위험이 있고 이를 통해 보안체계를 우회하는 공격이 수행될 수 있다 |
대응 | ① 쿠키의 만료시간은 최소한으로 설정 ② 영속적인 쿠키에는 중요정보를 저장하지 않는다. 예) setMaxAge (60*60*24*30*12) ; <-- 만료시간을 1년으로 설정..위험.. setMaxAge (60*60*24); <-- 만료시간을 1일로 했지만 이것보다는 암호화해서 저장하는게 안전 |
2-13. 주석문 안에 포함된 시스템 주요 정보
구분 | 설명 |
원인/영향 | 개발자편의로 주석문안에 시스템 주요정보를 남겨두게 되면 역컴파일을 통해 쉽게 유출이 가능하며 이를 통해 공격자는 시스템공격이 가능 |
대응 | ① 주석문에는 시스템 중요정보를 적지않는다. ② 개발시 필요해서 남겨둔 주석문이라면 개발완료후 확실하게 제거한다. |
2-14. 솔트없이 일방향 해쉬 함수 사용
구분 | 설명 |
원인/영향 | 일방향 해쉬함수 사용시 salt 를 사용하지 않으면 공격자는 레인보우 테이블과 같이 가능한 모든 해쉬값을 미리 계산한 후 전수조사를 통해 평문을 추출할 수 있다 |
대응 | ① 해쉬함수 사용시 반드시 salt를 적용한다. 취약) md = MessageDigest.getInstance("SHA-256"); md.update(password.getBytes()); <-- 패스워드만 입력하고 byte byteData[] = md.digest(); <-- 해쉬한다. (즉 암호화한다) 안전) md = MessageDigest.getInstance("SHA-256"); md.update(password.getBytes()); md.update(salt); <-- 해쉬하기 전에 salt를 추가 입력해준다. byte byteData[] = md.digest(); |
2-15. 무결성 검사 없는 코드 다운로드
구분 | 설명 |
원인/영향 | 원격으로부터 소스코드나 실행파일을 다운로드하여 사용할 때 무결성 검사없이 수행하는 경우 중간에서 해당 소스코드나 실행파일에 악성코드를 삽입하는 등 위변조를 할수 있어서 의도하지 않은 결과를 유발할 수 있다 |
대응 | ① 다운로드시 해쉬값을 첨부해서 전송하거나, 암호화해서 전송한다. ② 다운로드를 받은 후에는 무결성검사를 수행한 뒤 최소권한으로 실행한다. 취약) URL[] classURLs = new URL[] { new URL("file:subdir/")}; URLClassLoader loader = new URLClassLoader(classURLs); Class loadedClass = Class.forName("LoadMe",true, loader);<-- 파일을 다운받아 바로 Load. 취약 안전) <서버측> String jarfile = "./download/util.jar"; byte[] loadfile = FileManager.getBytes(jarfile); loadfile = encrypt(loadfile, privateKey); <-- 다운로드할 파일을 개인키로 암호화 FileManager.createfile(loadfile, jarFileName); <-- 암호화된 파일을 생성함. <클라이언트측> URL[] classURLs = new URL[] { new URL("http://filesave.com/download/util.jar")}; <-- 다운로드 ... 중간생략 loadfile = decrypt(loadfile,publicKey); <-- 복호화 FileManager.createfile(loadfile, jarFile) ; URLClassLoader loader = new URLClassLoader(classURLs); Class loadedClass = Class.forName("MyClass",true, loader); <-- 복호화된 파일을 Load . 안전 |
2-16. 반복된 인증시도 제한 기능 부재
구분 | 설명 |
원인/영향 | 인증기능 구현 시 인증시도 횟수를 적절한 로직으로 제한하지 않으면 무작위 대입 인증시도 공격을 받을 수 있다. |
대응 | ① 인증시도 횟수 제한 안전) while ((isValidUser == 0) && (count < MAX_ATTEMPS)) { < 횟수 제한 추가 } |
'정보보안' 카테고리의 다른 글
SW보안약점진단원 : 구현단계 - 에러처리 (0) | 2019.11.27 |
---|---|
SW보안약점진단원 : 구현단계 - 시간 및 상태 (0) | 2019.11.26 |
SW보안약점진단원 : 구현단계 - 보안기능 (1/2) (0) | 2019.11.24 |
SW보안약점진단원 : 구현단계 - 입력데이터 검증 및 표현 (2/2) (0) | 2019.11.23 |
SW보안약점진단원 : 구현단계 - 입력데이터 검증 및 표현 (1/2) (0) | 2019.11.22 |