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("&", "&") .replaceAll("<", "<") .replaceAll(">", ">") .replaceAll("\"", """) .replaceAll("'", "'") .replaceAll("/", "/"); }
위 함수를 JSP 코드에서 사용하여 XSS 공격을 방지할 수 있습니다.
<% String userInput = request.getParameter("userInput"); if (userInput != null) { out.println("입력된 값: " + escapeHtml(userInput)); } %>
이렇게 JSP에서 보안 문제를 예방하고 애플리케이션을 안전하게 유지하기 위해 다양한 방법을 사용할 수 있습니다. 입력 유효성 검사, SQL 인젝션 방지, XSS 방지는 모두 웹 애플리케이션 보안의 중요한 요소입니다.