다음을 통해 공유


CA3009: XML 삽입 취약성에 대한 코드 검토

속성
규칙 ID CA3009
타이틀 코드에서 XML 삽입 취약성에 대해 검토합니다.
범주 보안
수정 사항이 주요 변경인지 여부 주요 변경 아님
.NET 8에서 기본적으로 사용 아니요

원인

잠재적으로 신뢰할 수 없는 HTTP 요청 입력이 원시 XML 출력에 도달합니다.

기본적으로 이 규칙은 전체 코드베이스를 분석하지만 이는 구성 가능합니다.

규칙 설명

신뢰할 수 없는 입력을 사용하는 경우 XML 삽입 공격에 유의해야 합니다. 공격자가 XML 삽입을 사용해 특수 문자를 XML 문서에 삽입하여 해당 문서를 유효하지 않은 XML로 만들 수 있습니다. 또는 공격자가 악의적으로 선택한 XML 노드를 삽입할 수 있습니다.

이 규칙은 원시 XML 쓰기에 도달하는 HTTP 요청에서 입력을 검색합니다.

참고 항목

이 규칙은 어셈블리 간에 데이터를 추적할 수 없습니다. 예를 들어 한 어셈블리가 HTTP 요청 입력을 읽은 다음 원시 XML을 작성하는 다른 어셈블리에 전달하는 경우 이 규칙은 경고를 생성하지 않습니다.

참고 항목

이 규칙이 메서드 호출 간의 데이터 흐름을 분석하는 깊이에는 구성 가능한 제한이 있습니다. EditorConfig 파일에서 제한을 구성하는 방법은 분석기 구성을 참조하세요.

위반 문제를 해결하는 방법

위반 문제를 해결하려면 다음 기술 중 하나를 사용합니다.

  • 원시 XML을 작성하지 않습니다. 대신 입력을 XML 인코드하는 메서드 또는 속성을 사용합니다.
  • 원시 XML을 작성하기 전에 XML 인코딩 입력입니다.
  • 기본 형식 변환 및 XML 인코딩에 소독기를 사용하여 사용자 입력의 유효성을 검사합니다.

경고를 표시하지 않는 경우

이 규칙의 경고를 표시하지 않습니다.

의사 코드 예제

위반

이 예제에서는 입력이 루트 요소의 InnerXml 속성으로 설정됩니다. 유효한 XML을 포함하는 입력이 제공되면 악의적인 사용자가 문서를 완전히 변경할 수 있습니다. 사용자 입력이 alice 문서에 추가된 후에는 더 이상 허용되는 사용자가 아닙니다.

protected void Page_Load(object sender, EventArgs e)
{
    XmlDocument d = new XmlDocument();
    XmlElement root = d.CreateElement("root");
    d.AppendChild(root);

    XmlElement allowedUser = d.CreateElement("allowedUser");
    root.AppendChild(allowedUser);
    allowedUser.InnerXml = "alice";

    string input = Request.Form["in"];
    root.InnerXml = input;
}
Sub Page_Load(sender As Object, e As EventArgs)
    Dim d As XmlDocument = New XmlDocument()
    Dim root As XmlElement = d.CreateElement("root")
    d.AppendChild(root)

    Dim allowedUser As XmlElement = d.CreateElement("allowedUser")
    root.AppendChild(allowedUser)
    allowedUser.InnerXml = "alice"

    Dim input As String = Request.Form("in")
    root.InnerXml = input
End Sub

공격자가 입력 some text<allowedUser>oscar</allowedUser>에 이를 사용하는 경우 XML 문서는 다음과 같습니다.

<root>some text<allowedUser>oscar</allowedUser>
</root>

솔루션

이 위반을 해결하려면 입력을 InnerText 속성 대신 루트 요소의 속성으로 InnerXml 설정합니다.

protected void Page_Load(object sender, EventArgs e)
{
    XmlDocument d = new XmlDocument();
    XmlElement root = d.CreateElement("root");
    d.AppendChild(root);

    XmlElement allowedUser = d.CreateElement("allowedUser");
    root.AppendChild(allowedUser);
    allowedUser.InnerText = "alice";

    string input = Request.Form["in"];
    root.InnerText = input;
}
Sub Page_Load(sender As Object, e As EventArgs)
    Dim d As XmlDocument = New XmlDocument()
    Dim root As XmlElement = d.CreateElement("root")
    d.AppendChild(root)

    Dim allowedUser As XmlElement = d.CreateElement("allowedUser")
    root.AppendChild(allowedUser)
    allowedUser.InnerText = "alice"

    Dim input As String = Request.Form("in")
    root.InnerText = input
