조민수 조민수 09-04
이미지 클릭시 session 제거 로직 수정
@97ed848eb3fba55da92bdb78d3b32b84aa18d36c
src/main/java/itn/com/cmm/interceptor/InterceptorHandler.java
--- src/main/java/itn/com/cmm/interceptor/InterceptorHandler.java
+++ src/main/java/itn/com/cmm/interceptor/InterceptorHandler.java
@@ -16,136 +16,137 @@
 import itn.com.cmm.LoginVO;
 import itn.com.cmm.util.XssFilterUtil;
 
-public class InterceptorHandler extends HandlerInterceptorAdapter{
+public class InterceptorHandler extends HandlerInterceptorAdapter {
 
-	@Override
+    @Override
     public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
-		
-		//SameSite 설정하기
-		addSameSite(response , "None");
-		
-    	/**
-    	 * URL 호출 전 넘어오는 파라미터 체크
-    	 * request로 넘어오는 모든 파라미터 데이터를 검사하여 XSS 문자가 포함되어 있으면 메인화면으로 튕김
-    	 * */
-    	boolean returnSts1 = true;
-    	Enumeration e = request.getParameterNames();
-		while ( e.hasMoreElements() ){
-			String name = (String) e.nextElement();
-			System.out.println("@@@@     "+name.toLowerCase());
-			if(!name.toLowerCase().contains("url") 
-				&& !name.toLowerCase().contains("pagetype")
-				&& !name.toLowerCase().contains("searchsortcnd")
-				&& !name.toLowerCase().contains("imgfilepath")
-				&& !name.toLowerCase().contains("msgpreview")
-				&& !name.toLowerCase().contains("smstxtarea")
-				&& !name.toLowerCase().contains("smstxt")
-				&& !name.toLowerCase().contains("rep1list")
-				&& !name.toLowerCase().contains("rep2list")
-				&& !name.toLowerCase().contains("rep3list")
-				&& !name.toLowerCase().contains("rep4list")
-				&& !name.toLowerCase().contains("namelist")
-				&& !name.toLowerCase().contains("memolist")
-				&& !name.toLowerCase().contains("info1list")
-				&& !name.toLowerCase().contains("info2list")
-				&& !name.toLowerCase().contains("info3list")
-				&& !name.toLowerCase().contains("info4list")
-				&& !name.toLowerCase().contains("nttcn")
-				&& !name.toLowerCase().contains("ci")
-				&& !name.toLowerCase().contains("certdi")
-				&& !name.toLowerCase().contains("di")
-				&& !name.toLowerCase().contains("mbldn")
-				&& !name.toLowerCase().contains("mberid")
-				&& !name.toLowerCase().contains("userid")
-				&& !name.toLowerCase().contains("id_text")
-				&& !name.toLowerCase().contains("mberemailadres")
-				&& !name.toLowerCase().contains("recommendid")
-				&& !name.toLowerCase().contains("mbernm")
-				&& !name.toLowerCase().contains("varvallist")
-				&& !name.toLowerCase().contains("templatecontent")
-				&& !name.toLowerCase().contains("buttonvolist")
-			) {	
-				//파라미터 중에 URL 주소를 넘겨주는 부분이 있어서 해당 부분에것 select~, update~, delete~ 로 시작하는 주소경로가 있어서 제외처리를 하였음
-				String[] values = request.getParameterValues(name);
-				
-				//HTML 태그 관련 부분이 들어있으면 필터링 해주는 정규식 <> ~ </> 구문 찾아줌
-				//Pattern regex = Pattern.compile("<(/)?([a-zA-Z]*)(\\\\s[a-zA-Z]*=[^>]*)?(\\\\s)*(/)?>");
-				//23.7.18 이지우 - XSS 필터링을 위한 정규식 수정
-				Pattern regex = Pattern.compile("<[^ㄱ-ㅎㅏ-ㅣ가-힣<>]+>");
-				for (String value : values) {
-					
-					//정규식과 동일한 패턴인지 비교해준다.
-					Matcher matcher = regex.matcher(value);
-					boolean rsltMatch = matcher.find();
-					
-					//패턴이 일치하면 오류 발생
-					if(rsltMatch) {
-						
-						returnSts1 = false;
-						System.out.println("+++++++++++++++++++++++++++XSS Html 필터 처리 Filter Start::: ");
-						System.out.println("name="+ name + ", value="+ value);
-						System.out.println("+++++++++++++++++++++++++++XSS Html 필터 처리 Filter End::: ");
-						response.sendRedirect(request.getContextPath() + "/");
-						
-					}
-					
-					boolean returnSts = XssFilterUtil.cleanXSS(value);
-					if(!returnSts) {//XSS 문자 체크 결과 false일 경우 메인화면으로 이동
-						returnSts1 = returnSts;
-						System.out.println("+++++++++++++++++++++++++++XSS 필터 처리 Filter::: ");
-						System.out.println("name="+ name + ", value="+ value);
-						System.out.println("+++++++++++++++++++++++++++XSS 필터 처리 Filter End::: ");
-						response.sendRedirect(request.getContextPath() + "/");
-					}
-				}   
-			}
-		}
-		
-		if(!returnSts1) {//XSS 포함문자가 있는경우 메인화면으로 이동시킨다.
-			response.sendRedirect(request.getContextPath() + "/");
-			return true;
-		}
-		
-		//관리자 페이지 로그인 후 사용자 페이지 접근시 로그아웃 처리_220421_이준호
-		HttpSession session = request.getSession();
-		LoginVO loginVO = (LoginVO) session.getAttribute("LoginVO");
-		if(
-			!request.getServletPath().contains("/utl/wed/imageSrc.do")
-			&& !request.getServletPath().contains("/utl/wed/insertImage.do")
-			&& !request.getServletPath().contains("/cmm/fms/getImage2.do")
-				) {
-			if(loginVO != null) {
-				if("USR".equals(loginVO.getUserSe())) {
-					request.getSession().invalidate();
-					response.sendRedirect(request.getContextPath() + "/");
-					return true;
-				}
-			}
-		}
-    	
+
+        //SameSite 설정하기
+        addSameSite(response, "None");
+
+        /**
+         * URL 호출 전 넘어오는 파라미터 체크
+         * request로 넘어오는 모든 파라미터 데이터를 검사하여 XSS 문자가 포함되어 있으면 메인화면으로 튕김
+         * */
+        boolean returnSts1 = true;
+        Enumeration e = request.getParameterNames();
+        while (e.hasMoreElements()) {
+            String name = (String) e.nextElement();
+            System.out.println("@@@@     " + name.toLowerCase());
+            if (!name.toLowerCase().contains("url")
+                    && !name.toLowerCase().contains("pagetype")
+                    && !name.toLowerCase().contains("searchsortcnd")
+                    && !name.toLowerCase().contains("imgfilepath")
+                    && !name.toLowerCase().contains("msgpreview")
+                    && !name.toLowerCase().contains("smstxtarea")
+                    && !name.toLowerCase().contains("smstxt")
+                    && !name.toLowerCase().contains("rep1list")
+                    && !name.toLowerCase().contains("rep2list")
+                    && !name.toLowerCase().contains("rep3list")
+                    && !name.toLowerCase().contains("rep4list")
+                    && !name.toLowerCase().contains("namelist")
+                    && !name.toLowerCase().contains("memolist")
+                    && !name.toLowerCase().contains("info1list")
+                    && !name.toLowerCase().contains("info2list")
+                    && !name.toLowerCase().contains("info3list")
+                    && !name.toLowerCase().contains("info4list")
+                    && !name.toLowerCase().contains("nttcn")
+                    && !name.toLowerCase().contains("ci")
+                    && !name.toLowerCase().contains("certdi")
+                    && !name.toLowerCase().contains("di")
+                    && !name.toLowerCase().contains("mbldn")
+                    && !name.toLowerCase().contains("mberid")
+                    && !name.toLowerCase().contains("userid")
+                    && !name.toLowerCase().contains("id_text")
+                    && !name.toLowerCase().contains("mberemailadres")
+                    && !name.toLowerCase().contains("recommendid")
+                    && !name.toLowerCase().contains("mbernm")
+                    && !name.toLowerCase().contains("varvallist")
+                    && !name.toLowerCase().contains("templatecontent")
+                    && !name.toLowerCase().contains("buttonvolist")
+            ) {
+                //파라미터 중에 URL 주소를 넘겨주는 부분이 있어서 해당 부분에것 select~, update~, delete~ 로 시작하는 주소경로가 있어서 제외처리를 하였음
+                String[] values = request.getParameterValues(name);
+
+                //HTML 태그 관련 부분이 들어있으면 필터링 해주는 정규식 <> ~ </> 구문 찾아줌
+                //Pattern regex = Pattern.compile("<(/)?([a-zA-Z]*)(\\\\s[a-zA-Z]*=[^>]*)?(\\\\s)*(/)?>");
+                //23.7.18 이지우 - XSS 필터링을 위한 정규식 수정
+                Pattern regex = Pattern.compile("<[^ㄱ-ㅎㅏ-ㅣ가-힣<>]+>");
+                for (String value : values) {
+
+                    //정규식과 동일한 패턴인지 비교해준다.
+                    Matcher matcher = regex.matcher(value);
+                    boolean rsltMatch = matcher.find();
+
+                    //패턴이 일치하면 오류 발생
+                    if (rsltMatch) {
+
+                        returnSts1 = false;
+                        System.out.println("+++++++++++++++++++++++++++XSS Html 필터 처리 Filter Start::: ");
+                        System.out.println("name=" + name + ", value=" + value);
+                        System.out.println("+++++++++++++++++++++++++++XSS Html 필터 처리 Filter End::: ");
+                        response.sendRedirect(request.getContextPath() + "/");
+
+                    }
+
+                    boolean returnSts = XssFilterUtil.cleanXSS(value);
+                    if (!returnSts) {//XSS 문자 체크 결과 false일 경우 메인화면으로 이동
+                        returnSts1 = returnSts;
+                        System.out.println("+++++++++++++++++++++++++++XSS 필터 처리 Filter::: ");
+                        System.out.println("name=" + name + ", value=" + value);
+                        System.out.println("+++++++++++++++++++++++++++XSS 필터 처리 Filter End::: ");
+                        response.sendRedirect(request.getContextPath() + "/");
+                    }
+                }
+            }
+        }
+
+        if (!returnSts1) {//XSS 포함문자가 있는경우 메인화면으로 이동시킨다.
+            response.sendRedirect(request.getContextPath() + "/");
+            return true;
+        }
+
+        //관리자 페이지 로그인 후 사용자 페이지 접근시 로그아웃 처리_220421_이준호
+        HttpSession session = request.getSession();
+        LoginVO loginVO = (LoginVO) session.getAttribute("LoginVO");
+        if (
+                !request.getServletPath().contains("/utl/wed/imageSrc.do")
+                        && !request.getServletPath().contains("/utl/wed/insertImage.do")
+                        && !request.getServletPath().contains("/cmm/fms/getImage2.do")
+                        && !request.getServletPath().contains("/cmm/fms/getImage.do")
+        ) {
+            if (loginVO != null) {
+                if ("USR".equals(loginVO.getUserSe())) {
+                    request.getSession().invalidate();
+                    response.sendRedirect(request.getContextPath() + "/");
+                    return true;
+                }
+            }
+        }
+
         return true;
     }
-    
-	/*
-	 * view 화면으로 데이터가 넘어가기 이전에 실행
-	 * modelAndView 값을 체크할 수 있음
-	 * */
+
+    /*
+     * view 화면으로 데이터가 넘어가기 이전에 실행
+     * modelAndView 값을 체크할 수 있음
+     * */
     @Override
     public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
         super.postHandle(request, response, handler, modelAndView);
     }
