우선, 저는 보안에 대해 전문가가 아니며 웹페이지 구축 중 습득한 정보, 공부한 정보를 바탕으로 정리를 기반하여 이 글을 작성합니다.
XSS란?
XSS는 Cross Site Scripting의 약자로 악의적인 스크립트 언어를 웹페이지에 삽입 후 그 웹페이지에 방문하는 사람의 쿠키, 세션의 정보를 탈취하여 해커에서 전송하거나 악의적인 행동을 하는 공격 기법입니다.
이 XSS는 여러가지 공격 기법이 있는데 대표적으로 url에 코드 삽입, 검증되지 않은 url로 값 전송, script 삽입 등이 있다. XSS공격은 방법이 무수히도 많고 방문하는 웹사이트를 공격하여 악의적인 스크립트를 심어두고 방문자를 공격하는 방식이라 안전한 사이트라고 생각한 곳에서도 공격을 당할 수 있습니다.
공격 종류
콘텍스트 | 코딩 | 방어책 |
HTML Body | <span> 악성 데이터 </span> | ● HTML Entity 인코딩 |
안전한 HTML Attributes | <input type="text" name="fname" value=" 악성 데이터"> | ●HTML Entity 인코딩 ●악성 데이터를 화이트리스트 방 식 또는 안전한 속성에만 위치 ●background, id 및 name과 같 은 안전하지 않은 속성을 철저히 검증 |
GET 파라미터 | <a href="/site/search?value=악성 데이 터">clickme</a> | ●URL 인코딩 |
SRC 또는 HREF 속성에 악성 URL | <a href="악성 URL">clickme</a> <iframesrc="악성 URL" /> | ●입력 값 정규화 ● URL 검증 ● URL 안전성 확인 ● 화이트 리스트된 http 및 https URL 만 허용(새로운 창을 열기 위해 자바스크립트 프로토콜 사 용금지) ● 속성 인코더 사용 |
CSS 값 | <div style="width : 악성 데이터;">Selection</div> | ● 엄격하게 구조적 검증 ● CSS 16진수 인코딩 ● CSS 기능 설계 강화 |
자바스크립트 변수 | <script>var currentValue='악성 데이터';</ script> <script>함수('악성 데이터');</script> | ● 자바스크립트 변수를 문자화 ● 자바스크립트 헥스 인코딩 ● 자바스크립트 16진수 인코딩 ● 자바스크립트 유니코드 인코딩 ● 백슬래쉬(\", \' 또는 \\)사용금지 |
HTML Body | <div>악성 HTML</div> | ●HTML 검증 (JSoup, AntiSamy, HTML Sanitizer) |
DOM XSS | <script>document.write("악성 입력 값: " + document.location.hash);<script/> | ● DOM 기반 XSS 예방 |
대응 방법
node기반의 웹페이지 개발자라면 helmet.js와 같은 라이브러리를 사용하여 대응을 해도 괜찮다고 생각합니다.
helmet
help secure Express/Connect apps with various HTTP headers. Latest version: 7.0.0, last published: 4 months ago. Start using helmet in your project by running `npm i helmet`. There are 3798 other projects in the npm registry using helmet.
www.npmjs.com
XSS 뿐 아니라 Cros문제 등 보안에 뛰어난 라이브러리이고 많은 사람이 사용중에 있습니다.
라이브러리을 사용하지 않거나 node기반이 아니라면, Spring에 필터기능 혹은 정규식을 사용하여 문자열을 replace하는 것도 대응 방법 중 하나입니다.
위에 나온 방식대로 웹페이지를 구성하는 <>'" 이러한 특수문자에 대해 Entity 인코딩을 적용한다면 이 특수문자는 <>'"와 같이 변경되게 됩니다. document.getCookie라는 코드로 쿠키의 값을 가져올 수 있다고 가정하고 정규식을 이용하여 아래와 같이 replace할 수 있다.
// java version
Matcher m;
ArrayList<Pattern> regs = new ArrayList<>();
regs.add(Pattern.compile("(?i)<(no)?script[^>]*>.*?</(no)?script>", Pattern.DOTALL));
for (Pattern reg : regs) {
m = reg.matcher(str);
str = m.replaceAll("");
}
// javascript version
let body = '<script>document.getCookie()</script>'
body.replaceAll(/<(no)?script[^>]*>.*?</(no)?script>/gi, '')
하지만 가장 좋은 방법은 개발자의 세심한 주의라고 생각합니다. 새로운 XSS공격이 나온다면 공격에 대한 지식을 습득하여 이를 미리 방지하는 코드를 빠르게 업데이트하고 주기적으로 코드와 URL등 소스코드를 확인하는 방법이 가장 안전한 방법이라고 생각됩니다.
일반 사용자라면 보안 프로그램을 설치하고 사용하는게 이를 방지하는데 좋습니다.
'Study > 보안' 카테고리의 다른 글
[CSRF] 사이트간 요청 위조, 원리 및 대응 방법 (0) | 2023.07.25 |
---|---|
[네트워크 보안] Dos / DDos 공격 차이 및 설명 (0) | 2023.07.11 |