$id = "test234';
$sQuery="select a_id, a_name, a_pwd from T_ADMIN where a_id ='".$id. "'";
$sQuery = $this->db->escape($sQuery);
echo $squery // 아래 찍힌 쿼리요
$this->db->query($sQuery); 이렇게 하면 오류가 납니다. 찍어보니깐 escape된건지 ' 앞에 \가 붙어있네요
escape 한 이유가
일반적으로 쿼리빌더(액티브레코드) $this->db->insert(), update(), set(), where() 등등을 이용하면
메뉴얼에도 나와았는거 같은데 escape 가 자동으로 설정된다고 하였고
$this->db->query() 는 안붙기 때문에 escape를 하거나 쿼리에 ? 를 붙이고 $this->db->뭐였더라 (array($id, .... )) 식으로 하라고 했던거
같은데요
그렇다면 $this->db->escape는 안써도 되는 것인지요? 아니면 2번째 ? , array() 방식으로 해야 하는 것인지요?
'select a_id, a_name, a_pwd from T_ADMIN where a_id =\'ljstyles\''
1. escape 는 액티브레코드 쿼리 빌더를 사용하여도 선택에 따라서 false로 놓고 사용합니다.
이유는 보시는 바와같이 특정 조건은 백틱이 붙으면 오류가 나기때문에. 혹은 알맞게 붙지 않아서.
[예 : $this->db->select('a_id', false); 뒤에 false가 붙으면 escape 하지 않음. ]
2. 조건에 ? 가 붙는걸 [쿼리 바인딩] 라고 부릅니다.
다만 원리는 escape와 같습니다.
? 가 붙는것에 대해서만 백틱이 붙어서 오류가 날 가능성이 적습니다.
코어를 보시면 ? 순서 대로 들어오는 배열 인덱스별로 매칭한후에 escape 합니다.
[정확한 명칭은 쿼리 바인딩 ... 혹은 바인드 쿼리라고 지칭되어있지만, 실제는 리터럴 쿼리입니다. 단지 CI 에서는 바인딩 한다고 부릅니다.]
결론적으로 처음부터 쿼리빌더를 사용하면 이러한 문제에 대한 고민이 적어집니다.
$this->db->query(); 는 있는 그대로 쿼리 사용이 가능한 만큼 사용자가 잘 판단해서 사용해야만 합니다.
마지막으로 쿼리 보호의 핵심은 파라미터 값에 산술오류를 넣어도 방어 하게끔 한다는 점입니다.
$id 가 1234가 들어올거라고 생각 하고 쿼리를 짯다면 해커는 1234가 아니라 고의적으로 1=1; select * from member; 이러한 문자를 삽입 하고는 맴버 테이블이 있다면 모든 정보를 긁어 오는 가장 기초적인 해킹 방법을 시도합니다.
escape 는 앞뒤로 백틱을 감싸기 때문에 저러한 문자열이 들어와도 실행되지 않고 오류가 납니다.
이 부분만 잘 판단 하시면 escape를 하시든, bind 하시든 어떻게 방어해야 하는지 감이 오실거라 생각 됩니다.