Cascading Style Sheet (CSS)는 HTML로 정의된 문서를 다채롭게 하는 역할을 한다. 개발자는 CSS로 HTML 요소들이 사용자에게 어떻게 보여질지 정의할 수 있다. 문서의 배경 사진, 색상을 비롯해 버튼에 마우스를 올려두었을 때 어떤 색상과 속도로 표현할 수 있다. 표현에 사용될 임의의 CSS 코드를 주입시켜 의도하지 않은 속성이 정의되는 것을 CSS Injection이라고 한다. 임의 Javascript가 삽입되는 것에 대한 두려움은 이미 많은 개발자들이 가지고 있지만, 악의적인 CSS의 위험성은 잘 알려져있지 않아 대개 무시되고 있다. 그 결과로, 많은 회사에서 CSS Injection 취약점이 발생했다.
CSS Injection
CSS Injection은 XSS와 비슷하게 웹 페이지 로딩 시 악의적인 문자열을 삽입하여 악의적인 동작을 이끄는 공격이다. 공격자가 임의 CSS 속성을 삽입해 웹페이지의 UI (생김새)를 변조하거나 CSS 속성의 다양한 기능을 통해 웹 페이지내의 데이터를 외부로 훔칠 수 있다.
데이터의 예로는 CSRF Token, 피해자의 API Key등 웹 페이지에 직접적으로 보여지는 값처럼 CSS 선택자(Selector)를 통해 표현이 가능해야 한다. 그래서 CSS 선택자로 표현이 불가능한 "script" 태그 내 데이터들은 탈취할 수 없다.
CSS Injection은 그 파급력과 심각성에 비해 대중에 널리 알려지지 않았으며 다양한 웹 방화벽에서 차단하지 않는 입력 값을 갖고 있다.
보통의 웹 방화벽의 경우 "<script>", "alert", "eval" 등의 키워드는 차단하지만, CSS Injection에 주로 사용 되는 "background:", "url" 등의 키워드는 차단하지 않는다.
CSS injection은 HTML (style) 영역에 공격자가 임의 입력 값을 넣을 수 있거나 임의 HTML을 삽입할 수 있지만 Content-Security-Policy로 인해 자바스크립트를 실행할 수 없는 등 다양한 상황에서 사용할 수 있다.
CSS Injection을 CSS가 제공하는 기능들과 연계하면 다양한 공격을 수행할 수 있다. 공격 대상 서버의 코드가 다음과 같은 의사코드로 나타내어지며, 사용자의 입력에 해당하는 theme이 ${theme}을 대체하는 상황을 가정해보자.
<style>
body { background-color: ${theme}; }
</style>
<h1>Hello, it's dreame. Interesting with CSS Injection?</h1>
if '<' in theme:
exit(0)
위 서버 의사코드는 사용자 입력인 theme에서 < 문자를 필터링하고 있기 때문에, style 태그를 벗어날 수는 없다. 대신 적절한 입력을 통해 CSS 속성을 변경할 수 있으며, CSS Injection 공격에 취약하다.
색상 변경
CSS Injection을 이용하면 임의 영역의 UI를 바꿀 수 있으며, 적절한 요소를 지정하는 것으로 특정 버튼 혹은 h1 태그 등의 크기 및 색상 등을 변경할 수 있다.
기본적으로 사용자가 theme에 yellow, blue 등 CSS named-color를 제공하면, 배경 색상이 해당 색상으로 변경된다.
<style>
body { background-color: yellow; }
</style>
<h1>Hello, it's dreame. Interesting with CSS Injection?</h1>