userName에는 게임 사용자가 입력한 문자열이 서버에서 수신한 그대로 들어갑니다. 여기서는 무엇이 문제가 될 수 있을까요? 게임 사용자가 해커고, 그 해커가 userName에 고의적으로 다음 코드를 보낼 수도 있습니다.
'; delete from table1; select * from table1 where a='
뭔가 모양이 좀 이상하죠? 맨 앞과 맨 뒤에 작은따옴표(‘)가 있고 그 사이에 질의 구문이 있습니다.
이제 queryString의 sprintf 결과물을 봅시다.
select * from t1 where a=''; delete from table1; select * from table1 where a=''
이 구문을 실행하면 table1의 모든 레코드가 사라집니다. 여러분은 select 구문만 실행하고 싶었음에도 말이지요. 이는 게임 서비스에 대재앙이 될 것입니다.
이러한 공격을 질의 구문 인젝션(query injection)이라고 합니다. 이를 막으려면 애당초 sprint 같은 질의 구문을 사용자 입력 값으로 만들지 않아야 합니다. 물론 공격을 막는 방법도 있지만, 장기간 프로그램을 유지 보수하다 보면 예상치 못한 복병이 됩니다.
웬만한 데이터베이스 연결 모듈은 매개변수화된 질의 구문(parameterized query) 실행 기능을 갖고 있습니다. 매개변수화된 질의 구문이란 질의 구문 자체에는 여러분이 만든 문장만 들어가게 하고, 질의 구문에 들어갈 수 있는 다른 입력 값들은 별도의 매개변수로 격리해서 입력하는 것을 의미합니다. 매개변수화된 질의 구문 예시는 이미 7.10절에서 잠깐 다루었습니다.