스터디를 하며 JPA공부 및 과제를 하다가 문득 제목에 대한 호기심이 생겼다.
나의 1차적 질문은, 'preparedstatement방식이 sql injection도 방지해준다 써있는데 그 이유가 파라미터 바인딩이지 않냐. 근데 파라미터 바인딩은 쿼리에 작성되는 특정 속성을 매개변수로 매핑하는(즉 대명사같은,,?)거라고 되어있는데, 사용자가 입력한 다음에 공격자가 임의로 파라미터를 조작한거면 의미가 있을까?파라미터 바인딩과 어떻게 연결되는지 정확히 모르겠다'였다.
사실 이 질문은 내가 parameter binding에 대한 자세한, 그리고 정확한 설명을 몰라서 드는 의문일지도 있지만, 나는 이것을 해결했어야만 했다. 인터넷을 찾아봐도 나를 100% 이해시키기에는 아직 역부족이기에 나는 스터디 멤버와 스터디 조장에게 물어보기로 했고, 이는 나에게 최선의 답이었다고 생각한다.
답변은 즉슨, 'statement를 사용해서 동적인 쿼리(즉, 사용자로부터 입력받는 쿼리)를 날린다면, 스트링에 값을 덧붙이는 식이 될것이다. 하지만, 악의적인 쿼리를 넣는다면,SQL injection이라는 건데, 이 때문에 statement방식을 이용하지 않는 것이다. 그래서 PreparedStatement를 사용하는 것이다. 그렇다면 질문에 대한 답을 여기서부터 구체적으로 설명할 수 있겠다. statement방식과 달리 파라미터가 들어갈 자리를 만들어놓고 주어진 메서드를 사용해서 그 자리에 값을 그대로 넣어서 쓰기 때문에 sql injection방지가 될 수 있는 것이다. 그렇다면 여기서 드는 의문은, 저 파라미터 자리에 쿼리를 넣을 수도 있지 않냐 이런 생각이 들 수도 있지만, 파라미터가 바인딩 되는 시점에 sql문법이 아니라 컴파일 언어로 처리하기 때문에 DBMS에 쿼리를 날리기 전에 실패한다는 것이다.'
그리고 이 설명을 들으니 나에게 드는 두번째 의문이 생겼다. 그래서 나는 두번째 의문을 해소하기 위해 또 다른 질문을 던졌다.
'그렇다면.. 공격자도 주어진 곳에 파라미터를 넣는다면, 그게 공격자인지 유저인지 어떻게 인식할까'
이에 대한 답변은,
'저 굵은 글씨를 주목해보라. 저 과정을 어떻게 수행하냐면,

이런식으로 문자 하나씩 보면서 특수문자를 제거하는 등의 작업을 한다
SQL INJECTION은 보통 특수 문자가 들어간 쿼리를 삽입하는 것이다 보니
특수 문자를 지워버리면 잘못된 쿼리 문법이니 DBMS에 쿼리를 날릴 때 실패할 것이다.
그렇다면 질문에 대한 답변을 결론적으로 말해보자면,
이것도 공격자인지 유저인지 완벽하게 구별한다기보단, 이런 것들은 사실 인증의 영역인거라서 그 쪽을 더 알아보는 것도 좋을 것 같다.
SQL 인젝션은 순수 들어오는 입력 값에 대한 검증만으로 방어해내는 것이다. '
나는 공격자와 유저를 구별하는 방법이 둘의 접근가능 경로가 달라서 값만 넣어도 구별하는 줄 알았는데, 그에 대한 답변은,
'다르지 않을 것이다. 그냥 들어오는 값에 대해서만 판단하는 것이다. 공격자가 정상 유저의 계정을 어떻게든 알아내서 공격한다거나 정상 유저를 사칭한다던가(토큰을 어떻게든 알아내서 요청 보낼 때 해당 토큰 사용) 그런 건 위에서 말했듯이 인증의 영역이다'
였다.
보안 쪽은 아직 때가 아닌 것 같아서 추후에 보안에 대해서도 흥미가 생기면 좀 더 알아보도록 하겠다. 아무튼 PREPAREDSTATEMENT & SQL INJECTION 부문은 이렇게 나의 의문이 해결이 되었다.
