All rules
CA2361Security Enabled by default: No

Ensure autogenerated class containing DataSet.ReadXml() is not used with untrusted data

Ensure autogenerated class containing DataSet.ReadXml() is not used with untrusted data

Microsoft docs

Description

When deserializing a System.Data.DataSet with untrusted input, an attacker can craft malicious input to perform a denial of service attack. There may be unknown remote code execution vulnerabilities.

This rule is like CA2351, but for autogenerated code for an in-memory representation of data within a GUI application. Usually, these autogenerated classes aren't deserialized from untrusted input. Your application's usage may vary.

For more information, see DataSet and DataTable security guidance.

Cause

The System.Data.DataSet.ReadXml method was called or referenced, and is within autogenerated code.

This rule classifies autogenerated code b:

  • Being inside a method named ReadXmlSerializable.
  • The ReadXmlSerializable method has a System.Diagnostics.DebuggerNonUserCodeAttribute.
  • The ReadXmlSerializable method is within a type that has a System.ComponentModel.DesignerCategoryAttribute.

CA2351 is a similar rule, for when System.Data.DataSet.ReadXml appears within non-autogenerated code.

How to fix violations

  • If possible, use Entity Framework rather than the System.Data.DataSet.
  • Make the serialized data tamper-proof. After serialization, cryptographically sign the serialized data. Before deserialization, validate the cryptographic signature. Protect the cryptographic key from being disclosed and design for key rotations.

Example

namespace ExampleNamespace
{
    /// <summary>
    ///Represents a strongly typed in-memory cache of data.
    ///</summary>
    [global::System.Serializable()]
    [global::System.ComponentModel.DesignerCategoryAttribute("code")]
    [global::System.ComponentModel.ToolboxItem(true)]
    [global::System.Xml.Serialization.XmlSchemaProviderAttribute("GetTypedDataSetSchema")]
    [global::System.Xml.Serialization.XmlRootAttribute("Package")]
    [global::System.ComponentModel.Design.HelpKeywordAttribute("vs.data.DataSet")]
    public partial class Something : global::System.Data.DataSet {

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
        [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")]
        protected override void ReadXmlSerializable(global::System.Xml.XmlReader reader) {
            if ((this.DetermineSchemaSerializationMode(reader) == global::System.Data.SchemaSerializationMode.IncludeSchema)) {
                this.Reset();
                global::System.Data.DataSet ds = new global::System.Data.DataSet();
                ds.ReadXml(reader);
                if ((ds.Tables["Something"] != null)) {
                    base.Tables.Add(new SomethingTable(ds.Tables["Something"]));
                }
                this.DataSetName = ds.DataSetName;
                this.Prefix = ds.Prefix;
                this.Namespace = ds.Namespace;
                this.Locale = ds.Locale;
                this.CaseSensitive = ds.CaseSensitive;
                this.EnforceConstraints = ds.EnforceConstraints;
                this.Merge(ds, false, global::System.Data.MissingSchemaAction.Add);
                this.InitVars();
            }
            else {
                this.ReadXml(reader);
                this.InitVars();
            }
        }
    }
}
Group results
0 yes 0 no
ConsensusNone (disabled)
Severity preference (yes voters)
Suggestion0
Warning0
Error0