diff --git a/docs/fundamentals/code-analysis/quality-rules/ca3009.md b/docs/fundamentals/code-analysis/quality-rules/ca3009.md index 22194d24ff3a5..2204d6937c1c3 100644 --- a/docs/fundamentals/code-analysis/quality-rules/ca3009.md +++ b/docs/fundamentals/code-analysis/quality-rules/ca3009.md @@ -1,7 +1,7 @@ --- title: "CA3009: Review code for XML injection vulnerabilities (code analysis)" description: "Learn about code analysis rule CA3009: Review code for XML injection vulnerabilities" -ms.date: 07/21/2020 +ms.date: 07/19/2023 ms.topic: reference author: dotpaul ms.author: paulming @@ -38,139 +38,58 @@ This rule attempts to find input from HTTP requests reaching a raw XML write. ## How to fix violations -Don't write raw XML. Instead, use methods or properties that XML-encode their input. +To fix a violation, use one of the following techniques: -Or, XML-encode input before writing raw XML. - -Or, validate user input by using sanitizers for primitive type conversion and XML encoding. +- Don't write raw XML. Instead, use methods or properties that XML-encode their input. +- XML-encode input before writing raw XML. +- Validate user input by using sanitizers for primitive type conversion and XML encoding. ## When to suppress warnings Don't suppress warnings from this rule. -## Configure code to analyze - -Use the following options to configure which parts of your codebase to run this rule on. - -- [Exclude specific symbols](#exclude-specific-symbols) -- [Exclude specific types and their derived types](#exclude-specific-types-and-their-derived-types) +## Pseudo-code examples -You can configure these options for just this rule, for all rules it applies to, or for all rules in this category ([Security](security-warnings.md)) that it applies to. For more information, see [Code quality rule configuration options](../code-quality-rule-options.md). +### Violation -[!INCLUDE[excluded-symbol-names](../includes/excluded-symbol-names.md)] +In this example, the input is set to the property of the root element. Given input that contains valid XML, a malicious user can then completely alter the document. Notice that `alice` is no longer an allowed user after the user input is added to the document. -[!INCLUDE[excluded-type-names-with-derived-types](../includes/excluded-type-names-with-derived-types.md)] +:::code language="csharp" source="snippets/csharp/netfx/ca3009.cs" id="violation" highlight="12"::: -## Pseudo-code examples +:::code language="vb" source="snippets/vb/netfx/ca3009.vb" id="violation" highlight="11"::: -### Violation +If an attacker uses this for input: `some textoscar`, then the XML document will be: -```csharp -using System; -using System.Xml; - -public partial class WebForm : System.Web.UI.Page -{ - protected void Page_Load(object sender, EventArgs e) - { - string input = Request.Form["in"]; - XmlDocument d = new XmlDocument(); - XmlElement root = d.CreateElement("root"); - d.AppendChild(root); - - XmlElement allowedUser = d.CreateElement("allowedUser"); - root.AppendChild(allowedUser); - - allowedUser.InnerXml = "alice"; - - // If an attacker uses this for input: - // some textoscar - // Then the XML document will be: - // some textoscar - root.InnerXml = input; - } -} +```xml +some textoscar + ``` -```vb -Imports System -Imports System.Xml +### Solution -Public Partial Class WebForm - Inherits System.Web.UI.Page +To fix this violation, set the input to the property of the root element instead of the property. - Sub Page_Load(sender As Object, e As EventArgs) - Dim input As String = Request.Form("in") - Dim d As XmlDocument = New XmlDocument() - Dim root As XmlElement = d.CreateElement("root") - d.AppendChild(root) +:::code language="csharp" source="snippets/csharp/netfx/ca3009.cs" id="fix" highlight="12"::: - Dim allowedUser As XmlElement = d.CreateElement("allowedUser") - root.AppendChild(allowedUser) +:::code language="vb" source="snippets/vb/netfx/ca3009.vb" id="fix" highlight="11"::: - allowedUser.InnerXml = "alice" +If an attacker uses this for input: `some textoscar`, then the XML document will be: - ' If an attacker uses this for input: - ' some textoscar - ' Then the XML document will be: - ' some textoscar - root.InnerXml = input - End Sub -End Class +```xml +some text<allowedUser>oscar</allowedUser> +alice + ``` -### Solution - -```csharp -using System; -using System.Xml; - -public partial class WebForm : System.Web.UI.Page -{ - protected void Page_Load(object sender, EventArgs e) - { - string input = Request.Form["in"]; - XmlDocument d = new XmlDocument(); - XmlElement root = d.CreateElement("root"); - d.AppendChild(root); - - XmlElement allowedUser = d.CreateElement("allowedUser"); - root.AppendChild(allowedUser); - - allowedUser.InnerText = "alice"; - - // If an attacker uses this for input: - // some textoscar - // Then the XML document will be: - // <allowedUser>oscar</allowedUser>some textalice - root.InnerText = input; - } -} -``` - -```vb -Imports System -Imports System.Xml +## Configure code to analyze -Public Partial Class WebForm - Inherits System.Web.UI.Page +Use the following options to configure which parts of your codebase to run this rule on. - Sub Page_Load(sender As Object, e As EventArgs) - Dim input As String = Request.Form("in") - Dim d As XmlDocument = New XmlDocument() - Dim root As XmlElement = d.CreateElement("root") - d.AppendChild(root) +- [Exclude specific symbols](#exclude-specific-symbols) +- [Exclude specific types and their derived types](#exclude-specific-types-and-their-derived-types) - Dim allowedUser As XmlElement = d.CreateElement("allowedUser") - root.AppendChild(allowedUser) +You can configure these options for just this rule, for all rules it applies to, or for all rules in this category ([Security](security-warnings.md)) that it applies to. For more information, see [Code quality rule configuration options](../code-quality-rule-options.md). - allowedUser.InnerText = "alice" +[!INCLUDE[excluded-symbol-names](../includes/excluded-symbol-names.md)] - ' If an attacker uses this for input: - ' some textoscar - ' Then the XML document will be: - ' <allowedUser>oscar</allowedUser>some textalice - root.InnerText = input - End Sub -End Class -``` +[!INCLUDE[excluded-type-names-with-derived-types](../includes/excluded-type-names-with-derived-types.md)] diff --git a/docs/fundamentals/code-analysis/quality-rules/snippets/csharp/netfx/ca3009.cs b/docs/fundamentals/code-analysis/quality-rules/snippets/csharp/netfx/ca3009.cs new file mode 100644 index 0000000000000..9a97376520eee --- /dev/null +++ b/docs/fundamentals/code-analysis/quality-rules/snippets/csharp/netfx/ca3009.cs @@ -0,0 +1,40 @@ +using System; +using System.Xml; + +public partial class WebForm1 : System.Web.UI.Page +{ + // + 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; + } + // +} + +public partial class WebForm2 : System.Web.UI.Page +{ + // + 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; + } + // +} diff --git a/docs/fundamentals/code-analysis/quality-rules/snippets/csharp/netfx/project.csproj b/docs/fundamentals/code-analysis/quality-rules/snippets/csharp/netfx/project.csproj new file mode 100644 index 0000000000000..cdba31d53c4b9 --- /dev/null +++ b/docs/fundamentals/code-analysis/quality-rules/snippets/csharp/netfx/project.csproj @@ -0,0 +1,12 @@ + + + + Library + net48 + + + + + + + diff --git a/docs/fundamentals/code-analysis/quality-rules/snippets/vb/netfx/ca3009.vb b/docs/fundamentals/code-analysis/quality-rules/snippets/vb/netfx/ca3009.vb new file mode 100644 index 0000000000000..fc92c93e7ca0f --- /dev/null +++ b/docs/fundamentals/code-analysis/quality-rules/snippets/vb/netfx/ca3009.vb @@ -0,0 +1,41 @@ + +Imports System +Imports System.Xml + +Public Partial Class WebForm1 + Inherits System.Web.UI.Page + + ' + 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 + ' +End Class + +Public Partial Class WebForm2 + Inherits System.Web.UI.Page + + ' + 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 + ' +End Class diff --git a/docs/fundamentals/code-analysis/quality-rules/snippets/vb/netfx/project.vbproj b/docs/fundamentals/code-analysis/quality-rules/snippets/vb/netfx/project.vbproj new file mode 100644 index 0000000000000..1216668729024 --- /dev/null +++ b/docs/fundamentals/code-analysis/quality-rules/snippets/vb/netfx/project.vbproj @@ -0,0 +1,12 @@ + + + + Library + net48 + + + + + + +