Outsider's Dev Story

Stay Hungry. Stay Foolish. Don't Be Satisfied.
RetroTech 팟캐스트 44BITS 팟캐스트

잘못된 Javascript의 사용에 대해서....

제목이 좀 거창하기는 한데(ㅡ..ㅡ) 을 아예 이해를 못한채 개발된 코드를 좀 보게 된다. 개발이라는 것이 순수 자기 머릿속에 있는 것만 가지고 처음부터 끝까지 개발하는 사람이 어디 있겠는가... 요즘 같으면 개발능력이 검색 능력이라고 농담할 정도로 소스가 인터넷에 널려있고 그걸 갔다가 잘 조합하다보면 그럭저럭 돌아간다. 또한 사수나 이전에 구축되어 있는 사이트들도 있고.... 근데 여기서 돌아가는 동작을 이해하지 못하면 결국 잘못된 소스가 나올 경우가 많다.

실용주의 프로그래머에 보면 "디버깅을 하지 못하는 것은 원래 어떻게 돌아갔는지 몰랐기 때문이다."라는 말이 있다. 철저히 공감한다.






최근에 본 소스에 대해서 얘기를 해보려고 한다. 머 그녀석이 작성한 소스는 아니었지만 이런 내용을 보면 프로젝트의 일원으로써 기분나쁠수도 있지만 머 잘못된 것은 잘못된거다. 약간 상황상 초기단계에도 그 프로젝트의 소스를 좀 보았었는데 초반에도 많이 잘못된 부분이 있었는데 내가 관여할 상황이 아니기 때문에 그냥 나뒀다. 몇달만에 다시 보았을때는 괜찮은 사이트의 모습을 갖추고 있었지만 내부는 영 부실했다. 로그인 체크가 이런식으로 되어 있었다.


if (isLogin) {
    // 로그인되었을 때의 동작
} else {
    // 로그인 안되었을때의 동작   
 }


동작은 중요하지 않으므로 그냥 한글로 처리했다. 아이디/패스워드를 입력하면 서블릿을 호출해서 결과값을 xml로 가져와서 파싱한다. 그리고 결과값을 isLogin에 넣어서 로그인 여부를 보여준다. 아마 작성자는 로그인을 하지 않았을때 권한이 없는 메뉴에 대해서 페이지가 넘어갔다가 오는 것도 낭비라고 생각한것 같다. Ajax로 할때 많이 하듯이 로그인 처리도 현재 페이지에서 바로 처리했고 권한이 없는 메뉴에 대해서 isLogin이라는 자바스크립트 변수로 접근하지 못하게 막고 있다.


이건 완전히 잘못됐다. 이건 브라우저 주소창에 다음과 같은 한줄만 입력하면 isLogin의 값을 접속자 맘대로 바꿔버릴 수 있다.

javascript:isLogin=true;void 0;

정확히는 모르겠지만 내가 보기엔 이건 해킹도 아니고 XSS(크로스 사이트스크립팅)도 아니다. 그냥 잘못만든거다. 보안 문제는 서버쪽에서 체크해야지 클라이언트단이 자바스크립트에서 하겠다는 생각은 잘못 된것이다.(물론 자바스크립트에서도 신경써야하는 보안문제가 있지만...) 자바스크립트는 유저 편의성과 HTML강화를 위해서 제공하는 것이지 자바스크립트로 모든 걸 다 할 수는 없다. Ajax를 쓰다보면 자바스크립트에서 처리해야 하는 부분도 있지만 이부분은 UI를 위한 부분이지 검증을 위한 부분이 아니기 때문에 검정을 Javascript에 의존하지 말고 당연히 서버쪽에서도 재확인 해주어야 한다.





여기서 또하나를 보자


<script type="text/javascript">
var usrId = "<% session.getAttribute("userId") %>";

if (userid != null) {
      로그인에 대한 동작
} else {
      <% session.remove("userId"); %>
      <% session.remove("memberType"); %>
}
</script>


위 코드가 로그인하고 메뉴에 들어간 페이지에 들어있던 자바스크립트 코드이다. 무엇이 잘못된지 알겠는가.... 해당부분만 잘라온 라서 약간 헷갈릴수도 있지만 이건 JSP와 자바스크립트의 동작을 전혀 이해하지 못한 것이다. 그냥 보면 뭘 하고 싶었는지 까지는 이해할 수 있다. 세션에 값이 있으면 로그인하고 세션에 값이 없으면 로그인에 문제가 있었다고 생각하고 세션을 초기화 해주겠다는 것이다. 결론적으로 이 코드는 돌아가지 않는다.

아주 단순한 원리인데 인터넷에서 사람들이 질문하는 것을 봐도 이걸 이해하지 못하는 사람들을 꽤 많이 볼 수 있다.

웹이라는 것은 서버가 있다. 서버에는 웹서버가 있고 WAS(컨테이너포함)라고 얘기하는 웹어플리케이션서버가 있다. 설정나름이지만 이렇게 존재하는 이유는 서버에서 컴파일등의 동작이 필요없는 html, javscript파일, css, 이미지등을 사용자가 요청이 오면 그냥 돌려준다. 그렇지 않고 jsp등 서버의 해석이 필요한 페이지는 WAS가 페이지를 해석해서 나온 결과값을 원래의 html파일에 넣어서 사용자에게 돌려준다. 그러면 사용자의 웹브라우저(IE, Firefox 등등)가 해당 페이지를 받아서 렌더링을 한다. 여기서 웹브라우저가 html을 렌더링해서 보여주고 javascript를 해석해서 해당 동작을 수행한다.



이게 간단히 요약한 동작방식이다. 위에서 보듯이 jsp코드와 자바스크립트는 그 수행시점과 장소가 완전히 다르다. 그 순서로 보면 저위의 코드는 if문의 참여부의 상관없이 무조건 session.remove()가 동작한다. WAS는 jsp의 <% %>안에 있는 스크립틀릿 코드만 수행하지 그 외의 부분은 전혀 신경쓰지 않기 때문에....

그렇기 때문에 저 사이트는 첫페이지에서 세션을 심고는 두번째 페이지에서 무조건 세션을 날려버린다. 이런 동작방식을 이해하고 있어야 개발할 때 헷갈리지 않고 많이 나오는 질문중에 하나인 자바스크립트의 변수에 있는 값을 jsp의 변수에 넣으려고 하는 것이 불가능한지를 이해할 수 있다. (물론 js와 jsp간에 서로 값을 주고 받을 수 있는 프레임워크는 존재하지만 여기선 그 얘기가 아니므로....)



항상 어디서나 기본적인 개념이 중요하다는 생각......

2008/08/26 01:21 2008/08/26 01:21