JSP Security

JSP 보안 (JSP Security)

입력 유효성 검사 (Input Validation)

입력 유효성 검사는 사용자가 웹 애플리케이션에 제공하는 데이터를 검증하여, 악성 데이터가 시스템에 침투하는 것을 방지하는 첫 번째 방어선입니다. 클라이언트 측과 서버 측 모두에서 유효성 검사를 수행하는 것이 중요합니다.

클라이언트 측 유효성 검사 (Client-side Validation)

HTML 폼과 JavaScript를 사용하여 클라이언트 측 유효성 검사를 수행할 수 있습니다.

<form id="userForm" action="submit.jsp" method="post">
    이름: <input type="text" name="name" id="name" required><br>
    이메일: <input type="email" name="email" id="email" required><br>
    <input type="submit" value="제출">
</form>

<script>
document.getElementById("userForm").onsubmit = function() {
    var name = document.getElementById("name").value;
    var email = document.getElementById("email").value;
    if (name == "" || email == "") {
        alert("모든 필드를 입력해주세요.");
        return false;
    }
    return true;
};
</script>

서버 측 유효성 검사 (Server-side Validation)

서버 측 유효성 검사는 신뢰할 수 없는 입력으로부터 애플리케이션을 보호합니다. JSP에서 서버 측 유효성 검사를 수행하는 예제입니다.

<%@ page import="java.util.regex.*" %>
<%
    String name = request.getParameter("name");
    String email = request.getParameter("email");
    String namePattern = "^[a-zA-Z가-힣\\s]+$";
    String emailPattern = "^[\\w-\\.]+@([\\w-]+\\.)+[\\w-]{2,4}$";

    if (name == null || !Pattern.matches(namePattern, name)) {
        out.println("유효한 이름을 입력해주세요.");
    } else if (email == null || !Pattern.matches(emailPattern, email)) {
        out.println("유효한 이메일 주소를 입력해주세요.");
    } else {
        out.println("입력이 유효합니다.");
    }
%>

SQL 인젝션 방지 (Preventing SQL Injection)

SQL 인젝션은 공격자가 SQL 쿼리를 조작하여 데이터베이스에 악성 명령을 실행하는 공격입니다. 이를 방지하기 위해 준비된 문(Prepared Statements)을 사용합니다.

예제: 준비된 문 사용

<%@ page import="java.sql.*" %>
<%
    String username = request.getParameter("username");
    String password = request.getParameter("password");

    Connection conn = null;
    PreparedStatement pstmt = null;
    ResultSet rs = null;

    try {
        Class.forName("com.mysql.jdbc.Driver");
        conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb", "root", "password");
        String sql = "SELECT * FROM users WHERE username = ? AND password = ?";
        pstmt = conn.prepareStatement(sql);
        pstmt.setString(1, username);
        pstmt.setString(2, password);
        rs = pstmt.executeQuery();

        if (rs.next()) {
            out.println("로그인 성공");
        } else {
            out.println("로그인 실패");
        }
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        if (rs != null) try { rs.close(); } catch (SQLException e) { e.printStackTrace(); }
        if (pstmt != null) try { pstmt.close(); } catch (SQLException e) { e.printStackTrace(); }
        if (conn != null) try { conn.close(); } catch (SQLException e) { e.printStackTrace(); }
    }
%>

위 예제는 사용자 입력을 직접 SQL 쿼리에 포함하지 않고, PreparedStatement를 사용하여 SQL 인젝션 공격을 방지합니다.

XSS (Cross-Site Scripting) 방지 (Preventing XSS)

XSS 공격은 공격자가 웹 페이지에 악성 스크립트를 삽입하여 다른 사용자가 실행하도록 만드는 공격입니다. 이를 방지하기 위해 사용자 입력을 적절하게 이스케이프(Escape)해야 합니다.

예제: 사용자 입력 이스케이프

JSP에서 사용자 입력을 출력할 때 HTML 이스케이프를 수행하는 예제입니다.

<%@ page import="org.apache.commons.text.StringEscapeUtils" %>
<%
    String userInput = request.getParameter("userInput");
    if (userInput != null) {
        out.println("입력된 값: " + StringEscapeUtils.escapeHtml4(userInput));
    }
%>

위 예제는 Apache Commons Text 라이브러리를 사용하여 사용자 입력을 HTML로 이스케이프하여 XSS 공격을 방지합니다. 라이브러리를 사용하지 않는 경우, 다음과 같은 간단한 함수를 사용할 수 있습니다.

public String escapeHtml(String input) {
    if (input == null) {
        return null;
    }
    return input.replaceAll("&", "&amp;")
                .replaceAll("<", "&lt;")
                .replaceAll(">", "&gt;")
                .replaceAll("\"", "&quot;")
                .replaceAll("'", "&#x27;")
                .replaceAll("/", "&#x2F;");
}

위 함수를 JSP 코드에서 사용하여 XSS 공격을 방지할 수 있습니다.

<%
    String userInput = request.getParameter("userInput");
    if (userInput != null) {
        out.println("입력된 값: " + escapeHtml(userInput));
    }
%>

이렇게 JSP에서 보안 문제를 예방하고 애플리케이션을 안전하게 유지하기 위해 다양한 방법을 사용할 수 있습니다. 입력 유효성 검사, SQL 인젝션 방지, XSS 방지는 모두 웹 애플리케이션 보안의 중요한 요소입니다.

Leave a Reply

Your email address will not be published. Required fields are marked *