상세 컨텐츠

본문 제목

JSP웹보안 3대 취약점

JSP·자바·코틀린

by 김일국 2015. 8. 12. 18:56

본문

지난번 PHP웹 5대 취약점 글에 이어서 JSP웹 3대 취약점을 적어 봅니다.

소스 진행은 join.jsp -> moving.jsp 로 폼전송시 처리 방법 입니다.

 

********** join.jsp 스트럿츠2소스 입니다. 하지만, 일반 JSP 폼전송에도 같은 방식을 적용하게 됩니다.

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<%@ taglib prefix="s" uri="/struts-tags" %>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<div style="margin:0 auto">
 <h1>회원 정보</h1>
 <h2>${fieldErrors.result} ${actionErrors}</h2>
 <form name='join' action='join/join.action' method='post'>
 아이디 : <s:textfield name='id' size='10' maxlength='8'/><br>
 이름 : <s:textfield name='name' size='8' maxlength='6'/><br>
 전화번호 : <s:textfield name='tel' size='17' maxlength='15'/><br>
 <input type='submit' value='회원가입'>
 <input type='reset' value='취소'>   
 </form>
 <h6>아이디 길이는 4자이상 6자이하 입력</h6>
 
 <form name="frm1" action="/struts_test/move.action" method="post">
  이름 <input type="text" name="name1">
  암호 <input type="password" name="pwd1">
  <input type="submit" value="로그인">
 </form>
 
 <form name="frm2" action="/struts_test/redirect.action" method="post">
  이름 <input type="text" name="name2">
  암호 <input type="password" name="pwd2">
  <input type="submit" value="Login">
 </form>
</div>
</body>
</html>

 

***** moving.jsp ( 내용중 XSS 크로스사이드스크립팅 공격방어 , sql injection 공격방어 , 폼변조 공격방어 부분에서 방어 합니다.

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<%!
public String XSS(String content) {
 //XSS 크로스사이드스크립팅 공격방어 -예,<script>alert("a");</script>
 content = content.replaceAll("<","<");    // 태그를 무력화시킵니다.
 content = content.replaceAll(">",">");     // 이렇게 바꾸게되면 코드가 실행되지 않고 그대로 출력됩니다.
 // 개행이나 문단정렬에 관련된 html태그는 허용해줍니다.
 content = content.replaceAll("<p>","<p>");
 content = content.replaceAll("<P>","<P>");
 content = content.replaceAll("<br>","<br>");
 content = content.replaceAll("<BR>","<BR>");
 return content;
}
public boolean Injection(String content) {
 //sql injection 공격방어 -예,asdf' or 1=1 --'
 boolean result = false;
 if(content.indexOf("\'") > 0) result = true;
 return result;
}
%>
<%  //폼변조 공격방어 -예, 폼전송방식을 GET방식으로 변조 방지 + 헤더값 없는 로컬PC전송 방지
 if(request.getMethod()!="POST" || request.getHeader("referer") == null){
 out.println("<script type='text/javascript'>");
 out.println("alert('잘못된 접근 입니다.');window.location.replace('"+request.getHeader("referer")+"')");
 out.println("</script>");
 out.println("잘못된 접근 입니다.");
 out.println("<a href='"+request.getHeader("referer")+"'>홈으로</a>");
 out.close();
 return;
}

//디버그 out.println(request.getMethod() + request.getHeader("referer"));
String p1 = request.getParameter("name1"); //getter,setter방식으로 변환시 request.getAttribute("name1");
String p2 = request.getParameter("pwd1");

if(Injection(p1) || Injection(p2) ){
 out.println("<script type='text/javascript'>");
 out.println("alert('잘못된 접근 입니다.');window.location.replace('"+request.getHeader("referer")+"')");
 out.println("</script>");
 out.println("잘못된 접근 입니다.");
 out.println("<a href='"+request.getHeader("referer")+"'>홈으로</a>");
 out.close();

return;
}
%>
 <% out.println(XSS(p1)); %>
 <% out.print(XSS(p2)); %>
</body>
</html>

관련글 더보기

댓글 영역