레이블이 Secure Coding인 게시물을 표시합니다. 모든 게시물 표시
레이블이 Secure Coding인 게시물을 표시합니다. 모든 게시물 표시

2015년 12월 6일 일요일

보안기능 - 사용자 하드디스크에 저장되는 쿠키를 통한 정보 노출

1)     사용자 하드디스크에 저장되는 쿠키를 통한 정보노출
대부분의 웹 응용프로그램에서 쿠키는 메모리에 상주하며, 브라우저 실행이 종료되면 사라진다. 프로그래머가 원하는 경우, 브라우저 세션에 관계없이 지속적으로 저장되도록 설정할 수 있으며, 이것은 디스크에 기록되고 다음 브라우저 세션이 시작되었을 때 메모리에 로드된다. 개인정보, 인증정보 등이 영속적인 쿠키(persistent Cookie)에 저장된다면, 공격자는 쿠키에 접근할 수 잇는 보다 많은 기회를 가지게 되며, 이는 시스템을 취약하게 만든다.

n  안전한 코딩 기법

     쿠키의 만료시간은 세션이 지속되는 시간과 관련하여 최소한으로 설정하고 영속적인 쿠키에는 사용자 권한 등급, 세션ID가 포함되지 않도록 한다.


  1. private final String LOGIN_ACT = "login";  
  2. private final String LOGOUT_ACT = "logout";  
  3. private final String OTHER_ACT = "other_action";  
  4. private final String USER_ID_PARM = "user_id";  
  5. private final String PASSWORD_PARM = "password";  
  6. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {  
  7.     String action = request.getParameter("action");  
  8.     if(action == null || "".equals(action)) {  
  9.         RequestDispatcher requestDispatcher = request.getRequestDispatcher("/index");  
  10.         requestDispatcher.forward(request, response);  
  11.     }  
  12.       
  13.     if(LOGIN_ACT.equals(action)) {  
  14.         String userId = request.getParameter(USER_ID_PARM);  
  15.         String password = request.getParameter(PASSWORD_PARM);  
  16.           
  17.         /* do something. For example, password encryption */  
  18.           
  19.         Cookie idCookie = new Cookie("id", userId);  
  20.         Cookie passwordCookie = new Cookie("password", password);  
  21.       
  22.         idCookie.setMaxAge(-60 * 2); // 브라우저 종료시, 삭제되도록 음수 값 설정. 계속 사용해야 하 는경우 cookie 갱신  
  23.         passwordCookie.setMaxAge(-60 * 2);  
  24.           
  25.         idCookie.setSecure(true);  
  26.         passwordCookie.setSecure(true);  
  27.           
  28.         response.addCookie(idCookie);  
  29.         response.addCookie(passwordCookie);  
  30.     } else if(LOGOUT_ACT.equals(action)) {  
  31.         /* do something. */  
  32.         Cookie[] cookies = request.getCookies();  
  33.         if(cookies != null && cookies.length > 0) {  
  34.             for(int i = 0; i < cookies.length; i++) {  
  35.                 Cookie cookie = new Cookie("id""");  
  36.                 if(cookies[i].getName().equals("id")) {  
  37.                     cookie = new Cookie("id""");  
  38.                 } else if(cookies[i].getName().equals("password")) {  
  39.                     cookie = new Cookie("password""");  
  40.                 }  
  41.                 cookie.setMaxAge(0);  
  42.                 response.addCookie(cookie);  
  43.             }  
  44.         }  
  45.         /* do something. */  
  46.     } else if(OTHER_ACT.equals(action)) {  
  47.         /* do something. */  
  48.         Cookie[] cookies = request.getCookies();  
  49.         if(cookies != null && cookies.length > 0) {  
  50.             for(int i = 0; i < cookies.length; i++) {  
  51.                 Cookie cookie = new Cookie("id", cookies[i].getValue());  
  52.                 if(cookies[i].getName().equals("id")) {  
  53.                     cookie = new Cookie("id""");  
  54.                 } else if(cookies[i].getName().equals("password")) {  
  55.                     cookie = new Cookie("password", cookies[i].getValue());  
  56.                 }  
  57.                 cookie.setMaxAge(-60 * 2);  
  58.                 response.addCookie(cookie);  
  59.             }  
  60.         }  
  61.         /* do something. */  
  62.     }  
  63. }  


