1. XSS(3)


※ 주의 사항 :

1. 교육 목적으로만 이용 해주세요.
2. 무단 침입, 데이터 유출, 개인 정보 침해 등 불법적인 활동은 심각한 법적 결과를 초래할 수 있습니다.
3. 개인적인 테스트 환경을 구축해서 실습하시길 바랍니다.


1.1 개요 


이전에 XSS의 공격 기법 3 가지에 대해 알아보았다. Stored XSS, flected XSS, DOM Based XSS
그렇다면 어떻게 이러한 공격을 막을 수 있을까. 스크립트를 작성할 수 없도록 차단하는 법,
스크립트를 작성할 수 있지만 차단하는 법을 소개하겠다.

1.2 스크립트 작성 자체를 방지하기 

1.2.1 필터링

필터링에는 2 가지의 필터링 방법이 있다. 블랙 리스트, 화이트 리스트 이다.
블랙 리스트는 특정 단어나 패턴을 금지하는 방법이고, 화이트 리스트는 허용된 단어나 패턴만 사용할 수 있게 하는 방법이다.

화이트 리스트는 스크립트 작성 자체를 방지하기 위해 사용되지는 않는다.
이 방식은 매우 안전하고 강력한 보안을 제공하지만 사용자가 입력할 수 있는 범위가 제한되어 불편함을 느낄 수 있다. 특히, 다양한 입력이 필요한 애플리케이션에서는 적용하기 어렵다.

// [화이트 리스트 예시, hi 와 hello 만 쓸 수 있도록 작성] //

function whitelist(input) {
    const list = ['hi', 'hello'];
    //toLowercase: 모두 소문자로 바꾸기, includes: 포함된 글자가 있으면 true 없으면 false
    if (list.includes(input.toLowerCase())) {
        return input;
    } else {
        return '';
    }
}

const userInput1 = "hi";
const userInput2 = "hello";
const userInput3 = "hey";
const userInput4 = "HELLO";

console.log(whitelist(userInput1)); // "hi"
console.log(whitelist(userInput2)); // "hello"
console.log(whitelist(userInput3)); // ""
console.log(whitelist(userInput4)); // "HELLO"


그러한 이유로 블랙 리스트 필터링 방식을 많이 사용한다. 금지할 단어나 패턴을 미리 정의하고, 사용자가 정의한 내용을 입력하면 차단한다. 이러한 방식은 사용자에게 더 많은 입력의 자유를 제공하면서도 XSS 공격을 차단할 수 있는 장점이 있다. 그러나 새로운 공격 방법이 생겨날 때 마다 블랙 리스트를 지속적으로 업데이트를 해야 하고 우회 될 가능성이 있다는 단점이 존재한다.

// [블랙 리스트 예시, 우회하기] //

/* 1. Script를 차단 하는 경우 */

// 1.1 이용자의 입력칸 글자 수를 제한 하는 경우, 외부 스크립트를 가져오는 우회. 
		<script>글자  제한</script>
		<script scr= "http://우회/js" ></script> 


// 1.2 스크립트 글자 자체를 제한하는 경우 
		<script> => <>
    
    		//대소문자 혼용//
   	 	<ScRipT></ScrIpt>

		//분할 작성//
		<scrscriptipt></scrscriptipt>
    
// 1.3 대소문자를 포함해서 여러 문자를 다른 문자로 바꿔서 제한한 경우
    		<xript></xript>
//scr에 파일이 없으면 404에러 나타나는 것을 이용, onerror onload onclick...와 같은 이벤트 핸들러를 차단할 것// 
		<img src=우회 onerror='alert(1)'> 
    
            
            
/* 2.그외 태그에서 */
        
// href 주소창의 역할을 이용한 우회, javascript: alert(1)를 작성 가능하다. 차단할 것.
        <a href="javascript:alert(1)"></a>

// input 이벤트 핸들러를 이용한 우회, value에 꺽쇠를 차단 했을 경우에 이벤트 핸들러도 같이 차단할 것.
	<input type="text" onmouseover="alert(1)">
        <input type="text" onfocus="alert(1)">
        <input type="text" autofocus onfocus="alert(1)">

위의 우회 또한 일부이며, 우회할 수 있는 방법은 무수히 많이 존재한다. 블랙 리스트는 모든 공격을 완벽히 막을 수 없다는 한계를 가지고 있기 때문에 이후에 ‘스크립트를 작성할 수 있지만 실행 차단하는 방법’ 에 대해 알아볼 것이다.


1.3 스크립트를 작성할 수 있지만 실행을 차단하기 


1.3.1 HTML Entity 

