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

+ Recent posts