앞으로 Development 분류에서 웹 언어 중 가장 많이 사용되고 있는 PHP에 관해서 다룰 예정이다. 그 중에서도 많은 사용자가 잘 모르고 있는 여러 가지 사실에 대해 알아보려고 한다. (일반 사용자들도 PHP를 사용하기 시작하면서 많은 보안 문제가 발생하게 되었다. 이는 대부분 잘못된 코딩 습관으로 인해 발생하는 문제이다.) 나도 인터넷에 있는 여러 정보를 통해 PHP를 배웠기 때문에 정확히 알지 못하는 부분이 있을 수도 있다.
이번 글에서는 PHP에서 가장 문제가 되고 있는 보안 이슈 중 하나인 register_globals 옵션에 대해 알아보기로 하자. 이미 몇 번 이슈화 되었기 때문에 알고 있는 사용자들도 많지만, 아직도 모르는 사용자들도 많은 문제이다.
EGPCS(환경, GET, POST, 쿠키, 서버) 변수를 전역 변수로 등록할지를 결정합니다. 예를 들어, register_globals = on 이라면 URL http://www.example.com/test.php?id=3 요청에 $id를 생성합니다. 또는, $_SERVER[‘DOCUMENT_ROOT’]에서 $DOCUMENT_ROOT를 등록합니다. 스크립트의 전역 위치에 유저 데이터로 채워지는것을 원하지 않는다면, 이 옵션을 끄십시오. PHP 4.2.0부터는 이 지시자의 기본값은 off입니다. 자동전역: $_ENV, $_GET, $_POST, $_COOKIE, $_SERVER 등의 PHP 예약 정의 변수를 사용하는 것을 권장합니다. 보안 챕터의 register_globals 사용에 대한 관련 정보를 읽어보십시오.
register_globals는 실행시에 설정(ini_set())할 수 없는 점에 주의하십시오. 그러나, 호스트가 .htaccess를 허용한다면, 그것을 이용할 수 있습니다. 예제 .htaccess 엔트리: php_flag register_globals on
register_globals 옵션을 on으로 두면 $_GET[‘id’]를 $id로 줄여서 쓸 수 있다는 편리함이 있기 때문에 일부 프로그래머들이 이를 이용하는 것으로 알고 있다. 그래서 register_globals가 off일 경우 작동하지 않는 문제를 해결하기 위해서 extract($_GET) 등을 사용하기도 하는 것으로 본 적이 있다. (내 기억이 맞다면 제로보드가 이런 형태로 되어 있는 것으로 기억한다. 또한 이 때문에 include path 관련 보안 문제가 발생해서 패치가 있었던 것으로 알고 있다.)
하지만 이 옵션을 on으로 두었다고 가정하고 코딩하면 보안상 문제가 발생한다. PHP 코드 안의 변수 값을 바꿀 수 있는 방법을 제공하는 것이 되기 때문이다. 다음 예제 코드는 register_globals가 on으로 되어 있을 때 보안상 문제가 발생할 수 있는 코드이다.
1 2 3 4 5 6 7 8 9 |
<?php if ($pw == 'pass') { $auth_ok = true; } ..... if ($auth_ok) { // 비밀번호를 알아야 볼 수 있는 정보 } ?> |
위 코드는 GET으로 비밀번호를 받아서 지정한 비밀번호와 같을 때에만 정보를 표시하기 위한 간단한 프로그램이다. 이 프로그램은 GET으로 auth_ok 변수에 1을 넘겨줄 경우 pass 없이도 정보를 볼 수 있다는 보안 문제가 생기게 된다. 이를 막기 위해서는 자동 전역 변수인 $_GET을 사용해서 검사해야 한다.
이 외에도 register_globals가 off 되어 있을 때 변수를 사용하는 것은 그 변수가 GET 요청에서 온 것인지, POST 요청에서 온 것인지 구분할 수 없기 때문에 문제가 발생한다. (보안상 문제가 발생하지 않을지는 몰라도 POST로 넘어온 값과 GET으로 넘어온 값이 중복될 때 예상치 못한 문제가 발생할 수 있다.)
대안은 위에서도 언급했듯이 자동 전역 변수를 사용하는 것이다. $_GET, $_POST 등과 같은 자동 전역 변수를 사용해서 코딩하면 register_globals의 값에 상관 없이 프로그램이 정상적으로 동작하며, 위와 같은 문제를 피할 수 있다. 약간 귀찮을 수는 있지만 보안 문제가 발생하는 것을 막기 위해서는 register_globals가 off라고 가정하고 프로그래밍하는 것이 필수적이다.
4 Responses to 간단하지만 중요한 PHP 보안 이슈, register_globals