프로그래밍/- eGov
filter 에서 xss 보안처리
즐겁게 하하하
2025. 1. 17. 21:19
728x90
web.xml
<!-- 필터 등록 -->
<filter>
<filter-name>baseFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>baseFilter</filter-name>
<url-pattern>*.do</url-pattern>
</filter-mapping>
<filter>
<filter-name>baseXssFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>baseXssFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
DelegatingFilterProxy란?
- Spring Framework에서 제공하는 필터 구현체로, 실제 필터링 로직을 Spring Context에 정의된 Bean으로 위임(delegate)합니다.
- Java Servlet 필터를 구현하고, Spring IoC 컨테이너 안에서 관리되는 Bean과 연동하기 위해 사용됩니다.
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.RequestDispatcher;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@Service("baseXssFilter")
public class XSSFilter implements Filter {
protected final Logger logger = LoggerFactory.getLogger(this.getClass());
@Override
public void init(FilterConfig filterConfig) throws ServletException {
// 필터 초기화 작업 (필요시 사용)
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest httpRequest = (HttpServletRequest) request;
HttpServletResponse httpResponse = (HttpServletResponse) response;
try {
// 요청 파라미터에서 악성 스크립트 감지
if (containsMaliciousScript(httpRequest)) {
// 악성 스크립트 발견 시 에러 페이지로 이동
handleMaliciousScript(httpRequest, httpResponse);
return;
}
} catch (Exception e) {
// 예외 처리
handleException(httpRequest, httpResponse, e);
}
HttpServletRequest httpRequest = (HttpServletRequest) request;
XSSUrlRequestWrapper wrappedRequest = new XSSUrlRequestWrapper(httpRequest);
chain.doFilter(wrappedRequest , response);
}
/**
* URL 파라미터에서 악성 스크립트가 포함되어 있는지 검사
*/
private boolean containsMaliciousScript(HttpServletRequest request) {
// 모든 파라미터 검사
for (String param : request.getParameterMap().keySet()) {
String[] values = request.getParameterValues(param);
if (values != null) {
for (String value : values) {
if (isMalicious(value)) {
return true; // 악성 값 발견
}
}
}
}
return false; // 악성 값 없음
}
/**
* 문자열에서 악성 스크립트를 탐지
*/
private boolean isMalicious(String value) {
if (value == null) return false;
// 간단한 패턴 탐지: 스크립트 태그, JavaScript 이벤트, 기타 악성 코드
String lowerValue = value.toLowerCase();
return lowerValue.contains("<script") || lowerValue.contains("javascript:")
|| lowerValue.matches(".*on[a-z]+\\s*=.*")
|| lowerValue.contains("<img") && lowerValue.contains("onerror");
}
private void handleMaliciousScript(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 에러 메시지 설정
response.setStatus(HttpServletResponse.SC_NOT_FOUND); // 상태 코드 설정
request.setAttribute("javax.servlet.error.status_code", HttpServletResponse.SC_NOT_FOUND); // 추가 설정
request.setAttribute("errorMsg", "악성 스크립트가 감지되었습니다. 요청이 차단되었습니다.");
// 내부 JSP로 포워딩
RequestDispatcher dispatcher = request.getRequestDispatcher("/error.do");
dispatcher.forward(request, response);
}
private void handleException(HttpServletRequest request, HttpServletResponse response, Exception e)
throws ServletException, IOException {
// 예외 메시지 설정
request.setAttribute("errorMsg", "예기치 못한 에러가 발생했습니다: " + e.getMessage());
// 내부 JSP로 포워딩
RequestDispatcher dispatcher = request.getRequestDispatcher("/error.do");
dispatcher.forward(request, response);
}
@Override
public void destroy() {
// 필터 종료 작업 (필요시 사용)
}
}
728x90