1. 입력데이터 검증 및 표현
프로그램 입력 값에 대한 검증 누락 또는 부적절한 검증, 데이터의 잘못된 형식지정, 일관되지 않은 언어셋 사용 등으로 인해
발생하는 보안약점으로 SQL 삽입, 크로스사이트 스크립트(XSS) 등의 공격을 유발할 수 있다.
1)
SQL 삽입(SQL Injection)
데이터베이스(DB)와
연동된 웹 어플리케이션에서 입력된 데이터에 대한 유효성 검증을 하지 않을 경우, 공격자가 입력 폼 및 URL 입력란에 SQL 문을 삽입하여 DB로부터 정보를 열람하거나 조작할 수 있는 보안약점을 말한다.
n 안전한 코딩
기법
① PreparedStatement 클래스와 하위 메소드 excuteQuery(),
execute(), excuteUpdate()를 사용한다.
② PreparedStatement 클래스를 사용할 수 없는 환경이라면, 입력
값을 필터링 처리한 후 사용한다.
③ Mybatis Data Map 파일의 인자를 받는 질의 명령어 정의시에 문자열 삽입 인자($..$)를 사용하지 않고, 질의 구조에 영향을 주지 않는 #<인자이름># 형태의 질의문을 사용한다. 부득이하게 삽입인자($..$)를 사용할 경우에는 입력 값을 필터링
처리하여 사용한다.
- import java.io.IOException;
- import java.sql.Connection;
- import java.sql.DriverManager;
- import java.sql.ResultSet;
- import java.sql.SQLException;
- import java.sql.Statement;
- import java.util.regex.Matcher;
- import java.util.regex.Pattern;
- import javax.servlet.ServletConfig;
- import javax.servlet.ServletException;
- import javax.servlet.http.HttpServlet;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
- public class SQLInjectionSample extends HttpServlet {
- private static final long serialVersionUID = 1L;
- private Connection conn;
- private final static int MAX_USER_ID_LENGTH = 14;
- private final static int MAX_PASSWORD_LENGTH = 16;
- private final static String UNSECURED_CHAR_REGULAR_EXPRESSION = "[^\\p{Alnum}]|select|delete|update|insert|create|alter|drop";
- private static Pattern unsecuredCharPattern = Pattern.compile(UNSECURED_CHAR_REGULAR_EXPRESSION, Pattern.CASE_INSENSITIVE);
- public void init(ServletConfig config) throws ServletException {
- unsecuredCharPattern = Pattern.compile(UNSECURED_CHAR_REGULAR_EXPRESSION, Pattern.CASE_INSENSITIVE);
- }
- protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
- Statement stmt = null;
- ResultSet rs = null;
- String action = request.getParameter("action");
- if(action == null || "".equals(action)) { action = "default"; }
- if(action.equals("login")) {
- try {
- conn = DriverManager.getConnection("url", "user", "password");
- stmt = conn.createStatement();
- String userId = request.getParameter("user_id");
- String password = request.getParameter("password");
- if(userId == null || "".equals(userId) || password == null || "".equals(password)) {
- throw new Exception("check login info");
- } else {
- }
- userId = makeSecureString(userId, MAX_USER_ID_LENGTH);
- password = makeSecureString(password, MAX_PASSWORD_LENGTH);
- String query = "SELECT * FROM MEMBERS WHERE userid=" + userId + " AND password=" + password;
- rs = stmt.executeQuery(query);
- } catch (SQLException e) {
- System.out.println(e.getMessage());
- e.printStackTrace();
- } catch (Exception e) {
- System.out.println(e.getMessage());
- } finally {
- try {
- if(rs != null) { rs.close(); }
- if(stmt != null) { stmt.close(); }
- if(conn != null) { conn.close(); }
- } catch (SQLException e) {
- System.out.println(e.getMessage());
- }
- }
- }
- }
- private String makeSecureString(final String str, int maxLength) {
- String secureStr = str.substring(0, maxLength);
- Matcher matcher = unsecuredCharPattern.matcher(secureStr);
- return matcher.replaceAll("");
- }
- }
댓글 없음:
댓글 쓰기