End Sub

공격자가 입력 some text<allowedUser>oscar</allowedUser>에 이를 사용하는 경우 XML 문서는 다음과 같습니다.

<root>some text&lt;allowedUser&gt;oscar&lt;/allowedUser&gt;
<allowedUser>alice</allowedUser>
</root>

분석할 코드 구성

다음 옵션을 사용하여 이 규칙이 실행될 코드베이스 부분을 구성합니다.

이 규칙, 적용되는 모든 규칙 또는 적용되는 이 범주(보안)의 모든 규칙에 대해 이러한 옵션을 구성할 수 있습니다. 자세한 내용은 코드 품질 규칙 구성 옵션을 참조하세요.

특정 기호 제외

분석에서 형식 및 메서드와 같은 특정 기호를 제외할 수 있습니다. 예를 들어 MyType이라는 형식 내 코드에서 규칙을 실행하지 않도록 지정하려면 프로젝트의 .editorconfig 파일에 다음 키-값 쌍을 추가합니다.

dotnet_code_quality.CAXXXX.excluded_symbol_names = MyType

옵션 값의 허용되는 기호 이름 형식(|로 구분):

  • 기호 이름만(포함하는 형식 또는 네임스페이스와 관계없이 해당 이름의 모든 기호 포함).
  • 기호의 설명서 ID 형식에 있는 정규화된 이름. 각 기호 이름에는 메서드의 경우 M:, 형식의 경우 T:, 네임스페이스의 경우 N:과 같은 기호 종류 접두사가 필요합니다.
  • 생성자의 경우 .ctor이고 정적 생성자의 경우 .cctor입니다.

예:

옵션 값 요약
dotnet_code_quality.CAXXXX.excluded_symbol_names = MyType MyType이라는 모든 기호와 일치합니다.
dotnet_code_quality.CAXXXX.excluded_symbol_names = MyType1|MyType2 MyType1 또는 MyType2라는 모든 기호와 일치합니다.
dotnet_code_quality.CAXXXX.excluded_symbol_names = M:NS.MyType.MyMethod(ParamType) 특정 메서드 MyMethod를 지정된 정규화된 시그니처와 비교합니다.
dotnet_code_quality.CAXXXX.excluded_symbol_names = M:NS1.MyType1.MyMethod1(ParamType)|M:NS2.MyType2.MyMethod2(ParamType) 특정 메서드 MyMethod1MyMethod2를 개별 정규화된 시그니처와 비교합니다.

특정 형식 및 해당 파생 형식 제외

분석에서 특정 형식과 해당 파생 형식을 제외할 수 있습니다. 예를 들어 MyType이라는 형식 및 해당 파생 형식 내에 있는 메서드에서 규칙이 실행되지 않도록 지정하려면 프로젝트의 .editorconfig 파일에 다음 키-값 쌍을 추가합니다.

dotnet_code_quality.CAXXXX.excluded_type_names_with_derived_types = MyType

옵션 값의 허용되는 기호 이름 형식(|로 구분):

  • 형식 이름만(포함하는 형식이나 네임스페이스와 관계없이 해당 이름의 모든 형식 포함)
  • 기호의 설명서 ID 형식에 있는 정규화된 이름(선택적 T: 접두사 포함)

예:

옵션 값 요약
dotnet_code_quality.CAXXXX.excluded_type_names_with_derived_types = MyType MyType이라는 모든 형식 및 모든 해당 파생 형식과 일치합니다.
dotnet_code_quality.CAXXXX.excluded_type_names_with_derived_types = MyType1|MyType2 MyType1 또는 MyType2라는 모든 형식 및 모든 해당 파생 형식과 일치합니다.
dotnet_code_quality.CAXXXX.excluded_type_names_with_derived_types = M:NS.MyType 지정된 정규화된 이름의 특정 MyType 형식 및 모든 해당 파생 형식과 일치합니다.
dotnet_code_quality.CAXXXX.excluded_type_names_with_derived_types = M:NS1.MyType1|M:NS2.MyType2 개별 정규화된 이름의 특정 MyType1, MyType2 형식 및 모든 해당 파생 형식과 일치합니다.