2015년 12월 1일 화요일

보안기능 - 하드코드된 패스워드

1)     하드코드된 패스워드
프로그램 코드 내부에 하드코드된 패스워드를 포함하고, 이를 이용하여 내부 인증에 사용하거나 외부 컴포넌트와 통신을 하는 경우 관리자 정보가 노출 될 수 있어 위험하다. 또한, 코드 내부에 하드코드된 패스워드가 인증실패를 야기하는 경우, 시스템 관리자가 그 실패의 원인을 파악하기 쉽지 않은 단점이 있다.

n  안전한 코딩 기법
     패드워드는 암호화하여 별도의 파일에 저장하여 사용하는 것이 바람직하다.
     SW 설치 시 사용하는 디폴트 패스워드, 키 등을 사용하는 대신 최초-로그인 모드를 두어 사용자가 직접 강력한 패스워드나 키를 입력하도록 설계한다.


1.   private Connection connection = null;  
2.   private Connection connect(Properties props) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {  
3.       try {  
4.           String url = props.getProperty("url");  
5.           String id = props.getProperty("id");  
6.           String pwd = props.getProperty("passwd");  
7.             
8.           if(url != null && !"".equals(url) && id != null && !"".equals(id) && pwd != null && !"".equals(pwd)) {  
9.               KeyGenerator kgen = KeyGenerator.getInstance("Blowfish");  
10.              SecretKey skey = kgen.generateKey();  
11.              byte[] raw = skey.getEncoded();  
12.              SecretKeySpec skeySpec = new SecretKeySpec(raw, "Blowfish");  
13.                
14.              Cipher cipher = Cipher.getInstance("Blowfish");  
15.              cipher.init(Cipher.DECRYPT_MODE, skeySpec);  
16.              byte[] decrypted_pwd = cipher.doFinal(pwd.getBytes());  
17.              pwd = new String(decrypted_pwd);  
18.              connection = DriverManager.getConnection(url, id, pwd);  
19.          }  
20.            
21.      } catch(SQLException e) {  
22.          /* Exception Control */  
23.      }  
24.        
25.      /* do something */  
26.      return connection;  
27.  }  

보안기능 - 취약한 암호화 알고리즘 사용

1)     취약한 암호화 알고리즘 사용
정보보호 측면에서 취약하거나 위험한 암호화 알고리즘을 사용해서는 안 된다. 표준화되지 않은 암호 알고리즘을 사용하는 것은 공격자가 알고리즘을 분석하여 무력화시킬 수 있는 가능성을 높일 수도 있다. 몇몇 오래된 암호 알고리즘의 경우는 컴퓨터의 성능이 향상됨에 따라 취약해지기도 해서, 예전에는 해독하는데 몇 십 억년이 걸리던 알고리즘이 최근에는 며칠이나 몇 시간 내에 해독되기도 한다. RC2, RC4, RC5, RC6, MD4, MD5, SHA1, DES 알고리즘이 여기에 해당된다.

n  안전한 코딩 기법
     검증된 표준화된 알고리즘을 사용한다. 기존에 취약하다고 알려진 DES, RC5등의 암호알고리즘을 대신하여, 3DES, AES, SEED 등의 안전한 암호알고리즘으로 대체하여 사용한다. 또한 업무관련 내용, 개인정보 등에 대한 암호 알고리즘 적용시, IT보안인증 사무국이 안정성을 확인한 검증필 암호모듈을 사용해야한다.

