'jsp'에 해당되는 글 2건
JAVA/JSP SQL Injection 해킹 방지를 위한 코딩
Java 2011. 11. 16. 00:32
SQL Injection 은 사용자가 요상한 문자열을 입력해서 쿼리를 요상하게 바꿔 버려서 아무 아이디로나 로그인이 훅 되버린다던지 하는 쪼금은 싱거운 해킹방법중의 하나라고 나는 알고 있다.
뭐 예를들어 아이디 비번을 입력하고 로그인 할때
아이디로 admin' OR '1'='1 요런걸 입력하고 로그인을 했을때 admin 으로 싹 로그인 되 버리는 어처구니 없는 일이 발생하는 것이 SQL Injection 처리를 쪽바로 해주지 않았을때 일어나는 참혹한 일이다.
SQL Injection 이 발생하는 전형적인 코드는 다음과 같다.
String userid=request.getParameter("userid"); String password=request.getParameter("password"); .... .... Statement stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery("select count(*) as cnt from member where userid='"+userid+"' and password='"+password+"'"); .... ....
위 코드처럼 사용자 정보를 받아서 쿼리를 실행하고 실행결과가 1 이면 로그인 시켜주는 코드가 있다.
그런데 사용자가 아디디로 admin' OR '1'='1 을 입력하고 비밀번호로 abcd 를 입력한 후 로그인 시켜주셈~ 이라고 하면 우째될까?
위 코드대로라면 select count(*) from member where userid='amdin' OR '1'='1' and password = 'abcd' 이 쿼리가 실행되 버린다 -_-;;;
무섭다. 만약 사용자 테이블에 userid 가 admin 이라는 레코드가 있다면 admin 으로 로그인 되버리는 것이다.
이런 어처구니 없는일이 놀랍게도 몇몇 허접한 사이트에서는 더러 통하는데도 있다 . -_-
아무튼 헛소리는 고만하고 본론으로 들어가서 SQL Injection 을 방지하려면 우째해야 될까?
Statement 대신 PreparedStatement 를 쓰면 된다. 요렇게.
.... .... PreparedStatement stmt = conn.prepareStatement("select count(*) from member where userid=? and password=?"); stmt.setString(1, userid); stmt.setString(2, password); ResultSet rs = stmt.executeQuery(); .... ....
PreparedStatement 만 쓰면 해결된다고 해서 또 요렇게는 쓰지 말길 -.-;
PreparedStatement stmt = conn.prepareStatement("select count(*) from member where userid='" + userid + "'" and password='" + password + "'");
※ 하이버네이트는 한번도 안써봐서 잘 모르겠는데 mybatis 나 ibatis 같은 경우는 무난하게 #{xxxx} 요런것만 썼다면 SQL Injection 이 방지된다.
그런데 WHERE 절에 ${xxxx} 이렇게 있다면 다시 한번 생각해 보기 바란다.
${xxxx} 이거는 문자열 더하는것과 똑같기 때문에 위험하다. ${xxxx} 요런건 ORDER BY 절 같은데만 사용하자.
2011/10/26 - [maven] - maven 으로 executable jar 맨들기(maven-jar-plugin, maven-dependency-plugin 이용)
2011/10/25 - [mybatis] - mybatis Oracle Procedure 호출하기
2011/10/12 - [mybatis] - mybatis 쿼리, 쿼리결과 로깅을 위한 log4j.xml 설정
2011/10/10 - [Java] - Runtime 에 jar 파일 클래스패스에 추가 시키기 : RuntimeJarLoader
2011/08/22 - [Java] - mybatis 에서 Oracle LONG, CLOB Select 시 에러날때 : getCLOB not implemented for class oracle.jdbc.driver.XXX
2011/08/19 - [Java] - Java JSON 처리 라이브러리 Jackson JSON Processor #2 : Map, List <--> JSON String 상호변환
2011/10/25 - [mybatis] - mybatis Oracle Procedure 호출하기
2011/10/12 - [mybatis] - mybatis 쿼리, 쿼리결과 로깅을 위한 log4j.xml 설정
2011/10/10 - [Java] - Runtime 에 jar 파일 클래스패스에 추가 시키기 : RuntimeJarLoader
2011/08/22 - [Java] - mybatis 에서 Oracle LONG, CLOB Select 시 에러날때 : getCLOB not implemented for class oracle.jdbc.driver.XXX
2011/08/19 - [Java] - Java JSON 처리 라이브러리 Jackson JSON Processor #2 : Map, List <--> JSON String 상호변환
'Java' 카테고리의 다른 글
xpath 를 이용, java 에서 xml 문서 쉽게 파싱하기 (5) | 2011.11.23 |
---|---|
재귀함수(Recursive funtion)을 이용한 특정 폴더 아래의 모든 파일정보 읽어서 출력하기 (0) | 2011.11.16 |
Java Map 반복(Iteration)시키는 3가지 방법 (5) | 2011.11.13 |
디폴트 패키지에 있는 자바 class 실행하기 ( Could not find the main class 에러날때 ) (1) | 2011.11.09 |
WAS(Tomcat 또는 기타등등~) 메모리 사용현황 모니터링 JSP (3) | 2011.10.18 |
ContentNegotiatingViewResolver 활용 : 하나의 RequestMapping 으로 JSP, JSON, JSONP 처리하기
Spring 2011. 8. 19. 19:28
뭔가를 맨들다 보면 데이터를 가져와서 대부분 JSP 를 이용해서 랜더링을 하게 되지만 똑같은 데이터를 ajax 호출을 통해 json 형식으로 받고 싶은 경우도 종종 있다.
그리고 JSONP 형식으로 같은 도메인이 아닌 다른 도메인으로 데이터를 제공하고 싶은 경우도 있다.
고럴때 ContentNegotiatingViewResolver 를 활용하면 하나의 리퀘스트 핸들러를 맹글어 놓고 맨 뒤에 URL 만 살짝 바꾸면 URL 에 따라 다른 View 를 이용해서 랜더링 시킬 수 있다.
예를 들어
http://127.0.0.1:8080/test/view 요럴땐 jsp 로 랜더링
http://127.0.0.1:8080/test/view.json 요럴땐 json 형식으로 랜더링
http://127.0.0.1:8080/test/view.jsonp 요럴땐 jsonp 형식으로 랜더링~
또 약간의 노력을 더해주면 xml 형식이나 rss 형식으로도 랜더링 시킬 수 있다.
죠런 기능을 구현하기 위해서 ContentNegotiatingViewResolver 를 사용하도록 설정해 주고 필요에 따라 AbstractView 클래스를 구현해서 원하는 View를 맹글면 된다.
스프링 설정파일
stove99.views.JSONPView 클래스 소스
컨트롤러 소스
테스트 결과 화면
그리고 JSONP 형식으로 같은 도메인이 아닌 다른 도메인으로 데이터를 제공하고 싶은 경우도 있다.
고럴때 ContentNegotiatingViewResolver 를 활용하면 하나의 리퀘스트 핸들러를 맹글어 놓고 맨 뒤에 URL 만 살짝 바꾸면 URL 에 따라 다른 View 를 이용해서 랜더링 시킬 수 있다.
예를 들어
http://127.0.0.1:8080/test/view 요럴땐 jsp 로 랜더링
http://127.0.0.1:8080/test/view.json 요럴땐 json 형식으로 랜더링
http://127.0.0.1:8080/test/view.jsonp 요럴땐 jsonp 형식으로 랜더링~
또 약간의 노력을 더해주면 xml 형식이나 rss 형식으로도 랜더링 시킬 수 있다.
죠런 기능을 구현하기 위해서 ContentNegotiatingViewResolver 를 사용하도록 설정해 주고 필요에 따라 AbstractView 클래스를 구현해서 원하는 View를 맹글면 된다.
스프링 설정파일
<bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver"> <!-- ViewResolver 우선순위 설정 --> <property name="order" value="1" /> <property name="mediaTypes"> <!-- 맵핑될 확장자 정의 --> <map> <entry key="json" value="application/json" /> <entry key="jsonp" value="javascript/jsonp" /> </map> </property> <property name="defaultViews"> <list> <!-- JSON 요청을 처리할 뷰 --> <bean class="org.springframework.web.servlet.view.json.MappingJacksonJsonView"/> <!-- JSONP 요청을 처리할 뷰 --> <bean class="stove99.views.JSONPView"> <property name="contentType" value="javascript/jsonp"/> </bean> </list> </property> <property name="ignoreAcceptHeader" value="true" /> </bean> <!-- 맵핑되는 확장자가 없을때 JSP 로 뷰 처리 --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="order" value="2" /> <property name="prefix" value="/WEB-INF/views/"/> <property name="suffix" value=".jsp"/> </bean>mediaTypes에 정의된 entry 들은 URL 맨 뒤에 붙은 확장자와 mediaType 을 설정한다. 여기에서 설정된 mediaType 정보를 바탕으로 아래쪽 defaultViews 목록에 정의된 View 들 중에서 랜더링 가능한 View 를 찾아서 그 View 로 랜더링 시킨다. 뭐 설명이 허접하긴 하지만 내가 이해한 바로는 그렇다.
stove99.views.JSONPView 클래스 소스
package stove99.views; import java.io.Writer; import java.util.Map; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.codehaus.jackson.map.ObjectMapper; import org.springframework.web.servlet.view.AbstractView; public class JSONPView extends AbstractView{ @Override protected void renderMergedOutputModel(Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) throws Exception { String callback = request.getParameter("callback"); ObjectMapper om = new ObjectMapper(); String json = om.writeValueAsString(model); Writer out = response.getWriter(); out.append(callback).append("(").append(json).append(")"); } }
컨트롤러 소스
package stove99.controller; import java.util.HashMap; import java.util.Map; import org.springframework.stereotype.Controller; import org.springframework.ui.ModelMap; import org.springframework.web.bind.annotation.RequestMapping; @Controller @RequestMapping("/test/*") public class TestController { @RequestMapping public void view(ModelMap model) { Map<String, String> data = new HashMap<String, String>(); data.put("data1", "value1"); data.put("data2", "value2"); data.put("data3", "value3"); model.addAttribute("model", data); } }
테스트 결과 화면
ContentNegotiatingViewResolverTest.war
'Spring' 카테고리의 다른 글
Spring @ResponseBody 로 리턴시 한글이 깨질때 (0) | 2013.04.16 |
---|---|
<util:properties/> 와 Spring EL 로 값 가져오기 (0) | 2013.04.12 |
Spring 개발시 개발, 운영환경 프로퍼티 파일 관리하기 (1) | 2011.10.11 |
bean property 간단하게 설정하기 : http://www.springframework.org/schema/p 활용 (1) | 2011.08.22 |
<context:property-placeholder/> 를 사용할때 property file의 encoding 지정하기 (0) | 2011.08.03 |