차이
문서의 선택한 두 판 사이의 차이를 보여줍니다.
이전 판 | |||
— | guide:ajax_개발_보안_가이드 [2024/04/04 05:12] (현재) – 바깥 편집 127.0.0.1 | ||
---|---|---|---|
줄 1: | 줄 1: | ||
+ | ====== Ajax 보안 개발 가이드 ====== | ||
+ | ===== 1절. Ajax 취약점 및 대응방안 ===== | ||
+ | Ajax(Asynchronous Java Script and XML)는 비동기식 JavaScript를 사용하는 웹 애플리케이션 개발 방식으로서 Http 프로토콜을 통해 XML 데이터를 웹 서버와 교환한다. 따라서 웹 페이지는 동적으로 업데이트 되는 기존 웹과 는 달리 응답속도가 떨어지지 않는다. Ajax는 기술이 아니며, 오히려 여러가지 기술이 복합된 방법론 또는 패턴에 더 가깝다. 해당 문서에서는 Ajax에서 나타날수 있는 위험 요소에 대한 보안 대책에 대해서 다루고있다. 또한 Ajax는 기존에 웹과 함께 구현되는 경우가 많으므로 해당 보안가이드 라인에 제시된 내용 외에도 기존 웹에서 발생하는 취약점(OWASP TOP 10)도 고려하여 개발시에 적용되어야 한다. | ||
+ | ==== 1. 입력값 검증 ==== | ||
+ | === 가. XSS(Cross-site Scripting) in Ajax === | ||
+ | XSS(Cross-site Scripting)는 해커들이 웹 어플리케이션에 몰래 침투하기 위해 이용하는 가장 일반적인 어플리케이션 계층 공격 중에 하나이다. JavaScript로 구성된 Ajax에게 XSS는 치명적인 공격이 될 수 있다. 일반 사용자에게 악의적인 스크립트를 실행시키는 공격 기법 종류와 발생 지점에 따라서 위험요소를 분류 하였으며 해당 취약점에 대해서는 공통적으로 XSS 취약점에 대한 보안대책이 적용된다. | ||
+ | |||
+ | == (1) 위험 요소 == | ||
+ | == Malformed JS Object serialization (부적절한 JavaScript 객체사용) == | ||
+ | JavaScript는 객체지향 프로그래밍을 제공하기 때문에 사용자가 원하는 많은 임의의 객체를 만들 수 있다. New object()를 사용하여 새로운 객체를 만들거나 다음과 같은 코드를 통하여 만들수 있다. | ||
+ | < | ||
+ | message = { | ||
+ | from : " | ||
+ | to : " | ||
+ | subject : "I am fine", | ||
+ | body : "Long message here", | ||
+ | showsubject : function(){document.write(this.subject)} | ||
+ | }; | ||
+ | </ | ||
+ | 위 코드는 이메일 작성시에 필요한 각 필드를 message 오브젝트로 간단히 작성한 예제이다. 작성된 message 개체를 JavaScript 코드 또는 Ajax를 이용하여 사용된다. | ||
+ | \\ | ||
+ | 악의적인 사용자는 게시물이나 메일 제목에 악의적인 스크립트를 삽입하여 메일을 열람한 사용자에게 XSS 공격을 수행할 수 있다. | ||
+ | \\ | ||
+ | JavaScript 객체는 메소드와 중요 데이터를 모두 소유할 수 있기 때문에 부적절한 JavaScript 객체사용은 악의적인 코드 삽입으로부터 보안 허점이 발생하여 타 사용자가 공격 당할 수 있다. | ||
+ | == JSON pair injection == | ||
+ | JavaScript 객체 표기법 (json)은 자료를 주고 받을 때 경량의, 텍스트 기반, 언어로 독립적인 데이터 교환 포맷이다. ECMAScript 언어의 하위 세트에 기반하고 있으며(JavaScript 언어의 일부이다.), | ||
+ | \\ | ||
+ | 그 형식은 JavaScript의 구문 형식을 따르지만, | ||
+ | Json 은 web 2.0 어플리케이션에서 매우 효과적인 데이터 교환 형식을 제공한다. 개발자는 매우 자주 DOM 에서 필요한 정보를 가져오기위해 Ajax에서 JSON를 사용하는데 다음과 같은 문제점이 존재한다. | ||
+ | \\ | ||
+ | 아래는 즐겨찾기 객체를 다른이름으로 만든 간단한 코드이다. | ||
+ | \\ | ||
+ | {" | ||
+ | \\ | ||
+ | 위 코드중 공격자는 Desc 또는 Link 부분에 악의적인 스크립트를 삽입하여 스크립트를 삽입하여 XSS 공격을 실행할 수 있다. | ||
+ | == JS Array poisoning == | ||
+ | JS array는 객체 직렬화를 위한 가장 중요한 객체 중 하나이며, | ||
+ | <code | 예제> | ||
+ | new Array(“Laptop”, | ||
+ | </ | ||
+ | 위의 배열은 경매사이트에서 중고 노트북거래시에 데이터를 전송하기 위한 배열이다. 만약에 배열 객체가 적절하지 않다면 서버사이드에서 사용자가 마지막 필드에 삽입한 스크립트에 대해서 검증해야 한다. 이 공격기법은 브라우저를 위태롭게 하거나 공격에이전트에 의해서 공격기법으로 사용될수 있다. | ||
+ | == Manipulated XML stream == | ||
+ | Ajax은 다양한 위치에서 XML을 불러온다. 이러한 XML 블록들은 SOAP, REST 또는 XML-RPC등 웹서비스 구동으로 시작된다. 이러한 웹서비스들은 Third Party로 부터 Proxy brideges를 통해 이용된다. | ||
+ | \\ | ||
+ | 만약 Third Party XML Stream이 공격자에게 조작된다면 공격자는 악성 컨텐츠를 삽입할 수 있다. | ||
+ | \\ | ||
+ | 브라우저가 가지고 있는 작은 XML parser가 이 스트림을 처리하며, | ||
+ | == One-click bomb == | ||
+ | Web 2.0 어플리케이션은 그 자체인 처음 인스턴스는 안전할지 모르지만, | ||
+ | == DOM Injection == | ||
+ | DOM(Document Object Model)은 객체지향 모델로써 구조화된 문서를 표현하는 형식으로 동적으로 문서의 내용 및 구조, 스타일에 스크립트를 통해 다이나믹하게 접근 변경할 수 있는 수단이다. JavaScript 코드로 DOM을 프로그램적으로 수정하는 것이 API로 가능하도록 되어있어 아래와 같은 JavaScript 객체를 이용할 경우 XSS 공격에 노출될 수 있다. | ||
+ | * Raw HTML | ||
+ | * document.write(…) | ||
+ | * document.writeln(…) | ||
+ | * document.body.innerHtml=… | ||
+ | * Directly modifying the DOM (including DHTML events) | ||
+ | * document.forms[0].action=… | ||
+ | * document.attachEvent(…) | ||
+ | * document.create…(…) | ||
+ | * document.execCommand(…) | ||
+ | * document.body. … | ||
+ | * window.attachEvent(…) | ||
+ | * Replacing the document URL | ||
+ | * document.location=… | ||
+ | * document.location.hostname=… | ||
+ | * document.location.replace(…) | ||
+ | * document.location.assign(…) | ||
+ | * document.URL=… | ||
+ | * window.navigate(…) | ||
+ | * Opening/ | ||
+ | * document.open(…) | ||
+ | * window.open(…) | ||
+ | * window.location.href=… | ||
+ | * Directly executing script, e.g.: | ||
+ | * eval(…) | ||
+ | * window.execScript(…) | ||
+ | * window.setInterval(…) | ||
+ | * window.setTimeout(…) | ||
+ | DOM을 이용하기 위한 클라이언트 자바 스크립트 객체에 대한 검증을 실시하고. Server Side에서 사용자 입력값 중 특정 기능을 가질 수 있는 특수문자를 아래와 같이 필터링을 하여 악성스크립트의 삽입을 제한한다. | ||
+ | \\ | ||
+ | 다음과 같이 허용 가능한 문자에 대하여 필터링을 한다. | ||
+ | <code | 취약한 소스 예제> | ||
+ | < | ||
+ | Var pos=document.URL.indexOf(“name=”)+5; | ||
+ | Document.write(document.URL.substring(pos.document.URL.length)); | ||
+ | </ | ||
+ | </ | ||
+ | <code | 안전한 소스 예제> | ||
+ | < | ||
+ | var pos=document.URL.indexOf(" | ||
+ | var name=document.URL.substring(pos, | ||
+ | if (name.match(/ | ||
+ | { | ||
+ | document.write(name); | ||
+ | } | ||
+ | else | ||
+ | { | ||
+ | window.alert(" | ||
+ | } | ||
+ | </ | ||
+ | </ | ||
+ | == (2) 보안 대책 == | ||
+ | XSS는 공격자들이 웹 어플리케이션에 몰래 침투하기 위해 이용하는 가장 일반적인 공격 중에 하나이다. XSS는 JavaScript를 통해 이루어지는 공격이므로 JavaScript로 구성된 Ajax에게 치명적인 공격이 될 수 있다. Ajax가 비동기 방식으로 웹 페이지를 불러오는 과정에서 악성 스크립트가 삽입된다면 Ajax의 특성상 사용자는 공격 당하고 있다는 사실을 모른 채 공격 코드가 사용자의 시스템에서 실행된다. 또한 Ajax는 한번 신뢰된 사이트는 지속적으로 신뢰를 하게 되기 때문에 방화벽 등을 우회할 수 있다는 것이 가장 큰 문제점이라 할 수 있다. | ||
+ | \\ | ||
+ | 결국 악의적인 사용자는 Ajax의 XSS 취약점을 가지고 여러 가지 방법으로 악성 스크립트를 삽입하여 임의의 사용자의 세션 및 쿠키, 패스워드, | ||
+ | \\ | ||
+ | - Server-Side에서 입력값 검증이 이루어져야 한다. | ||
+ | - 사용자 입력처리 모듈을 사용하여 비정상적인 악성 스크립트 삽입이 되지 않도록 필터링을 해야 한다. | ||
+ | - 사용자 계정 및 패스워드 타입\\ 사용자 인증 부분에는 SQL Injection 유형을 차단하기 위해 숫자, 영문 대/ | ||
+ | - 게시판 타입\\ 입력문자의 타입(영문 대/ | ||
+ | - 주민등록번호 타입\\ 주민등록번호를 입력 받기 위해 숫자형태의 6~7자리를 정의한다. | ||
+ | - 날짜타입\\ 사전에 정의된 날짜 형식을 사용하거나 날짜형식에 맞는 표현식을 작성한다. | ||
+ | - 숫자타입\\ 계좌이체의 경우 이체금액을 음수(-)로 입력할 경우 잔액계좌에는 오히려 금액만큼 증가될 수 있기 대문에 금액을 입력 받는 부분은 양수(+)만을 입력 해야한다. | ||
+ | - 기타 취약성 문자\\ < > \ ” | ||
+ | \\ | ||
+ | ^ From ^ To ^ | ||
+ | | < | < | | ||
+ | | > | > | | ||
+ | | ( | ( | | ||
+ | | ) | ) | | ||
+ | | # | # | | ||
+ | | & | & | | ||
+ | == Anti XSS Ajax == | ||
+ | XSS는 대부분의 웹 개발자들이 현재까지 여전히 고통 받는 문제점이라고 이야기한다. 검증 없이 사용자 입력 값을 출력하는 코드의 한 라인 한 라인의 모든 사용자 입력 값을 검증하는 게 힘들기 때문에, 한번 취약한 몇 개의 공격 메소드들을 웹 어플리케이션 사용자에게 적용 된다면 이 공격들은 방어 할 수 없을 정도로 위험할 수 있다. | ||
+ | \\ | ||
+ | 우리가 이미 알다시피, | ||
+ | \\ | ||
+ | - XSS 공격은 기본적으로 사용자 단에서 발생된다. | ||
+ | - XSS 공격은 보통 javaScript를 이용해서 발생된다. | ||
+ | \\ | ||
+ | 위의 두 관점을 살펴보면 우리는 서버 단에의 방어와 검증을 빠져 나오는 XSS공격을 멈추기 위해 클라이언트 단에서 이를 막아야 한다는 결론이 나온다. 이는 XSS공격이 < | ||
+ | \\ | ||
+ | 지금 당면한 진짜 과제는 어떻게 정상적인 javascript에서 공격자 javascript를 확인하는가 하는 것이다. | ||
+ | |||
+ | 위의 예제에서 모든 javascript에 사용되는 랜덤 값을 발생 시키기 위해 rand()함수를 사용했다. 사용자 악성 스크립트가 아래와 같이 보이는 키로그 스크립트에 보내지는 동안 그의 패스워드를 변경하는 것은 경고 될 수 있다. 이런, rand()함수는 다른 악성 script로부터 정상적인 모든 javascript를 서명하기 위해 사용된다. | ||
+ | < | ||
+ | <? | ||
+ | $file = fopen(" | ||
+ | $timestamp = date(" | ||
+ | fwrite($file, | ||
+ | fwrite($file, | ||
+ | fclose($file); | ||
+ | ?> | ||
+ | </ | ||
+ | 악성 스크립트 컨텐츠들은 로그를 남길수 있는데, 후에 사이트 관리자는 이 공격을 분석 할 수 있다. 로그 파일은 다음과 같다. | ||
+ | < | ||
+ | -------------------- | ||
+ | Fri 20th Jul,2007 12:38 am | ||
+ | alert(\" | ||
+ | -------------------- | ||
+ | Fri 20th Jul,2007 12:41 am | ||
+ | alert(\" | ||
+ | -------------------- | ||
+ | </ | ||
+ | 또한 우리는 사용자가 타고 온 링크에 referral URL 더 중요한 정보를 남길 수 있다. 그래서 우리는 어떻게 공격자가 공격했는지 메일이나 다른 방법으로 알 수 있을 것이며, 사용자 이름을 기록할 수 있고, 도움을 요청하기 위해 연락하거나 또한 그 공격에 대해 더 많은 정보를 얻을 수도 있다. | ||
+ | \\ | ||
+ | \\ | ||
+ | Ajax 코딩 기법을 사용해서 사용자나 운영자에게 미리 경고하는것이 가능하고, | ||
+ | \\ | ||
+ | \\ | ||
+ | 그러나 이 기법은 큰 과제를 남기는데, | ||
+ | \\ | ||
+ | \\ | ||
+ | JavaScript가 sleep()함수를 지원한다면 이는 아주 좋은 해결책이 될 것이다. 그러나 JavaScript는sleep함수를 지원하지 않는다. | ||
+ | \\ | ||
+ | \\ | ||
+ | 다른 해결책은 완전한 Ajax 웹 페이지에 XMLHttpRequest 객체를 사용해서 HTML 컨텐츠를 요청하는 것이다. 그리고 사용자가 클릭할 때마다 그 페이지를 검증 JavaScript가 담긴 새로운 링크로 업데이트 하는 것이다. 그러나 이 작업은 많은 부하가 걸릴 것이다. | ||
+ | === 나. SQL Injection in Ajax === | ||
+ | 일반적인 웹 어플리케이션은 클라이언트 측의 쿼리 요청에 대해 서버에서 결과 데이터를 파싱하여 사용자가 보는 HTML에서 결과를 출력해 준다. 하지만 Ajax 어플리케이션은 서버에서 원시 데이터의 결과를 클라이언트에게 돌려주고 클라이언트는 받은 원시 데이터를 분석하여 HTML로 변형시키도록 설계하는 경우가 있다. | ||
+ | \\ | ||
+ | \\ | ||
+ | 성능 측면에서 이런 접근 방법은 상당히 좋다. 데이터 변형 루틴은 시간이 걸리므로, |