정보보안 스터디 - 15주차 6일 - Prepared Statement 대응
☞ 다양한 SQL 쿼리문 구현 방법
이런식으로도 connect 등 SQL쿼리문을 구현 가능합니다.
현재 non-prepared 이기 때문에
wonder12' union select 1,2,3,4,5#
wonder12' union select 1,2,3,4,5 limit 1,1#
해당 SQL문을 인젝션했을 때 결과가 뜨는 것을 볼 수 있습니다.
SELECT 대문자로 시작해줘야 실제 쿼리가 어떻게 진행되는지 알 수 있어서 보기에 편합니다.
☞ prepared statement 구현
SELECT 문
여기서의 핵심은 concat으로 % ? % 를 붙여 줘야 검색창과 같이 결과가 나온다는 점입니다.
또한 execute()는 필수고 Prepared statement 구문을 get_result()를 추가해줘야 결과가 노출됩니다.
bind하는 파라미터를 제외한 SQL문은 미리 기계어로 처리가 되기 때문에
굳이 다른 escape 문을 쓰거나 취약점을 일일이 신경쓸 필요가 없어 더 수월하다고 할 수 있습니다.
또한 명령문이 여러번 실행되더라도 쿼리가 준비가 한번만 수행되기 때문에 구문 분석 시간을 줄일 수 있는 장ㅈㅁ이 있습니다.
prepare를 잘 수행하고 있기 때문에
wonder12,'%') union select 1,2,3,4,5#
인젝션을 해도 결과가 뜨지않습니다.
INSERT문
POST로 받아오는 방식이 아니라 직접적으로 문자를 bind하고 싶을 때는 문자를 넣는게 아닌 $pwd2 변수 설정을 통해서 입력합니다.
wonder12, wa)#
wonder12#
를 삽입했을 때도 #가 작동하지 않고, 잘 prepared 된 것을 확인할 수 있습니다.
☞ PDO(PHP Data Object) 방식
PDO를 사용하면 mysql, oracle, mssql, postgresql을 포함한 12개의 데이터 베이스를 같은 방식으로 다룰 수 있는 장점이 있습니다. 이런식으로 구현하는 방법도 있습니다.
☞ 세션 만료 기한 설정
php/php.ini 설정 파일에서, 웹 브라우저를 종료할 때까지 세션을 유지하고 브라우저 종료 10분이 뒤에 세션을 만료하고 재생성 되도록 설정합니다.
session.cookie_lifetime=0
session.gc_maxlifetime=600
사실 브라우저를 종료하지 않는 이상 유지되는 것도 위험하기 때문에
10분동안 아무 입력이 없다면 세션을 재생성하는 것도 좋은 방법입니다.
session.cookie_lifetime=600
☞ 세션 VS 쿠키 차이점
쿠키랑 세션은 다릅니다.
세션 생성
session_start();
$_SESSION['isLogin'] = $uid;
이런식으로 로그인 아이디(wonder)를 세션으로 생성했습니다. = 세션을 시작하면 클라이언트 측에도 쿠키가 뜨긴 뜨지만(user_session=34vd0k2m2b1g0vdvlrhkrd1jqm) 실제 세션값(wonder)은 보이지 않습니다. = 서버측에 저장되기 때문에 보안에 더 좋습니다.
쿠키 생성
setcookie("assa","안녕");
처럼 쿠키로 생성을 했다면
쿠키의 값이 이렇게 노출이 되고, 변조가 가능합니다.
로그아웃 했을 때 실제로 세션은 파기되서 해당 쿠키로 로그인이 안되겠지만 쿠키가 고정이여서 값이 남아 있습니다.
이 때 위험한 점은 뭘까요?
사실 로그아웃을 잘하면 큰 문제는 없습니다.
근데 로그아웃을 안했을 때 세션이 만료되지 않고 남아있기 때문에,
이런 부분에는 대응을 해줘야합니다. 브라우저가 꺼졌을 때 10분이 지나면 삭제해야 안전합니다.
한번 탈취를 하면 계속 사용할 수 있기 때문입니다.
이건 확실하지 않아 고민이 필요한 사항이지만
이용중에도 세션을 변경하는 게아니라(세션을 만료시키고 재생성하면 로그아웃이 되는 것이기 때문에.) 쿠키를 변경시키는 게 좋습니다 >> 그러면 공격자입장에서는 쿠키가 만료돼서 로그아웃 될 것입니다. 이건 확실하지 않습니다.