본문 바로가기

보안 취약점/Cross Site Scripting (XSS)

Cross Site Scripting (XSS)

Cross Site Scripting(XSS) 란?


게시글과 같은 페이지에, 공격자가 악성 스크립트를 삽입하여, 사용자의 정보를 탈취, 악성코드등을 유입시키는 공격을 말합니다. 이 공격의 특징으로는 사용자(클라이언트) 대상으로 이루어 진다는 점입니다.




1. XSS 공격 패턴



2. XSS 공격을 사전 예방하는 방법


   2-1. 위험한 문자열을 인코딩하여 저장하거나, 인코딩하여 표시하는 방법

     

 문자 인코딩 된 문자

 &

 &

 <

 &lt;

 >

 &gt;

 '

 &#x27;

 "

 &quot;

 (

&#40;

 )

&#41;

 /

 &#x2F;


- 클라이언트에서 위험한 특수문자를 인코딩하는 함수

1
2
3
4
5
6
//받은 입력값 특수문자 변환 처리
function XFN_ChangeInputValue(pValue) {
    var strReturenValue = "";
    strReturenValue = pValue.replace(/&/gi, '&amp;').replace(/</gi, '&lt;').replace(/>/gi, '&gt;').replace(/"/gi, '&quot;').replace(/'/gi, '&apos;');
    return strReturenValue;
}
cs

   

    - 클라이언트에서 인코딩된 특수문자를 원래의 문자로 변환해주는 함수

1
2
3
4
5
6
//받은 입력값 특수문자 변환 처리
function ChangeOutputValue(pValue) {
    var strReturenValue = "";
    strReturenValue = pValue.replace(/&amp;/gi, '&').replace(/&lt;/gi, '<').replace(/&gt;/gi, '>').replace(/&quot;/gi, '"').replace(/&apos;/gi, '\'').replace(/&nbsp;/gi, ' ');
    return strReturenValue;
}
cs


    - 서버에서 전달 받은 위험한 특수문자를 인코딩하는 메서드 (C#)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
   /// <summary>
    /// Input 데이터를 DB에 넣을 때 특수문자 처리
    /// </summary>
    /// <param name="pValue"></param>
    /// <returns></returns>
    public static string ConvertInputValue(string pValue)
    {
        pValue = pValue.Replace("&""&amp;");
        pValue = pValue.Replace("<""&lt;");
        pValue = pValue.Replace(">""&gt;");
        pValue = pValue.Replace("\"""&quot;");
        pValue = pValue.Replace("'""&apos;");
        pValue = pValue.Replace("\\""&#x2F;");
        pValue = pValue.Replace(" ""&nbsp;");
        pValue = pValue.Replace("\n""<br />");
 
        return pValue;
    }
cs


    - 서버에서 인코딩된 특수문자를 원래의 문자로 변환해주는 메서드 (C#)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
 /// <summary>
    /// 데이터를 불러올때 특수문자 처리
    /// </summary>
    /// <param name="pValue"></param>
    /// <returns></returns>
    public static string ConvertOutputValue(string pValue)
    {
        pValue = pValue.Replace("&amp;""&");
        pValue = pValue.Replace("&lt;""<");
        pValue = pValue.Replace("&gt;"">");
        pValue = pValue.Replace("&quot;""\"");
        pValue = pValue.Replace("&apos;""'");
        pValue = pValue.Replace("&#x2F;""\\");
        pValue = pValue.Replace("&nbsp;"" ");
        pValue = pValue.Replace("<br />""\n");
 
        return pValue;
    }
cs


   2-2. 본문 내용 저장 시 form, object, embed, applet등의 태그는 정규식을 통하여 제거하여 준다.


       - img태그의 src, iframe의 src 등을 통하여 악성 파일을 강제로 다운로드시키거나, 악성 페이지로
         이동될 수 있으므로, 불필요한 태그는 제거하여야 합니다.

       - img 태그의 경우 사용을 아예 안할수는 없는 태그이기 때문에, 화이트리스트를 관리하는 등의
         차선책이 필요합니다.

       - 요즘에는 웹 에디터 제품을 많이 사용하게 되는데, 해당 제품을 만든 업체에서 기본적인 XSS 
         방지 기능을 제공하나, 서버측에서 체크는 반드시 추가적으로 해주셔야 합니다.

       - 서버에서 본문 내용 저장 시 불필요한 태그를 제거하는 메서드 (C#)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
 /// <summary>
    /// 불필요한 태그 삭제
    /// </summary>
    /// <param name="str"></param>
    /// <returns></returns>
    public static string HtmlRemove(string pHtml)
    {
        Regex rgScript = new Regex("<(no)?script.*?script>", RegexOptions.IgnoreCase | RegexOptions.Singleline);
        Regex rgStyle = new Regex("<(no)?style.*?style>", RegexOptions.IgnoreCase | RegexOptions.Singleline);
        Regex rgApplet = new Regex("<(no)?applet.*?applet>", RegexOptions.IgnoreCase | RegexOptions.Singleline);
        Regex rgObject = new Regex("<(no)?object.*?object>", RegexOptions.IgnoreCase | RegexOptions.Singleline);
        Regex rgForm = new Regex("<(no)?form.*?form>", RegexOptions.IgnoreCase | RegexOptions.Singleline);
        Regex rgEmbed = new Regex("<(no)?embed.*?embed>", RegexOptions.IgnoreCase | RegexOptions.Singleline);
        Regex rgTag = new Regex("<.*?>", RegexOptions.Singleline);
        Regex rgBlank = new Regex(@"\s+", RegexOptions.Singleline);
 
        pHtml = rgScript.Replace(pHtml, "");
        pHtml = rgStyle.Replace(pHtml, "");
        pHtml = rgApplet.Replace(pHtml, "");
        pHtml = rgObject.Replace(pHtml, "");
        pHtml = rgForm.Replace(pHtml, "");
        pHtml = rgEmbed.Replace(pHtml, "");
        pHtml = rgTag.Replace(pHtml, "");
        pHtml = rgBlank.Replace(pHtml, " ");
 
        return pHtml;
    }
cs


  2-3. 전달받은 URL 파라메터를 서버측 변수에 저장 후 클라이언트로 노출 시킬 경우. (ASP.NET)


       - .NET Framework 4.5 부터 지원

       - 전달받은 Request를 AntiXssEncoder 로 인코딩 후 클라이언트 측에 노출시켜야 함.

1
string strMenuID = System.Web.Security.AntiXss.AntiXssEncoder.HtmlEncode(Request["MenuID"].ToString(), false);
cs