[SPRING] ch02. SQL Injection - 방어

2017. 9. 21. 10:14·SKILL/Security
728x90
반응형

* 에러 페이지를 준비해서, DB 관련 오류 메세지가 브라우저에 노출되지 않도록 한다.a

/WEB-INF/web.xml (수정)

 <error-page>
        <error-code>500</error-code>
        <location>/error</location>
    </error-page>
</web-app>

 

 
MainController.java
 
package secure.ch02.ex01.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller("ch02.ex01.mainController")
public class MainController {    
    @RequestMapping("/error")
    public String error(){
        return "ch02/ex01/error";
    }
}
 
 
/WEB-INF/views/ch02/ex01/error.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
에러가 발생했습니다. <br>
<p><a href="/secure">메인으로</a></p>
 
실험
로그인 화면 ID란에 ' 입력 -> 에러 화면 출력, 화면에 더 이상 에러 메세지를 노출하지 않는다.
--
 
* STATIC SQL을 사용한다.
/WEB-INF/spring-servlet.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xmlns:mybatis="http://mybatis.org/schema/mybatis-spring"    
    xsi:schemaLocation="http://www.springframework.org/schema/mvc 
        http://www.springframework.org/schema/mvc/spring-mvc.xsd        
        http://www.springframework.org/schema/beans 
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context 
        http://www.springframework.org/schema/context/spring-context.xsd
        http://mybatis.org/schema/mybatis-spring
        http://mybatis.org/schema/mybatis-spring.xsd">
    <!-- ch01 -->
    <context:component-scan base-package="secure" />
    <mvc:annotation-driven />
    <bean
        class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/views/" />
        <property name="suffix" value=".jsp" />
    </bean>
    
    <bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
        <property name="jndiName" value="java:comp/env/jdbc/secure" />
        <property name="resourceRef" value="true" />
    </bean>
    
    <!-- ch02 -->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
    </bean> 
    <mybatis:scan base-package="secure.**.dao.mapper" />    
</beans>
 
 
User.java
 
package secure.ch02.ex01.domain;

public class User {
    private String userId;
    private String userPw;
    
    public String getUserId() {
        return userId;
    }
    public void setUserId(String userId) {
        this.userId = userId;
    }
    public String getUserPw() {
        return userPw;
    }
    public void setUserPw(String userPw) {
        this.userPw = userPw;
    }
}
 
LoginMapper.java
 
package secure.ch02.ex01.dao.mapper;

import org.apache.ibatis.annotations.Select;
import secure.ch02.ex01.domain.User;

public interface LoginMapper {
    @Select("select count(user_id) from users where user_id=#{userId} and user_pw=#{userPw}")
    int getUserCnt(User user);
}
 
LoginDao.java
 
package secure.ch02.ex01.dao;

import secure.ch02.ex01.domain.User;

public interface LoginDao {
    public int getUserCnt(User user) throws Exception;
}
 
 
 
LoginDaoImpl.java
 
package secure.ch02.ex01.dao;

import java.sql.SQLException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import secure.ch02.ex01.domain.User;
import secure.ch02.ex01.dao.mapper.LoginMapper;

@Repository("ch02.ex01.loginDao")
public class LoginDaoImpl implements LoginDao {
    @Autowired private LoginMapper loginMapper;
    
    public int getUserCnt(User user) throws SQLException{
        return loginMapper.getUserCnt(user);
    }
}
 
LoginService.java
 
package secure.ch02.ex01.service;

import secure.ch02.ex01.domain.User;

public interface LoginService {
    public boolean authUser(User user) throws Exception;
}
 
 
LoginServiceImpl.java
package secure.ch02.ex01.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import secure.ch02.ex01.dao.LoginDao;
import secure.ch02.ex01.domain.User;

@Service("ch02.ex01.loginService")
public class LoginServiceImpl implements LoginService{
    @Autowired private LoginDao loginDao;
    
    public boolean authUser(User user) throws Exception{
        return loginDao.getUserCnt(user)>0;
    }
}
 
 
LoginController.java
 
package secure.ch02.ex01.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import secure.ch02.ex01.domain.User;
import secure.ch02.ex01.service.LoginService;

@Controller("ch02.ex01.loginController")
@RequestMapping("/ch02/ex01/login")
public class LoginController {
    @Autowired private LoginService loginService;    
    
    @RequestMapping(method=RequestMethod.GET)
    public String login(){
        return "ch02/ex01/loginIn";
    }
    
    @RequestMapping(method=RequestMethod.POST)    
    public String authUser(User user, Model model) throws Exception{
        model.addAttribute("isLogin", loginService.authUser(user));
        return "ch02/ex01/loginOut";
    }
}
 
 
 
/WEB-INF/views/ch02/ex01/loginIn.jsp
 
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<title>로그인</title>
<form method="post">
    <input type="text" name="userId" placeholder="아이디"><br>
    <input type="text" name="userPw" placeholder="암호"><br><br>
    <button type="submit">제출</button>
</form>
<p><a href="/secure">메인으로</a></p>
 
 
/WEB-INF/views/ch02/ex01/loginOut.jsp
 
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<title>로그인 결과</title>
${isLogin?"로그인 성공":"로그인 실패"}
<p><a href="xxxxxxxxxxxxjavascript:history.back();">돌아가기</a></p>
 
 
실험
로그인 화면에서, 아이디에 ' or 1=1 -- 를 입력한 뒤 제출하면, 인증 우회되지 않고, 에러 화면으로 이동한다.
--
 
SQLFilter.java
 
package secure.ch02.ex02.controller;

import java.util.regex.Pattern;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@Controller
@RequestMapping("/ch02/ex02/sql")
public class SQLFilter {
    @RequestMapping(method=RequestMethod.GET)
    public void main(){}
    
