차이

문서의 선택한 두 판 사이의 차이를 보여줍니다.

차이 보기로 링크

양쪽 이전 판 이전 판
다음 판
이전 판
guide:ajax_개발_보안_가이드 [2013/11/29 17:18]
121.140.124.172
guide:ajax_개발_보안_가이드 [2013/11/29 17:38]
121.140.124.172
줄 133: 줄 133:
 \\ \\
 지금 당면한 진짜 과제는 어떻게 정상적인 javascript에서 공격자 javascript를 확인하는가 하는 것이다. ​ 우리는 정상적인 javascript 어떤 시그니쳐 같은 것을 적용하여 웹 페이지에 삽입된 악의적인 javascript인지 확인할 수 있고, 다른 javascript를 사용해 공격자의 비정상적인 javascript인지를 확인해 페이지 내용을 필터 할 수 있을 것이다. 다음은 클라이언트 단에서 비정상적인 javascript가 발견되었을 때 비정상 적인 행동을 유발할 수 있는 javascript의 예이다. 지금 당면한 진짜 과제는 어떻게 정상적인 javascript에서 공격자 javascript를 확인하는가 하는 것이다. ​ 우리는 정상적인 javascript 어떤 시그니쳐 같은 것을 적용하여 웹 페이지에 삽입된 악의적인 javascript인지 확인할 수 있고, 다른 javascript를 사용해 공격자의 비정상적인 javascript인지를 확인해 페이지 내용을 필터 할 수 있을 것이다. 다음은 클라이언트 단에서 비정상적인 javascript가 발견되었을 때 비정상 적인 행동을 유발할 수 있는 javascript의 예이다.
-<​code>​ +
-1 :<​body>​ +
-2 :<​html>​ +
-3 :<? +
-4 ://our signature will be a random number generated by the server +
-5 :$signature = rand(); +
-6 :?> +
-7 :<!-- here is our legitimate script with the signature as its element id --> +
-8 :<script id="<?​ echo $signature ?>">​ +
-9 :​alert("​hello world"​) +
-10 :</​script>​ +
-11 :<!-- here is the injected attacker script that doesn'​t have the signature --> +
-12 :<​script>​ +
-13 :​alert("​evil code"​) +
-14 :</​script>​ +
-15 :<!-- here is a more evil script where the attacker will try to imitate the signature --> +
-16 :<script id="​1234">​ +
-17 :​alert("​more evil code"​) +
-18 :</​script>​ +
-19 :<!-- here is the script that will do the check and of course it have the signature too --> +
-20 :<script id="<?​ echo $signature ?>">​ +
-21 ://here we gather all the script tags elements in one array +
-22 :var scripts = document.getElementsByTagName("​script"​) +
-23 :for(var i = 0; i < scripts.length;​ i++) +
-24 :  if(scripts[i].id != null) +
-25 :  { +
-26 :    //then we compare it with our signature if it have one, if it’s invalid we warn the user/​admin +
-27 :    if(scripts[i].id != <? echo $signature ?>) +
-28 :      warn(scripts[i].innerHTML) ​  +
-29 :  } +
-30 :  else //else if there is no signature in the 1st place we warn the user/​admin +
-31 :    warn(scripts[i].innerHTML) +
-32 :  +
-33 :function warn(attackscript) +
-34 :{ +
-35 :  //here we create our XMLHttpRequest object +
-36 :  xmlHttp=GetXmlHttpObject() +
-37 :  //and here we create a request string to our logger script then send the attacker script +
-38 :  //to be logged for later analysis so we can tell what exactly happened +
-39 :  var url="​http://​host/​logger.php?​attackscript="​ + attackscript +
-40 :  xmlHttp.open("​GET",​url,​true) +
-41 :  xmlHttp.send(null) +
-42 :  //then we warn the user about what is going on and advice him/her to change his/her password +
-43 :  alert("​put your favorite warning message here"​) +
-44 :} +
-45 ://the rest of this code is the code that is responsible of creating  +
-46 ://the XMLHttpRequest object for different browsers +
-47 :function GetXmlHttpObject() +
-48 :{ +
-49 :  var xmlHttp=null;​ +
-50 :  try +
-51 :    { +
-52 :    // Firefox, Opera 8.0+, Safari +
-53 :    xmlHttp=new XMLHttpRequest();​ +
-54 :    } +
-55 :  catch (e) +
-56 :    { +
-57 :    // Internet Explorer +
-58 :    try +
-59 :      { +
-60 :      xmlHttp=new ActiveXObject("​Msxml2.XMLHTTP"​);​ +
-61 :      } +
-62 :    catch (e) +
-63 :      { +
-64 :      xmlHttp=new ActiveXObject("​Microsoft.XMLHTTP"​);​ +
-65 :      } +
-66 :    } +
-67 :  return xmlHttp; +
-68 :} +
-69 :</​script>​ +
-70 :</​body>​ +
-71 :</​html>​ +
-</​code>​+
 위의 예제에서 모든 javascript에 사용되는 랜덤 값을 발생 시키기 위해 rand()함수를 사용했다. 사용자 악성 스크립트가 아래와 같이 보이는 키로그 스크립트에 보내지는 동안 그의 패스워드를 변경하는 것은 경고 될 수 있다. 이런, rand()함수는 다른 악성 script로부터 정상적인 모든 javascript를 서명하기 위해 사용된다. 위의 예제에서 모든 javascript에 사용되는 랜덤 값을 발생 시키기 위해 rand()함수를 사용했다. 사용자 악성 스크립트가 아래와 같이 보이는 키로그 스크립트에 보내지는 동안 그의 패스워드를 변경하는 것은 경고 될 수 있다. 이런, rand()함수는 다른 악성 script로부터 정상적인 모든 javascript를 서명하기 위해 사용된다.
 <​code>​ <​code>​
