어제 꽃지야님의 Photo Gallery에 조회수 항목을 추가시켜놓고 잘 돌아가는 것까지
확인했는데, 오늘 가서 보니 사진 Thumbnail 도 제대로 안뜨고, 글을 읽는 것도
제대로 안됐다.
원인을 잘 보니 프로그램에 변수값을 넘기는 것이 제대로 동작하지 않는 거였다.
PHP 언어가 초창기 CGI 보다 편하다고 하는 것중의 하나가 바로 변수값을 편리하게
다룰 수 있다는 거였다.
HTTP에서 변수값을 넘기는 방식이 여러 가지 있겠지만, 그중에서도 가장 범용적인
것이 바로 GET 방식가 POST 방식이 있다.
GET 방식은 http://xxx.com/abc.html?id=xxx&mode=ddd 라고 표시해서 URL에
바로 변수값을 표시해줄 수 있는 방식이다. 위의 뜻은 abc.html 이라는 프로그램에
ID라는 변수에 xxx, 그리고 mode 변수에 ddd라는 값을 지정해서 넘긴다는 뜻이다.
(&로 변수 사이를 구분짓는다)
혹은 <form method=GET action=abc.html>이라고 지정하고 그 안에 <INPUT>,
<SELECT>, <TEXTAREA> 등의 값을 지정하고는, Submit 해서 abc.html로 넘길
수 있는데, 이 경우 Submit하고 난 다음의 URL을 보면 <INPUT>, <SELECT> 등의
안에 Name= 이라고 지정해둔 부분의 변수명과 값이 다 표시된다.
예를 들어
<form method=GET action=abc.html>
<input type=text name=id>
<select name=mode><option value=3></option></select>
<input type=submit value='확인'>
</form>
이라고 했을 때 확인 버튼을 누르면 URL이 abc.html?id=입력값&mode=선택값
이런 식으로 표시된다.
이에 비해 POST 방식은 <form method=POST action=abc.html>라고 해놓고는
역시 그 안에 <INPUT><SELECT> 등의 값을 넣는데, 이 방식은 Submit 하더라도
URL에 그 값들이 표시되지 않는다. Submit하고 난 다음의 URL을 보면 그냥
abc.html 만 덜렁 표시될 뿐이다. 즉 POST와 GET 방식의 차이는 한 페이지에서
다른 페이지로 값을 넘기는 것이 URL에 표시되느냐, 안되느냐로 보면 간단하다.
다른 CGI 언어들이 저렇게 넘어온 값을 인식하기 위해서 몇 가지 사전 처리를 해줘야
하는 데에 비해서 PHP는 변수명에 $ 만 붙여주면 바로 값을 처리해줄 수 있기때문에
프로그래밍이 무척이나 편해서 나 같은 사람도 쉽게 다룰 수 있는 장점이 있었다.
abc.html?mode=edit&id=10 이라고 넘겨져왔을 때에, abc.html에서는 $mode라고
써주면 그 안에 edit 라는 값이 들어있고, $id 에는 10 이라는 값이 들어가 있게 되는
것이었다.
헌데 이렇게 간단하게 처리하다보면 문제가 생기기 마련. 바로 저렇게 URL에서 바로
변수명을 넘겨준다면, 몇몇 변수명을 쉽게 해킹할 수 있게 되는 것이었다.
예를 들어서 사용자 레벨이나 암호 등의 값을 지정한 변수명을 안다면 URL을 통해
쉽게 접근 가능한 것. 만약 abc.html 프로그램에서 사용자 레벨을 $level 이라고
해놓고는 그 $level을 가지고 권한을 판단한다고 할 때, abc.html?level=admin 이런
식으로 써버리면, 굳이 로그인하지 않고서도 abc.html에서 $level에 admin 값으로
각종 처리를 할 수 있게 되는 거였다.
이런 보안상 문제때문에 PHP 가 발전하면서 지정된 경로를 통해 넘겨진 값이 아니면
받아들이지 않을 수 있게 됐다. abc.html?level=admin 이라고 해봐야, $level은
그 경로로는 넘겨받을 수 없게 지정하는 것, 그게 바로 PHP의 셋팅중 register_globals
= Off 라는 항목이었다.
$level 이라는 변수는 쿠키나 세션을 통해서만 받게 지정할 수 있게 하는 대신에,
프로그래밍은 조금 복잡해진다. 기존에는 어떤 방식으로 값이 넘어오든 간에 변수명만
맞으면 값을 받아들이니 그냥 변수를 처리하던 방식에 비해서, 이 방식은 프로그램 초기에
모든 항목을 어떤 식으로 받는 거다라고 지정을 해줘야 하니까. 지정안해주면 값을 전혀
받을 수가 없게 되는 문제가 발생하는 것이다.
Photo Gallery는 프로그래밍하기 편하게끔 register_globals = on 상태에서 돌아가도록
되어 있었는데, 만약 서버의 셋팅이 register_globals = off 되어 있다면 변수값을
전혀 못받게 된다.
그렇다. 하고 싶은 얘기가 본격적으로 나온다. 꽃지야~님의 서버 설정을 봤더니
register_globals가 off 되어 있어서, 변수값을 하나도 못받는 것이었다.
index.php에서 $id 가 값이 있어야 글을 볼 수가 있는데, register_globals가 off
되어 있으니 아무리 index.php?id=1 이렇게 넘겨봐야 index.php에서 $id 값이 없다고
나오는 것은 당연한 것.
그래서 오늘 작업한 것들은 register_globals가 off 된 상태에서도 값을 받을 수 있게
하는 부분들이 대부분이었다.
문제는, 어제까지도 멀쩡하게 돌아가던 것이 왜 갑자기 안되느냐는 것. 추측할 것은
byus.net 에서 어제까지는 register_globals를 on 해놓았다가 오늘에 와서야 off로
바꿔놓은 것이 아닌가 하는데.
근데 byus.net 을 쓰는 다른 사람들의 프로그램들은 멀쩡히 돌아가고, 심지어 꽃지야~
님의 제로보드도 멀쩡하게 돌아가는데, 왜 저것만 안되느냐는 사실. 제로보드는 여러
군데에서 쓰이는 것을 가정했기때문에 프로그램에서 그걸 대비해서 프로그래밍되어
있다고 짐작은 하겠는데, 왜 다른 사람의 홈페이지의 것은 잘 돌아가는지...
아직까지 그게 가장 큰 의문이다.
여튼, 이번에 고친 것으로 어떤 서버에서든지 register_globals 에 상관없이 돌아가게
해놨다는 데에 의의를 둬보자.
확인했는데, 오늘 가서 보니 사진 Thumbnail 도 제대로 안뜨고, 글을 읽는 것도
제대로 안됐다.
원인을 잘 보니 프로그램에 변수값을 넘기는 것이 제대로 동작하지 않는 거였다.
PHP 언어가 초창기 CGI 보다 편하다고 하는 것중의 하나가 바로 변수값을 편리하게
다룰 수 있다는 거였다.
HTTP에서 변수값을 넘기는 방식이 여러 가지 있겠지만, 그중에서도 가장 범용적인
것이 바로 GET 방식가 POST 방식이 있다.
GET 방식은 http://xxx.com/abc.html?id=xxx&mode=ddd 라고 표시해서 URL에
바로 변수값을 표시해줄 수 있는 방식이다. 위의 뜻은 abc.html 이라는 프로그램에
ID라는 변수에 xxx, 그리고 mode 변수에 ddd라는 값을 지정해서 넘긴다는 뜻이다.
(&로 변수 사이를 구분짓는다)
혹은 <form method=GET action=abc.html>이라고 지정하고 그 안에 <INPUT>,
<SELECT>, <TEXTAREA> 등의 값을 지정하고는, Submit 해서 abc.html로 넘길
수 있는데, 이 경우 Submit하고 난 다음의 URL을 보면 <INPUT>, <SELECT> 등의
안에 Name= 이라고 지정해둔 부분의 변수명과 값이 다 표시된다.
예를 들어
<form method=GET action=abc.html>
<input type=text name=id>
<select name=mode><option value=3></option></select>
<input type=submit value='확인'>
</form>
이라고 했을 때 확인 버튼을 누르면 URL이 abc.html?id=입력값&mode=선택값
이런 식으로 표시된다.
이에 비해 POST 방식은 <form method=POST action=abc.html>라고 해놓고는
역시 그 안에 <INPUT><SELECT> 등의 값을 넣는데, 이 방식은 Submit 하더라도
URL에 그 값들이 표시되지 않는다. Submit하고 난 다음의 URL을 보면 그냥
abc.html 만 덜렁 표시될 뿐이다. 즉 POST와 GET 방식의 차이는 한 페이지에서
다른 페이지로 값을 넘기는 것이 URL에 표시되느냐, 안되느냐로 보면 간단하다.
다른 CGI 언어들이 저렇게 넘어온 값을 인식하기 위해서 몇 가지 사전 처리를 해줘야
하는 데에 비해서 PHP는 변수명에 $ 만 붙여주면 바로 값을 처리해줄 수 있기때문에
프로그래밍이 무척이나 편해서 나 같은 사람도 쉽게 다룰 수 있는 장점이 있었다.
abc.html?mode=edit&id=10 이라고 넘겨져왔을 때에, abc.html에서는 $mode라고
써주면 그 안에 edit 라는 값이 들어있고, $id 에는 10 이라는 값이 들어가 있게 되는
것이었다.
헌데 이렇게 간단하게 처리하다보면 문제가 생기기 마련. 바로 저렇게 URL에서 바로
변수명을 넘겨준다면, 몇몇 변수명을 쉽게 해킹할 수 있게 되는 것이었다.
예를 들어서 사용자 레벨이나 암호 등의 값을 지정한 변수명을 안다면 URL을 통해
쉽게 접근 가능한 것. 만약 abc.html 프로그램에서 사용자 레벨을 $level 이라고
해놓고는 그 $level을 가지고 권한을 판단한다고 할 때, abc.html?level=admin 이런
식으로 써버리면, 굳이 로그인하지 않고서도 abc.html에서 $level에 admin 값으로
각종 처리를 할 수 있게 되는 거였다.
이런 보안상 문제때문에 PHP 가 발전하면서 지정된 경로를 통해 넘겨진 값이 아니면
받아들이지 않을 수 있게 됐다. abc.html?level=admin 이라고 해봐야, $level은
그 경로로는 넘겨받을 수 없게 지정하는 것, 그게 바로 PHP의 셋팅중 register_globals
= Off 라는 항목이었다.
$level 이라는 변수는 쿠키나 세션을 통해서만 받게 지정할 수 있게 하는 대신에,
프로그래밍은 조금 복잡해진다. 기존에는 어떤 방식으로 값이 넘어오든 간에 변수명만
맞으면 값을 받아들이니 그냥 변수를 처리하던 방식에 비해서, 이 방식은 프로그램 초기에
모든 항목을 어떤 식으로 받는 거다라고 지정을 해줘야 하니까. 지정안해주면 값을 전혀
받을 수가 없게 되는 문제가 발생하는 것이다.
Photo Gallery는 프로그래밍하기 편하게끔 register_globals = on 상태에서 돌아가도록
되어 있었는데, 만약 서버의 셋팅이 register_globals = off 되어 있다면 변수값을
전혀 못받게 된다.
그렇다. 하고 싶은 얘기가 본격적으로 나온다. 꽃지야~님의 서버 설정을 봤더니
register_globals가 off 되어 있어서, 변수값을 하나도 못받는 것이었다.
index.php에서 $id 가 값이 있어야 글을 볼 수가 있는데, register_globals가 off
되어 있으니 아무리 index.php?id=1 이렇게 넘겨봐야 index.php에서 $id 값이 없다고
나오는 것은 당연한 것.
그래서 오늘 작업한 것들은 register_globals가 off 된 상태에서도 값을 받을 수 있게
하는 부분들이 대부분이었다.
문제는, 어제까지도 멀쩡하게 돌아가던 것이 왜 갑자기 안되느냐는 것. 추측할 것은
byus.net 에서 어제까지는 register_globals를 on 해놓았다가 오늘에 와서야 off로
바꿔놓은 것이 아닌가 하는데.
근데 byus.net 을 쓰는 다른 사람들의 프로그램들은 멀쩡히 돌아가고, 심지어 꽃지야~
님의 제로보드도 멀쩡하게 돌아가는데, 왜 저것만 안되느냐는 사실. 제로보드는 여러
군데에서 쓰이는 것을 가정했기때문에 프로그램에서 그걸 대비해서 프로그래밍되어
있다고 짐작은 하겠는데, 왜 다른 사람의 홈페이지의 것은 잘 돌아가는지...
아직까지 그게 가장 큰 의문이다.
여튼, 이번에 고친 것으로 어떤 서버에서든지 register_globals 에 상관없이 돌아가게
해놨다는 데에 의의를 둬보자.






