2014-01-19 4 views
2

Java에서 MySQL을 사용하는 방법을 배우려고하고 있습니다. 제목에서 말하는 것처럼 준비된 문과 관련된 문제가 있습니다. 자바에서준비된 구문의 매개 변수로 테이블 이름을 전달합니다.

mysql> select * from temp; 
+------+-----------------------------------------------+ 
| id | value           | 
+------+-----------------------------------------------+ 
| 1 | this is a first item       | 
| 2 | this is the second item      | 
| 3 | This is the third item and slightly redundant | 
+------+-----------------------------------------------+ 
3 rows in set (0.00 sec) 

나는이 같은 DB에 접근하고 있습니다 :

stmt = conn.prepareStatment("select * from ?"); 
stmt.setString(1,"temp"); 
ResultSet rs = stmt.executeQuery(); //This method call throws the exception 

stmt.toString는 알 수

나는 (MySQL의 콘솔에서 직접 출력) 값이 포함 된 MySQL의 테이블라는 이름의 온도가 : select * from 'temp' 예외 메시지는 다음과 같습니다. You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''temp'' at line 1

입력 할 때 select * from 'temp'stmt.toString())를 MySQL 콘솔에 직접 입력하면 동일한 메시지가 나타납니다.

상상했을 것입니다.이 개념을 JSP 웹 페이지에 적용 할 계획입니다. 여기서 JSP 이름은 HTTP GET 매개 변수입니다. 그래서 내 질문 : 테이블 이름을 준비된 문을 바인딩 할 수 및 불가능한 경우 (나는 PHP에 대한 비슷한 질문에서 얻는 분위기입니다) 어떻게 테이블 이름에 대한 입력을 sanitize 것인가?

+0

그래, 나는 그것을 보았지만 대답은 그다지 확신이 없거나 도움이되지 않았다. 나는 미래에이 문제에 부딪히는 모든 사람들을 위해서 보안을 희생하지 않는 더 나은 해답이나 문제에 대한 해결책을 기대하고 있습니다. – Alex

+0

(양식 데이터와 달리) 테이블 이름을 정제 할 필요가 없으므로 문제의 원인을 알 수 없습니다. – blackcompe

+0

여러 개의 카드 주제로 플래시 카드 프로그램을 만들려고합니다. 그래서 각 주제가 다른 표 (다른 주제는 다른 정보를 저장할 필요가있을 수 있습니다)가되고 싶습니다. – Alex

답변

1

당신은 그렇게 할 수 없습니다. 문자열 연결을 사용하여 sql을 생성해야합니다. PreparedStatement은 테이블 이름이 아닌 열 값입니다.

+0

NO! 테이블 이름에 대해 외부에서 제공된 값을 사용하지 마십시오! –

1

테이블 이름에 stmt.setString() 또는 setInt() 함수를 사용할 수 없으며 열 값에만 유효합니다.

0

이러한 종류의 요구 사항은 데이터베이스 디자인의 결함을 나타냅니다. "주체"테이블에 다른 정보가 포함되어있는 경우 어떻게 동일한 쿼리를 사용하여 정보를 검색 할 수 있습니까?

테이블에서 모든 열을 선택하고 응용 프로그램이 원하는 것과하지 않는 것을 정렬하도록합니다. 따라서 응용 프로그램의 위험과 취약성, 통신 채널의 중복 데이터 전송 및 응용 프로그램이 대중화 될 때 데이터베이스 최적화의 어려움이 발생합니다. 귀하의 응용 프로그램 코드가 다시 열을 정렬 할 수있는 경우와 경우의 얽힌 것으로 의심됩니다. 이 코드를 합리화하여 각 테이블 형식을 알고 특정 클래스에서 처리하도록하면 코드가 훨씬 단순 해지고 테이블 이름이 더 이상 매개 변수가 될 필요가 없습니다.

테이블 이름을 바꾸면 SQL 주입 취약점으로 인해 극복 할 수없는 보안 문제가 발생합니다. 누군가가 당신에게 테이블 이름으로 (fish INNER JOIN mysql.user ON TRUE)을 주면 어떨까요? 즉, 전체 컬럼 선택과 함께 MySQL 사용자 테이블을 제공합니다! 너 저걸 원하니?? 테이블 값을 이스케이프해도 전혀 도움이되지 않습니다. 사실 그것은 공격자에게 SQL 문에 삽입 할 수있는 더 넓은 범위의 문자만을 제공합니다.

데이터베이스 설계를 준비된 문 매개 변수를 사용하여 선택할 수있는 "주제"열이있는 테이블로 합리화하고 표준화해야합니다.

관련 문제