줄 227: 줄 155:
 </​code>​ </​code>​
 또한 우리는 사용자가 타고 온 링크에 referral URL 더 중요한 정보를 남길 수 있다. 그래서 우리는 어떻게 공격자가 공격했는지 메일이나 다른 방법으로 알 수 있을 것이며, 사용자 이름을 기록할 수 있고, 도움을 요청하기 위해 연락하거나 또한 그 공격에 대해 더 많은 정보를 얻을 수도 있다. 또한 우리는 사용자가 타고 온 링크에 referral URL 더 중요한 정보를 남길 수 있다. 그래서 우리는 어떻게 공격자가 공격했는지 메일이나 다른 방법으로 알 수 있을 것이며, 사용자 이름을 기록할 수 있고, 도움을 요청하기 위해 연락하거나 또한 그 공격에 대해 더 많은 정보를 얻을 수도 있다.
 +\\
 \\ \\
 Ajax 코딩 기법을 사용해서 사용자나 운영자에게 미리 경고하는것이 가능하고,​ 이 점은 눈치 채지 못하게 하면서 공격자가 어플리케이션에 XSS 취약성을 테스트 하는것을 더 어렵게 만들 것이다. Ajax 코딩 기법을 사용해서 사용자나 운영자에게 미리 경고하는것이 가능하고,​ 이 점은 눈치 채지 못하게 하면서 공격자가 어플리케이션에 XSS 취약성을 테스트 하는것을 더 어렵게 만들 것이다.
 +\\
 \\ \\
 그러나 이 기법은 큰 과제를 남기는데,​ 이것은 단지 사고가 일어나서 사용자가 손해를 입은 후에 경고를 한다는 점이다. ​ 이는 웹서버로부터 브라우져에 의해 순차적으로 읽히는 순차적 언어인 JavaScript의 특징때문이다. 반면에 이는 아직 읽지 않은 스크립트에 대해서는 파싱하지 못할 것이다. 그러면 순차적인 언어를 이용하여 페이지가 로딩 되는 동안 기다리게 만들거나 각각에 milliseconds 정도의 대기 시간을 둘 수 있다. 그러나 실행되기 전에 악성 스크립트가 로드된 때를 정확하게 알고 이를 수행하기가 힘들다. 그러나 이 기법은 큰 과제를 남기는데,​ 이것은 단지 사고가 일어나서 사용자가 손해를 입은 후에 경고를 한다는 점이다. ​ 이는 웹서버로부터 브라우져에 의해 순차적으로 읽히는 순차적 언어인 JavaScript의 특징때문이다. 반면에 이는 아직 읽지 않은 스크립트에 대해서는 파싱하지 못할 것이다. 그러면 순차적인 언어를 이용하여 페이지가 로딩 되는 동안 기다리게 만들거나 각각에 milliseconds 정도의 대기 시간을 둘 수 있다. 그러나 실행되기 전에 악성 스크립트가 로드된 때를 정확하게 알고 이를 수행하기가 힘들다.
 \\ \\