    @RequestMapping(method=RequestMethod.POST)
    public void main(String inStr, Model model){
        Pattern pattern = Pattern.compile("['\\-#();=*/+]");
        inStr = pattern.matcher(inStr).replaceAll("");        
        
        inStr = inStr.toLowerCase();
        inStr = inStr.replaceAll("union", "q-union")
                .replaceAll("select", "q-select")
                .replaceAll("insert", "q-insert")
                .replaceAll("update", "q-update")
                .replaceAll("delete", "q-delete")
                .replaceAll("drop", "q-drop")
                .replaceAll("and", "q-and")
                .replaceAll("or", "q-or")
                .replaceAll("join", "q-join")
                .replaceAll("substr", "q-substr")
                .replaceAll("where", "q-where")
                .replaceAll("declare", "q-declare")                
                .replaceAll("user_tables", "q-user_tables")
                .replaceAll("user_tab_columns", "q-user_tab_columns")
                .replaceAll("table_name", "q-table_name")
                .replaceAll("column_name", "q-column_name")
                .replaceAll("row_num", "q-row_num");
        model.addAttribute("inStr", inStr);
        System.out.println("ch02.ex02: " + inStr);
    }
}
 

 

/WEB-INF/views/ch02/ex02/sql.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<form method="post">
    <input type="text" size="50" name="inStr"><br><br>
    <button type="submit">제출</button>
</form>
<br>
${inStr}
 

 

실험

입력란에, select * from users where 1=1 -- 를 입력한 뒤, 제출한다.

728x90
반응형

'SKILL > Security' 카테고리의 다른 글

LETSENCRYPT 에서 SSL 인증서를 무료로 발급 받아 웹 서버에 적용하기  (0) 2018.05.17
SSL 보안 인증서 발급 - CSR 발급  (0) 2018.05.17
[SPRING] ch04. 로그인  (0) 2017.09.21
[SPRING] ch03. OS 명령어  (0) 2017.09.21
[SPRING] ch01.SQL Injection - 공격  (0) 2017.09.21
'SKILL/Security' 카테고리의 다른 글
  • SSL 보안 인증서 발급 - CSR 발급
  • [SPRING] ch04. 로그인
  • [SPRING] ch03. OS 명령어
  • [SPRING] ch01.SQL Injection - 공격
밍글링글링
밍글링글링
mingling - 밍글링, 밍글밍글링. 코드와 어우러지다. IT/ 프로그래밍/소스
    반응형
    250x250
  • 밍글링글링
    mingling
    밍글링글링
  • 전체
    오늘
    어제
    • 밍글링글링 (407) N
      • Flutter (2)
      • 일상생활 (8)
        • 리뷰 (1)
        • 생활정보 (4)
        • 맛집 (0)
        • 여행 (0)
        • 모든정보 (3)
      • JAVA (126)
        • 개념 (6)
        • 예제 (115)
        • Exception (2)
      • C (1)
        • C (1)
        • C++ (0)
        • C# (0)
      • JS (29)
        • JavaScript (18)
        • JQuery (5)
        • AJax (0)
        • NODE.JS (6)
        • Angular.JS 2.0 (0)
      • WEB (87)
        • HTML (6)
        • CSS (61)
        • JSP (20)
        • JSTL (0)
      • FrameWork (8)
        • Spring (8)
        • BootStrap (0)
        • MyBATIS (0)
        • JUnit (0)
      • 외부 라이브러리 (5)
      • 공유 소스 관리 (5)
        • Git (5)
        • SVN (0)
      • 빅데이터 프로그래밍 (37)
        • Python (37)
        • R Programming (0)
      • DB (7)
        • ORACLE (0)
        • MySql (6)
      • Development Tools (7)
        • StarUML (0)
        • eXERD (0)
        • Eclipse (4)
      • SKILL (6)
        • Migration (0)
        • Security (6)
      • MicroSoft (0)
        • Excel (0)
        • Word (0)
      • Android (0)
      • Server (21)
        • Ubuntu (5)
        • Linux (15)
      • IOS (0)
      • XML (0)
      • 미디어 (0)
      • 공지사항 (3)
      • NETWORK (1)
      • 게임 (4)
        • 피파 (1)
        • 리니지M (0)
        • 배틀그라운드 (1)
        • 듀랑고 (2)
      • 세상 이슈 (6)
      • 일렉트론 (0)
      • 대회 소식 (4)
      • 업무 (2)
      • Express, Vue (6)
      • docker (11)
      • svelte (3)
      • 블록체인 (1)
      • IT (10) N
      • Rust (0)
  • 블로그 메뉴

    • 홈
    • 태그
    • 미디어로그
    • 위치로그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    API 설계
    mysql db
    css perspective
    proxy pass
    자바 for문
    jsp include
    nginx ssl 설정
    nginx ssl 적용
    프런트엔드
    css transition
    Rust lang
    리눅스 설치
    lang rust
    ubuntu
    servlet class
    브라우저 자동화
    Node
    css block
    svelte
    자바 배열
    에디터 팁
    자바 생성자
    클론코딩
    docker
    vscode
    SSL 인증서
    java casting
    css tb
    css table
    Extension Bisect
    자바 객체 지향
    VS Code 팁
    rust linux
    자바 클래스
    css float
    gitlab 설치
    AI 코딩 에이전트
    자바 exception
    티스토리 자동화
    vue 설치
    Java Array
    jsp parameter
    러스트
    spring java
    css list
    vue cli
    오류
    nginx
    React Compiler
    ssl 인증서 발급
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.6
밍글링글링
[SPRING] ch02. SQL Injection - 방어
상단으로

티스토리툴바