-    
+
     /*
-     * 
+     *
      * view에서 모든 처리를 완료한 후에 실행
      * */
     @Override
     public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
         super.afterCompletion(request, response, handler, ex);
     }
-    
+
     private void addSameSite(HttpServletResponse response, String sameSite) {
-    	
+
         Collection<String> headers = response.getHeaders(HttpHeaders.SET_COOKIE);
         boolean firstHeader = true;
         for (String header : headers) { // there can be multiple Set-Cookie attributes
@@ -156,7 +157,7 @@
             }
             response.addHeader(HttpHeaders.SET_COOKIE, String.format("%s; Secure; %s", header, "SameSite=" + sameSite));
         }
-        
+
     }
-	
+
 }
src/main/java/itn/com/cmm/web/EgovImageProcessController.java
--- src/main/java/itn/com/cmm/web/EgovImageProcessController.java
+++ src/main/java/itn/com/cmm/web/EgovImageProcessController.java
@@ -7,6 +7,7 @@
 import java.util.Map;
 
 import javax.annotation.Resource;
+import javax.servlet.ServletOutputStream;
 import javax.servlet.http.HttpServlet;
 import javax.servlet.http.HttpServletResponse;
 
@@ -60,99 +61,79 @@
 	 * @param response
 	 * @throws Exception
 	 */