1.   public String encryptSHA256(String str) {  
2.       String SHA = "";  
3.         
4.       try {  
5.           MessageDigest msgDigest = MessageDigest.getInstance("SHA-256");  
6.           msgDigest.update(str.getBytes());  
7.           byte byteData[] = msgDigest.digest();  
8.             
9.           StringBuffer sb = new StringBuffer();  
10.          for(int i=0; i < byteData.length; i++) {  
11.              sb.append(Integer.toString((byteData[i]&0xff) + 0x10016).substring(1));  
12.          }  
13.          SHA = sb.toString();  
14.            
15.      }catch (NoSuchAlgorithmException e) {  
16.          System.out.println("error");  
17.          SHA = "";  
18.      }  
19.        
20.      return SHA;  
21.  }  


1.   import java.security.InvalidAlgorithmParameterException;  
2.   import java.security.InvalidKeyException;  
3.   import java.security.NoSuchAlgorithmException;  
4.     
5.   import javax.crypto.BadPaddingException;  
6.   import javax.crypto.Cipher;  
7.   import javax.crypto.IllegalBlockSizeException;  
8.   import javax.crypto.NoSuchPaddingException;  
9.   import javax.crypto.SecretKey;  
10.  import javax.crypto.spec.IvParameterSpec;  
11.  import javax.crypto.spec.SecretKeySpec;  
12.    
13.  import org.apache.commons.codec.binary.Base64;  
14.    
15.  public class AES256Cipher {  
16.    
17.      private static volatile AES256Cipher INSTANCE;  
18.    
19.      final static String secretKey = "12345678901234567890123456789012"// 32 bit  
20.      static String IV = ""// 16bit  
21.    
22.      public static AES256Cipher getInstance() {  
23.          if (INSTANCE == null) {  
24.              synchronized (AES256Cipher.class) {  
25.                  if (INSTANCE == null)  
26.                      INSTANCE = new AES256Cipher();  
27.              }  
28.          }  
29.          return INSTANCE;  
30.      }  
31.    
32.      private AES256Cipher() {  
33.          IV = secretKey.substring(0, 16);  
34.      }  
35.    
36.      public static String encryptAES256(String str)  
37.              throws java.io.UnsupportedEncodingException,  
38.              NoSuchAlgorithmException, NoSuchPaddingException,  
39.              InvalidKeyException, InvalidAlgorithmParameterException,  
40.              IllegalBlockSizeException, BadPaddingException {  
41.          byte[] keyData = secretKey.getBytes();  
42.    
43.          SecretKey secureKey = new SecretKeySpec(keyData, "AES");  
44.    
45.          Cipher c = Cipher.getInstance("AES/CBC/PKCS5Padding");  
46.          c.init(Cipher.ENCRYPT_MODE, secureKey,  
47.                  new IvParameterSpec(IV.getBytes()));  
48.    
49.          byte[] encrypted = c.doFinal(str.getBytes("UTF-8"));  
50.          String enStr = new String(Base64.encodeBase64(encrypted));  
51.    
52.          return enStr;  
53.      }  
54.    
55.      public static String decryptAES256(String str)  
56.              throws java.io.UnsupportedEncodingException,  
57.              NoSuchAlgorithmException, NoSuchPaddingException,  
58.              InvalidKeyException, InvalidAlgorithmParameterException,  
59.              IllegalBlockSizeException, BadPaddingException {  
60.          byte[] keyData = secretKey.getBytes();  
61.          SecretKey secureKey = new SecretKeySpec(keyData, "AES");  
62.          Cipher c = Cipher.getInstance("AES/CBC/PKCS5Padding");  
63.          c.init(Cipher.DECRYPT_MODE, secureKey,  
64.                  new IvParameterSpec(IV.getBytes("UTF-8")));  
65.    
66.          byte[] byteStr = Base64.decodeBase64(str.getBytes());  
67.    
68.          return new String(c.doFinal(byteStr), "UTF-8");  
69.      }  
70.  }