2009-03-26 2 views
13

누군가가 부분적으로 사용자 입력에서 형성된 SQL 쿼리를 안전하게 실행하는 데 필요한 초보자 가이드가 될 수 있습니까? Java를 사용하고 있지만 언어 중립성 가이드도 좋습니다.Java에서 데이터베이스 입력을 어떻게 정리해야합니까?

원하는 동작은

very nice;) DROP TABLE FOO;

같은 GUI 뭔가에 누군가 유형이 데이터베이스는 리터럴 문자열로 취급하고 테이블을 삭제하지 않고 안전하게 저장해야하는 경우이다. 대신 Statement

답변

7

사용 PreparedStatement, 당신은 입력을 연결, 대신 PreparedStatement를 사용하여 쿼리를 작성해서는 안됩니다.

이렇게하면 쿼리 내에서 매개 변수를 설정할 위치를 지정할 수 있으므로 Java가 모든 입력을 위생 처리합니다.

3

PreparedStatement? 네 그럼요. 하지만 한 가지 더 단계가 있다고 생각합니다. UI에서 입력을 검증하고 데이터베이스에 접근하기 전에 객체에 바인딩하는 것입니다.

내가 PreparedStatement의의 String 여전히 SQL 주입 공격에 취약 당신을 떠날 수있는 바인딩 위치를 확인할 수 있습니다 :이 원격 인 경우

String userInput = "Bob; DELETE FROM FOO"; 
String query = "SELECT * FROM FOO WHERE NAME = ?"; 

PreparedStatement ps = connection.prepareStatement(query); 
ps.setString(1, userInput); 
ps.executeQuery(); 

나는 그것을 자신을 시도하지 않은 것을 인정 돼했지만, PreparedStatement는 필요하지만 충분하지 않다고 말할 수 있습니다. 서버 측에서 검증 및 바인딩이 중요합니다.

스프링의 바인딩 API를 사용하는 것이 좋습니다.

+0

이것은 준비된 진술이 보호하려는 공격 유형과 정확히 같습니다. 그것은 탈출 할 것이다; – danieltalsky

+0

기술적으로 PreparedStatement 인터페이스는 그것을 보장하지 않습니다. 운전 기사가 다른 것을 시도하더라도 새로운 공급 업체를 찾으십시오. –

+0

@ 다니엘 - 나는 그것을 시도하고 나 자신을 위해보아야 할 것입니다. 내가 맞는지 여부에 관계없이 서버 측 유효성 검사가 여전히 좋은 생각인지 동의하지 않습니까? – duffymo

3

귀하의 사용자 입력이 실제로 "Bob'; delete from foo; select '" (또는 뭔가처럼) 그렇게 준비된 명령문에 의해 추가 된 암시 따옴표가 폐쇄 될 수있을 것입니다 :

SELECT * FROM FOO WHERE NAME = 'Bob'; delete from foo; select '' 

을하지만, 당신이 경우에 준비된 명령문 코드는 인용 것 견적은 그래서 당신은

SELECT * FROM FOO WHERE NAME = 'Bob''; delete from foo; select ''' 

의 실제 쿼리를 얻고 이름이 "Bob', delete from foo; select '" 대신 여러 쿼리를 실행으로 저장 될 것이다.

관련 문제