XSS 공격이 나날이 늘어남에 따라 많은 웹 개발자들도 XSS 공격에 대해 공부하고 이를 방어하는 코드를 작성한다. 또한 XSS 공격을 막기 위한 다양한 오픈 소스 라이브러리들을 개발하고 있다. 그러나 올바르지 않은 패치와 XSS 키워드 필터링으로 인해 끊임없이 이를 우회하고 다시 방어하는 방법들이 고안되어 왔다.
XSS 방어를 올바르지 않게 수행할 경우, 기존의 XSS 공격 방어 역할을 올바르게 수행하지 못할 뿐더러 오히려 웹 방화벽이나 기타 방어 기법들을 우회해 새로운 공격을 수행할 수 있도록 기회를 제공하기도 한다.
Tim Berners-Lee가 창시한 HTML은 SGML을 바탕으로 하였다. 오늘날에는 자주 언급되지 않지만 SGML은 당시 존재하였던 마크업 언어를 일반화하였던 표준이다. HTML은 문맥에 따른 태그 시작 및 끝 생략 기능, 자유로운 인용(quotation) 구문, 요소에 따른 내용 태그 해석 여부 변이 등 사용자의 문서 작성 편의를 초점으로 둔 기능을 상당 수 유지함으로써 문법이 복잡해졌고, 이에 따라 HTML을 해석하는 소프트웨어의 구조 또한 정교해졌다.
이에 더해 Netscape 사와 Microsoft 사의 “브라우저 전쟁” 등을 거치면서 서로 자신의 웹 브라우저가 해석할 수 있는 HTML에 별다른 규율 없이 태그 등을 늘려 나갔다. 이로 인해 표준화가 제대로 정립되기 전까지 쌓여온 이 기능들은 현재에 들어서 잘 쓰이지 않거나 오히려 불편함을 야기하게 되었다. 이를 IT 용어로 **유산(legacy)**이라고 부른다.
별다른 체계 없이 정립된 이러한 규칙들이 쌓여 HTML를 해석하는 소프트웨어 작성에 어려움을 더했고, HTML의 일부 기능을 비활성화하고자 하는 XSS 필터링들 역시 예외는 아니게 되었다.
HTML에서 자바스크립트 코드를 실행하거나 페이지에 변형을 가하는 방법은 여러 가지가 있으며, XSS 필터링은 이를 모두 막아 웹 페이지의 보안을 유지하여야 한다. HTML 표준과 브라우저의 기능은 나날이 변화하고 발전하고 있는 가운데 안전하지 않은 코드를 실행할 수 있는 방법의 개수는 계속 증가하고 있다. 따라서 보안을 위해 XSS 필터링은 안전하다고 알려진 마크업만 허용하는 보수적인 방식 (Allowlist 필터링)을 취해야 한다.
또한 일부 문자열만을 바탕으로 필터링을 하게 되면 허위양성 (False Positive) 또는 허위음성 (False Negative)이 발생하여 필터링 자체가 제대로 이루어지지 못해 취약점이 발생할 수도 있다.
자바스크립트 코드를 실행할 수 있는 HTML 태그는 <script> 이외에도 상당수 존재한다. 보통 태그의 속성 값으로 스크립트를 포함할 수 있는 경우가 다수 존재하며, 대표적으로 이벤트 핸들러를 지정하는 on으로 시작하는 속성들이 있다.
이벤트 핸들러란 특정 요소에서 발생하는 이벤트를 처리하기 위해 존재하는 콜백 형태의 핸들러 함수이다. 따라서 이벤트 핸들러 내에 XSS 공격 코드를 삽입해두면 해당 이벤트가 발생했을 때 우리의 XSS 공격 코드가 실행되게 된다.
태그의 속성 값으로 들어가는 이벤트 핸들러의 종류는 굉장히 다양하며 각 이벤트가 발생하는 원리도 다양하다. 자세한 정보는 Mozila Developer Network에서 확인해볼 수 있다.
자주 사용되는 이벤트 핸들러 속성으로 onload와 onerror, onfocus가 있으며, 각 사용 예시는 다음과 같다.