Javascript에서 크로스사이트 스크립트(XSS)

크로스사이트 스크립트(XSS)

웹사이트에 악성코드를 삽입하는 공격방법입니다. 공격자는 대상 웹 응용프로그램의 결함을 이용해 악성코드(일반적으로 클라이언트 측 자바스크립트 사용)를 사용자에게 보냅니다. XSS 공격은 일반적으로 애플리케이션 호스트 자체보다 사용자를 목표로 삼는다.
XSS는 공격자가 웹 응용프로그램을 속여 브라우저에서 실행될 수 있는 형식의 데이터를 다른 사용자에게 전달할 때 발생한다. 공격자가 임의로 구성한 기본 웹 코드 외에도 악성코드 다운로드, 플러그인 또는 미디어 콘텐츠를 이용할 수도 있다. 사용자가 폼 양식에 입력한 데이터 또는 서버에서 클라이언트 단말(브라우저) 전달된 데이터가 적절한 검증 없이 사용자에게 표시되도록 허용되는 경우 발생한다.

XSS 공격의 종류

XSS 공격에는 크게 3가지 유형의 방식이 있다.

🟢 Reflective XSS (or Non-persistent XSS)

Reflective XSS는 공격 코드를 사용자의 HTTP 요청에 삽입한 후, 해당 공격 코드를 서버 응답 내용에 그대로 반사(Reflective)시켜 브라우저에서 실행하는 공격 기법입니다. Reflective XSS 공격을 수행하려면 사용자로 하여금 공격자가 만든 서버로 데이터를 보내도록 해야 합니다. 이 방법은 보통 악의적으로 제작된 링크를 사용자가 클릭하도록 유도하는 방식을 수반합니다. 공격자는 피해자가 취약한 사이트를 참조하는 URL을 방문하도록 유도하고, 피해자가 링크를 방문하면 스크립트가 피해자의 브라우저에서 자동으로 실행됩니다. 대부분의 경우, Reflective XSS 공격 메커니즘은 공개 게시판, 피싱 이메일, 단축 URL 또는 실제와 유사한 URL을 사용합니다.
예를 들어

이러한 input 창에 "안녕하세요" 라고 입력했을때 안녕하세요 라고 알림이 오면 해당하는 input은 XSS 공격에 취약할 가능성이 높습니다. 추가적으로 다음과 같은 간단한 스크립트를 입력해 실행되는지 확인해봅니다.

<script>alert(document.cookie)</script>

XSS 공격에 취약한 상태이면 세션id 쿠키값을 그대로 받을수가 있습니다. 해당하는 세션id 와 아이피로 사용자에 대한 모니터링을 하며 개인정보와 입력된 아이디 비밀번호 또한 가져올수 있습니다.

🟢 Persistent XSS (or Stored XSS)

Persistent XSS는 신뢰할 수 없거나 확인되지 않은 사용자 입력(코드)이 서버에 저장되고, 이 데이터가 다른 사용자들에게 전달될 때 발생합니다. Persistent XSS는 게시글 및 댓글 또는 방문자 로그 기능에서 발생할 수 있습니다. 해당 기능을 통해 공격자의 악성 콘텐츠를 다른 사용자들이 열람할 수 있습니다. 소셜 미디어 사이트 및 회원 그룹에서 흔히 볼 수 있는 것이 같이 공개적으로 표시되는 프로필 페이지는 Persistent XSS의 대표적인 공격 대상 중 하나입니다. 공격자는 프로필 입력 폼에 악성 스크립트를 주입해 다른 사용자가 프로필을 방문하면 브라우저에서 자동으로 코드가 실행되도록 할 수 있습니다.

🟢DOM XSS(or Client-Side XSS)

DOM XSS은 웹 페이지에 있는 사용자가 입력값을 적절하게 처리하기 위한 자바스크립트 검증 로직을 무효화 하는 것을 목표로 합니다. 공격 스크립트가 포함된 악성 URL을 통해 전달된다는 관점에서 Reflective XSS와 유사하다고 볼 수 있습니다. 그러나 신뢰할 수 있는 사이트 HTTP 응답에 페이로드를 포함하는 대신 DOM또는 문서 개체 모델을 수정해 브라우저와 독립적인 공격을 실행한다는 점에서 차이가 있습니다.
공격자는 DOM XSS 공격을 통해 세션 및 개인 정보를 포함한 쿠기 데이터를 피해자의 컴퓨터에서 공격자 시스템으로 전송할 수 있습니다. 이 정보를 사용해 특정 웹사이트에 악의적인 요청을 보낼 수 있으며, 피해자가 해당 사이트를 관리 할 수 있는 관리자 권한이 있는 경우 심각한 윕협을 초래할 수도 있습니다. 또한, 신뢰할 수 있는 웹 사이트를 모방하고 피해자가 암호를 입력하도록 속여 공격자가 해당 웹 사이트에서 피해자의 계정을 손상시키는 피싱(Phishing) 공격으로도 이어질 수 있습니다.

이처럼 웹 서비스 개발에 사용되는 다른 언어와 달리, 자바스크립트는 클라이언트측 코드와 서버측 코드 모두 개발이 가능한 언어로, XSS 공격 예방을 위해 클라이언트와 서버 양쪽 모두를 고려해야합니다. 서버가 생성한 HTML응답 데이터 내에 신뢰할 수 없는 데이터가 포함되거나, 위험한 자바스크립트 호출을 통해 DOM을 업데이트 하는데 사용되는 입력값이 전달될 경우 XSS 공격이 발생하게 됩니다.

안전한 코딩기법?

외부 입력값 또는 출력값에 스크립트가 삽입되지 못하도록 문자열 치환 함수를 사용하여 &<>*'/() 등을

&amp; &lt; &gt; &quot; &#x27; &#x2F; &#x28; &#x29;

로 치환하거나, 자바스크립트 라이브러리에서 제공하는 escape 기능을 사용해 문자열을 변환해야 한다. 자바스크립트에서 기본적으로 제공하는 escape() 함수는 deprecated 되어 더 이상 사용을 권장하지 않고 있으며, 그 대신 encodeURL() 또는 encodeURLComponent() 함수를 사용하면 된다. HTML 태크를 허용해야 하는 게시판에서는 허용할 HTML 태크들을 화이트리스트로 만들어 해당 태크만 지원하도록 합니다.
또한 XSS 방어 코드는 클라이언트측과 서버측에 모두 적용해야 합니다. 물론 클라이언트측 코드는 공격자가 중간에 가로채 변조하거나 코드를 수정할 수 있지만 서버로 데이터가 넘어가기 전 1차적인 방어선 역할을 해줄 수 있습니다. 흔히 말해 이제 막 해킹을 시작하는 꼬마 해커들을 잡는 수단이라고 생각하면 됩니다. 클라이언트측 코드를 조작하더라고 서버에서 사용자 입력값을 검증하면 XSS 공격을 예방할 수 있습니다. 마지막으로, 서버로부터 가져온 데이터를 클라이언트 측에서 다시 사용자에게 보여줄 때 코드가 포함된 내용일 경우에도 공격에 사용되는 문자열을 필터링해야한다.

profile
여러길중 하나의 길

0개의 댓글