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 방지는 모두 웹 애플리케이션 보안의 중요한 요소입니다.
