문제

동일한 상자의 여러 SQL Server 데이터베이스와 통신하는 Java 응용 프로그램이 있습니다.이러한 데이터베이스의 수와 이름은 다양합니다.대체로 CallableStatement와 함께 거의 독점적으로 저장 프로시저를 사용하여 데이터베이스에 액세스합니다.우리는 SQL 주입을 피하고 바인드 변수를 사용하는 데 매우 능숙합니다.

유일한 관심 영역은 데이터베이스 이름 자체가 다음과 같이 CallableStatement에 전달하는 SQL에 연결된다는 것입니다.

"{call [" + dbName + ".dbo." + procName + "(?, ?, ?)}"

procName은 템플릿 메서드 패턴을 사용하여 하위 클래스에 하드 코딩되므로 문자열의 안전성이 보장됩니다.

dbName은 외부적으로 정의됩니다.구문을 이스케이프 처리하고 개발 환경에서 이를 활용하기 위해 dbName을 모든 종류의 패턴으로 설정하려고 시도했지만 성공하지 못했습니다.

다음 SQL 호출을 생성하기 위해 다음과 같이 설정했습니다(무고한 것을 보호하기 위해 테이블 ​​및 proc 이름이 변경됨).

securitytest].nx_proc()};delete from poor_victim_table;

된다

{call [securitytest].nx_proc()};delete from poor_victim_table;].dbo.proper_proc_name()}

그리고

securitytest].nx_proc()};exec('delete from poor_victim_table');

된다

{call [securitytest].nx_proc()};exec('delete from poor_victim_table');].dbo.proper_proc_name(?,?,?,?,?,?,?)}

결과 Incorrect syntax near ')'. 그리고 poor_victim_table 아직 행이 있습니다.나는 사용했다 truncate table, drop table 그리고 drop database 작동하지 않을 때 Simple로 전환했습니다. delete 보안 설정을 배제합니다.

바인드 매개변수를 사용하는 proc을 사용하면 항상 예상 매개변수 수와 다음과 같이 제공된 매개변수 수가 일치하지 않습니다. The index 1 is out of range..

securitytest]};exec('delete from poor_victim_table');

된다

{call [securitytest]};exec('delete from poor_victim_table');].dbo.proper_proc_name(?,?,?,?,?,?,?)}

모든 도로에서 런타임 오류가 발생하는 것으로 보이며 SQL이 실행되지 않습니다.물론 이것은 훌륭합니다.하지만 나는 그것이 실패하고 있는지 확인하고 싶습니다. 할 수 없다 올바른 조합을 시도하지 못했기 때문에 성공하고 실패하지 않습니다.

대중적인 의견/도시 신화는 저장 프로시저를 사용하면 SQL 주입에 면역이 된다는 것입니다. 그러나 저는 보안에 관해서는 그러한 절대적인 진술을 신뢰하지 않는 것을 선호합니다.

이것을 한동안 조사한 후 내가 생각해낸 가장 좋은 질문은 다음과 같은 스택오버플로 질문입니다. SQL 주입 - 저장 프로시저 호출 시 위험이 없습니까(iSeries에서)?.SQL 주입으로부터 보호하기 때문에 CallableStatement 사용을 지원하는 것 같습니다. proc 코드 자체가 입력 매개변수에서 동적 SQL을 만들지 않는 한.

그래서 커뮤니티에 대한 제 질문은 proc의 SQL 코드가 안전하다고 가정할 때 JDBC에서 CallableStatement를 사용하면 실제로 SQL 주입을 방지할 수 있습니까?입니다.아니면 SQL Server 드라이버는 이를 방지하는 방식으로 문자열을 구문 분석하지만 다른 드라이버는 그렇지 않을 수 있습니까?아니면 내가 충분히 노력하지 않는 걸까?

안전하다면 그 보증은 어떻게 이루어지나요?사용의 추상 구문 때문입니까? { call blah(?) } 실제 SQL은 아니지만 SQL로 변환되는 것은 무엇입니까?

도움이 되었습니까?

해결책

~해야 한다 안전하세요. 하지만 당신처럼 나도 그것을 믿지 않을 것입니다. 특히 당신이 다른 JDBC 드라이버 등을 사용하여 다른 데이터베이스에 인터페이스하는 경우에는 더욱 그렇습니다.

내가 당신이라면 당신이 게시한 성명을 게시하기 전에 dbName에 문자, 숫자 및 밑줄이 아닌 다른 것이 포함되어 있는지 확인했을 것입니다.이는 모든 유효한 dbName을 허용하고 모든 종류의 혼란을 방지해야 합니다.

다른 팁

db 연결 URL을 확인하세요. 정적 db를 참조하는 것 같습니다. 따라서 호출 가능 문에 db 이름을 쓰면 db 이름이 변경될 때마다 문제가 발생합니다. 코드는 die(대부분 변경할 위치)이므로 db 이름을 사용하지 마세요. 쿼리에서는 다른 DB 연결이나 그에 대한 다른 도우미 클래스에 대해 다른 개체를 만들 수 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top