-JavaScript가 sleep()함수를 지원한다면 이는 아주 좋은 해결책이 될 것이다. 그러나 ​javascript는sleep함수를 지원하지 않는다.+\\ 
 +JavaScript가 sleep()함수를 지원한다면 이는 아주 좋은 해결책이 될 것이다. 그러나 ​JavaScript는sleep함수를 지원하지 않는다. 
 +\\
 \\ \\
 다른 해결책은 완전한 Ajax 웹 페이지에 XMLHttpRequest 객체를 사용해서 HTML 컨텐츠를 요청하는 것이다. 그리고 사용자가 클릭할 때마다 그 페이지를 검증 JavaScript가 담긴 새로운 링크로 업데이트 하는 것이다. 그러나 이 작업은 많은 부하가 걸릴 것이다. 다른 해결책은 완전한 Ajax 웹 페이지에 XMLHttpRequest 객체를 사용해서 HTML 컨텐츠를 요청하는 것이다. 그리고 사용자가 클릭할 때마다 그 페이지를 검증 JavaScript가 담긴 새로운 링크로 업데이트 하는 것이다. 그러나 이 작업은 많은 부하가 걸릴 것이다.
 === 나. SQL Injection in Ajax === === 나. SQL Injection in Ajax ===
 일반적인 웹 어플리케이션은 클라이언트 측의 쿼리 요청에 대해 서버에서 결과 데이터를 파싱하여 사용자가 보는 HTML에서 결과를 출력해 준다. 하지만 Ajax 어플리케이션은 서버에서 원시 데이터의 결과를 클라이언트에게 돌려주고 클라이언트는 받은 원시 데이터를 분석하여 HTML로 변형시키도록 설계하는 경우가 있다. 일반적인 웹 어플리케이션은 클라이언트 측의 쿼리 요청에 대해 서버에서 결과 데이터를 파싱하여 사용자가 보는 HTML에서 결과를 출력해 준다. 하지만 Ajax 어플리케이션은 서버에서 원시 데이터의 결과를 클라이언트에게 돌려주고 클라이언트는 받은 원시 데이터를 분석하여 HTML로 변형시키도록 설계하는 경우가 있다.
 +\\
 \\ \\
 성능 측면에서 이런 접근 방법은 상당히 좋다. 데이터 변형 루틴은 시간이 걸리므로,​ 클라이언트 단에서 이를 처리하면 속도 향상의 결과를 가져올 수 있다. ​ 하지만 잠재적인 보안 문제가 있다. 서버가 원시 결과를 클라이언트에 보내므로 쿼리 명령 로직에 어떠한 형태로든 인젝션 공격을 할 수 있기 때문이다. 수천개의 참/거짓 질의를 하는 대신에, 데이터 자체만을 요청해 받을 수 있다. 대개 뒷단에 저장된 데이터는 한 두개의 요청문만으로 모두 추출할 수 있다. 요청 횟수가 적으므로 IDS와 같은 보안장비에서 탐지될 가능성이 낮아지고 결국 공격 성공 가능성이 높아지게 된다. 성능 측면에서 이런 접근 방법은 상당히 좋다. 데이터 변형 루틴은 시간이 걸리므로,​ 클라이언트 단에서 이를 처리하면 속도 향상의 결과를 가져올 수 있다. ​ 하지만 잠재적인 보안 문제가 있다. 서버가 원시 결과를 클라이언트에 보내므로 쿼리 명령 로직에 어떠한 형태로든 인젝션 공격을 할 수 있기 때문이다. 수천개의 참/거짓 질의를 하는 대신에, 데이터 자체만을 요청해 받을 수 있다. 대개 뒷단에 저장된 데이터는 한 두개의 요청문만으로 모두 추출할 수 있다. 요청 횟수가 적으므로 IDS와 같은 보안장비에서 탐지될 가능성이 낮아지고 결국 공격 성공 가능성이 높아지게 된다.