SQL 삽입
DB와 연동된 웹 응용프로그램에서 입력된 데이터에 대한 유효성을 검증을 하지 않을경우 발생할 수 있는 보안약점으로
공격자가 입력에 SQL문을 삽입하여 DB로부터 정보를 열람하거나 조작할 수 있는 보안 약점이다.
보안대책
1) 입력 검증
쿼리에 사용되는 외부 입력값에 대하여 특수문자 및 예약어를 필터링 한다.
스프링과 같은 프레임워크 사용시 외부 보안모듈,검증모듈을 사용해야 한다.
2) Error Message 노출 금지
DB에러 발생시 쿼리문과 함꼐 에러 내용을 반환해 주는데 여기서 쿼리문,컬럼명 등의 내용이 노출 될 수 있다. 따라서
오류 발생 시 처리를 해주는 예외처리를 해주어 사용자에게 따로 메시지 박스를 띄우도록 해야한다.
3) preparedStatment 객체 사용
PreparedStatement객체 등을 이용해 DB에 컴파일 된 쿼리문을 전달하는 방법을 사용한다.
prepareStatement란
statement를 상속하고 있는 Interface로 구문 분석의 결과를 캐싱하여 과정을 생략할 수 있으므로 성능리 향상된다.
preparedStatement는 Statement와 다르게 Select * From member where Id = ? And password = ? 형식으로 작성되어 ?를 하나의 필드로 가져가기에 sql인젝션에 안전하다.
코드 예제
vulnerable code
//외부로붙 입력받은 값을 검증 없이 사용할 경우 안전하지 않다.
String gubun : request.getParameter("gubun");
String sql = "SELECT * FROM board WHERE b_gubun = "+gubun+"";
Conntection con = de.getConnection();
//외부로부터 입력받은 값이 검증 또는 처리 없이 쿼리로 수행되어 안전하지 않다.
ResultSet rs = stmt.executeQuery(sql);
safety code
String gubun = request.getParameter("gubun");
//사용자에 의해 외부로부터 입력받은 값은 안전하지 않을 수 있으므로, PreparedStatment사용을 위해? 문자로
바인딩 변수를 사용한다.
String sql = "SELCT * FRP< board WHERE b_gubun = ?";
Connenction con = db.getConnection();
// PreparedStatement 사용한다.
PreparedStatement pstmt = con.prepareStatement(sql);
//PreparedStatement 객체를 상수 스트링으로 생성하고, 파라미터 부분을 setString 등의 메소드로 설정하여 안전하다.
psmt.setString(1,gubun);
ResultSet rs = pstmt.executeQuery();
외부 입력값을 MyBatis 쿼립맴에 바인딩할 경우 $ 기호가 아닌 #기호를 사용해야 한다. $기호를 사용하는 경우 입력값을 문자열에 결합하는 형태로 쿼리문이 조작될 수 있다.
vulnerable code
<select id = "boardSearch" parameterType = "map" resultType = "BoardDto">
select * form tbl_board where title like '%'||${keyword}||'%' order by pos asc
</select>
safety code
<select id = "boardSearch" parameterType = "map" resultType = "BoardDto">
select * form tbl_board where title like '%'||#{keyword}||'%' order by pos asc
</select>
『소프트웨어 개발보안 가이드』, 행정안전부, 한국인터넷진흥원, 2021.
'시큐어 코딩' 카테고리의 다른 글
XSS Injection (0) | 2023.06.07 |
---|