'jdbc'에 해당되는 글 2건
- 2013.04.23 Mysql ssl 설정 & JDBC 로 SSL 통신 5
- 2011.11.16 JAVA/JSP SQL Injection 해킹 방지를 위한 코딩 5
Mysql ssl 설정 & JDBC 로 SSL 통신
그냥 쌩으로 쿼리 날리고 데이터 받으면 되지 왜 귀찮게시리 SSL 로 통신을 해야 되느냐..?
바로 요 이유 때문이다.
TCP 패킷 캡쳐프로그램으로 보면 select * from user where user='root' 라는 쿼리문장이 고대로 노출이 된다.
요렇게 되면 로그인할때 비밀번호가 들어간 쿼리도 노출이 된다는 뜻이다.
자~~ 요것을 해결해 보자!
먼저 mysql 서버쪽에서 ssl 접속을 허용하도록 설정을 해주야 된다.
그러기 위해선 인증서를 맹글어야 된다. 인증서에 대해선 자세히 나도 잘 모르기 때문에 대충~~ 개인키랑 공개키를 맨들어야 한다쯤으로 이해하고 넘어갔다.
아무튼 인증서를 맹글기 위해서는 openssl 이라는 프로그램을 설치해야 한다.
다 설치가 됬으면 커맨드 창을 열어 명령어를 입력해 인증서를 맹글면 된다.
개인키 맹글기
openssl genrsa -out key.pem 2048
공개키 맹글기
openssl req -new -x509 -key key.pem -out cert.pem -days 0
요렇게 하면 개인키 파일(key.pem)이랑 공개키 파일(cert.pem) 두개가 생성된다.
요 파일을 리눅스 서버일 경우 my.cnf 파일을, 윈도우서버에 깔린 mysql 일 경우 my.ini 파일을 편집해 설정을 추가해 주면 된다.
※ 우분투일 경우 일반적인 경로는 /etc/mysql/my.cnf
※ 윈도우일 경우 일반적인 경로는 C:\Program Files\MySQL\MySQL Server\my.ini
설정파일을 보면 [mysqld] 요런 섹션이 있을껀데 요 섹션 안에다 위에서 만든 인증서 파일을에 대해 아래와 같이 설정을 추가해 준다.
※ 위에서 생성한 key.pem 파일과 cert.pem 파일은 C 드라이브 cert 폴더에 있다고 가정.
ssl-ca=C:\\cert\\cert.pem ssl-cert=C:\\cert\\cert.pem ssl-key=C:\\cert\\key.pem
요런 설정을 해주고 mysql 서버를 리스탓트 하면 mysql을 SSL 로 접속할 수 있게 된다.
확실하게 적용이 쪽바로 됐나 확인 할려면 아무툴이나 mysql 로 접속해서 요런 쿼리를 날려보면 간단하게 확인할 수 있다.
show variables like '%ssl%';
죠 두항목이 YES 이면 설정이 쪽바로 적용된 것이다.
※ 인증서를 가지고 SSL 로 접속할려면 요런 옵션으로 접속하면 된다.
mysql -u root -p --ssl --ssl-ca=c:\cert\cert.pem
※ Toad for MySQL 에서 SSL 로 접속하기
커넥션 타입중에 보면 SSL 이라고 있는데 고걸 선택하고 계정정보를 입력하면된다, 인증서 파일을 선택하라고 하는데 굳이 선택하지 않아도 접속이 잘된다.
자~~~ 이제 마지막으로 JDBC로 SSL 접속을 하는 방법을 알아보자.
검색을 해 보니 이것저것 나오던데 방법이 쓸데없이 쫌 복잡해서~~~
간단 of 간단한 방법을 재수좋게 검색을 해서 찾아냈다. 아래와 같은 코드를 쓰면 된다.
키뽀인트는 JDBC URL 에 verifyServerCertificate=false 를 추가해 주는것이다.
저 옵션을 추가해주지 않으면 keytool 로 자바용 keystore 도 맹글어야 하고, 맹글어진 keystore를 시스템 프로퍼티에 추가해 줘야 되는 귀찮은걸 해야 한다.
저 옵션은 말그대로 서버 인증서를 verify 하지 않겠다는 옵션이다.
그리고 당연히 useSSL=true 옵션을 줘야 SSL 로 접속을 한다.
import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; public class Test { public static void main(String[] args) throws SQLException { Connection con = null; try { String url = "jdbc:mysql://127.0.0.1:3306/mysql?useSSL=true&verifyServerCertificate=false"; Class.forName("com.mysql.jdbc.Driver"); con = DriverManager.getConnection(url, "user_name", "user_password"); Statement st = con.createStatement(); ResultSet rs = st.executeQuery("select * from user where user='root'"); while (rs.next()) { System.out.println(String.format("%-20s %-20s", rs.getString(1), rs.getString(2))); } } catch (Exception ex) { ex.printStackTrace(); } finally { if (con != null) con.close(); } } }
요걸 실행시키고 TCP 패킷 캡쳐 프로그램으로 보면 요렇게 암호화가 잘되 있다~~
결론 :
MySQL 서버에 SSL 설정만 해주고, 기존 프로젝트 JDBC URL 에 useSSL=true&verifyServerCertificate=false 요것만 추가해 주면 간단하게 SSL 로 암호화 할 수 있다.
MySQL 서버에 접속하던 다른 서비스가 있어도 다른 서비스에는 영향이 없다.
'쓸만한지식' 카테고리의 다른 글
Windows 8 에서 Android SDK Manager 및 AVD Manager 가 실행이 안될때 (5) | 2013.06.20 |
---|---|
apt-get 으로 Ubuntu 12.04에서 Oracle JDK 설치 & Tomcat 설치 (2) | 2013.04.25 |
Windows Command 창에서 프로그램 종료 시 (2) | 2013.03.26 |
베가S5 무선링크 단절 팝업창 안뜨게 하기 (3) | 2013.01.03 |
windows8에서 듀얼모니터 사용시 작업표시줄 유용한 옵션 (0) | 2012.12.27 |
JAVA/JSP 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/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 |