728x90
반응형
SMALL
SW개발보안가이드중 구현단계에서의 점검항목은 크게 7가지 이다. (입보시에코캡아)
1. 입력데이터 검증 및 표현
1-1. SQL삽입
1-2. 경로조작 및 자원삽입
1-3. 크로스 사이트 스크립트 (XSS)
1-4. 운영체제 명령어 삽입
1-5. 위험한 형식 파일 업로드
1-6. 신뢰하지 않은 URL주소로 자동 접속 연결
1-7. XQuery 삽입
1-8. XPath 삽입
1-9. LDAP삽입
1-10 크로스사이트 요청 위조 (CSRF)
1-11 HTTP 응답 분할
1-12 정수형 오버플로우
1-13 보안기능 결정에 사용되는 부적절한 입력값
1-14 메모리 버퍼 오버플로우
1-15 포맷 스트링 삽입
2. 보안기능
3. 시간 및 상태
4. 에러처리
5. 코드오류
6. 캡슐화
7. API 오용
이 장에서는 "1.입력데이터 검증 및 표현" 에 대한 점검항목을 설명한다. (첫번째)
1-1. SQL삽입
구분 | 설명 |
원인/영향 | DB와 연동하는 웹어플리케이션에서 입력된 데이터를 검증하지 않고 쿼리문의 일부로 사용하는 경우 쿼리문조작을 통해 인증을 우회하거나 다른 DB데이터를 유출,수정,삭제할수 있다. (거기다가 Stored Procedure 를 호출하여 원격으로 시스템 명령어를 실행시킬 수 있다) |
대응 | ① 정적쿼리를 사용하여 쿼리문의 구조가 변경되지 않도록 한다. ② 조작문자열 필터링 - 동적쿼리를 사용시 쿼리문의 구조를 변경할 수 있는 문자열을 필터링 한다. ③ 사용자권한을 최소화함으로써 공격을 당하더라도 최소한의 데이터만 유출될수 있도록 한다. JDBC API 안전) PreparedStatement pstmt = con.PrepareStatement(sql); pstme.setString (1, getParamenter("gubn")); MyBatis 취약) where a.confirm_seq = ${confirmSeq} ; 안전) where a.confirm_seq = #{confirmSeq} ; <-- 정적쿼리 Hibernate 안전) query = session.createQuery("from Student where studentName = ? "); query.setString(0, name) |
1-2. 경로조작 및 자원삽입
구분 | 설명 |
원인/영향 | 외부입력값을 시스템자원(IP, Port, 파일..) 의 식별자로 이용하는 경우 공격자는 입력값을 조작하여 ①자원에 임의로 접근할 수 있거나, ②허용되지 않은 권한을 획득하거나, ③인증을 우회해서 파일등을 열람 할수 있다. |
대응 | ① WhiteList - 사전에 사용 가능한 자원 목록을 정의하여 제공한다. ② 경조로작문자열 제거 - 입력값에 포함된 경로조작 문자열을 제거한다. 취약) String fileName = request.getParameter("P"); response.setHeader("Content-Disposition',"attachment;filename=" + fileName + "';"); fis = new FileInputStream("C:/datas/" + fileName ); <-- 경로문자열 제거 안하고 바로 참조 안전) fileName = fileName.replaceAll("\\","").replaceAll("\","").replaceAll("\\\\",""); <-- 제거 fis = new FileInputStream("C:/datas/" + fileName ); |
취약) String helpFile = args[0]; br = new BufferedReader(new FileReader(safeDir + helpFile)) <-- args[0]의 값으로 "../../../windows/system32/drivers/etc/hosts" 와 같이 경로조작문자열이 포함된 입력이 들어오는 경우 제한된 경로의 파일에 접근할수 있다. 안전) String helpFile = args[0]; if (helpFile != null) { helpFile = helpFile.replaceAll("\\.{2,}[/\\\\]",""}; <- 경로조작가능 문자열 제거 } br = new BufferedReader(new FileReader(safeDir + helpFile)) |
1-3. 크로스 사이트 스크립트 (XSS)
구분 | 설명 |
원인/영향 | 외부입력값이나 DB에 저장되어 있는 값을 사용하여 동적으로 웹페이지를 생성하는 경우 클라이언트에서 웹페이지에 포함된 악성스크립트가 실행되어 사용자의 중요정보를 탈취할 수 있다. - 쿠키 등 사용자 정보 탈취 - 쿠키 등 정보 노출로 세션 하이재킹 공격을 당할수 있다 |
대응 | ① 입력값 - (WhiteList) 정규식을 이용하여 허용되는 패턴의 데이터만 입력되도록 한다. - (XSS필터링) 서버로 전달되는 요청에 대해 XSS필터를 적용한다. ② 출력값 - (HTML 인코딩) 웹페이지로 출력 시 HTML인코딩을 적용하여 스크립트가 동작안되게한다. - (XSS필터링) 클라이언트로 전달되는 출력값에 대해 XSS필터를 적용한다. |
취약) <% String customerID = request.getParameter("id") ; %> <td>요청한 사용자 : <%=customerID%></td> 안전) 서블릿 출력값에 HTML인코딩 적용 String cleanData = input.replaceAll ("<", "<").replaceAll(">",">"); 안전) JSP에서 출력값에 HTML인코딩 적용 <textarea name="content"><c:out value="$(model.content}"/> </textarea> 안전) JSP에서 출력값에 JSTL Core 출력포맷을 사용하여 텍스트로 처리 안전) 외부 XSS Filter 라이브러리 이용해서 출력값에 필터링 적용 XssFilter filter = XssFilter.getInstance("lucy-xss-superset.xml"); out.append(filter.doFilter(data)); |
1-4. 운영체제 명령어 삽입
항목 | 설명 |
원인/영향 | 외부입력값을 운영체제 명령어 생성의 일부 또는 전부로 사용하는 경우 공격자는 입력값에 운영체제 명령어를 삽입하여 서버의 실행권한으로 실행되게 함으로써 중요파일이 삭제되거나 백도어가 실행 |
대응 | ① 기본적으로 운영체제 명령어가 애플리케이션 내부에서 실행되지 않도록 설계한다. ② WhiteList - 운영체제 명령어 실행이 필요하다면 허용 가능한 목록을 정의해서 사용한다. |
취약) String cmd = args[0] ; ps = Runtime.getRuntime().exec(cmd); <-- 외부입력값인 args[0] 값을 바로 사용 안전) 해당 애플리케이션에서 실행할 수 있는 프로그램을 노트패드와 계산기로 제한함. allowedCommands.add("notepad"); allowedCommands.add("calc"); String cmd = args[0] if (!allowedCommands.contains(cmd) { <-- 목록에 있는 명령어만 허용 System.err.println("허용되지 않는 명령어입니다"); } |
|
취약) String data = request.getParameter("data"); if (osName.toLowerCase().startWith(window")) { cmd = new String[] {"cmd.exe","/c", data }; } Runtime.getRuntime().exec(cmd); <-- 외부입력값을 바로 사용 안전) String[] allowCommand = { "type", "dir"}; <-- 허용할 명령어를 사전에 정의함. String data = request.getParameter("data); int index = TestUtil.getInt(data); <-- 목록에서 선택한 index가 넘어옴 if (index == 0 || index == 1) { <-- 목록에 있는 명령어만 허용. data = allowCommand[index]; if (osName.toLowerCase().startWith(window")) { cmd = new String[] {"cmd.exe","/c", data }; } Runtime.getRuntime().exec(cmd); } else { System.err.println("허용되지 않는 명령어입니다"); } |
1-5. 위험한 형식 파일 업로드
구분 | 설명 |
원인/영향 | 첨부파일과 같이 업로드되는 파일의 안전성을 검사하지 않는 경우 공격자는 서버측에서 실행될수 있는 스크립트파일(asp,jsp,php)이나 웹셀(webshell) 을 업로드 해서 이 파일을 통해 시스템 내부 명령어를 실행하거나 외부에서 시스템을제어할 수 있다. - 키로그를 설치하여 인증정보를 획득한다던지, - 악성코드가 포함된 파일을 업로드하여 사용자의 PC를 감염시킨다. |
대응 | ① 업로드되는 파일의 크기와 개수를 제한한다. ② 업로드되는 파일의 종류를 WhiteList 로 제한한다. ③ 업로드한 파일은 외부에서 접근할 수 없는 경로에 저장한다. ④ 업로드한 파일의 저장경로와 파일명등을 외부에서는 알수 없도록 한다. ⑤ 업로드한 파일의 실행권한을 제거하고 저장한다. |
취약) String fineName = multi.getFilesystemName("filename"); String sql = " INSERT INTO borad (email, r_num, w_date, pwd, content, filename) " + values ( ?, 0 , sysdate(), ? , ? , ?) " ; PreparedStatement pstmt = con.prepareStatement(sql); pstmt.setString(1, email); ..... pstme.setString(6, fileName); <-- 정적쿼리로 안전하게 파일명 DB 저장.. // 파일에 대한 검사없이 바로 서버의 폴더에 저장 Thumnail.create(savepath + "/" + fileName, savepath + "/" + fileName, 150); |
|
안전) String fineName = multi.getFilesystemName("filename"); if (fileName != null) { // 확장자 가져옴. String fileExt = fileName.substring(fileNam.lastIndexof(".") + 1).toLowerCase(); if (!"gif".equals(fileExt) && !"jpg".equals(fileExt) && !"png".equals(fileExt)) { alermessage("업로드가 불가능한 파일입니다"); <-- 허용된 확장자인지 체크 return; } String sql = " INSERT INTO borad (email, r_num, w_date, pwd, content, filename) " + values ( ?, 0 , sysdate(), ? , ? , ?) " ; '''''' 중간생략 '''''' // 파일에 대한 검사를 한후 서버의 폴더에 저장 Thumnail.create(savepath + "/" + fileName, savepath + "/" + fileName, 150); |
728x90
반응형
LIST
'정보보안' 카테고리의 다른 글
SW보안약점진단원 : 구현단계 - 보안기능 (1/2) (0) | 2019.11.24 |
---|---|
SW보안약점진단원 : 구현단계 - 입력데이터 검증 및 표현 (2/2) (0) | 2019.11.23 |
SW 개발보안 가이드 : 분석/설계단계 - 에러처리 와 세션통제 (0) | 2019.11.21 |
SW보안약점진단원 : 분석/설계단계 - 보안기능 (0) | 2019.11.20 |
SW보안약점진단원 : 분석/설계단계 - 입력 데이터 검증 및 표현 (1) | 2019.11.19 |