XSS(Cross-Site-Scripting)란?
● XSS 는 Cross-Site-Srripting의 약자로 공격자가 웹사이트에 악성 스크립트를 삽입하여 다른 사용자 등에게 공격자가 의도한 스크립트를 실행하게 하는 공격 방법이다.
● XSS는 스크립트 언어와 취약한 코드를 공격대상으로 하며 공격의 주요 목적은 사용자의 정보를 도용하는 것이며, 로그인 입력란을 감염시켜 로그인 세부 정보와 쿠키를 탈취하는 방식으로 진행된다. 악성 소프트웨어는 사용자의 세부정보를 기록해 공격자에게 전송하고, 공격자는 해당 정보를 사용해 피해자의 계정을 제어할 수 있게 된다.
● XSS는 OWASP TOP10에 포함되어 있을정도로 자주 발생하는 공격이며 현재까지도 자주 발생하는 취약점으로 웹 해킹을 대표하는 공격이다.
● XSS는 원래 자바스크립트만을 지칭하는데 사용되었으나, 현재는 ActiveX, Flash,HTML 등과 괕은 비 JS 벡터도 포함한다.
● XSS 공격에는 크게 3가지 유형이 있다.
- 악성 스크립트가 현재 HTTP 요청에서 오는, Reflected XSS
- 악성 스크립트가 웹사이트의 데이터베이스에서 오는, Stored Xss
- 서버측 코드가 아닌 클라이언트 측 코드에 취약점이 존재하는, DOM-based XSS
Reflected XSS
가장 일반적인 XSS 공격으로 애플리 케이션이 HTTP 요청에서 데이터를 수신하고 안전하지 않은 방빗으로 즉각적인 응답에 해당 데이터를 포함할 때 발생한다.
피해자가 직접 스크립트를 실행하도록 유도하기 때문에 1회성 공격이라고 할 수있다.
다음은 Reflected XSS 의 간단한 예이다.
https://insecure-website.com/status?message=All+is+well.
<p>Status: All is well.</p>
→ 애플리 케이션은 데이터의 다른 처리를 수행하지 않으므로 공격자는 다음과 같은 공격을 쉽게 구성할 수 있다.
https://insecure-website.com/status?message=<script>/*+Bad+stuff+here...+*/</script>
<p>Status: <script>/* Bad stuff here... */</script></p>
→ 사용자가 공격자가 구성한 URL을 방문하면 공격자의 스크립트는 해당 사용자의 브라우저에서 실행되며, 이시점에서 스크립트는 모든 작업을 수행하고 공격자는 사용자가 액세스 할 수 있는 모든 데이터를 검색할 수 있다.
Stored XSS
Stored XSS (persistent or second-order XSS라고도 함)는 응용 프로그램이 신뢰할 수 없는 소스에서 데이터를 수신하고 안전하지 않은 방식으로 이후 HTTP 응답에 해당 데이터를 포함할 때 발생한다.
게시글, 사용자 정보등 한번 저장되면 장기적으로 XSS 공격코드가 웹 서비스에 남아 사용자에게 지속적으로 피해를 줄 수 있는 XSS를 의미하며 프로필 저장, 게시글 작성, 댓글 작성등의 기능에서 많이 나타난다.
다음은 Stored XSS의 간단한 예이다
<p>Hello, this is my message!</p>
→ 메시지 게시판에 사용자가 다른 사용자에게 표시되는 메시지를 작성할 수 있다.
<p><script>/* Bad stuff here... */</script></p>
→ 애플리 케이션은 데이터의 다른 처리를 수행하지 않으므로 공격자는 다른 사용자를 공격하는 메시지를 쉽게 보낼 수 있다.
DOM-based XSS
DOM-based XSS 는 Reflected,Stored XSS와 유사하지만 일반적으로 JavaScript가 URL과 같이 공격자가 제어할 수 있는 소스에서 데이터를 가져와 eval()또는 innerHTML 과 같은 동적 코드 실행을 지원하는 싱크로 전달할 때 발생한다. 이를 통해 공격자는 일반적으로 다른 사용자의 계정을 가로채는 악성 JavaScript를 실행할 수 있다.
다음은 DOM-based XSS의 간단한 예이다
var search = document.getElementById('search').value;
var results = document.getElementById('results');
results.innerHTML = 'You searched for: ' + search;
→ 위 코드에서 응용 프로그램인 일부 JavaScript를 사용하여 입력 필드에서 값을 읽고 해당 값을 HTML내의 요소에 쓴다.
You searched for: <img src=1 onerror='/* Bad stuff here... */'>
→ 공격자가 입력 필드의 값을 제어할 수 있다면 자신의 스크립트가 실행 되도록 하는 악의적인 값을 쉽게 구성할 수 있다.
XSS는 어디에 사용할수 있나?
- 피해자(사용자)로 가장한다.
- 피해자(사용자)가 수행할 수 있는 모든 작업을 수행한다.
- 피해자(사용자)가 액세스 할 수 있는 모든 데이터를 읽을 수 있다.
- 피해자(사용자)의 로그인 자격을 가져온다
- 웹사이트에 가상피해를 입힌다.
- 웹 사이트에 트로이 목마 기능을 삽입한다.
콘텐츠 보안 정책(CSP)
콘텐츠 보안 정책( CSP )은 XSS 및 기타 취약점의 영향을 완화하는 것을 목표로 하는 브라우저 메커니즘이다. CSP를 사용하는 응용 프로그램에 XSS와 유사한 동작이 포함되어 있으면 CSP가 취약점 악용을 방해하거나 방지할 수 있다. 하지만 현재 다양한 CSP를 우회기법의 출현으로 취약점을 악용할 수 있습니다.
XSS 공격 방지 방법
1. 출력시 데이터 인코딩
문맥에 따라 사용해야 하는 인코딩의 종류가 결정되기 때문에 사용자가 제어할 수 있는 데이터를 페이지에 쓰기전에 인코딩을 직접 적용해야 한다. 예를 들어 자바 스크립트 문자열 내의 값은 HTML 문맥 값과 다른 유형의 이스케이핑이 필요하다.
※ HTML 문맥에서 허용되지 않은 값을 HTML 엔터티로 변환해야 한다.
● " < " 을 다음으로 변환 : " < "
● " > " 을 다음으로 변환 : " > "
※ JavaScript 문자열 문맥에서 영어,숫자가 아닌 값은 유니코드로 이스케이프되어야 한다.
● " < " 을 다음으로 변환 : " \u003c "
● " > " 을 다음으로 변환 : " \u003e "
때로는 올바른 순서로 여러 인코딩 레이어를 적용해야 한다. 예를 들어, 이벤트 핸들러 내부에 사용자 입력을 안전하게 포함하려면 JavaScript 문맥과 HTML 문맥을 모두 처리해야 합니다. 따라서 먼저 입력을 유니코드로 이스케이프한 다음 HTML로 인코딩해야 합니다.
<a href="#" onclick="x='This string needs two layers of escaping'">test</a>
2. 도착시 입력 확인
인코딩은 아마도 XSS 방어의 가장 중요한 방법일 것이다. 그러나 모든 상황에서 XSS 취약점을 방지하는 것만으로는 충분하지 않다. 또한 사용자로부터 처음 수신되는 시점에서 입력을 가능한 한 엄격하게 검증해야 합니다.
<입력 검증 방법의 예>
1. 사용자가 응답으로 반환될 때 URL을 제출하면 HTTP 및 HTTPS 와 같은 안전한 프로토콜로 시작하는지 확인한다. 그렇지 않으면 누군가가 Javascript 나 data 와 같은 유해한 프로토콜로 사이트를 악용할 수 있다.
2. 사용자가 숫자로 예상되는 값을 제공하는 경우, 값에 실제로 정수가 포함되어 있는지 확인한다.
3. 입력에 예상되는 문자 집합만 포함되어 있는지 확인한다.
Whitelisting vs blacklisting
입력 유효성 검사는 일반적으로 블랙리스트가 아닌 화이트리스트를 사용해야 한다.예를 들어 모든 유해한 프로토콜( javascript, data, 등), 단순히 안전한 프로토콜(HTTP, HTTPS)의 목록을 만들고 목록에 없는 것은 허용하지 않는다. 이렇게 하면 새로운 유해 프로토콜이 나타날 때 방어가 중단되지 않고 블랙리스트를 피하기 위해 잘못된 값을 난독화하려는 공격에 덜 취약해진다
3. 안전한 HTML 허용
사용자가 HTML 마크업을 게시하도록 허용하는 것은 가능한 한 피해야 하지만 때로는기업의 요구에 따라 어쩔수 없이 허용해야 할 때가 있다. 예를 들어 블로그 사이트에서 제한된 HTML 마크업이 포함된 댓글을 게시할 수 있습니다.
고전적인 접근 방식은 잠재적으로 유해한 태그와 JavaScript를 필터링하는 것이다. 안전한 태그 및 속성의 화이트리스트를 사용하여 이를 구현하려고 시도할 수 있지만 브라우저 구문 분석 엔진의 불일치 및 돌연변이 XSS와 같은 이유로 인해 이 접근 방식은 안전하게 구현하기가 극히 어렵다.
최선의 방법은은 DOMPurify와 같이 사용자 브라우저에서 필터링 및 인코딩을 수행하는 JavaScript 라이브러리를 사용하는 것이다. 다른 라이브러리를 사용하면 사용자가 콘텐츠를 마크다운 형식으로 제공하고 마크다운을 HTML로 변환할 수 있다. 불행히도 이러한 모든 라이브러리에는 때때로 XSS 취약점이 있으므로 이것은 완벽한 솔루션이될 수는 없다. 하나를 사용하는 경우 보안 업데이트를 면밀히 모니터링해야 한다.
4. 템플릿 엔진을 사용하여 XSS 방지하는 방법
많은 최신 웹 사이트는 Twig 및 Freemarker와 같은 서버 측 템플릿 엔진을 사용하여 HTML에 동적 콘텐츠를 포함한다. 이들은 일반적으로 자체 이스케이프 시스템을 정의하는데 예를 들면 Twig에서 문맥을 정의하는 변수를 사용할때 다음과 같이 e() 필터를 사용할 수 있다.
{{ user.firstname | e('html') }}
Jinja 및 React와 같은 일부 다른 템플릿 엔진은 기본적으로 대부분의 XSS 발생을 효과적으로 방지하는 동적 콘텐츠를 이용해 이스케이프 한다.
주어진 템플릿 엔진이나 프레임워크를 사용할지 여부를 평가할 때 이스케이프 기능을 자세히 검토하는 것이 좋다.
5. PHP를 이용해 XSS 방지하는 방법
참고한 사이트
https://dreamhack.io/lecture/courses/173
https://portswigger.net/web-security/cross-site-scripting
https://www.hahwul.com/cullinan/xss/
'Web Hacking > Web' 카테고리의 다른 글
웹해킹 공부시 참고할만한 문서들 (0) | 2022.07.13 |
---|---|
취약점 관리 할 때 알아두면 도움 되는 사이트 10 (0) | 2022.07.13 |
BurpSuite 사용시 유용한 단축키 모음 (0) | 2022.07.07 |
동일 출처 정책 SOP(Same-Origin-Poliy) (0) | 2022.07.06 |
Cookie & Session (0) | 2022.07.05 |