설명
크로스 사이트 스크립팅(XSS)은 웹 애플리케이션이 사용자 입력값을 적절히 검증하지 않고 웹 페이지에 반영할 때 발생하는 취약점입니다. jQuery의 html() 함수는 입력된 내용을 HTML로 해석하여 DOM에 삽입하므로, 만약 사용자가 악의적인 스크립트를 입력하면 브라우저에서 그대로 실행될 수 있습니다. 이를 통해 공격자는 피해자의 브라우저에서 악성 코드를 실행하거나, 세션 탈취, 계정 도용, 피싱 등 다양한 공격을 할 수 있습니다.
잠재적 영향
- 정보 탈취 (개인정보, 세션 쿠키 등): 공격자가 사용자의 세션 쿠키나 민감한 정보를 획득할 수 있습니다.
- 브라우저 악성코드 실행: 사용자 브라우저에 악성 스크립트를 실행할 수 있습니다.
- UI 변조 및 피싱: 정상적인 화면에 피싱 화면을 삽입하여 사용자를 속일 수 있습니다.
해결 방법
- 텍스트를 출력할 때는 jQuery의
html()대신text()를 사용하세요. - HTML 본문에 텍스트를 넣어야 한다면 HTML 이스케이프를 적용하세요. 실제 마크업을 허용해야 한다면 검증된 HTML 정화 도구로 태그와 속성을 제한하세요.
- 출력 위치에 맞는 처리를 적용하고, HTML 인코딩을 JavaScript나 URL 검증의 대체 수단으로 사용하지 마세요.
예시
변경 전
javascript
// XSS 취약 코드 예시
function showMessage(userInput) {
$("#message").html(userInput);
}
// 사용자가 <script>alert('XSS')</script> 를 입력하면 스크립트가 실행됩니다.
변경 후
다음 두 방법은 각각 사용하는 대안입니다. 첫 번째는 텍스트로 출력하고, 두 번째는 HTML 본문에 넣을 문자열을 인코딩합니다.
javascript
// 안전한 코드 예시 1 (text() 사용)
function showMessage(userInput) {
$("#message").text(userInput);
}
// 안전한 코드 예시 2 (HTML 이스케이프 처리)
function escapeHtml(str) {
return str.replace(/[&<>"']/g, function(tag) {
const chars = {'&':'&', '<':'<', '>':'>', '"':'"', "'":'''};
return chars[tag] || tag;
});
}
function showMessage(userInput) {
$("#message").html(escapeHtml(userInput));
}
설명:
- 변경 전: 사용자 입력값을 html() 함수에 직접 전달하면, 입력에 포함된 스크립트가 실행되어 XSS 공격에 노출됩니다.
- 변경 후: 변경 후에는 text() 함수로 사용자 입력을 출력하여 HTML 태그와 스크립트가 해석되지 않도록 하거나, HTML로 삽입할 경우 입력값을 이스케이프 처리하여 악성 스크립트가 동작하지 않도록 막습니다.