XSS 방지하는 데 확실하고 필수적인 방법이다. 이는 HTML에서 특수 문자를 치환하는 방식으로, 필터링과는 다르다. 필터링이 특정 문자의 사용을 금지하는 것이라면, HTML 엔티티는 사용자가 특수 문자를 자유롭게 입력하고 그 문자를 안전하게 표시할 수 있게 한다. 예를 들어, 다음과 같이 표시한다.

결과 설명 이름  숫자 
  공백 &nbsp; &#160;
< 보다 작은 &lt; &#60;
> 보다 큰 &gt; &#62;
& 앰퍼샌드 &amp; &#38;
큰 따옴표 &quot; &#34;
작은 따옴표 &apos; &#39;


image-20240630032336205
[그림 1-1]

HTML Editor를 사용하는 웹페이지의 경우⚠

간혹 웹페이지 중에 이용자가 직접 HTML을 이용해서 작성할 수 있도록 만든 사이트를 볼 수 있다. 이때는 HTML Entity를 적용할 수 없어서 보안 측면에서 매우 위험하다. HTML Editor 기능을 삭제하도록 권고하지만 만약 사용해야 한다면 다음과 같은 절차를 따라야 한다.

  1. 파라미터를 보내는 HTML 특수 문자들은 전부 HTML Entity로 치환한다.
  2. 꼭 필요한 기능을 선별하고 그 중 허용할 Tag를 정한다. 그리고 그 Tag화이트 리스트 필터링을 통해 다시 기능을 살린다.
  3. 살린 Tag내에 악의적인 Event Handler블랙 리스트 필터링로 제한한다.

1.3.2 Content Security Policy(CSP) 설정

스크립트, 스타일, 이미지 등 허용된 리소스만 사용하도록 설정하여 제한한다. 다양한 설정 방식이 존재하지만 중요한 설정을 위주로 소개하도록 하겠다.

default-src 'self' : 모든 외부 리소스 유형(스크립트, 스타일시트, 이미지 등)를 제한한다.
script-src 'self' : 외부 스크립트를 차단하며, default-src 'self'의 범주 안에 포함되지만, 추가적인 정책을 사용하려면 별도로 작성해야 한다.

앞선 정책들은 외부 스크립트를 제한한다. 하지만 Reflected xss를 시도하는 경우는 외부 스크립트가 아닌 내부 스크립트에 의해 파라미터의 내용이 페이지에 나타나는 것을 이용하므로 인라인 스크립트를 삽입을 방지해야 한다.


▶추가 정책 : Reflected XSS의 인라인 스크립트를 방지

nonce : 시시각각 웹페이지가 변하는 동작을 구사할 때 이용되며, 서버가 매 요청마다 새롭게 nonce값을 생성하여 csp에 포함한다. 다른 nonce값을 적은 스크립트를 작성하면 제한한다.

=> nonce 값을 개발자 도구(페이지소스)에서 설정을 보고 그대로 넣어 스크립트를 작성할 수 있지 않느냐고 반문할 수 도 있다. 이를 방지하기 위해 nonce 값을 세션에 저장하고, 서버가 요청마다 검증할 수 있다.

// 간단 예시 (세션 저장 포함x)

<html>
<head>
    <meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self' 'nonce-1234'">
</head>
<body>
    <script nonce="1234">
        console.log('hi');
    </script>
</body>
</html>	

hash : 스크립트 내용이 변경되지 않는 경우에 유용하며, 특정 스크립트 내용의 해시를 미리 정의하여 해당 스크립트만 실행되도록 한다. 다른 스크립트 내용을 적는다면 제한한다.

// 간단 예시

<html>
<head>
    <meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self' 'sha256-V7Q9/DwmqvdPGQ4dy6ncNMsD52hvmuqtLSJ0fK6Mdr8='">
</head>
<body>
    <script>
        console.log('hi'); // 이 값이 위의 설정된 sha256으로 해시처리하고, base64로 인코딩한 값	
    </script>
</body>
</html>	

1.3.3 HttpOnly 및 Secure 속성 설정

둘 다 모두 쿠키의 보안을 강화하기 위해 설정한다. 좀 더 정확하게 설명하면 HttpOnly는 클라이언트 측 스크립트가 쿠키에 접근할 수 없게 제한하는 설정이고
Secure은 쿠키가 HTTPS 의 연결을 통해서 만 전송되도록 하는 설정이다. 그리고 다음과 같이 설정한다.

res.cookie('sessionId', '1234', { httpOnly: true, secure: true});


1.4 결론


1. 필수적으로 모든 HTML 특수 문자를 HTML Entity로 변환하여 출력한다.

2.CSP설정을 통해 허용된 리소스만 삽입할 수 있도록 한다.

3. Httponly , Secure 설정을 함으로서 클라이언트 측 쿠키를 보호한다.

4. 필요에 따라 블랙 리스트 필터링을 적용해서 추가적인 보안을 적용한다.

카테고리:

업데이트:

댓글남기기