-	@SuppressWarnings("resource")
 	@RequestMapping("/cmm/fms/getImage.do")
 	public void getImageInf(SessionVO sessionVO, ModelMap model, @RequestParam Map<String, Object> commandMap, HttpServletResponse response) throws Exception {
 
 		String atchFileId = (String) commandMap.get("atchFileId");
 		String fileSn = (String) commandMap.get("fileSn");
 		String isThumbFile = (String) commandMap.get("isThumbFile");
-		
-		FileVO vo = new FileVO();
-
-		vo.setAtchFileId(atchFileId);
-		vo.setFileSn(fileSn);
-
-		//------------------------------------------------------------
-		// fileSn이 없는 경우 마지막 파일 참조
-		//------------------------------------------------------------
-		if (fileSn == null || fileSn.equals("")) {
-			int newMaxFileSN = fileService.getMaxFileSN(vo);
-			vo.setFileSn(Integer.toString(newMaxFileSN - 1));
-		}
-		//------------------------------------------------------------
-		FileVO fvo = fileService.selectFileInf(vo);
-
-		String fileNm = fvo.getStreFileNm();
-		// 섬네일 이미지 경우
-		if (isThumbFile != null && ("thumbFile").equals(isThumbFile) && fvo.getThumbFileNm() != null) {
-			fileNm = fvo.getThumbFileNm();
-		}
-		
-		File file = new File(fvo.getFileStreCours(), fileNm);
-		
-		FileInputStream fis = null;
 		try {
-			new FileInputStream(file);
-		}catch(Exception e) {}
-		
-		BufferedInputStream in = null;
-		ByteArrayOutputStream bStream = null;
-		try {
-			fis = new FileInputStream(file);
-			in = new BufferedInputStream(fis);
-			bStream = new ByteArrayOutputStream();
-			int imgByte;
-			/*while ((imgByte = in.read()) != -1) {
-				bStream.write(imgByte);
-			}*/
-			
-			byte[] outputByte=new byte[104096];
-			while ((imgByte =in.read(outputByte, 0, 4096 )) > 0 ) {
-				bStream.write(outputByte,0,imgByte);
+			if (atchFileId == null || atchFileId.trim().isEmpty()) {
+				response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
+				return;
 			}
-			String type = "";
-			if (fvo.getFileExtsn() != null && !"".equals(fvo.getFileExtsn())) {
-				if ("jpg".equals(fvo.getFileExtsn().toLowerCase())) {
-					type = "image/jpeg";
-				} else {
-					type = "image/" + fvo.getFileExtsn().toLowerCase();
+
+			FileVO vo = new FileVO();
+			vo.setAtchFileId(atchFileId);
+			vo.setFileSn(fileSn);
+
+			//------------------------------------------------------------
+			// fileSn이 없는 경우 마지막 파일 참조
+			//------------------------------------------------------------
+			if (fileSn == null || fileSn.trim().isEmpty()) {
+				int newMaxFileSN = fileService.getMaxFileSN(vo);
+				if (newMaxFileSN <= 0) {
+					response.setStatus(HttpServletResponse.SC_NOT_FOUND);
+					return;
 				}
-				//type = "image/" + fvo.getFileExtsn().toLowerCase();
-
-			} else {
-				LOGGER.debug("Image fileType is null.");
+				vo.setFileSn(Integer.toString(newMaxFileSN - 1));
 			}
 
-			response.setHeader("Content-Type", type);
-			response.setContentLength(bStream.size());
-			bStream.writeTo(response.getOutputStream());
-			response.getOutputStream().flush();
-			response.getOutputStream().close();
+			FileVO fvo = fileService.selectFileInf(vo);
+			if (fvo == null) {
+				LOGGER.warn("이미지 파일 정보 없음: atchFileId={}, fileSn={}", atchFileId, vo.getFileSn());
+				response.setStatus(HttpServletResponse.SC_NOT_FOUND);
+				return;
+			}
+
+			String fileNm = fvo.getStreFileNm();
+			if ("thumbFile".equals(isThumbFile) && fvo.getThumbFileNm() != null
+					&& !fvo.getThumbFileNm().trim().isEmpty()) {
+				fileNm = fvo.getThumbFileNm();
+			}
+
+			File file = new File(fvo.getFileStreCours(), fileNm);
+			if (!file.isFile() || !file.canRead()) {
+				LOGGER.warn("이미지 파일 없음: atchFileId={}, fileSn={}, path={}",
+						atchFileId, vo.getFileSn(), file.getAbsolutePath());
+				response.setStatus(HttpServletResponse.SC_NOT_FOUND);
+				return;
+			}
+
+			String type = null;
+			if (fvo.getFileExtsn() != null && !fvo.getFileExtsn().trim().isEmpty()) {
+				String extension = fvo.getFileExtsn().toLowerCase();
+				type = "jpg".equals(extension) ? "image/jpeg" : "image/" + extension;
+			}
+
+			response.setContentType(type != null ? type : "application/octet-stream");
+			response.setContentLengthLong(file.length());
+
+			try (BufferedInputStream in = new BufferedInputStream(new FileInputStream(file))) {
+				ServletOutputStream out = response.getOutputStream();
+				byte[] buffer = new byte[8192];
+				int length;
+				while ((length = in.read(buffer)) != -1) {
+					out.write(buffer, 0, length);
+				}
+				out.flush();
+			}
 
 		} catch (Exception e) {
-			LOGGER.debug("{}", e);
-		} finally {
-			if (bStream != null) {
-				try {
-					bStream.close();
-				} catch (Exception est) {
-					LOGGER.debug("IGNORED: {}", est.getMessage());
-				}
-			}
-			if (in != null) {
-				try {
-					in.close();
-				} catch (Exception ei) {
-					LOGGER.debug("IGNORED: {}", ei.getMessage());
-				}
-			}
-			if (fis != null) {
-				try {
-					fis.close();
-				} catch (Exception efis) {
-					LOGGER.debug("IGNORED: {}", efis.getMessage());
-				}
+			LOGGER.error("이미지 조회 실패: atchFileId={}, fileSn={}", atchFileId, fileSn, e);
+			if (!response.isCommitted()) {
+				response.reset();
+				response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
 			}
 		}
 	}
Add a comment
List