diff --git a/src/Microsoft.CodeAnalysis.FxCopAnalyzers/Microsoft.CodeAnalysis.FxCopAnalyzers.md b/src/Microsoft.CodeAnalysis.FxCopAnalyzers/Microsoft.CodeAnalysis.FxCopAnalyzers.md index 701902405e..d4f06704b7 100644 --- a/src/Microsoft.CodeAnalysis.FxCopAnalyzers/Microsoft.CodeAnalysis.FxCopAnalyzers.md +++ b/src/Microsoft.CodeAnalysis.FxCopAnalyzers/Microsoft.CodeAnalysis.FxCopAnalyzers.md @@ -8,7 +8,7 @@ Rule ID | Title | Category | Enabled | Severity | CodeFix | Description | [CA1005](https://docs.microsoft.com/visualstudio/code-quality/ca1005) | Avoid excessive parameters on generic types | Design | False | Warning | False | The more type parameters a generic type contains, the more difficult it is to know and remember what each type parameter represents. | [CA1008](https://docs.microsoft.com/visualstudio/code-quality/ca1008) | Enums should have zero value | Design | False | Warning | True | The default value of an uninitialized enumeration, just as other value types, is zero. A nonflags-attributed enumeration should define a member by using the value of zero so that the default value is a valid value of the enumeration. If an enumeration that has the FlagsAttribute attribute applied defines a zero-valued member, its name should be ""None"" to indicate that no values have been set in the enumeration. | [CA1010](https://docs.microsoft.com/visualstudio/code-quality/ca1010) | Generic interface should also be implemented | Design | True | Warning | False | To broaden the usability of a type, implement one of the generic interfaces. This is especially true for collections as they can then be used to populate generic collection types. | -[CA1012](https://docs.microsoft.com/visualstudio/code-quality/ca1012) | Abstract types should not have constructors | Design | False | Warning | True | Constructors on abstract types can be called only by derived types. Because public constructors create instances of a type, and you cannot create instances of an abstract type, an abstract type that has a public constructor is incorrectly designed. | +[CA1012](https://docs.microsoft.com/visualstudio/code-quality/ca1012) | Abstract types should not have public constructors | Design | False | Warning | True | Constructors on abstract types can be called only by derived types. Because public constructors create instances of a type, and you cannot create instances of an abstract type, an abstract type that has a public constructor is incorrectly designed. | [CA1014](https://docs.microsoft.com/visualstudio/code-quality/ca1014) | Mark assemblies with CLSCompliant | Design | False | Warning | False | The Common Language Specification (CLS) defines naming restrictions, data types, and rules to which assemblies must conform if they will be used across programming languages. Good design dictates that all assemblies explicitly indicate CLS compliance by using CLSCompliantAttribute . If this attribute is not present on an assembly, the assembly is not compliant. | [CA1016](https://docs.microsoft.com/visualstudio/code-quality/ca1016) | Mark assemblies with assembly version | Design | True | Warning | False | The .NET Framework uses the version number to uniquely identify an assembly, and to bind to types in strongly named assemblies. The version number is used together with version and publisher policy. By default, applications run only with the assembly version with which they were built. | [CA1017](https://docs.microsoft.com/visualstudio/code-quality/ca1017) | Mark assemblies with ComVisible | Design | False | Warning | False | ComVisibleAttribute determines how COM clients access managed code. Good design dictates that assemblies explicitly indicate COM visibility. COM visibility can be set for the whole assembly and then overridden for individual types and type members. If this attribute is not present, the contents of the assembly are visible to COM clients. | @@ -62,7 +62,7 @@ Rule ID | Title | Category | Enabled | Severity | CodeFix | Description | [CA1505](https://docs.microsoft.com/visualstudio/code-quality/ca1505) | Avoid unmaintainable code | Maintainability | False | Warning | False | The maintainability index is calculated by using the following metrics: lines of code, program volume, and cyclomatic complexity. Program volume is a measure of the difficulty of understanding of a symbol that is based on the number of operators and operands in the code. Cyclomatic complexity is a measure of the structural complexity of the type or method. A low maintainability index indicates that code is probably difficult to maintain and would be a good candidate to redesign. | [CA1506](https://docs.microsoft.com/visualstudio/code-quality/ca1506) | Avoid excessive class coupling | Maintainability | False | Warning | False | This rule measures class coupling by counting the number of unique type references that a symbol contains. Symbols that have a high degree of class coupling can be difficult to maintain. It is a good practice to have types and methods that exhibit low coupling and high cohesion. To fix this violation, try to redesign the code to reduce the number of types to which it is coupled. | [CA1507](https://docs.microsoft.com/visualstudio/code-quality/ca1507) | Use nameof to express symbol names | Maintainability | True | Warning | True | Using nameof helps keep your code valid when refactoring. | -[CA1508](https://docs.microsoft.com/visualstudio/code-quality/ca1508) | Avoid dead conditional code | Maintainability | False | Warning | False | '{0}' is always '{1}'. Remove or refactor the condition(s) to avoid dead code. | +[CA1508](https://docs.microsoft.com/visualstudio/code-quality/ca1508) | Avoid dead conditional code | Maintainability | False | Warning | False | '{0}' is never '{1}'. Remove or refactor the condition(s) to avoid dead code. | [CA1509](https://docs.microsoft.com/visualstudio/code-quality/ca1509) | Invalid entry in code metrics rule specification file | Maintainability | False | Warning | False | Invalid entry in code metrics rule specification file | [CA1700](https://docs.microsoft.com/visualstudio/code-quality/ca1700) | Do not name enum values 'Reserved' | Naming | False | Warning | False | This rule assumes that an enumeration member that has a name that contains "reserved" is not currently used but is a placeholder to be renamed or removed in a future version. Renaming or removing a member is a breaking change. | [CA1707](https://docs.microsoft.com/visualstudio/code-quality/ca1707) | Identifiers should not contain underscores | Naming | True | Warning | False | By convention, identifier names do not contain the underscore (_) character. This rule checks namespaces, types, members, and parameters. | @@ -81,7 +81,7 @@ Rule ID | Title | Category | Enabled | Severity | CodeFix | Description | [CA1725](https://docs.microsoft.com/visualstudio/code-quality/ca1725) | Parameter names should match base declaration | Naming | False | Warning | True | Consistent naming of parameters in an override hierarchy increases the usability of the method overrides. A parameter name in a derived method that differs from the name in the base declaration can cause confusion about whether the method is an override of the base method or a new overload of the method. | [CA1801](https://docs.microsoft.com/visualstudio/code-quality/ca1801) | Review unused parameters | Usage | True | Warning | True | Avoid unused paramereters in your code. If the parameter cannot be removed, then change its name so it starts with an underscore and is optionally followed by an integer, such as '_', '_1', '_2', etc. These are treated as special discard symbol names. | [CA1802](https://docs.microsoft.com/visualstudio/code-quality/ca1802) | Use literals where appropriate | Performance | True | Warning | True | A field is declared static and read-only (Shared and ReadOnly in Visual Basic), and is initialized by using a value that is computable at compile time. Because the value that is assigned to the targeted field is computable at compile time, change the declaration to a const (Const in Visual Basic) field so that the value is computed at compile time instead of at run?time. | -[CA1805](https://docs.microsoft.com/visualstudio/code-quality/ca1805) | Do not initialize unnecessarily | Performance | True | Warning | True | The common language runtime initializes all fields to their default values before running the constructor. In most cases, initializing a field to its default value in a constructor is redundant, which adds to maintenance costs and may degrade performance (such as with increased assembly size). One case where it is not redundant occurs when the constructor calls another constructor of the same class or a base class constructor and that constructor initializes the field to a non-default value. In this case, changing the value of the field back to its default value can be appropriate. | +[CA1805](https://docs.microsoft.com/visualstudio/code-quality/ca1805) | Do not initialize unnecessarily | Performance | True | Warning | True | The .NET runtime initializes all fields of reference types to their default values before running the constructor. In most cases, explicitly initializing a field to its default value in a constructor is redundant, adding maintenance costs and potentially degrading performance (such as with increased assembly size), and the explicit initialization can be removed. In some cases, such as with static readonly fields that permanently retain their default value, consider instead changing them to be constants or properties. | [CA1806](https://docs.microsoft.com/visualstudio/code-quality/ca1806) | Do not ignore method results | Performance | True | Warning | False | A new object is created but never used; or a method that creates and returns a new string is called and the new string is never used; or a COM or P/Invoke method returns an HRESULT or error code that is never used. | [CA1810](https://docs.microsoft.com/visualstudio/code-quality/ca1810) | Initialize reference type static fields inline | Performance | True | Warning | False | A reference type declares an explicit static constructor. To fix a violation of this rule, initialize all static data when it is declared and remove the static constructor. | [CA1812](https://docs.microsoft.com/visualstudio/code-quality/ca1812) | Avoid uninstantiated internal classes | Performance | True | Warning | False | An instance of an assembly-level type is not created by code in the assembly. | @@ -105,7 +105,7 @@ Rule ID | Title | Category | Enabled | Severity | CodeFix | Description | [CA1832](https://docs.microsoft.com/visualstudio/code-quality/ca1832) | Use AsSpan or AsMemory instead of Range-based indexers when appropriate | Performance | True | Warning | True | The Range-based indexer on array values produces a copy of requested portion of the array. This copy is usually unnecessary when it is implicitly used as a ReadOnlySpan or ReadOnlyMemory value. Use the AsSpan method to avoid the unnecessary copy. | [CA1833](https://docs.microsoft.com/visualstudio/code-quality/ca1833) | Use AsSpan or AsMemory instead of Range-based indexers when appropriate | Performance | True | Warning | True | The Range-based indexer on array values produces a copy of requested portion of the array. This copy is often unwanted when it is implicitly used as a Span or Memory value. Use the AsSpan method to avoid the copy. | [CA1834](https://docs.microsoft.com/visualstudio/code-quality/ca1834) | Consider using 'StringBuilder.Append(char)' when applicable. | Performance | True | Warning | True | 'StringBuilder.Append(char)' is more efficient than 'StringBuilder.Append(string)' when the string is a single character. When calling 'Append' with a constant, prefer using a constant char rather than a constant string containing one character. | -[CA1835](https://docs.microsoft.com/visualstudio/code-quality/ca1835) | Prefer the 'Memory'-based overloads for 'ReadAsync' and 'WriteAsync'. | Performance | True | Warning | True | 'Stream' has a 'ReadAsync' overload that takes a 'Memory' as the first argument, and a 'WriteAsync' overload that takes a 'ReadOnlyMemory' as the first argument. Prefer calling the memory based overloads, which are more efficient. | +[CA1835](https://docs.microsoft.com/visualstudio/code-quality/ca1835) | Prefer the 'Memory'-based overloads for 'ReadAsync' and 'WriteAsync' | Performance | True | Warning | True | 'Stream' has a 'ReadAsync' overload that takes a 'Memory' as the first argument, and a 'WriteAsync' overload that takes a 'ReadOnlyMemory' as the first argument. Prefer calling the memory based overloads, which are more efficient. | [CA1836](https://docs.microsoft.com/visualstudio/code-quality/ca1836) | Prefer IsEmpty over Count | Performance | True | Warning | True | For determining whether the object contains or not any items, prefer using 'IsEmpty' property rather than retrieving the number of items from the 'Count' property and comparing it to 0 or 1. | [CA2000](https://docs.microsoft.com/visualstudio/code-quality/ca2000) | Dispose objects before losing scope | Reliability | True | Warning | False | If a disposable object is not explicitly disposed before all references to it are out of scope, the object will be disposed at some indeterminate time when the garbage collector runs the finalizer of the object. Because an exceptional event might occur that will prevent the finalizer of the object from running, the object should be explicitly disposed instead. | [CA2002](https://docs.microsoft.com/visualstudio/code-quality/ca2002) | Do not lock on objects with weak identity | Reliability | True | Warning | False | An object is said to have a weak identity when it can be directly accessed across application domain boundaries. A thread that tries to acquire a lock on an object that has a weak identity can be blocked by a second thread in a different application domain that has a lock on the same object. | @@ -117,6 +117,7 @@ Rule ID | Title | Category | Enabled | Severity | CodeFix | Description | [CA2013](https://docs.microsoft.com/visualstudio/code-quality/ca2013) | Do not use ReferenceEquals with value types | Reliability | True | Warning | False | Value type typed arguments are uniquely boxed for each call to this method, therefore the result is always false. | [CA2014](https://docs.microsoft.com/visualstudio/code-quality/ca2014) | Do not use stackalloc in loops. | Reliability | True | Warning | False | Stack space allocated by a stackalloc is only released at the end of the current method's invocation. Using it in a loop can result in unbounded stack growth and eventual stack overflow conditions. | [CA2015](https://docs.microsoft.com/visualstudio/code-quality/ca2015) | Do not define finalizers for types derived from MemoryManager | Reliability | True | Warning | False | Adding a finalizer to a type derived from MemoryManager may permit memory to be freed while it is still in use by a Span. | +[CA2016](https://docs.microsoft.com/visualstudio/code-quality/ca2016) | Forward the 'CancellationToken' parameter to methods that take one | Reliability | True | Warning | True | Forward the 'CancellationToken' parameter to methods that take one to ensure the operation cancellation notifications gets properly propagated, or pass in 'CancellationToken.None' explicitly to indicate intentionally not propagating the token. | [CA2100](https://docs.microsoft.com/visualstudio/code-quality/ca2100) | Review SQL queries for security vulnerabilities | Security | True | Warning | False | SQL queries that directly use user input can be vulnerable to SQL injection attacks. Review this SQL query for potential vulnerabilities, and consider using a parameterized SQL query. | [CA2101](https://docs.microsoft.com/visualstudio/code-quality/ca2101) | Specify marshaling for P/Invoke string arguments | Globalization | True | Warning | True | A platform invoke member allows partially trusted callers, has a string parameter, and does not explicitly marshal the string. This can cause a potential security vulnerability. | [CA2109](https://docs.microsoft.com/visualstudio/code-quality/ca2109) | Review visible event handlers | Security | True | Warning | False | A public or protected event-handling method was detected. Event-handling methods should not be exposed unless absolutely necessary. | @@ -167,6 +168,13 @@ Rule ID | Title | Category | Enabled | Severity | CodeFix | Description | [CA2328](https://docs.microsoft.com/visualstudio/code-quality/ca2328) | Ensure that JsonSerializerSettings are secure | Security | False | Warning | False | When deserializing untrusted input, allowing arbitrary types to be deserialized is insecure. When using JsonSerializerSettings, ensure TypeNameHandling.None is specified, or for values other than None, ensure a SerializationBinder is specified to restrict deserialized types. | [CA2329](https://docs.microsoft.com/visualstudio/code-quality/ca2329) | Do not deserialize with JsonSerializer using an insecure configuration | Security | False | Warning | False | When deserializing untrusted input, allowing arbitrary types to be deserialized is insecure. When using deserializing JsonSerializer, use TypeNameHandling.None, or for values other than None, restrict deserialized types with a SerializationBinder. | [CA2330](https://docs.microsoft.com/visualstudio/code-quality/ca2330) | Ensure that JsonSerializer has a secure configuration when deserializing | Security | False | Warning | False | When deserializing untrusted input, allowing arbitrary types to be deserialized is insecure. When using deserializing JsonSerializer, use TypeNameHandling.None, or for values other than None, restrict deserialized types with a SerializationBinder. | +[CA2350](https://docs.microsoft.com/visualstudio/code-quality/ca2350) | Do not use insecure deserialization with DataTable.ReadXml() | Security | False | Warning | False | The method '{0}' is insecure when deserializing untrusted data. If deserializing untrusted data, replace with TBD. | +[CA2351](https://docs.microsoft.com/visualstudio/code-quality/ca2351) | Do not use insecure deserialization with DataSet.ReadXml() | Security | False | Warning | False | The method '{0}' is insecure when deserializing untrusted data. If deserializing untrusted data, replace with TBD. | +[CA2352](https://docs.microsoft.com/visualstudio/code-quality/ca2352) | Unsafe DataSet or DataTable in serializable type can be vulnerable to remote code execution attacks | Security | False | Warning | False | When deserializing untrusted input with an IFormatter-based serializer, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. | +[CA2353](https://docs.microsoft.com/visualstudio/code-quality/ca2353) | Unsafe DataSet or DataTable in serializable type | Security | False | Warning | False | When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. | +[CA2354](https://docs.microsoft.com/visualstudio/code-quality/ca2354) | Unsafe DataSet or DataTable in deserialized object graph can be vulnerable to remote code execution attacks | Security | False | Warning | False | When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. | +[CA2355](https://docs.microsoft.com/visualstudio/code-quality/ca2355) | Unsafe DataSet or DataTable type found in deserializable object graph | Security | False | Warning | False | When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. | +[CA2356](https://docs.microsoft.com/visualstudio/code-quality/ca2356) | Unsafe DataSet or DataTable type in web deserializable object graph | Security | False | Warning | False | When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. | [CA3001](https://docs.microsoft.com/visualstudio/code-quality/ca3001) | Review code for SQL injection vulnerabilities | Security | False | Warning | False | Potential SQL injection vulnerability was found where '{0}' in method '{1}' may be tainted by user-controlled data from '{2}' in method '{3}'. | [CA3002](https://docs.microsoft.com/visualstudio/code-quality/ca3002) | Review code for XSS vulnerabilities | Security | False | Warning | False | Potential cross-site scripting (XSS) vulnerability was found where '{0}' in method '{1}' may be tainted by user-controlled data from '{2}' in method '{3}'. | [CA3003](https://docs.microsoft.com/visualstudio/code-quality/ca3003) | Review code for file path injection vulnerabilities | Security | False | Warning | False | Potential file path injection vulnerability was found where '{0}' in method '{1}' may be tainted by user-controlled data from '{2}' in method '{3}'. | diff --git a/src/Microsoft.CodeAnalysis.FxCopAnalyzers/Microsoft.CodeAnalysis.FxCopAnalyzers.sarif b/src/Microsoft.CodeAnalysis.FxCopAnalyzers/Microsoft.CodeAnalysis.FxCopAnalyzers.sarif index 855c5751d8..f16ab10d5b 100644 --- a/src/Microsoft.CodeAnalysis.FxCopAnalyzers/Microsoft.CodeAnalysis.FxCopAnalyzers.sarif +++ b/src/Microsoft.CodeAnalysis.FxCopAnalyzers/Microsoft.CodeAnalysis.FxCopAnalyzers.sarif @@ -156,7 +156,7 @@ }, "CA1012": { "id": "CA1012", - "shortDescription": "Abstract types should not have constructors", + "shortDescription": "Abstract types should not have public constructors", "fullDescription": "Constructors on abstract types can be called only by derived types. Because public constructors create instances of a type, and you cannot create instances of an abstract type, an abstract type that has a public constructor is incorrectly designed.", "defaultLevel": "warning", "helpUri": "https://docs.microsoft.com/visualstudio/code-quality/ca1012", @@ -971,7 +971,7 @@ "CA1508": { "id": "CA1508", "shortDescription": "Avoid dead conditional code", - "fullDescription": "'{0}' is always '{1}'. Remove or refactor the condition(s) to avoid dead code.", + "fullDescription": "'{0}' is never '{1}'. Remove or refactor the condition(s) to avoid dead code.", "defaultLevel": "warning", "helpUri": "https://docs.microsoft.com/visualstudio/code-quality/ca1508", "properties": { @@ -1350,7 +1350,7 @@ "CA1805": { "id": "CA1805", "shortDescription": "Do not initialize unnecessarily", - "fullDescription": "The common language runtime initializes all fields to their default values before running the constructor. In most cases, initializing a field to its default value in a constructor is redundant, which adds to maintenance costs and may degrade performance (such as with increased assembly size). One case where it is not redundant occurs when the constructor calls another constructor of the same class or a base class constructor and that constructor initializes the field to a non-default value. In this case, changing the value of the field back to its default value can be appropriate.", + "fullDescription": "The .NET runtime initializes all fields of reference types to their default values before running the constructor. In most cases, explicitly initializing a field to its default value in a constructor is redundant, adding maintenance costs and potentially degrading performance (such as with increased assembly size), and the explicit initialization can be removed. In some cases, such as with static readonly fields that permanently retain their default value, consider instead changing them to be constants or properties.", "defaultLevel": "warning", "helpUri": "https://docs.microsoft.com/visualstudio/code-quality/ca1805", "properties": { @@ -2558,7 +2558,7 @@ }, "CA1835": { "id": "CA1835", - "shortDescription": "Prefer the 'Memory'-based overloads for 'ReadAsync' and 'WriteAsync'.", + "shortDescription": "Prefer the 'Memory'-based overloads for 'ReadAsync' and 'WriteAsync'", "fullDescription": "'Stream' has a 'ReadAsync' overload that takes a 'Memory' as the first argument, and a 'WriteAsync' overload that takes a 'ReadOnlyMemory' as the first argument. Prefer calling the memory based overloads, which are more efficient.", "defaultLevel": "warning", "helpUri": "https://docs.microsoft.com/visualstudio/code-quality/ca1835", @@ -3382,6 +3382,139 @@ ] } }, + "CA2350": { + "id": "CA2350", + "shortDescription": "Do not use insecure deserialization with DataTable.ReadXml()", + "fullDescription": "The method '{0}' is insecure when deserializing untrusted data. If deserializing untrusted data, replace with TBD.", + "defaultLevel": "warning", + "helpUri": "https://docs.microsoft.com/visualstudio/code-quality/ca2350", + "properties": { + "category": "Security", + "isEnabledByDefault": false, + "typeName": "DoNotUseDataTableReadXml", + "languages": [ + "C#", + "Visual Basic" + ], + "tags": [ + "Telemetry" + ] + } + }, + "CA2351": { + "id": "CA2351", + "shortDescription": "Do not use insecure deserialization with DataSet.ReadXml()", + "fullDescription": "The method '{0}' is insecure when deserializing untrusted data. If deserializing untrusted data, replace with TBD.", + "defaultLevel": "warning", + "helpUri": "https://docs.microsoft.com/visualstudio/code-quality/ca2351", + "properties": { + "category": "Security", + "isEnabledByDefault": false, + "typeName": "DoNotUseDataSetReadXml", + "languages": [ + "C#", + "Visual Basic" + ], + "tags": [ + "Telemetry" + ] + } + }, + "CA2352": { + "id": "CA2352", + "shortDescription": "Unsafe DataSet or DataTable in serializable type can be vulnerable to remote code execution attacks", + "fullDescription": "When deserializing untrusted input with an IFormatter-based serializer, deserializing a {0} object is insecure. '{1}' either is or derives from {0}.", + "defaultLevel": "warning", + "helpUri": "https://docs.microsoft.com/visualstudio/code-quality/ca2352", + "properties": { + "category": "Security", + "isEnabledByDefault": false, + "typeName": "DataSetDataTableInSerializableTypeAnalyzer", + "languages": [ + "C#", + "Visual Basic" + ], + "tags": [ + "Telemetry" + ] + } + }, + "CA2353": { + "id": "CA2353", + "shortDescription": "Unsafe DataSet or DataTable in serializable type", + "fullDescription": "When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}.", + "defaultLevel": "warning", + "helpUri": "https://docs.microsoft.com/visualstudio/code-quality/ca2353", + "properties": { + "category": "Security", + "isEnabledByDefault": false, + "typeName": "DataSetDataTableInSerializableTypeAnalyzer", + "languages": [ + "C#", + "Visual Basic" + ], + "tags": [ + "Telemetry" + ] + } + }, + "CA2354": { + "id": "CA2354", + "shortDescription": "Unsafe DataSet or DataTable in deserialized object graph can be vulnerable to remote code execution attacks", + "fullDescription": "When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}.", + "defaultLevel": "warning", + "helpUri": "https://docs.microsoft.com/visualstudio/code-quality/ca2354", + "properties": { + "category": "Security", + "isEnabledByDefault": false, + "typeName": "DataSetDataTableInIFormatterSerializableObjectGraphAnalyzer", + "languages": [ + "C#", + "Visual Basic" + ], + "tags": [ + "Telemetry" + ] + } + }, + "CA2355": { + "id": "CA2355", + "shortDescription": "Unsafe DataSet or DataTable type found in deserializable object graph", + "fullDescription": "When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}.", + "defaultLevel": "warning", + "helpUri": "https://docs.microsoft.com/visualstudio/code-quality/ca2355", + "properties": { + "category": "Security", + "isEnabledByDefault": false, + "typeName": "DataSetDataTableInSerializableObjectGraphAnalyzer", + "languages": [ + "C#", + "Visual Basic" + ], + "tags": [ + "Telemetry" + ] + } + }, + "CA2356": { + "id": "CA2356", + "shortDescription": "Unsafe DataSet or DataTable type in web deserializable object graph", + "fullDescription": "When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}.", + "defaultLevel": "warning", + "helpUri": "https://docs.microsoft.com/visualstudio/code-quality/ca2356", + "properties": { + "category": "Security", + "isEnabledByDefault": false, + "typeName": "DataSetDataTableInWebSerializableObjectGraphAnalyzer", + "languages": [ + "C#", + "Visual Basic" + ], + "tags": [ + "Telemetry" + ] + } + }, "CA3001": { "id": "CA3001", "shortDescription": "Review code for SQL injection vulnerabilities", @@ -4635,6 +4768,24 @@ "Telemetry" ] } + }, + "CA2016": { + "id": "CA2016", + "shortDescription": "Forward the 'CancellationToken' parameter to methods that take one", + "fullDescription": "Forward the 'CancellationToken' parameter to methods that take one to ensure the operation cancellation notifications gets properly propagated, or pass in 'CancellationToken.None' explicitly to indicate intentionally not propagating the token.", + "defaultLevel": "warning", + "helpUri": "https://docs.microsoft.com/visualstudio/code-quality/ca2016", + "properties": { + "category": "Reliability", + "isEnabledByDefault": true, + "typeName": "CSharpForwardCancellationTokenToInvocationsAnalyzer", + "languages": [ + "C#" + ], + "tags": [ + "Telemetry" + ] + } } } }, @@ -4700,6 +4851,24 @@ "Telemetry" ] } + }, + "CA2016": { + "id": "CA2016", + "shortDescription": "Forward the 'CancellationToken' parameter to methods that take one", + "fullDescription": "Forward the 'CancellationToken' parameter to methods that take one to ensure the operation cancellation notifications gets properly propagated, or pass in 'CancellationToken.None' explicitly to indicate intentionally not propagating the token.", + "defaultLevel": "warning", + "helpUri": "https://docs.microsoft.com/visualstudio/code-quality/ca2016", + "properties": { + "category": "Reliability", + "isEnabledByDefault": true, + "typeName": "BasicForwardCancellationTokenToInvocationsAnalyzer", + "languages": [ + "Visual Basic" + ], + "tags": [ + "Telemetry" + ] + } } } }, diff --git a/src/Microsoft.CodeQuality.Analyzers/Microsoft.CodeQuality.Analyzers.md b/src/Microsoft.CodeQuality.Analyzers/Microsoft.CodeQuality.Analyzers.md index d97753d78c..56ec528269 100644 --- a/src/Microsoft.CodeQuality.Analyzers/Microsoft.CodeQuality.Analyzers.md +++ b/src/Microsoft.CodeQuality.Analyzers/Microsoft.CodeQuality.Analyzers.md @@ -8,7 +8,7 @@ Rule ID | Title | Category | Enabled | Severity | CodeFix | Description | [CA1005](https://docs.microsoft.com/visualstudio/code-quality/ca1005) | Avoid excessive parameters on generic types | Design | False | Warning | False | The more type parameters a generic type contains, the more difficult it is to know and remember what each type parameter represents. | [CA1008](https://docs.microsoft.com/visualstudio/code-quality/ca1008) | Enums should have zero value | Design | False | Warning | True | The default value of an uninitialized enumeration, just as other value types, is zero. A nonflags-attributed enumeration should define a member by using the value of zero so that the default value is a valid value of the enumeration. If an enumeration that has the FlagsAttribute attribute applied defines a zero-valued member, its name should be ""None"" to indicate that no values have been set in the enumeration. | [CA1010](https://docs.microsoft.com/visualstudio/code-quality/ca1010) | Generic interface should also be implemented | Design | True | Warning | False | To broaden the usability of a type, implement one of the generic interfaces. This is especially true for collections as they can then be used to populate generic collection types. | -[CA1012](https://docs.microsoft.com/visualstudio/code-quality/ca1012) | Abstract types should not have constructors | Design | False | Warning | True | Constructors on abstract types can be called only by derived types. Because public constructors create instances of a type, and you cannot create instances of an abstract type, an abstract type that has a public constructor is incorrectly designed. | +[CA1012](https://docs.microsoft.com/visualstudio/code-quality/ca1012) | Abstract types should not have public constructors | Design | False | Warning | True | Constructors on abstract types can be called only by derived types. Because public constructors create instances of a type, and you cannot create instances of an abstract type, an abstract type that has a public constructor is incorrectly designed. | [CA1014](https://docs.microsoft.com/visualstudio/code-quality/ca1014) | Mark assemblies with CLSCompliant | Design | False | Warning | False | The Common Language Specification (CLS) defines naming restrictions, data types, and rules to which assemblies must conform if they will be used across programming languages. Good design dictates that all assemblies explicitly indicate CLS compliance by using CLSCompliantAttribute . If this attribute is not present on an assembly, the assembly is not compliant. | [CA1016](https://docs.microsoft.com/visualstudio/code-quality/ca1016) | Mark assemblies with assembly version | Design | True | Warning | False | The .NET Framework uses the version number to uniquely identify an assembly, and to bind to types in strongly named assemblies. The version number is used together with version and publisher policy. By default, applications run only with the assembly version with which they were built. | [CA1017](https://docs.microsoft.com/visualstudio/code-quality/ca1017) | Mark assemblies with ComVisible | Design | False | Warning | False | ComVisibleAttribute determines how COM clients access managed code. Good design dictates that assemblies explicitly indicate COM visibility. COM visibility can be set for the whole assembly and then overridden for individual types and type members. If this attribute is not present, the contents of the assembly are visible to COM clients. | @@ -54,7 +54,7 @@ Rule ID | Title | Category | Enabled | Severity | CodeFix | Description | [CA1505](https://docs.microsoft.com/visualstudio/code-quality/ca1505) | Avoid unmaintainable code | Maintainability | False | Warning | False | The maintainability index is calculated by using the following metrics: lines of code, program volume, and cyclomatic complexity. Program volume is a measure of the difficulty of understanding of a symbol that is based on the number of operators and operands in the code. Cyclomatic complexity is a measure of the structural complexity of the type or method. A low maintainability index indicates that code is probably difficult to maintain and would be a good candidate to redesign. | [CA1506](https://docs.microsoft.com/visualstudio/code-quality/ca1506) | Avoid excessive class coupling | Maintainability | False | Warning | False | This rule measures class coupling by counting the number of unique type references that a symbol contains. Symbols that have a high degree of class coupling can be difficult to maintain. It is a good practice to have types and methods that exhibit low coupling and high cohesion. To fix this violation, try to redesign the code to reduce the number of types to which it is coupled. | [CA1507](https://docs.microsoft.com/visualstudio/code-quality/ca1507) | Use nameof to express symbol names | Maintainability | True | Warning | True | Using nameof helps keep your code valid when refactoring. | -[CA1508](https://docs.microsoft.com/visualstudio/code-quality/ca1508) | Avoid dead conditional code | Maintainability | False | Warning | False | '{0}' is always '{1}'. Remove or refactor the condition(s) to avoid dead code. | +[CA1508](https://docs.microsoft.com/visualstudio/code-quality/ca1508) | Avoid dead conditional code | Maintainability | False | Warning | False | '{0}' is never '{1}'. Remove or refactor the condition(s) to avoid dead code. | [CA1509](https://docs.microsoft.com/visualstudio/code-quality/ca1509) | Invalid entry in code metrics rule specification file | Maintainability | False | Warning | False | Invalid entry in code metrics rule specification file | [CA1700](https://docs.microsoft.com/visualstudio/code-quality/ca1700) | Do not name enum values 'Reserved' | Naming | False | Warning | False | This rule assumes that an enumeration member that has a name that contains "reserved" is not currently used but is a placeholder to be renamed or removed in a future version. Renaming or removing a member is a breaking change. | [CA1707](https://docs.microsoft.com/visualstudio/code-quality/ca1707) | Identifiers should not contain underscores | Naming | True | Warning | False | By convention, identifier names do not contain the underscore (_) character. This rule checks namespaces, types, members, and parameters. | @@ -73,7 +73,7 @@ Rule ID | Title | Category | Enabled | Severity | CodeFix | Description | [CA1725](https://docs.microsoft.com/visualstudio/code-quality/ca1725) | Parameter names should match base declaration | Naming | False | Warning | True | Consistent naming of parameters in an override hierarchy increases the usability of the method overrides. A parameter name in a derived method that differs from the name in the base declaration can cause confusion about whether the method is an override of the base method or a new overload of the method. | [CA1801](https://docs.microsoft.com/visualstudio/code-quality/ca1801) | Review unused parameters | Usage | True | Warning | True | Avoid unused paramereters in your code. If the parameter cannot be removed, then change its name so it starts with an underscore and is optionally followed by an integer, such as '_', '_1', '_2', etc. These are treated as special discard symbol names. | [CA1802](https://docs.microsoft.com/visualstudio/code-quality/ca1802) | Use literals where appropriate | Performance | True | Warning | True | A field is declared static and read-only (Shared and ReadOnly in Visual Basic), and is initialized by using a value that is computable at compile time. Because the value that is assigned to the targeted field is computable at compile time, change the declaration to a const (Const in Visual Basic) field so that the value is computed at compile time instead of at run?time. | -[CA1805](https://docs.microsoft.com/visualstudio/code-quality/ca1805) | Do not initialize unnecessarily | Performance | True | Warning | True | The common language runtime initializes all fields to their default values before running the constructor. In most cases, initializing a field to its default value in a constructor is redundant, which adds to maintenance costs and may degrade performance (such as with increased assembly size). One case where it is not redundant occurs when the constructor calls another constructor of the same class or a base class constructor and that constructor initializes the field to a non-default value. In this case, changing the value of the field back to its default value can be appropriate. | +[CA1805](https://docs.microsoft.com/visualstudio/code-quality/ca1805) | Do not initialize unnecessarily | Performance | True | Warning | True | The .NET runtime initializes all fields of reference types to their default values before running the constructor. In most cases, explicitly initializing a field to its default value in a constructor is redundant, adding maintenance costs and potentially degrading performance (such as with increased assembly size), and the explicit initialization can be removed. In some cases, such as with static readonly fields that permanently retain their default value, consider instead changing them to be constants or properties. | [CA1806](https://docs.microsoft.com/visualstudio/code-quality/ca1806) | Do not ignore method results | Performance | True | Warning | False | A new object is created but never used; or a method that creates and returns a new string is called and the new string is never used; or a COM or P/Invoke method returns an HRESULT or error code that is never used. | [CA1812](https://docs.microsoft.com/visualstudio/code-quality/ca1812) | Avoid uninstantiated internal classes | Performance | True | Warning | False | An instance of an assembly-level type is not created by code in the assembly. | [CA1814](https://docs.microsoft.com/visualstudio/code-quality/ca1814) | Prefer jagged arrays over multidimensional | Performance | True | Warning | False | A jagged array is an array whose elements are arrays. The arrays that make up the elements can be of different sizes, leading to less wasted space for some sets of data. | diff --git a/src/Microsoft.CodeQuality.Analyzers/Microsoft.CodeQuality.Analyzers.sarif b/src/Microsoft.CodeQuality.Analyzers/Microsoft.CodeQuality.Analyzers.sarif index 2e3c70dda1..c723428d4d 100644 --- a/src/Microsoft.CodeQuality.Analyzers/Microsoft.CodeQuality.Analyzers.sarif +++ b/src/Microsoft.CodeQuality.Analyzers/Microsoft.CodeQuality.Analyzers.sarif @@ -141,7 +141,7 @@ }, "CA1012": { "id": "CA1012", - "shortDescription": "Abstract types should not have constructors", + "shortDescription": "Abstract types should not have public constructors", "fullDescription": "Constructors on abstract types can be called only by derived types. Because public constructors create instances of a type, and you cannot create instances of an abstract type, an abstract type that has a public constructor is incorrectly designed.", "defaultLevel": "warning", "helpUri": "https://docs.microsoft.com/visualstudio/code-quality/ca1012", @@ -956,7 +956,7 @@ "CA1508": { "id": "CA1508", "shortDescription": "Avoid dead conditional code", - "fullDescription": "'{0}' is always '{1}'. Remove or refactor the condition(s) to avoid dead code.", + "fullDescription": "'{0}' is never '{1}'. Remove or refactor the condition(s) to avoid dead code.", "defaultLevel": "warning", "helpUri": "https://docs.microsoft.com/visualstudio/code-quality/ca1508", "properties": { @@ -1335,7 +1335,7 @@ "CA1805": { "id": "CA1805", "shortDescription": "Do not initialize unnecessarily", - "fullDescription": "The common language runtime initializes all fields to their default values before running the constructor. In most cases, initializing a field to its default value in a constructor is redundant, which adds to maintenance costs and may degrade performance (such as with increased assembly size). One case where it is not redundant occurs when the constructor calls another constructor of the same class or a base class constructor and that constructor initializes the field to a non-default value. In this case, changing the value of the field back to its default value can be appropriate.", + "fullDescription": "The .NET runtime initializes all fields of reference types to their default values before running the constructor. In most cases, explicitly initializing a field to its default value in a constructor is redundant, adding maintenance costs and potentially degrading performance (such as with increased assembly size), and the explicit initialization can be removed. In some cases, such as with static readonly fields that permanently retain their default value, consider instead changing them to be constants or properties.", "defaultLevel": "warning", "helpUri": "https://docs.microsoft.com/visualstudio/code-quality/ca1805", "properties": { diff --git a/src/Microsoft.NetCore.Analyzers/Microsoft.NetCore.Analyzers.md b/src/Microsoft.NetCore.Analyzers/Microsoft.NetCore.Analyzers.md index 62fff6c68e..32c51a0307 100644 --- a/src/Microsoft.NetCore.Analyzers/Microsoft.NetCore.Analyzers.md +++ b/src/Microsoft.NetCore.Analyzers/Microsoft.NetCore.Analyzers.md @@ -23,7 +23,7 @@ Rule ID | Title | Category | Enabled | Severity | CodeFix | Description | [CA1832](https://docs.microsoft.com/visualstudio/code-quality/ca1832) | Use AsSpan or AsMemory instead of Range-based indexers when appropriate | Performance | True | Warning | True | The Range-based indexer on array values produces a copy of requested portion of the array. This copy is usually unnecessary when it is implicitly used as a ReadOnlySpan or ReadOnlyMemory value. Use the AsSpan method to avoid the unnecessary copy. | [CA1833](https://docs.microsoft.com/visualstudio/code-quality/ca1833) | Use AsSpan or AsMemory instead of Range-based indexers when appropriate | Performance | True | Warning | True | The Range-based indexer on array values produces a copy of requested portion of the array. This copy is often unwanted when it is implicitly used as a Span or Memory value. Use the AsSpan method to avoid the copy. | [CA1834](https://docs.microsoft.com/visualstudio/code-quality/ca1834) | Consider using 'StringBuilder.Append(char)' when applicable. | Performance | True | Warning | True | 'StringBuilder.Append(char)' is more efficient than 'StringBuilder.Append(string)' when the string is a single character. When calling 'Append' with a constant, prefer using a constant char rather than a constant string containing one character. | -[CA1835](https://docs.microsoft.com/visualstudio/code-quality/ca1835) | Prefer the 'Memory'-based overloads for 'ReadAsync' and 'WriteAsync'. | Performance | True | Warning | True | 'Stream' has a 'ReadAsync' overload that takes a 'Memory' as the first argument, and a 'WriteAsync' overload that takes a 'ReadOnlyMemory' as the first argument. Prefer calling the memory based overloads, which are more efficient. | +[CA1835](https://docs.microsoft.com/visualstudio/code-quality/ca1835) | Prefer the 'Memory'-based overloads for 'ReadAsync' and 'WriteAsync' | Performance | True | Warning | True | 'Stream' has a 'ReadAsync' overload that takes a 'Memory' as the first argument, and a 'WriteAsync' overload that takes a 'ReadOnlyMemory' as the first argument. Prefer calling the memory based overloads, which are more efficient. | [CA1836](https://docs.microsoft.com/visualstudio/code-quality/ca1836) | Prefer IsEmpty over Count | Performance | True | Warning | True | For determining whether the object contains or not any items, prefer using 'IsEmpty' property rather than retrieving the number of items from the 'Count' property and comparing it to 0 or 1. | [CA2000](https://docs.microsoft.com/visualstudio/code-quality/ca2000) | Dispose objects before losing scope | Reliability | True | Warning | False | If a disposable object is not explicitly disposed before all references to it are out of scope, the object will be disposed at some indeterminate time when the garbage collector runs the finalizer of the object. Because an exceptional event might occur that will prevent the finalizer of the object from running, the object should be explicitly disposed instead. | [CA2002](https://docs.microsoft.com/visualstudio/code-quality/ca2002) | Do not lock on objects with weak identity | Reliability | True | Warning | False | An object is said to have a weak identity when it can be directly accessed across application domain boundaries. A thread that tries to acquire a lock on an object that has a weak identity can be blocked by a second thread in a different application domain that has a lock on the same object. | @@ -33,6 +33,7 @@ Rule ID | Title | Category | Enabled | Severity | CodeFix | Description | [CA2013](https://docs.microsoft.com/visualstudio/code-quality/ca2013) | Do not use ReferenceEquals with value types | Reliability | True | Warning | False | Value type typed arguments are uniquely boxed for each call to this method, therefore the result is always false. | [CA2014](https://docs.microsoft.com/visualstudio/code-quality/ca2014) | Do not use stackalloc in loops. | Reliability | True | Warning | False | Stack space allocated by a stackalloc is only released at the end of the current method's invocation. Using it in a loop can result in unbounded stack growth and eventual stack overflow conditions. | [CA2015](https://docs.microsoft.com/visualstudio/code-quality/ca2015) | Do not define finalizers for types derived from MemoryManager | Reliability | True | Warning | False | Adding a finalizer to a type derived from MemoryManager may permit memory to be freed while it is still in use by a Span. | +[CA2016](https://docs.microsoft.com/visualstudio/code-quality/ca2016) | Forward the 'CancellationToken' parameter to methods that take one | Reliability | True | Warning | True | Forward the 'CancellationToken' parameter to methods that take one to ensure the operation cancellation notifications gets properly propagated, or pass in 'CancellationToken.None' explicitly to indicate intentionally not propagating the token. | [CA2100](https://docs.microsoft.com/visualstudio/code-quality/ca2100) | Review SQL queries for security vulnerabilities | Security | True | Warning | False | SQL queries that directly use user input can be vulnerable to SQL injection attacks. Review this SQL query for potential vulnerabilities, and consider using a parameterized SQL query. | [CA2101](https://docs.microsoft.com/visualstudio/code-quality/ca2101) | Specify marshaling for P/Invoke string arguments | Globalization | True | Warning | True | A platform invoke member allows partially trusted callers, has a string parameter, and does not explicitly marshal the string. This can cause a potential security vulnerability. | [CA2201](https://docs.microsoft.com/visualstudio/code-quality/ca2201) | Do not raise reserved exception types | Usage | False | Warning | False | An exception of type that is not sufficiently specific or reserved by the runtime should never be raised by user code. This makes the original error difficult to detect and debug. If this exception instance might be thrown, use a different exception type. | @@ -65,6 +66,13 @@ Rule ID | Title | Category | Enabled | Severity | CodeFix | Description | [CA2328](https://docs.microsoft.com/visualstudio/code-quality/ca2328) | Ensure that JsonSerializerSettings are secure | Security | False | Warning | False | When deserializing untrusted input, allowing arbitrary types to be deserialized is insecure. When using JsonSerializerSettings, ensure TypeNameHandling.None is specified, or for values other than None, ensure a SerializationBinder is specified to restrict deserialized types. | [CA2329](https://docs.microsoft.com/visualstudio/code-quality/ca2329) | Do not deserialize with JsonSerializer using an insecure configuration | Security | False | Warning | False | When deserializing untrusted input, allowing arbitrary types to be deserialized is insecure. When using deserializing JsonSerializer, use TypeNameHandling.None, or for values other than None, restrict deserialized types with a SerializationBinder. | [CA2330](https://docs.microsoft.com/visualstudio/code-quality/ca2330) | Ensure that JsonSerializer has a secure configuration when deserializing | Security | False | Warning | False | When deserializing untrusted input, allowing arbitrary types to be deserialized is insecure. When using deserializing JsonSerializer, use TypeNameHandling.None, or for values other than None, restrict deserialized types with a SerializationBinder. | +[CA2350](https://docs.microsoft.com/visualstudio/code-quality/ca2350) | Do not use insecure deserialization with DataTable.ReadXml() | Security | False | Warning | False | The method '{0}' is insecure when deserializing untrusted data. If deserializing untrusted data, replace with TBD. | +[CA2351](https://docs.microsoft.com/visualstudio/code-quality/ca2351) | Do not use insecure deserialization with DataSet.ReadXml() | Security | False | Warning | False | The method '{0}' is insecure when deserializing untrusted data. If deserializing untrusted data, replace with TBD. | +[CA2352](https://docs.microsoft.com/visualstudio/code-quality/ca2352) | Unsafe DataSet or DataTable in serializable type can be vulnerable to remote code execution attacks | Security | False | Warning | False | When deserializing untrusted input with an IFormatter-based serializer, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. | +[CA2353](https://docs.microsoft.com/visualstudio/code-quality/ca2353) | Unsafe DataSet or DataTable in serializable type | Security | False | Warning | False | When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. | +[CA2354](https://docs.microsoft.com/visualstudio/code-quality/ca2354) | Unsafe DataSet or DataTable in deserialized object graph can be vulnerable to remote code execution attacks | Security | False | Warning | False | When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. | +[CA2355](https://docs.microsoft.com/visualstudio/code-quality/ca2355) | Unsafe DataSet or DataTable type found in deserializable object graph | Security | False | Warning | False | When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. | +[CA2356](https://docs.microsoft.com/visualstudio/code-quality/ca2356) | Unsafe DataSet or DataTable type in web deserializable object graph | Security | False | Warning | False | When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. | [CA3001](https://docs.microsoft.com/visualstudio/code-quality/ca3001) | Review code for SQL injection vulnerabilities | Security | False | Warning | False | Potential SQL injection vulnerability was found where '{0}' in method '{1}' may be tainted by user-controlled data from '{2}' in method '{3}'. | [CA3002](https://docs.microsoft.com/visualstudio/code-quality/ca3002) | Review code for XSS vulnerabilities | Security | False | Warning | False | Potential cross-site scripting (XSS) vulnerability was found where '{0}' in method '{1}' may be tainted by user-controlled data from '{2}' in method '{3}'. | [CA3003](https://docs.microsoft.com/visualstudio/code-quality/ca3003) | Review code for file path injection vulnerabilities | Security | False | Warning | False | Potential file path injection vulnerability was found where '{0}' in method '{1}' may be tainted by user-controlled data from '{2}' in method '{3}'. | diff --git a/src/Microsoft.NetCore.Analyzers/Microsoft.NetCore.Analyzers.sarif b/src/Microsoft.NetCore.Analyzers/Microsoft.NetCore.Analyzers.sarif index 70cd2707ff..924a6ee7e7 100644 --- a/src/Microsoft.NetCore.Analyzers/Microsoft.NetCore.Analyzers.sarif +++ b/src/Microsoft.NetCore.Analyzers/Microsoft.NetCore.Analyzers.sarif @@ -382,7 +382,7 @@ }, "CA1835": { "id": "CA1835", - "shortDescription": "Prefer the 'Memory'-based overloads for 'ReadAsync' and 'WriteAsync'.", + "shortDescription": "Prefer the 'Memory'-based overloads for 'ReadAsync' and 'WriteAsync'", "fullDescription": "'Stream' has a 'ReadAsync' overload that takes a 'Memory' as the first argument, and a 'WriteAsync' overload that takes a 'ReadOnlyMemory' as the first argument. Prefer calling the memory based overloads, which are more efficient.", "defaultLevel": "warning", "helpUri": "https://docs.microsoft.com/visualstudio/code-quality/ca1835", @@ -1206,6 +1206,139 @@ ] } }, + "CA2350": { + "id": "CA2350", + "shortDescription": "Do not use insecure deserialization with DataTable.ReadXml()", + "fullDescription": "The method '{0}' is insecure when deserializing untrusted data. If deserializing untrusted data, replace with TBD.", + "defaultLevel": "warning", + "helpUri": "https://docs.microsoft.com/visualstudio/code-quality/ca2350", + "properties": { + "category": "Security", + "isEnabledByDefault": false, + "typeName": "DoNotUseDataTableReadXml", + "languages": [ + "C#", + "Visual Basic" + ], + "tags": [ + "Telemetry" + ] + } + }, + "CA2351": { + "id": "CA2351", + "shortDescription": "Do not use insecure deserialization with DataSet.ReadXml()", + "fullDescription": "The method '{0}' is insecure when deserializing untrusted data. If deserializing untrusted data, replace with TBD.", + "defaultLevel": "warning", + "helpUri": "https://docs.microsoft.com/visualstudio/code-quality/ca2351", + "properties": { + "category": "Security", + "isEnabledByDefault": false, + "typeName": "DoNotUseDataSetReadXml", + "languages": [ + "C#", + "Visual Basic" + ], + "tags": [ + "Telemetry" + ] + } + }, + "CA2352": { + "id": "CA2352", + "shortDescription": "Unsafe DataSet or DataTable in serializable type can be vulnerable to remote code execution attacks", + "fullDescription": "When deserializing untrusted input with an IFormatter-based serializer, deserializing a {0} object is insecure. '{1}' either is or derives from {0}.", + "defaultLevel": "warning", + "helpUri": "https://docs.microsoft.com/visualstudio/code-quality/ca2352", + "properties": { + "category": "Security", + "isEnabledByDefault": false, + "typeName": "DataSetDataTableInSerializableTypeAnalyzer", + "languages": [ + "C#", + "Visual Basic" + ], + "tags": [ + "Telemetry" + ] + } + }, + "CA2353": { + "id": "CA2353", + "shortDescription": "Unsafe DataSet or DataTable in serializable type", + "fullDescription": "When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}.", + "defaultLevel": "warning", + "helpUri": "https://docs.microsoft.com/visualstudio/code-quality/ca2353", + "properties": { + "category": "Security", + "isEnabledByDefault": false, + "typeName": "DataSetDataTableInSerializableTypeAnalyzer", + "languages": [ + "C#", + "Visual Basic" + ], + "tags": [ + "Telemetry" + ] + } + }, + "CA2354": { + "id": "CA2354", + "shortDescription": "Unsafe DataSet or DataTable in deserialized object graph can be vulnerable to remote code execution attacks", + "fullDescription": "When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}.", + "defaultLevel": "warning", + "helpUri": "https://docs.microsoft.com/visualstudio/code-quality/ca2354", + "properties": { + "category": "Security", + "isEnabledByDefault": false, + "typeName": "DataSetDataTableInIFormatterSerializableObjectGraphAnalyzer", + "languages": [ + "C#", + "Visual Basic" + ], + "tags": [ + "Telemetry" + ] + } + }, + "CA2355": { + "id": "CA2355", + "shortDescription": "Unsafe DataSet or DataTable type found in deserializable object graph", + "fullDescription": "When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}.", + "defaultLevel": "warning", + "helpUri": "https://docs.microsoft.com/visualstudio/code-quality/ca2355", + "properties": { + "category": "Security", + "isEnabledByDefault": false, + "typeName": "DataSetDataTableInSerializableObjectGraphAnalyzer", + "languages": [ + "C#", + "Visual Basic" + ], + "tags": [ + "Telemetry" + ] + } + }, + "CA2356": { + "id": "CA2356", + "shortDescription": "Unsafe DataSet or DataTable type in web deserializable object graph", + "fullDescription": "When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}.", + "defaultLevel": "warning", + "helpUri": "https://docs.microsoft.com/visualstudio/code-quality/ca2356", + "properties": { + "category": "Security", + "isEnabledByDefault": false, + "typeName": "DataSetDataTableInWebSerializableObjectGraphAnalyzer", + "languages": [ + "C#", + "Visual Basic" + ], + "tags": [ + "Telemetry" + ] + } + }, "CA3001": { "id": "CA3001", "shortDescription": "Review code for SQL injection vulnerabilities", @@ -2459,6 +2592,24 @@ "Telemetry" ] } + }, + "CA2016": { + "id": "CA2016", + "shortDescription": "Forward the 'CancellationToken' parameter to methods that take one", + "fullDescription": "Forward the 'CancellationToken' parameter to methods that take one to ensure the operation cancellation notifications gets properly propagated, or pass in 'CancellationToken.None' explicitly to indicate intentionally not propagating the token.", + "defaultLevel": "warning", + "helpUri": "https://docs.microsoft.com/visualstudio/code-quality/ca2016", + "properties": { + "category": "Reliability", + "isEnabledByDefault": true, + "typeName": "CSharpForwardCancellationTokenToInvocationsAnalyzer", + "languages": [ + "C#" + ], + "tags": [ + "Telemetry" + ] + } } } }, @@ -2524,6 +2675,24 @@ "Telemetry" ] } + }, + "CA2016": { + "id": "CA2016", + "shortDescription": "Forward the 'CancellationToken' parameter to methods that take one", + "fullDescription": "Forward the 'CancellationToken' parameter to methods that take one to ensure the operation cancellation notifications gets properly propagated, or pass in 'CancellationToken.None' explicitly to indicate intentionally not propagating the token.", + "defaultLevel": "warning", + "helpUri": "https://docs.microsoft.com/visualstudio/code-quality/ca2016", + "properties": { + "category": "Reliability", + "isEnabledByDefault": true, + "typeName": "BasicForwardCancellationTokenToInvocationsAnalyzer", + "languages": [ + "Visual Basic" + ], + "tags": [ + "Telemetry" + ] + } } } } diff --git a/src/NetAnalyzers/Core/AnalyzerReleases.Unshipped.md b/src/NetAnalyzers/Core/AnalyzerReleases.Unshipped.md index ec7d1d7a75..4f2ff9ff56 100644 --- a/src/NetAnalyzers/Core/AnalyzerReleases.Unshipped.md +++ b/src/NetAnalyzers/Core/AnalyzerReleases.Unshipped.md @@ -29,8 +29,15 @@ CA2016 | Reliability | Info | ForwardCancellationTokenToInvocationsAnalyzer, [Do CA2247 | Usage | Warning | DoNotCreateTaskCompletionSourceWithWrongArguments, [Documentation](https://docs.microsoft.com/visualstudio/code-quality/ca2247) CA2248 | Usage | Info | DoNotCheckFlagFromDifferentEnum, [Documentation](https://docs.microsoft.com/visualstudio/code-quality/ca2248) CA2249 | Usage | Info | PreferStringContainsOverIndexOfAnalyzer, [Documentation](https://docs.microsoft.com/visualstudio/code-quality/ca2249) +CA2350 | Security | Disabled | DoNotUseDataTableReadXml, [Documentation](https://docs.microsoft.com/visualstudio/code-quality/ca2350) +CA2351 | Security | Disabled | DoNotUseDataSetReadXml, [Documentation](https://docs.microsoft.com/visualstudio/code-quality/ca2351) +CA2352 | Security | Disabled | DataSetDataTableInSerializableTypeAnalyzer, [Documentation](https://docs.microsoft.com/visualstudio/code-quality/ca2352) +CA2353 | Security | Disabled | DataSetDataTableInSerializableTypeAnalyzer, [Documentation](https://docs.microsoft.com/visualstudio/code-quality/ca2353) +CA2354 | Security | Disabled | DataSetDataTableInIFormatterSerializableObjectGraphAnalyzer, [Documentation](https://docs.microsoft.com/visualstudio/code-quality/ca2354) +CA2355 | Security | Disabled | DataSetDataTableInSerializableObjectGraphAnalyzer, [Documentation](https://docs.microsoft.com/visualstudio/code-quality/ca2355) +CA2356 | Security | Disabled | DataSetDataTableInWebSerializableObjectGraphAnalyzer, [Documentation](https://docs.microsoft.com/visualstudio/code-quality/ca2356) ### Changed Rules Rule ID | New Category | New Severity | Old Category | Old Severity | Notes --------|--------------|--------------|--------------|--------------|------- -CA2208 | Usage | Info | Usage | Hidden | InstantiateArgumentExceptionsCorrectlyAnalyzer, [Documentation](https://docs.microsoft.com/visualstudio/code-quality/ca2208) \ No newline at end of file +CA2208 | Usage | Info | Usage | Hidden | InstantiateArgumentExceptionsCorrectlyAnalyzer, [Documentation](https://docs.microsoft.com/visualstudio/code-quality/ca2208) diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/MicrosoftNetCoreAnalyzersResources.resx b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/MicrosoftNetCoreAnalyzersResources.resx index 1bc0705847..aed234315f 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/MicrosoftNetCoreAnalyzersResources.resx +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/MicrosoftNetCoreAnalyzersResources.resx @@ -1269,6 +1269,48 @@ Symmetric encryption should always use a non-repeatable initialization vector to prevent dictionary attacks. + + The method '{0}' is insecure when deserializing untrusted data. If deserializing untrusted data, replace with TBD. + + + Do not use insecure deserialization with DataTable.ReadXml() + + + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + + + Unsafe DataSet or DataTable in serializable type + + + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + + + Unsafe DataSet or DataTable type in web deserializable object graph + + + The method '{0}' is insecure when deserializing untrusted data. If deserializing untrusted data, replace with TBD. + + + Do not use insecure deserialization with DataSet.ReadXml() + + + When deserializing untrusted input with an IFormatter-based serializer, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + + + Unsafe DataSet or DataTable in serializable type can be vulnerable to remote code execution attacks + + + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + + + Unsafe DataSet or DataTable type found in deserializable object graph + + + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + + + Unsafe DataSet or DataTable in deserialized object graph can be vulnerable to remote code execution attacks + Do not use stackalloc in loops. diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Security/DataSetDataTableInIFormatterSerializableObjectGraphAnalyzer.cs b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Security/DataSetDataTableInIFormatterSerializableObjectGraphAnalyzer.cs new file mode 100644 index 0000000000..7584533272 --- /dev/null +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Security/DataSetDataTableInIFormatterSerializableObjectGraphAnalyzer.cs @@ -0,0 +1,133 @@ +// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Collections.Immutable; +using System.Diagnostics.CodeAnalysis; +using Analyzer.Utilities; +using Analyzer.Utilities.Extensions; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.Diagnostics; +using Microsoft.CodeAnalysis.Operations; +using Microsoft.NetCore.Analyzers.Security.Helpers; + +namespace Microsoft.NetCore.Analyzers.Security +{ + /// + /// For detecting deserialization of or in an + /// IFormatter deserialized object graph. + /// + [SuppressMessage("Documentation", "CA1200:Avoid using cref tags with a prefix", Justification = "The comment references a type that is not referenced by this compilation.")] + [DiagnosticAnalyzer(LanguageNames.CSharp, LanguageNames.VisualBasic)] + public sealed class DataSetDataTableInIFormatterSerializableObjectGraphAnalyzer : DiagnosticAnalyzer + { + internal static readonly DiagnosticDescriptor ObjectGraphContainsDangerousTypeDescriptor = + SecurityHelpers.CreateDiagnosticDescriptor( + "CA2354", + nameof(MicrosoftNetCoreAnalyzersResources.DataSetDataTableInRceDeserializableObjectGraphTitle), + nameof(MicrosoftNetCoreAnalyzersResources.DataSetDataTableInRceDeserializableObjectGraphMessage), + RuleLevel.Disabled, + isPortedFxCopRule: false, + isDataflowRule: false); + + public override ImmutableArray SupportedDiagnostics => + ImmutableArray.Create(ObjectGraphContainsDangerousTypeDescriptor); + + public override void Initialize(AnalysisContext context) + { + context.EnableConcurrentExecution(); + + // Security analyzer - analyze and report diagnostics on generated code. + context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.Analyze | GeneratedCodeAnalysisFlags.ReportDiagnostics); + + context.RegisterCompilationStartAction( + (CompilationStartAnalysisContext compilationStartAnalysisContext) => + { + Compilation? compilation = compilationStartAnalysisContext.Compilation; + WellKnownTypeProvider wellKnownTypeProvider = WellKnownTypeProvider.GetOrCreate(compilation); + + if (!wellKnownTypeProvider.TryGetOrCreateTypeByMetadataName( + WellKnownTypeNames.SystemDataDataSet, + out INamedTypeSymbol? dataSetTypeSymbol) + || !wellKnownTypeProvider.TryGetOrCreateTypeByMetadataName( + WellKnownTypeNames.SystemDataDataTable, + out INamedTypeSymbol? dataTableTypeSymbol)) + { + return; + } + + INamedTypeSymbol? serializableAttributeTypeSymbol = wellKnownTypeProvider.GetOrCreateTypeByMetadataName( + WellKnownTypeNames.SystemSerializableAttribute); + INamedTypeSymbol? nonSerializedAttributeTypeSymbol = wellKnownTypeProvider.GetOrCreateTypeByMetadataName( + WellKnownTypeNames.SystemSerializableAttribute); + INamedTypeSymbol? binaryFormatterTypeSymbol = wellKnownTypeProvider.GetOrCreateTypeByMetadataName( + WellKnownTypeNames.SystemRuntimeSerializationFormattersBinaryBinaryFormatter); + INamedTypeSymbol? netDataContractSerializerTypeSymbol = wellKnownTypeProvider.GetOrCreateTypeByMetadataName( + WellKnownTypeNames.SystemRuntimeSerializationNetDataContractSerializer); + INamedTypeSymbol? objectStateFormatterTypeSymbol = wellKnownTypeProvider.GetOrCreateTypeByMetadataName( + WellKnownTypeNames.SystemWebUIObjectStateFormatter); + INamedTypeSymbol? soapFormatterTypeSymbol = wellKnownTypeProvider.GetOrCreateTypeByMetadataName( + WellKnownTypeNames.SystemRuntimeSerializationFormattersSoapSoapFormatter); + + if (serializableAttributeTypeSymbol == null + || (binaryFormatterTypeSymbol == null + && netDataContractSerializerTypeSymbol == null + && objectStateFormatterTypeSymbol == null + && soapFormatterTypeSymbol == null)) + { + return; + } + + InsecureDeserializationTypeDecider decider = InsecureDeserializationTypeDecider.GetOrCreate(compilation); + + compilationStartAnalysisContext.RegisterOperationAction( + (OperationAnalysisContext operationAnalysisContext) => + { + IInvocationOperation invocationOperation = + (IInvocationOperation)operationAnalysisContext.Operation; + string methodName = invocationOperation.TargetMethod.MetadataName; + if (!(((invocationOperation.Instance?.Type?.DerivesFrom(binaryFormatterTypeSymbol) == true + && SecurityHelpers.BinaryFormatterDeserializationMethods.Contains(methodName)) + || (invocationOperation.Instance?.Type?.DerivesFrom(netDataContractSerializerTypeSymbol) == true + && SecurityHelpers.NetDataContractSerializerDeserializationMethods.Contains(methodName)) + || (invocationOperation.Instance?.Type?.DerivesFrom(objectStateFormatterTypeSymbol) == true + && SecurityHelpers.ObjectStateFormatterDeserializationMethods.Contains(methodName)) + || (invocationOperation.Instance?.Type?.DerivesFrom(soapFormatterTypeSymbol) == true + && SecurityHelpers.SoapFormatterDeserializationMethods.Contains(methodName))) + && invocationOperation.Parent?.Kind == OperationKind.Conversion + && invocationOperation.Parent is IConversionOperation conversionOperation)) + { + return; + } + + ITypeSymbol deserializedType = conversionOperation.Type; + + ObjectGraphOptions options; + if (invocationOperation.Instance?.Type?.DerivesFrom(netDataContractSerializerTypeSymbol) == true) + { + options = ObjectGraphOptions.DataContractOptions; + } + else + { + options = ObjectGraphOptions.BinarySerializationOptions; + } + + if (decider.IsObjectGraphInsecure( + deserializedType, + options, + out ImmutableArray results)) + { + foreach (InsecureObjectGraphResult result in results) + { + operationAnalysisContext.ReportDiagnostic( + Diagnostic.Create( + ObjectGraphContainsDangerousTypeDescriptor, + invocationOperation.Parent.Syntax.GetLocation(), + result.InsecureType.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat), + result.GetDisplayString())); + } + } + }, + OperationKind.Invocation); + }); + } + } +} diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Security/DataSetDataTableInSerializableObjectGraphAnalyzer.cs b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Security/DataSetDataTableInSerializableObjectGraphAnalyzer.cs new file mode 100644 index 0000000000..0d02b9a294 --- /dev/null +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Security/DataSetDataTableInSerializableObjectGraphAnalyzer.cs @@ -0,0 +1,302 @@ +// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Collections.Generic; +using System.Collections.Immutable; +using System.Diagnostics.CodeAnalysis; +using System.Linq; +using Analyzer.Utilities; +using Analyzer.Utilities.Extensions; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.Diagnostics; +using Microsoft.CodeAnalysis.Operations; +using Microsoft.NetCore.Analyzers.Security.Helpers; + +namespace Microsoft.NetCore.Analyzers.Security +{ + /// + /// For detecting deserialization of or in an + /// deserialized object graph for certain serializers. + /// + /// + /// Serializers: + /// - DataContractSerializer + /// - DataContractJsonSerializer + /// - JavaScriptSerializer + /// - XmlSerializer + /// - Newtonsoft Json.NET (partial) + /// + [SuppressMessage("Documentation", "CA1200:Avoid using cref tags with a prefix", Justification = "The comment references a type that is not referenced by this compilation.")] + [DiagnosticAnalyzer(LanguageNames.CSharp, LanguageNames.VisualBasic)] + public sealed class DataSetDataTableInSerializableObjectGraphAnalyzer : DiagnosticAnalyzer + { + internal static readonly DiagnosticDescriptor ObjectGraphContainsDangerousTypeDescriptor = + SecurityHelpers.CreateDiagnosticDescriptor( + "CA2355", + nameof(MicrosoftNetCoreAnalyzersResources.DataSetDataTableInDeserializableObjectGraphTitle), + nameof(MicrosoftNetCoreAnalyzersResources.DataSetDataTableInDeserializableObjectGraphMessage), + RuleLevel.Disabled, + isPortedFxCopRule: false, + isDataflowRule: false); + + public override ImmutableArray SupportedDiagnostics => + ImmutableArray.Create(ObjectGraphContainsDangerousTypeDescriptor); + + public override void Initialize(AnalysisContext context) + { + context.EnableConcurrentExecution(); + + // Security analyzer - analyze and report diagnostics on generated code. + context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.Analyze | GeneratedCodeAnalysisFlags.ReportDiagnostics); + + context.RegisterCompilationStartAction( + (CompilationStartAnalysisContext compilationStartAnalysisContext) => + { + Compilation? compilation = compilationStartAnalysisContext.Compilation; + WellKnownTypeProvider wellKnownTypeProvider = WellKnownTypeProvider.GetOrCreate(compilation); + + if (!wellKnownTypeProvider.TryGetOrCreateTypeByMetadataName( + WellKnownTypeNames.SystemDataDataSet, + out INamedTypeSymbol? dataSetTypeSymbol) + || !wellKnownTypeProvider.TryGetOrCreateTypeByMetadataName( + WellKnownTypeNames.SystemDataDataTable, + out INamedTypeSymbol? dataTableTypeSymbol)) + { + return; + } + + INamedTypeSymbol? dataContractSerializerTypeSymbol = wellKnownTypeProvider.GetOrCreateTypeByMetadataName( + WellKnownTypeNames.SystemRuntimeSerializationDataContractSerializer); + INamedTypeSymbol? dataContractJsonSerializerTypeSymbol = + wellKnownTypeProvider.GetOrCreateTypeByMetadataName( + WellKnownTypeNames.SystemRuntimeSerializationJsonDataContractJsonSerializer); + INamedTypeSymbol? javaScriptSerializerTypeSymbol = wellKnownTypeProvider.GetOrCreateTypeByMetadataName( + WellKnownTypeNames.SystemWebScriptSerializationJavaScriptSerializer); + INamedTypeSymbol? typeTypeSymbol = wellKnownTypeProvider.GetOrCreateTypeByMetadataName( + WellKnownTypeNames.SystemType); + INamedTypeSymbol? xmlSerializerTypeSymbol = wellKnownTypeProvider.GetOrCreateTypeByMetadataName( + WellKnownTypeNames.SystemXmlSerializationXmlSerializer); + INamedTypeSymbol? jsonNetJsonSerializerTypeSymbol = wellKnownTypeProvider.GetOrCreateTypeByMetadataName( + WellKnownTypeNames.NewtonsoftJsonJsonSerializer); + INamedTypeSymbol? jsonNetJsonConvertTypeSymbol = wellKnownTypeProvider.GetOrCreateTypeByMetadataName( + WellKnownTypeNames.NewtonsoftJsonJsonConvert); + + if (dataContractSerializerTypeSymbol == null + && dataContractJsonSerializerTypeSymbol == null + && javaScriptSerializerTypeSymbol == null + && xmlSerializerTypeSymbol == null + && jsonNetJsonSerializerTypeSymbol == null + && jsonNetJsonConvertTypeSymbol == null) + { + return; + } + + InsecureDeserializationTypeDecider decider = InsecureDeserializationTypeDecider.GetOrCreate(compilation); + + compilationStartAnalysisContext.RegisterOperationAction( + (OperationAnalysisContext operationAnalysisContext) => + { + IInvocationOperation invocationOperation = + (IInvocationOperation)operationAnalysisContext.Operation; + if (!IsDeserializationMethod( + invocationOperation, + out ObjectGraphOptions? optionsToUse, + out IEnumerable<(ITypeSymbol DeserializedTypeSymbol, IOperation OperationForLocation)>? deserializedTypes)) + { + return; + } + + RoslynDebug.Assert(optionsToUse != null); + RoslynDebug.Assert(deserializedTypes != null); + + ReportDiagnosticsForInsecureTypes(operationAnalysisContext, optionsToUse, deserializedTypes); + }, + OperationKind.Invocation); + + compilationStartAnalysisContext.RegisterOperationAction( + (OperationAnalysisContext operationAnalysisContext) => + { + IObjectCreationOperation objectCreationOperation = + (IObjectCreationOperation)operationAnalysisContext.Operation; + if (!IsDeserializationConstructor( + objectCreationOperation, + out ObjectGraphOptions? optionsToUse, + out IEnumerable<(ITypeSymbol DeserializedTypeSymbol, IOperation OperationForLocation)>? deserializedTypes)) + { + return; + } + + RoslynDebug.Assert(optionsToUse != null); + RoslynDebug.Assert(deserializedTypes != null); + + ReportDiagnosticsForInsecureTypes(operationAnalysisContext, optionsToUse, deserializedTypes); + }, + OperationKind.ObjectCreation); + + return; + + // Local functions. + + // Determines if the invoked method is for deserialization, and what type of deserialization. + bool IsDeserializationMethod( + IInvocationOperation invocationOperation, + out ObjectGraphOptions? optionsToUse, + out IEnumerable<(ITypeSymbol DeserializedTypeSymbol, IOperation OperationForLocation)>? deserializedTypes) + { + optionsToUse = null; + deserializedTypes = null; + + IMethodSymbol targetMethod = invocationOperation.TargetMethod; + if (invocationOperation.Instance?.Type?.DerivesFrom(javaScriptSerializerTypeSymbol) == true) + { + if (targetMethod.MetadataName == "DeserializeObject" + && invocationOperation.Parent?.Kind == OperationKind.Conversion + && invocationOperation.Parent is IConversionOperation javaScriptConversionOperation) + { + optionsToUse = ObjectGraphOptions.JavaScriptSerializerOptions; + deserializedTypes = new[] + { + (javaScriptConversionOperation.Type, (IOperation)javaScriptConversionOperation) + }; + } + else if (targetMethod.MetadataName == "Deserialize") + { + if (targetMethod.IsGenericMethod + && targetMethod.Arity == 1 + && targetMethod.Parameters.Length == 1) + { + optionsToUse = ObjectGraphOptions.JavaScriptSerializerOptions; + deserializedTypes = new[] + { + (targetMethod.TypeArguments[0], (IOperation)invocationOperation) + }; + } + else if (!targetMethod.IsGenericMethod + && targetMethod.Parameters.Length == 2 + && targetMethod.Parameters[1].Type.Equals(typeTypeSymbol) + && invocationOperation.HasArgument(out ITypeOfOperation? typeOfOperation)) + { + optionsToUse = ObjectGraphOptions.JavaScriptSerializerOptions; + deserializedTypes = new[] + { + (typeOfOperation.TypeOperand, (IOperation)typeOfOperation) + }; + } + } + } + else if (targetMethod.ContainingType.Equals(xmlSerializerTypeSymbol) + && targetMethod.IsStatic + && targetMethod.MetadataName == "FromTypes" + && targetMethod.Parameters.Length == 1 + && targetMethod.Parameters[0].Type is IArrayTypeSymbol arrayTypeSymbol + && arrayTypeSymbol.ElementType.Equals(typeTypeSymbol)) + { + optionsToUse = ObjectGraphOptions.XmlSerializerOptions; + deserializedTypes = + invocationOperation + .Arguments[0] + .Descendants() + .OfType() + .Select(t => (t.TypeOperand!, (IOperation)t)); + } + else if ((invocationOperation.Instance?.Type.DerivesFrom(jsonNetJsonSerializerTypeSymbol) == true + && targetMethod.MetadataName == "Deserialize") + || (targetMethod.ContainingType.Equals(jsonNetJsonConvertTypeSymbol) + && targetMethod.MetadataName == "DeserializeObject")) + { + if (targetMethod.IsGenericMethod && targetMethod.Arity == 1) + { + optionsToUse = ObjectGraphOptions.NewtonsoftJsonNetOptions; + deserializedTypes = new[] + { + (targetMethod.TypeArguments[0], (IOperation)invocationOperation) + }; + } + else if (targetMethod.Parameters.Length == 2 + && targetMethod.Parameters[1].Type.Equals(typeTypeSymbol) + && invocationOperation.HasArgument(out ITypeOfOperation? typeOfOperation)) + { + optionsToUse = ObjectGraphOptions.NewtonsoftJsonNetOptions; + deserializedTypes = new[] + { + (typeOfOperation.TypeOperand, (IOperation)typeOfOperation) + }; + } + else if (invocationOperation.Parent?.Kind == OperationKind.Conversion + && invocationOperation.Parent is IConversionOperation conversionOperation) + { + optionsToUse = ObjectGraphOptions.NewtonsoftJsonNetOptions; + deserializedTypes = new[] + { + (conversionOperation.Type, (IOperation)conversionOperation) + }; + } + } + + return optionsToUse != null && deserializedTypes != null; + } + + // Determines if the object instantiation is for deserialization, and the type of deserialization. + bool IsDeserializationConstructor( + IObjectCreationOperation objectCreationOperation, + out ObjectGraphOptions? optionsToUse, + out IEnumerable<(ITypeSymbol DeserializedTypeSymbol, IOperation OperationForLocation)>? deserializedTypes) + { + optionsToUse = null; + deserializedTypes = null; + + IMethodSymbol constructor = objectCreationOperation.Constructor; + if (objectCreationOperation.Type?.Equals(dataContractSerializerTypeSymbol) == true + || objectCreationOperation.Type?.Equals(dataContractJsonSerializerTypeSymbol) == true) + { + optionsToUse = ObjectGraphOptions.DataContractOptions; + deserializedTypes = + objectCreationOperation + .Arguments + .SelectMany(a => a.Descendants()) + .OfType() + .Select(t => (t.TypeOperand!, (IOperation)t)); + } + else if (objectCreationOperation.Type?.Equals(xmlSerializerTypeSymbol) == true) + { + optionsToUse = ObjectGraphOptions.XmlSerializerOptions; + deserializedTypes = + objectCreationOperation + .Arguments + .SelectMany(a => a.Descendants()) + .OfType() + .Select(t => (t.TypeOperand!, (IOperation)t)); + } + + return optionsToUse != null && deserializedTypes != null; + } + + // For each deserialized type, determine if its object graph potentially contains an insecure type, and if + // report a diagnostic if so. + void ReportDiagnosticsForInsecureTypes( + OperationAnalysisContext operationAnalysisContext, + ObjectGraphOptions optionsToUse, + IEnumerable<(ITypeSymbol DeserializedTypeSymbol, IOperation OperationForLocation)> deserializedTypes) + { + foreach ((ITypeSymbol deserializedTypeSymbol, IOperation operationForLocation) in deserializedTypes) + { + if (decider.IsObjectGraphInsecure( + deserializedTypeSymbol, + optionsToUse, + out ImmutableArray results)) + { + foreach (InsecureObjectGraphResult result in results) + { + operationAnalysisContext.ReportDiagnostic( + Diagnostic.Create( + ObjectGraphContainsDangerousTypeDescriptor, + operationForLocation.Syntax.GetLocation(), + result.InsecureType.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat), + result.GetDisplayString())); + } + } + } + } + }); + } + } +} diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Security/DataSetDataTableInSerializableTypeAnalyzer.cs b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Security/DataSetDataTableInSerializableTypeAnalyzer.cs new file mode 100644 index 0000000000..afde9602a9 --- /dev/null +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Security/DataSetDataTableInSerializableTypeAnalyzer.cs @@ -0,0 +1,159 @@ +// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Collections.Concurrent; +using System.Collections.Immutable; +using System.Diagnostics.CodeAnalysis; +using System.Linq; +using Analyzer.Utilities; +using Analyzer.Utilities.Extensions; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.Diagnostics; +using Microsoft.NetCore.Analyzers.Security.Helpers; + +namespace Microsoft.NetCore.Analyzers.Security +{ + /// + /// For detecting or deserializable members. + /// + [SuppressMessage("Documentation", "CA1200:Avoid using cref tags with a prefix", Justification = "The comment references a type that is not referenced by this compilation.")] + [DiagnosticAnalyzer(LanguageNames.CSharp, LanguageNames.VisualBasic)] + public sealed class DataSetDataTableInSerializableTypeAnalyzer : DiagnosticAnalyzer + { + // At this time, treat IFormatter-based serializers differently, since they have different guidance and known impact. + internal static readonly DiagnosticDescriptor RceSerializableContainsDangerousType = + SecurityHelpers.CreateDiagnosticDescriptor( + "CA2352", + nameof(MicrosoftNetCoreAnalyzersResources.DataSetDataTableInRceSerializableTypeTitle), + nameof(MicrosoftNetCoreAnalyzersResources.DataSetDataTableInRceSerializableTypeMessage), + RuleLevel.Disabled, + isPortedFxCopRule: false, + isDataflowRule: false); + + internal static readonly DiagnosticDescriptor SerializableContainsDangerousType = + SecurityHelpers.CreateDiagnosticDescriptor( + "CA2353", + nameof(MicrosoftNetCoreAnalyzersResources.DataSetDataTableInSerializableTypeTitle), + nameof(MicrosoftNetCoreAnalyzersResources.DataSetDataTableInSerializableTypeMessage), + RuleLevel.Disabled, + isPortedFxCopRule: false, + isDataflowRule: false); + + public override ImmutableArray SupportedDiagnostics => + ImmutableArray.Create(RceSerializableContainsDangerousType, SerializableContainsDangerousType); + + [SuppressMessage("Style", "IDE0047:Remove unnecessary parentheses", Justification = "Group related conditions together.")] + public override void Initialize(AnalysisContext context) + { + context.EnableConcurrentExecution(); + + // Security analyzer - analyze and report diagnostics on generated code. + context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.Analyze | GeneratedCodeAnalysisFlags.ReportDiagnostics); + + context.RegisterCompilationStartAction( + (CompilationStartAnalysisContext compilationStartAnalysisContext) => + { + Compilation? compilation = compilationStartAnalysisContext.Compilation; + WellKnownTypeProvider wellKnownTypeProvider = WellKnownTypeProvider.GetOrCreate(compilation); + + if (!wellKnownTypeProvider.TryGetOrCreateTypeByMetadataName( + WellKnownTypeNames.SystemDataDataSet, + out INamedTypeSymbol? dataSetTypeSymbol) + || !wellKnownTypeProvider.TryGetOrCreateTypeByMetadataName( + WellKnownTypeNames.SystemDataDataTable, + out INamedTypeSymbol? dataTableTypeSymbol)) + { + return; + } + + INamedTypeSymbol? serializableAttributeTypeSymbol = wellKnownTypeProvider.GetOrCreateTypeByMetadataName( + WellKnownTypeNames.SystemSerializableAttribute); + + INamedTypeSymbol? generatedCodeAttributeTypeSymbol = wellKnownTypeProvider.GetOrCreateTypeByMetadataName( + WellKnownTypeNames.SystemCodeDomCompilerGeneratedCodeAttribute); + + // For completeness, could also consider CollectionDataContractAttribute + INamedTypeSymbol? dataContractAttributeTypeSymbol = wellKnownTypeProvider.GetOrCreateTypeByMetadataName( + WellKnownTypeNames.SystemRuntimeSerializationDataContractAttribute); + INamedTypeSymbol? dataMemberAttributeTypeSymbol = wellKnownTypeProvider.GetOrCreateTypeByMetadataName( + WellKnownTypeNames.SystemRuntimeSerializationDataMemberAttribute); + INamedTypeSymbol? ignoreDataMemberTypeSymbol = wellKnownTypeProvider.GetOrCreateTypeByMetadataName( + WellKnownTypeNames.SystemRuntimeSerializationIgnoreDataMemberAttribute); + INamedTypeSymbol? knownTypeAttributeTypeSymbol = wellKnownTypeProvider.GetOrCreateTypeByMetadataName( + WellKnownTypeNames.SystemRuntimeSerializationKnownTypeAttribute); + + XmlSerializationAttributeTypes xmlSerializationAttributeTypes = new XmlSerializationAttributeTypes( + wellKnownTypeProvider); + if (serializableAttributeTypeSymbol == null + && (dataContractAttributeTypeSymbol == null || dataMemberAttributeTypeSymbol == null) + && ignoreDataMemberTypeSymbol == null + && knownTypeAttributeTypeSymbol == null + && !xmlSerializationAttributeTypes.Any) + { + return; + } + + InsecureDeserializationTypeDecider decider = InsecureDeserializationTypeDecider.GetOrCreate(compilation); + + ConcurrentDictionary visitedTypes = + new ConcurrentDictionary(); + + compilationStartAnalysisContext.RegisterSymbolAction( + (SymbolAnalysisContext symbolAnalysisContext) => + { + INamedTypeSymbol namedTypeSymbol = (INamedTypeSymbol)symbolAnalysisContext.Symbol; + bool hasSerializableAttribute = namedTypeSymbol.HasAttribute(serializableAttributeTypeSymbol); + + // Assume that [GeneratedCode] means not used for serialization. + bool hasGeneratedCodeAttribute = namedTypeSymbol.HasAttribute(generatedCodeAttributeTypeSymbol); + bool hasDataContractAttribute = namedTypeSymbol.HasAttribute(dataContractAttributeTypeSymbol); + bool hasKnownTypeAttribute = namedTypeSymbol.HasAttribute(knownTypeAttributeTypeSymbol); + bool hasAnyIgnoreDataMemberAttribute = + namedTypeSymbol.GetMembers().Any(m => m.HasAttribute(ignoreDataMemberTypeSymbol)); + bool hasAnyXmlSerializationAttributes = + xmlSerializationAttributeTypes.HasAnyAttribute(namedTypeSymbol) + || namedTypeSymbol.GetMembers().Any(m => xmlSerializationAttributeTypes.HasAnyAttribute(m)); + if (!hasSerializableAttribute + && !hasDataContractAttribute + && !hasKnownTypeAttribute + && !hasAnyIgnoreDataMemberAttribute + && !hasAnyXmlSerializationAttributes) + { + // Don't have any attributes suggesting this class is serialized. + return; + } + + ObjectGraphOptions options = new ObjectGraphOptions( + recurse: false, + binarySerialization: hasSerializableAttribute, + dataContractSerialization: + hasDataContractAttribute + || hasAnyIgnoreDataMemberAttribute + || hasKnownTypeAttribute, + xmlSerialization: hasAnyXmlSerializationAttributes); + + if (decider.IsObjectGraphInsecure( + namedTypeSymbol, + options, + out ImmutableArray results)) + { + DiagnosticDescriptor diagnosticToReport = + hasSerializableAttribute + ? RceSerializableContainsDangerousType + : SerializableContainsDangerousType; + + foreach (InsecureObjectGraphResult result in results) + { + symbolAnalysisContext.ReportDiagnostic( + Diagnostic.Create( + diagnosticToReport, + result.GetLocation(), + result.InsecureType.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat), + result.GetDisplayString())); + } + } + }, + SymbolKind.NamedType); + }); + } + } +} diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Security/DataSetDataTableInWebSerializableObjectGraphAnalyzer.cs b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Security/DataSetDataTableInWebSerializableObjectGraphAnalyzer.cs new file mode 100644 index 0000000000..3f5042dcff --- /dev/null +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Security/DataSetDataTableInWebSerializableObjectGraphAnalyzer.cs @@ -0,0 +1,127 @@ +// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Collections.Immutable; +using System.Diagnostics.CodeAnalysis; +using System.Linq; +using Analyzer.Utilities; +using Analyzer.Utilities.Extensions; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.Diagnostics; +using Microsoft.NetCore.Analyzers.Security.Helpers; + +namespace Microsoft.NetCore.Analyzers.Security +{ + /// + /// For detecting deserialization of or in an + /// web API / WCF API serializable object graph. + /// + [SuppressMessage("Documentation", "CA1200:Avoid using cref tags with a prefix", Justification = "The comment references a type that is not referenced by this compilation.")] + [DiagnosticAnalyzer(LanguageNames.CSharp, LanguageNames.VisualBasic)] + public sealed class DataSetDataTableInWebSerializableObjectGraphAnalyzer : DiagnosticAnalyzer + { + internal static readonly DiagnosticDescriptor ObjectGraphContainsDangerousTypeDescriptor = + SecurityHelpers.CreateDiagnosticDescriptor( + "CA2356", + nameof(MicrosoftNetCoreAnalyzersResources.DataSetDataTableInWebDeserializableObjectGraphTitle), + nameof(MicrosoftNetCoreAnalyzersResources.DataSetDataTableInWebDeserializableObjectGraphMessage), + RuleLevel.Disabled, + isPortedFxCopRule: false, + isDataflowRule: false); + + public override ImmutableArray SupportedDiagnostics => + ImmutableArray.Create(ObjectGraphContainsDangerousTypeDescriptor); + + public override void Initialize(AnalysisContext context) + { + context.EnableConcurrentExecution(); + + // Security analyzer - analyze and report diagnostics on generated code. + context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.Analyze | GeneratedCodeAnalysisFlags.ReportDiagnostics); + + context.RegisterCompilationStartAction( + (CompilationStartAnalysisContext compilationStartAnalysisContext) => + { + Compilation? compilation = compilationStartAnalysisContext.Compilation; + WellKnownTypeProvider wellKnownTypeProvider = WellKnownTypeProvider.GetOrCreate(compilation); + + if (!wellKnownTypeProvider.TryGetOrCreateTypeByMetadataName( + WellKnownTypeNames.SystemDataDataSet, + out INamedTypeSymbol? dataSetTypeSymbol) + || !wellKnownTypeProvider.TryGetOrCreateTypeByMetadataName( + WellKnownTypeNames.SystemDataDataTable, + out INamedTypeSymbol? dataTableTypeSymbol)) + { + return; + } + + INamedTypeSymbol? webMethodAttributeTypeSymbol = wellKnownTypeProvider.GetOrCreateTypeByMetadataName( + WellKnownTypeNames.SystemWebServicesWebMethodAttribute); + INamedTypeSymbol? operationContractAttributeTypeSymbol = + wellKnownTypeProvider.GetOrCreateTypeByMetadataName( + WellKnownTypeNames.SystemServiceModelOperationContractAttribute); + + if (webMethodAttributeTypeSymbol == null && operationContractAttributeTypeSymbol == null) + { + return; + } + + InsecureDeserializationTypeDecider decider = InsecureDeserializationTypeDecider.GetOrCreate(compilation); + + // Symbol actions for SymbolKind.Method don't seem to trigger on interface methods, so we'll do register + // for SymbolKind.NamedTypeSymbol instead. + compilationStartAnalysisContext.RegisterSymbolAction( + (SymbolAnalysisContext symbolAnalysisContext) => + { + INamedTypeSymbol namedTypeSymbol = (INamedTypeSymbol)symbolAnalysisContext.Symbol; + if (namedTypeSymbol.TypeKind != TypeKind.Interface + && namedTypeSymbol.TypeKind != TypeKind.Class) + { + return; + } + + foreach (ISymbol? memberSymbol in namedTypeSymbol.GetMembers()) + { + if (!(memberSymbol is IMethodSymbol methodSymbol)) + { + continue; + } + + ObjectGraphOptions optionsToUse; + if (methodSymbol.HasAttribute(webMethodAttributeTypeSymbol)) + { + optionsToUse = ObjectGraphOptions.XmlSerializerOptions; + } + else if (methodSymbol.HasAttribute(operationContractAttributeTypeSymbol)) + { + optionsToUse = ObjectGraphOptions.DataContractOptions; + } + else + { + continue; + } + + foreach (IParameterSymbol parameterSymbol in methodSymbol.Parameters) + { + if (decider.IsObjectGraphInsecure( + parameterSymbol.Type, + optionsToUse, + out ImmutableArray results)) + { + foreach (InsecureObjectGraphResult result in results) + { + symbolAnalysisContext.ReportDiagnostic( + Diagnostic.Create( + ObjectGraphContainsDangerousTypeDescriptor, + parameterSymbol.DeclaringSyntaxReferences.First().GetSyntax().GetLocation(), + result.InsecureType.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat), + result.GetDisplayString())); + } + } + } + } + }, + SymbolKind.NamedType); + }); + } + } +} diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Security/DoNotUseDataSetReadXml.cs b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Security/DoNotUseDataSetReadXml.cs new file mode 100644 index 0000000000..0ab3d10ee8 --- /dev/null +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Security/DoNotUseDataSetReadXml.cs @@ -0,0 +1,36 @@ +// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Collections.Immutable; +using System.Diagnostics.CodeAnalysis; +using Analyzer.Utilities; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.Diagnostics; +using Microsoft.NetCore.Analyzers.Security.Helpers; + +namespace Microsoft.NetCore.Analyzers.Security +{ + /// + /// For detecting deserialization with . + /// + [SuppressMessage("Documentation", "CA1200:Avoid using cref tags with a prefix", Justification = "The comment references a type that is not referenced by this compilation.")] + [DiagnosticAnalyzer(LanguageNames.CSharp, LanguageNames.VisualBasic)] + internal class DoNotUseDataSetReadXml : DoNotUseInsecureDeserializerMethodsBase + { + internal static readonly DiagnosticDescriptor RealMethodUsedDescriptor = + SecurityHelpers.CreateDiagnosticDescriptor( + "CA2351", + nameof(MicrosoftNetCoreAnalyzersResources.DataSetReadXmlTitle), + nameof(MicrosoftNetCoreAnalyzersResources.DataSetReadXmlMessage), + RuleLevel.Disabled, + isPortedFxCopRule: false, + isDataflowRule: false); + + protected override string DeserializerTypeMetadataName => + WellKnownTypeNames.SystemDataDataSet; + + protected override ImmutableHashSet DeserializationMethodNames => + SecurityHelpers.DataSetDeserializationMethods; + + protected override DiagnosticDescriptor MethodUsedDescriptor => RealMethodUsedDescriptor; + } +} diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Security/DoNotUseDataTableReadXml.cs b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Security/DoNotUseDataTableReadXml.cs new file mode 100644 index 0000000000..e1eab71a27 --- /dev/null +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Security/DoNotUseDataTableReadXml.cs @@ -0,0 +1,36 @@ +// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Collections.Immutable; +using System.Diagnostics.CodeAnalysis; +using Analyzer.Utilities; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.Diagnostics; +using Microsoft.NetCore.Analyzers.Security.Helpers; + +namespace Microsoft.NetCore.Analyzers.Security +{ + /// + /// For detecting deserialization with . + /// + [SuppressMessage("Documentation", "CA1200:Avoid using cref tags with a prefix", Justification = "The comment references a type that is not referenced by this compilation.")] + [DiagnosticAnalyzer(LanguageNames.CSharp, LanguageNames.VisualBasic)] + internal class DoNotUseDataTableReadXml : DoNotUseInsecureDeserializerMethodsBase + { + internal static readonly DiagnosticDescriptor RealMethodUsedDescriptor = + SecurityHelpers.CreateDiagnosticDescriptor( + "CA2350", + nameof(MicrosoftNetCoreAnalyzersResources.DataTableReadXmlTitle), + nameof(MicrosoftNetCoreAnalyzersResources.DataTableReadXmlMessage), + RuleLevel.Disabled, + isPortedFxCopRule: false, + isDataflowRule: false); + + protected override string DeserializerTypeMetadataName => + WellKnownTypeNames.SystemDataDataTable; + + protected override ImmutableHashSet DeserializationMethodNames => + SecurityHelpers.DataTableDeserializationMethods; + + protected override DiagnosticDescriptor MethodUsedDescriptor => RealMethodUsedDescriptor; + } +} diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Security/DoNotUseInsecureDeserializerMethodsBase.cs b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Security/DoNotUseInsecureDeserializerMethodsBase.cs index eba18c8aba..48c81496ca 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Security/DoNotUseInsecureDeserializerMethodsBase.cs +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Security/DoNotUseInsecureDeserializerMethodsBase.cs @@ -67,7 +67,7 @@ public sealed override void Initialize(AnalysisContext context) { IInvocationOperation invocationOperation = (IInvocationOperation)operationAnalysisContext.Operation; - if (Equals(invocationOperation.Instance?.Type, deserializerTypeSymbol) + if (invocationOperation.Instance?.Type?.DerivesFrom(deserializerTypeSymbol) == true && cachedDeserializationMethodNames.Contains(invocationOperation.TargetMethod.MetadataName)) { operationAnalysisContext.ReportDiagnostic( @@ -85,7 +85,7 @@ public sealed override void Initialize(AnalysisContext context) { IMethodReferenceOperation methodReferenceOperation = (IMethodReferenceOperation)operationAnalysisContext.Operation; - if (Equals(methodReferenceOperation.Instance?.Type, deserializerTypeSymbol) + if (methodReferenceOperation.Instance?.Type?.DerivesFrom(deserializerTypeSymbol) == true && cachedDeserializationMethodNames.Contains(methodReferenceOperation.Method.MetadataName)) { operationAnalysisContext.ReportDiagnostic( diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Security/Helpers/InsecureDeserializationTypeDecider.cs b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Security/Helpers/InsecureDeserializationTypeDecider.cs new file mode 100644 index 0000000000..be8214e4fd --- /dev/null +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Security/Helpers/InsecureDeserializationTypeDecider.cs @@ -0,0 +1,440 @@ +// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Collections.Immutable; +using System.Diagnostics.CodeAnalysis; +using System.Linq; +using Analyzer.Utilities; +using Analyzer.Utilities.Extensions; +using Analyzer.Utilities.PooledObjects; +using Microsoft.CodeAnalysis; + +namespace Microsoft.NetCore.Analyzers.Security.Helpers +{ + /// + /// Determines if a given type is insecure for deserialization, by seeing if it contain known dangerous types. + /// + internal sealed partial class InsecureDeserializationTypeDecider + { + private static readonly string[] InsecureTypeNames = + { + WellKnownTypeNames.SystemDataDataSet, + WellKnownTypeNames.SystemDataDataTable, + }; + + private static readonly BoundedCacheWithFactory BoundedCache = + new BoundedCacheWithFactory(); + + /// + /// Gets a cached for the given compilation. + /// + /// Compilation that the decider is for. + /// Cached decider. + public static InsecureDeserializationTypeDecider GetOrCreate(Compilation compilation) + { + return BoundedCache.GetOrCreateValue(compilation, Create); + + // Local functions. + static InsecureDeserializationTypeDecider Create(Compilation c) => new InsecureDeserializationTypeDecider(c); + } + + /// + /// Constructs. + /// + /// Compilation being analyzed. + private InsecureDeserializationTypeDecider(Compilation compilation) + { + foreach (string typeName in InsecureTypeNames) + { + if (compilation.TryGetOrCreateTypeByMetadataName(typeName, out INamedTypeSymbol? namedTypeSymbol)) + { + this.InsecureTypeSymbols.Add(namedTypeSymbol); + } + } + + this.SymbolByDisplayStringComparer = new SymbolByDisplayStringComparer(compilation); + this.WellKnownTypeProvider = WellKnownTypeProvider.GetOrCreate(compilation); + + this.GeneratedCodeAttributeTypeSymbol = this.WellKnownTypeProvider.GetOrCreateTypeByMetadataName( + WellKnownTypeNames.SystemCodeDomCompilerGeneratedCodeAttribute); + + this.SerializableAttributeTypeSymbol = this.WellKnownTypeProvider.GetOrCreateTypeByMetadataName( + WellKnownTypeNames.SystemSerializableAttribute); + this.NonSerializedAttributeTypeSymbol = this.WellKnownTypeProvider.GetOrCreateTypeByMetadataName( + WellKnownTypeNames.SystemSerializableAttribute); + + this.DataContractAttributeTypeSymbol = this.WellKnownTypeProvider.GetOrCreateTypeByMetadataName( + WellKnownTypeNames.SystemRuntimeSerializationDataContractAttribute); + this.DataMemberAttributeTypeSymbol = this.WellKnownTypeProvider.GetOrCreateTypeByMetadataName( + WellKnownTypeNames.SystemRuntimeSerializationDataMemberAttribute); + this.IgnoreDataMemberTypeSymbol = this.WellKnownTypeProvider.GetOrCreateTypeByMetadataName( + WellKnownTypeNames.SystemRuntimeSerializationIgnoreDataMemberAttribute); + this.KnownTypeAttributeTypeSymbol = this.WellKnownTypeProvider.GetOrCreateTypeByMetadataName( + WellKnownTypeNames.SystemRuntimeSerializationKnownTypeAttribute); + this.XmlSerializationAttributeTypes = new XmlSerializationAttributeTypes( + this.WellKnownTypeProvider); + this.JsonIgnoreAttributeTypeSymbol = this.WellKnownTypeProvider.GetOrCreateTypeByMetadataName( + WellKnownTypeNames.NewtonsoftJsonJsonIgnoreAttribute); + } + + /// + /// Doesn't construct. + /// + private InsecureDeserializationTypeDecider() + { + throw new NotSupportedException(); + } + + /// + /// Comparer for the compilation's TypeSymbols. + /// + public SymbolByDisplayStringComparer SymbolByDisplayStringComparer { get; } + + /// + /// Type cache. + /// + private WellKnownTypeProvider WellKnownTypeProvider { get; } + + /// + /// Set of type symbols for types that are insecure if deserialized. + /// + private HashSet InsecureTypeSymbols { get; } = new HashSet(); + + private INamedTypeSymbol? GeneratedCodeAttributeTypeSymbol { get; } + private INamedTypeSymbol? SerializableAttributeTypeSymbol { get; } + private INamedTypeSymbol? NonSerializedAttributeTypeSymbol { get; } + private INamedTypeSymbol? DataContractAttributeTypeSymbol { get; } + private INamedTypeSymbol? DataMemberAttributeTypeSymbol { get; } + private INamedTypeSymbol? IgnoreDataMemberTypeSymbol { get; } + private INamedTypeSymbol? KnownTypeAttributeTypeSymbol { get; } + private XmlSerializationAttributeTypes XmlSerializationAttributeTypes { get; } + private INamedTypeSymbol? JsonIgnoreAttributeTypeSymbol { get; } + + // Cache results for IsTypeInsecure() + // Key: typeSymbol in IsTypeInsecure() + // Value: insecureTypeSymbol in IsTypeInsecure() + private readonly ConcurrentDictionary IsTypeInsecureCache = + new ConcurrentDictionary(); + + /// + /// Determines if the given type is insecure when deserialized, without looking at its child fields and properties. + /// + /// Type to check. + /// Insecure type, if the checked type is insecure. + /// True if insecure, false otherwise. + /// This only considers the type and its associated types (generic type arguments, base classes, etc), not + /// types of member fields and properties. + public bool IsTypeInsecure( + ITypeSymbol? typeSymbol, + [NotNullWhen(returnValue: true)] out ITypeSymbol? insecureTypeSymbol) + { + insecureTypeSymbol = null; + + if (typeSymbol == null || this.InsecureTypeSymbols.Count == 0) + { + return false; + } + + insecureTypeSymbol = this.IsTypeInsecureCache.GetOrAdd(typeSymbol, Compute(typeSymbol)); + return insecureTypeSymbol != null; + + // Local functions. + ITypeSymbol? Compute(ITypeSymbol typeSymbol) + { + // Sort type symbols by display string so that we get consistent results. + using PooledSortedSet associatedTypeSymbols = PooledSortedSet.GetInstance( + this.SymbolByDisplayStringComparer); + GetAssociatedTypes(typeSymbol, associatedTypeSymbols); + foreach (ITypeSymbol t in associatedTypeSymbols) + { + if (this.InsecureTypeSymbols.Contains(t)) + { + return t; + } + } + + return null; + } + } + + // Cache for IsObjectGraphInsecure results. + // Key: (rootType, options) arguments in IsObjectGraphInsecure() + // Value: results argument in IsObjectGraphInsecure(). + private readonly ConcurrentDictionary<(ITypeSymbol, ObjectGraphOptions), ImmutableArray> IsObjectGraphInsecureCache = + new ConcurrentDictionary<(ITypeSymbol, ObjectGraphOptions), ImmutableArray>(); + + /// + /// Determines if a type's object graph contains an insecure type, by walking through its serializable members. + /// + /// Type to check. + /// Options for the type of serialization. + /// List to populate results of which symbols (fields or properties) are an insecure + /// type. + /// True if are any insecure symbols, false otherwise. + [SuppressMessage("Style", "IDE0047:Remove unnecessary parentheses", Justification = "Group related conditions together.")] + public bool IsObjectGraphInsecure( + ITypeSymbol rootType, + ObjectGraphOptions options, + out ImmutableArray results) + { + options.ThrowIfInvalid(nameof(options)); + + if (this.InsecureTypeSymbols.Count == 0) + { + return false; + } + + results = this.IsObjectGraphInsecureCache.GetOrAdd((rootType, options), Compute); + return !results.IsEmpty; + + // Local functions. + ImmutableArray Compute((ITypeSymbol, ObjectGraphOptions) _) + { + ImmutableArray.Builder resultBuilder = + ImmutableArray.CreateBuilder(); + + using PooledHashSet visitedTypes = PooledHashSet.GetInstance(); + GetInsecureSymbol(rootType, visitedTypes, resultBuilder); + + return resultBuilder.ToImmutable(); + } + + void GetInsecureSymbol( + ITypeSymbol typeSymbol, + PooledHashSet visitedTypes, + ImmutableArray.Builder resultBuilder) + { + if (!visitedTypes.Add(typeSymbol)) + { + return; + } + + if (this.IsTypeInsecure(typeSymbol, out ITypeSymbol? typeInsecureTypeSymbol)) + { + resultBuilder.Add(new InsecureObjectGraphResult(typeSymbol, null, null, typeInsecureTypeSymbol)); + } + + bool[] hasAttributes = typeSymbol.HasAttributes( + this.GeneratedCodeAttributeTypeSymbol, + this.SerializableAttributeTypeSymbol, + this.DataContractAttributeTypeSymbol, + this.KnownTypeAttributeTypeSymbol); + int index = 0; + bool hasGeneratedCodeAttribute = hasAttributes[index++]; + bool hasSerializableAttribute = hasAttributes[index++]; + bool hasDataContractAttribute = hasAttributes[index++]; + bool hasKnownTypeAttribute = hasAttributes[index++]; + + bool hasAnyIgnoreDataMemberAttribute = + typeSymbol.GetMembers().Any(m => m.HasAttribute(this.IgnoreDataMemberTypeSymbol)); + + bool hasAnyXmlSerializationAttributes = + this.XmlSerializationAttributeTypes.HasAnyAttribute(typeSymbol) + || typeSymbol.GetMembers().Any(m => this.XmlSerializationAttributeTypes.HasAnyAttribute(m)); + + // Consider handling other Newtonsoft Json.NET member serialization modes other than its default. + + // Sort type symbols by display strings. + // Keep track of member types we see, and we'll recurse through those afterwards. + using PooledSortedSet typesToRecurse = PooledSortedSet.GetInstance( + this.SymbolByDisplayStringComparer); + foreach (ISymbol member in typeSymbol.GetMembers()) + { + switch (member) + { + case IFieldSymbol fieldSymbol: + if (!fieldSymbol.IsStatic + && !fieldSymbol.IsBackingFieldForProperty(out _) // Handle properties below. + && ((options.BinarySerialization + && hasSerializableAttribute + && !fieldSymbol.HasAttribute(this.NonSerializedAttributeTypeSymbol)) + || (options.DataContractSerialization + && ((hasDataContractAttribute && fieldSymbol.HasAttribute(this.DataMemberAttributeTypeSymbol)) + || (!hasDataContractAttribute && !fieldSymbol.HasAttribute(this.IgnoreDataMemberTypeSymbol)))) + || (options.XmlSerialization + && !fieldSymbol.HasAttribute( + this.XmlSerializationAttributeTypes.XmlIgnoreAttribute) + && fieldSymbol.DeclaredAccessibility == Accessibility.Public) + || (options.JavaScriptSerializer + && fieldSymbol.DeclaredAccessibility == Accessibility.Public) + || (options.NewtonsoftJsonNetSerialization + && fieldSymbol.DeclaredAccessibility == Accessibility.Public + && !fieldSymbol.HasAttribute(this.JsonIgnoreAttributeTypeSymbol) + && !fieldSymbol.HasAttribute(this.NonSerializedAttributeTypeSymbol)))) + { + if (this.IsTypeInsecure(fieldSymbol.Type, out ITypeSymbol? fieldInsecureTypeSymbol)) + { + resultBuilder.Add( + new InsecureObjectGraphResult( + fieldSymbol, + null, + null, + fieldInsecureTypeSymbol)); + } + else + { + typesToRecurse.Add(fieldSymbol.Type); + } + } + + break; + + case IPropertySymbol propertySymbol: + if (!propertySymbol.IsStatic + && ((options.BinarySerialization + && hasSerializableAttribute + && !propertySymbol.HasAttribute(this.NonSerializedAttributeTypeSymbol) + && propertySymbol.IsPropertyWithBackingField() + ) + || (options.DataContractSerialization + && ((hasDataContractAttribute && propertySymbol.HasAttribute(this.DataMemberAttributeTypeSymbol)) + || (!hasDataContractAttribute && !propertySymbol.HasAttribute(this.IgnoreDataMemberTypeSymbol))) + && propertySymbol.GetMethod != null + && propertySymbol.SetMethod != null) + || (options.XmlSerialization + && !propertySymbol.HasAttribute(this.XmlSerializationAttributeTypes.XmlIgnoreAttribute) + && propertySymbol.DeclaredAccessibility == Accessibility.Public + && propertySymbol.GetMethod != null + && propertySymbol.GetMethod.DeclaredAccessibility == Accessibility.Public + && propertySymbol.SetMethod != null + && propertySymbol.SetMethod.DeclaredAccessibility == Accessibility.Public) + || (options.JavaScriptSerializer + && propertySymbol.DeclaredAccessibility == Accessibility.Public + && propertySymbol.SetMethod != null + && propertySymbol.SetMethod.DeclaredAccessibility == Accessibility.Public) + || (options.NewtonsoftJsonNetSerialization + && propertySymbol.DeclaredAccessibility == Accessibility.Public + && !propertySymbol.HasAttribute(this.JsonIgnoreAttributeTypeSymbol) + && !propertySymbol.HasAttribute(this.NonSerializedAttributeTypeSymbol)))) + { + if (this.IsTypeInsecure(propertySymbol.Type, out ITypeSymbol? propertyInsecureTypeSymbol)) + { + resultBuilder.Add( + new InsecureObjectGraphResult( + propertySymbol, + null, + null, + propertyInsecureTypeSymbol)); + } + else + { + typesToRecurse.Add(propertySymbol.Type); + } + } + + break; + } + } + + if (options.DataContractSerialization) + { + // Look through [KnownType(typeof(Whatev))] attributes. + foreach (AttributeData knownTypeAttributeData in typeSymbol.GetAttributes(this.KnownTypeAttributeTypeSymbol)) + { + if (knownTypeAttributeData.AttributeConstructor.Parameters.Length != 1 + || knownTypeAttributeData.ConstructorArguments.Length != 1 + || !(knownTypeAttributeData.ConstructorArguments[0] is TypedConstant typedConstant) + || typedConstant.Kind != TypedConstantKind.Type // Not handling the string methodName overload + || !(typedConstant.Value is ITypeSymbol typedConstantTypeSymbol)) + { + continue; + } + + if (this.IsTypeInsecure(typedConstantTypeSymbol, out ITypeSymbol? knownTypeInsecureType)) + { + resultBuilder.Add( + new InsecureObjectGraphResult( + null, + knownTypeAttributeData, + typedConstant, + knownTypeInsecureType)); + } + else + { + typesToRecurse.Add(typedConstantTypeSymbol); + } + } + } + + if (options.XmlSerialization) + { + // Look through [XmlInclude(typeof(Whatev))] attributes. + foreach (AttributeData xmlIncludeAttributeData + in typeSymbol.GetAttributes(this.XmlSerializationAttributeTypes.XmlIncludeAttribute)) + { + if (xmlIncludeAttributeData.AttributeConstructor.Parameters.Length != 1 + || xmlIncludeAttributeData.ConstructorArguments.Length != 1 + || !(xmlIncludeAttributeData.ConstructorArguments[0] is TypedConstant typedConstant) + || typedConstant.Kind != TypedConstantKind.Type + || !(typedConstant.Value is ITypeSymbol typedConstantTypeSymbol)) + { + continue; + } + + if (this.IsTypeInsecure(typedConstantTypeSymbol, out ITypeSymbol? xmlIncludeInsecureType)) + { + resultBuilder.Add( + new InsecureObjectGraphResult( + null, + xmlIncludeAttributeData, + typedConstant, + xmlIncludeInsecureType)); + } + else + { + typesToRecurse.Add(typedConstantTypeSymbol); + } + } + } + + if (options.Recurse) + { + foreach (ITypeSymbol memberTypeSymbol in typesToRecurse) + { + GetInsecureSymbol(memberTypeSymbol, visitedTypes, resultBuilder); + } + } + } + } + + /// + /// Gets "associated" types, e.g. "List<Foo<Bar[]>>" means "List<T>", "Foo<T>", and "Bar". + /// + /// Type to get associated types for. + /// Set to populate with associated types. + private static void GetAssociatedTypes( + ITypeSymbol type, + PooledSortedSet results) + { + if (type == null || !results.Add(type)) + { + return; + } + + if (type is INamedTypeSymbol namedTypeSymbol) + { + // 1. Type arguments of generic type. + if (namedTypeSymbol.IsGenericType) + { + foreach (ITypeSymbol? arg in namedTypeSymbol.TypeArguments) + { + GetAssociatedTypes(arg, results); + } + } + + // 2. The type it constructed from. + GetAssociatedTypes(namedTypeSymbol.ConstructedFrom, results); + } + else if (type is IArrayTypeSymbol arrayTypeSymbol) + { + // 3. Element type of the array. + GetAssociatedTypes(arrayTypeSymbol.ElementType, results); + } + + // 4. Base type. + GetAssociatedTypes(type.BaseType, results); + } + } +} diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Security/Helpers/InsecureObjectGraphResult.cs b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Security/Helpers/InsecureObjectGraphResult.cs new file mode 100644 index 0000000000..2dc00e8ccf --- /dev/null +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Security/Helpers/InsecureObjectGraphResult.cs @@ -0,0 +1,98 @@ +// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Linq; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; + +namespace Microsoft.NetCore.Analyzers.Security.Helpers +{ + internal class InsecureObjectGraphResult + { + public InsecureObjectGraphResult( + ISymbol? insecureSymbol, + AttributeData? insecureAttribute, + TypedConstant? insecureAttributeTypedConstant, + ITypeSymbol insecureType) + { + if ((insecureSymbol == null && insecureAttribute == null) + || (insecureSymbol != null && insecureAttribute != null)) + { + throw new ArgumentException("Either insecureSymbol or insecureAttribute should be non-null"); + } + + if ((insecureAttribute == null && insecureAttributeTypedConstant != null) + || (insecureAttribute != null && insecureAttributeTypedConstant == null)) + { + throw new ArgumentException( + "Both insecureAttribute and insecureAttributeTypedConstant should be null or non-null"); + } + + InsecureSymbol = insecureSymbol; + InsecureAttribute = insecureAttribute; + InsecureAttributeTypedConstant = insecureAttributeTypedConstant; + InsecureType = insecureType ?? throw new ArgumentNullException(nameof(insecureType)); + } + + /// + /// The class / struct or its member field / property referencing an insecure type. + /// + public ISymbol? InsecureSymbol { get; } + + /// + /// Attribute referencing an insecure type. + /// + public AttributeData? InsecureAttribute { get; } + + /// + /// Typed constant in the attribute referencing an insecure type. + /// + public TypedConstant? InsecureAttributeTypedConstant { get; } + + /// + /// The insecure type being referenced. + /// + public ITypeSymbol InsecureType { get; } + + /// + /// Gets the of or . + /// + /// of or . + public Location GetLocation() + { + if (this.InsecureSymbol != null) + { + return this.InsecureSymbol.DeclaringSyntaxReferences.First().GetSyntax().GetLocation(); + } + else if (this.InsecureAttribute != null) + { + return this.InsecureAttribute.ApplicationSyntaxReference.GetSyntax().GetLocation(); + } + else + { + throw new NotImplementedException("Unhandled case"); + } + } + + /// + /// Gets the display string of or . + /// + /// Display string of or . + public string GetDisplayString() + { + if (this.InsecureSymbol != null) + { + return this.InsecureSymbol.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat); + } + else if (this.InsecureAttributeTypedConstant != null) + { + TypedConstant t = (TypedConstant)this.InsecureAttributeTypedConstant!; + return t.ToCSharpString(); + } + else + { + throw new NotImplementedException("Unhandled case"); + } + } + } +} diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Security/Helpers/ObjectGraphOptions.cs b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Security/Helpers/ObjectGraphOptions.cs new file mode 100644 index 0000000000..388a1e4b72 --- /dev/null +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Security/Helpers/ObjectGraphOptions.cs @@ -0,0 +1,152 @@ +// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Diagnostics.CodeAnalysis; + +namespace Microsoft.NetCore.Analyzers.Security.Helpers +{ + /// + /// Options for walking object graphs for . + /// + internal class ObjectGraphOptions + { + public ObjectGraphOptions( + bool recurse = false, + bool binarySerialization = false, + bool dataContractSerialization = false, + bool xmlSerialization = false, + bool javaScriptSerializer = false, + bool newtonsoftJsonNetSerialization = false) + { + Recurse = recurse; + BinarySerialization = binarySerialization; + DataContractSerialization = dataContractSerialization; + XmlSerialization = xmlSerialization; + JavaScriptSerializer = javaScriptSerializer; + NewtonsoftJsonNetSerialization = newtonsoftJsonNetSerialization; + } + + /// + /// Recurse into the types of fields and properties. + /// + public bool Recurse { get; private set; } + + /// + /// "Binary" serialization, like . + /// + [SuppressMessage("Documentation", "CA1200:Avoid using cref tags with a prefix", Justification = "Type not referenced by assembly.")] + public bool BinarySerialization { get; private set; } + + /// + /// DataContract serialization. + /// + public bool DataContractSerialization { get; private set; } + + /// + /// .NET XML serialization with . + /// + [SuppressMessage("Documentation", "CA1200:Avoid using cref tags with a prefix", Justification = "Type not referenced by assembly.")] + public bool XmlSerialization { get; private set; } + + /// + /// Serialization with . + /// + [SuppressMessage("Documentation", "CA1200:Avoid using cref tags with a prefix", Justification = "Type not referenced by assembly.")] + public bool JavaScriptSerializer { get; private set; } + + /// + /// Serialization with Newtonsoft Json.NET. + /// + [SuppressMessage("Documentation", "CA1200:Avoid using cref tags with a prefix", Justification = "Type not referenced by assembly.")] + public bool NewtonsoftJsonNetSerialization { get; private set; } + + /// + /// Options for BinarySerialization and recursing into member types. + /// + public static ObjectGraphOptions BinarySerializationOptions = new ObjectGraphOptions() + { + Recurse = true, + BinarySerialization = true, + }; + + /// + /// Options for DataContract serialization and recursing into member types. + /// + public static ObjectGraphOptions DataContractOptions = new ObjectGraphOptions() + { + Recurse = true, + DataContractSerialization = true, + }; + + /// + /// Options for XML serialization (XmlSerializer) and recursing into member types. + /// + public static ObjectGraphOptions XmlSerializerOptions = new ObjectGraphOptions() + { + Recurse = true, + XmlSerialization = true, + }; + + /// + /// Options for JavaScriptSerializer serialization and recursing into member types. + /// + public static ObjectGraphOptions JavaScriptSerializerOptions = new ObjectGraphOptions() + { + Recurse = true, + JavaScriptSerializer = true, + }; + + /// + /// Options for Newtonsoft Json.NET and recursing into member types. + /// + public static ObjectGraphOptions NewtonsoftJsonNetOptions = new ObjectGraphOptions() + { + Recurse = true, + NewtonsoftJsonNetSerialization = true, + }; + + public override bool Equals(object obj) + { + return this.Equals(obj as ObjectGraphOptions); + } + + public bool Equals(ObjectGraphOptions? other) + { + return other != null + && this.Recurse == other.Recurse + && this.BinarySerialization == other.BinarySerialization + && this.DataContractSerialization == other.DataContractSerialization + && this.JavaScriptSerializer == other.JavaScriptSerializer + && this.NewtonsoftJsonNetSerialization == other.NewtonsoftJsonNetSerialization + && this.XmlSerialization == other.XmlSerialization; + } + + public override int GetHashCode() + { + return (this.Recurse ? 1 : 0) + | (this.BinarySerialization ? 2 : 0) + | (this.DataContractSerialization ? 4 : 0) + | (this.JavaScriptSerializer ? 8 : 0) + | (this.NewtonsoftJsonNetSerialization ? 16 : 0) + | (this.XmlSerialization ? 32 : 0); + } + + /// + /// Determines if this instance is a valid argument (at least one type of serialization is specified). + /// + /// Name of the ObjectGraphOptions parameter; used in the ArgumentException. + internal void ThrowIfInvalid(string parameterName) + { + if (this.BinarySerialization + || this.DataContractSerialization + || this.XmlSerialization + || this.JavaScriptSerializer + || this.NewtonsoftJsonNetSerialization) + { + return; + } + + throw new ArgumentException("ObjectGraphOptions should specify at least one type serialization", parameterName); + } + } +} diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Security/Helpers/SecurityHelpers.cs b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Security/Helpers/SecurityHelpers.cs index 258cbd6830..9a66a58ee9 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Security/Helpers/SecurityHelpers.cs +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Security/Helpers/SecurityHelpers.cs @@ -112,6 +112,24 @@ public static DiagnosticDescriptor CreateDiagnosticDescriptor( "Deserialize", "DeserializeObject"); + /// + /// Deserialization methods for . + /// + [SuppressMessage("Documentation", "CA1200:Avoid using cref tags with a prefix", Justification = "The comment references a type that is not referenced by this compilation.")] + public static readonly ImmutableHashSet ObjectStateFormatterDeserializationMethods = + ImmutableHashSet.Create( + StringComparer.Ordinal, + "Deserialize"); + + /// + /// Deserialization methods for . + /// + [SuppressMessage("Documentation", "CA1200:Avoid using cref tags with a prefix", Justification = "The comment references a type that is not referenced by this compilation.")] + public static readonly ImmutableHashSet SoapFormatterDeserializationMethods = + ImmutableHashSet.Create( + StringComparer.Ordinal, + "Deserialize"); + private static readonly ImmutableDictionary ResourceManagerMapping = ImmutableDictionary.CreateRange( new[] @@ -151,6 +169,24 @@ public static DiagnosticDescriptor CreateDiagnosticDescriptor( "Deserialize", "Populate"); + /// + /// Deserialization methods for . + /// + [SuppressMessage("Documentation", "CA1200:Avoid using cref tags with a prefix", Justification = "The comment references a type that is not referenced by this compilation.")] + public static readonly ImmutableHashSet DataTableDeserializationMethods = + ImmutableHashSet.Create( + StringComparer.Ordinal, + "ReadXml"); + + /// + /// Deserialization methods for . + /// + [SuppressMessage("Documentation", "CA1200:Avoid using cref tags with a prefix", Justification = "The comment references a type that is not referenced by this compilation.")] + public static readonly ImmutableHashSet DataSetDeserializationMethods = + ImmutableHashSet.Create( + StringComparer.Ordinal, + "ReadXml"); + /// /// Gets a from . /// diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Security/Helpers/XmlSerializationAttributeTypes.cs b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Security/Helpers/XmlSerializationAttributeTypes.cs new file mode 100644 index 0000000000..5027a0487d --- /dev/null +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Security/Helpers/XmlSerializationAttributeTypes.cs @@ -0,0 +1,108 @@ +// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Linq; +using Analyzer.Utilities; +using Microsoft.CodeAnalysis; + +namespace Microsoft.NetCore.Analyzers.Security.Helpers +{ + /// + /// Just a common way to get s for attributes that affect XML serialization. + /// + /// + /// https://docs.microsoft.com/en-us/dotnet/standard/serialization/attributes-that-control-xml-serialization + /// + public class XmlSerializationAttributeTypes + { + /// + /// Indicates that at least one attribute is defined. + /// + public bool Any { get; private set; } + + public INamedTypeSymbol? XmlAnyAttributeAttribute { get; private set; } + public INamedTypeSymbol? XmlAnyElementAttribute { get; private set; } + public INamedTypeSymbol? XmlArrayAttribute { get; private set; } + public INamedTypeSymbol? XmlArrayItemAttribute { get; private set; } + public INamedTypeSymbol? XmlAttributeAttribute { get; private set; } + public INamedTypeSymbol? XmlChoiceIdentifierAttribute { get; private set; } + public INamedTypeSymbol? XmlElementAttribute { get; private set; } + public INamedTypeSymbol? XmlEnumAttribute { get; private set; } + public INamedTypeSymbol? XmlIgnoreAttribute { get; private set; } + public INamedTypeSymbol? XmlIncludeAttribute { get; private set; } + public INamedTypeSymbol? XmlRootAttribute { get; private set; } + public INamedTypeSymbol? XmlTextAttribute { get; private set; } + public INamedTypeSymbol? XmlTypeAttribute { get; private set; } + + /// + /// Constructs. + /// + /// The compilation's . + public XmlSerializationAttributeTypes(WellKnownTypeProvider wellKnownTypeProvider) + { + this.XmlAnyAttributeAttribute = wellKnownTypeProvider.GetOrCreateTypeByMetadataName( + WellKnownTypeNames.SystemXmlSerializationXmlAnyAttributeAttribute); + this.XmlAnyElementAttribute = wellKnownTypeProvider.GetOrCreateTypeByMetadataName( + WellKnownTypeNames.SystemXmlSerializationXmlAnyElementAttribute); + this.XmlArrayAttribute = wellKnownTypeProvider.GetOrCreateTypeByMetadataName( + WellKnownTypeNames.SystemXmlSerializationXmlArrayAttribute); + this.XmlArrayItemAttribute = wellKnownTypeProvider.GetOrCreateTypeByMetadataName( + WellKnownTypeNames.SystemXmlSerializationXmlArrayItemAttribute); + this.XmlAttributeAttribute = wellKnownTypeProvider.GetOrCreateTypeByMetadataName( + WellKnownTypeNames.SystemXmlSerializationXmlAttributeAttribute); + this.XmlChoiceIdentifierAttribute = wellKnownTypeProvider.GetOrCreateTypeByMetadataName( + WellKnownTypeNames.SystemXmlSerializationXmlChoiceIdentifierAttribute); + this.XmlElementAttribute = wellKnownTypeProvider.GetOrCreateTypeByMetadataName( + WellKnownTypeNames.SystemXmlSerializationXmlElementAttribute); + this.XmlEnumAttribute = wellKnownTypeProvider.GetOrCreateTypeByMetadataName( + WellKnownTypeNames.SystemXmlSerializationXmlEnumAttribute); + this.XmlIgnoreAttribute = wellKnownTypeProvider.GetOrCreateTypeByMetadataName( + WellKnownTypeNames.SystemXmlSerializationXmlIgnoreAttribute); + this.XmlIncludeAttribute = wellKnownTypeProvider.GetOrCreateTypeByMetadataName( + WellKnownTypeNames.SystemXmlSerializationXmlIncludeAttribute); + this.XmlRootAttribute = wellKnownTypeProvider.GetOrCreateTypeByMetadataName( + WellKnownTypeNames.SystemXmlSerializationXmlRootAttribute); + this.XmlTextAttribute = wellKnownTypeProvider.GetOrCreateTypeByMetadataName( + WellKnownTypeNames.SystemXmlSerializationXmlTextAttribute); + this.XmlTypeAttribute = wellKnownTypeProvider.GetOrCreateTypeByMetadataName( + WellKnownTypeNames.SystemXmlSerializationXmlTypeAttribute); + + this.Any = + this.XmlAnyAttributeAttribute != null + || this.XmlAnyElementAttribute != null + || this.XmlArrayAttribute != null + || this.XmlArrayItemAttribute != null + || this.XmlAttributeAttribute != null + || this.XmlChoiceIdentifierAttribute != null + || this.XmlElementAttribute != null + || this.XmlEnumAttribute != null + || this.XmlIgnoreAttribute != null + || this.XmlIncludeAttribute != null + || this.XmlRootAttribute != null + || this.XmlTextAttribute != null + || this.XmlTypeAttribute != null; + } + + /// + /// Determines if the given symbol has any XML serialization attributes on it. + /// + /// Symbol whose attributes to look through. + /// True if the symbol has an XML serialization attribute on it, false otherwise. + public bool HasAnyAttribute(ISymbol symbol) + { + return symbol.GetAttributes().Any(attributeData => + attributeData.AttributeClass.Equals(this.XmlAnyAttributeAttribute) + || attributeData.AttributeClass.Equals(this.XmlAnyElementAttribute) + || attributeData.AttributeClass.Equals(this.XmlArrayAttribute) + || attributeData.AttributeClass.Equals(this.XmlArrayItemAttribute) + || attributeData.AttributeClass.Equals(this.XmlAttributeAttribute) + || attributeData.AttributeClass.Equals(this.XmlChoiceIdentifierAttribute) + || attributeData.AttributeClass.Equals(this.XmlElementAttribute) + || attributeData.AttributeClass.Equals(this.XmlEnumAttribute) + || attributeData.AttributeClass.Equals(this.XmlIgnoreAttribute) + || attributeData.AttributeClass.Equals(this.XmlIncludeAttribute) + || attributeData.AttributeClass.Equals(this.XmlRootAttribute) + || attributeData.AttributeClass.Equals(this.XmlTextAttribute) + || attributeData.AttributeClass.Equals(this.XmlTypeAttribute)); + } + } +} diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.cs.xlf b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.cs.xlf index fa53255e8f..fae04ea798 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.cs.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.cs.xlf @@ -142,6 +142,76 @@ Spolehlivost + + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + + + + Unsafe DataSet or DataTable type found in deserializable object graph + Unsafe DataSet or DataTable type found in deserializable object graph + + + + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + + + + Unsafe DataSet or DataTable in deserialized object graph can be vulnerable to remote code execution attacks + Unsafe DataSet or DataTable in deserialized object graph can be vulnerable to remote code execution attacks + + + + When deserializing untrusted input with an IFormatter-based serializer, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + When deserializing untrusted input with an IFormatter-based serializer, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + + + + Unsafe DataSet or DataTable in serializable type can be vulnerable to remote code execution attacks + Unsafe DataSet or DataTable in serializable type can be vulnerable to remote code execution attacks + + + + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + + + + Unsafe DataSet or DataTable in serializable type + Unsafe DataSet or DataTable in serializable type + + + + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + + + + Unsafe DataSet or DataTable type in web deserializable object graph + Unsafe DataSet or DataTable type in web deserializable object graph + + + + The method '{0}' is insecure when deserializing untrusted data. If deserializing untrusted data, replace with TBD. + The method '{0}' is insecure when deserializing untrusted data. If deserializing untrusted data, replace with TBD. + + + + Do not use insecure deserialization with DataSet.ReadXml() + Do not use insecure deserialization with DataSet.ReadXml() + + + + The method '{0}' is insecure when deserializing untrusted data. If deserializing untrusted data, replace with TBD. + The method '{0}' is insecure when deserializing untrusted data. If deserializing untrusted data, replace with TBD. + + + + Do not use insecure deserialization with DataTable.ReadXml() + Do not use insecure deserialization with DataTable.ReadXml() + + HttpClients should enable certificate revocation list checks Komponenty HttpClient by měly povolit kontroly seznamu odvolaných certifikátů. diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.de.xlf b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.de.xlf index 54b7d63dd1..fa2514a053 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.de.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.de.xlf @@ -142,6 +142,76 @@ Zuverlässigkeit + + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + + + + Unsafe DataSet or DataTable type found in deserializable object graph + Unsafe DataSet or DataTable type found in deserializable object graph + + + + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + + + + Unsafe DataSet or DataTable in deserialized object graph can be vulnerable to remote code execution attacks + Unsafe DataSet or DataTable in deserialized object graph can be vulnerable to remote code execution attacks + + + + When deserializing untrusted input with an IFormatter-based serializer, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + When deserializing untrusted input with an IFormatter-based serializer, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + + + + Unsafe DataSet or DataTable in serializable type can be vulnerable to remote code execution attacks + Unsafe DataSet or DataTable in serializable type can be vulnerable to remote code execution attacks + + + + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + + + + Unsafe DataSet or DataTable in serializable type + Unsafe DataSet or DataTable in serializable type + + + + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + + + + Unsafe DataSet or DataTable type in web deserializable object graph + Unsafe DataSet or DataTable type in web deserializable object graph + + + + The method '{0}' is insecure when deserializing untrusted data. If deserializing untrusted data, replace with TBD. + The method '{0}' is insecure when deserializing untrusted data. If deserializing untrusted data, replace with TBD. + + + + Do not use insecure deserialization with DataSet.ReadXml() + Do not use insecure deserialization with DataSet.ReadXml() + + + + The method '{0}' is insecure when deserializing untrusted data. If deserializing untrusted data, replace with TBD. + The method '{0}' is insecure when deserializing untrusted data. If deserializing untrusted data, replace with TBD. + + + + Do not use insecure deserialization with DataTable.ReadXml() + Do not use insecure deserialization with DataTable.ReadXml() + + HttpClients should enable certificate revocation list checks HttpClients muss die Überprüfungen der Zertifikatsperrliste aktivieren. diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.es.xlf b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.es.xlf index f5f0e08733..51979bd1b0 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.es.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.es.xlf @@ -142,6 +142,76 @@ Fiabilidad + + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + + + + Unsafe DataSet or DataTable type found in deserializable object graph + Unsafe DataSet or DataTable type found in deserializable object graph + + + + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + + + + Unsafe DataSet or DataTable in deserialized object graph can be vulnerable to remote code execution attacks + Unsafe DataSet or DataTable in deserialized object graph can be vulnerable to remote code execution attacks + + + + When deserializing untrusted input with an IFormatter-based serializer, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + When deserializing untrusted input with an IFormatter-based serializer, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + + + + Unsafe DataSet or DataTable in serializable type can be vulnerable to remote code execution attacks + Unsafe DataSet or DataTable in serializable type can be vulnerable to remote code execution attacks + + + + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + + + + Unsafe DataSet or DataTable in serializable type + Unsafe DataSet or DataTable in serializable type + + + + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + + + + Unsafe DataSet or DataTable type in web deserializable object graph + Unsafe DataSet or DataTable type in web deserializable object graph + + + + The method '{0}' is insecure when deserializing untrusted data. If deserializing untrusted data, replace with TBD. + The method '{0}' is insecure when deserializing untrusted data. If deserializing untrusted data, replace with TBD. + + + + Do not use insecure deserialization with DataSet.ReadXml() + Do not use insecure deserialization with DataSet.ReadXml() + + + + The method '{0}' is insecure when deserializing untrusted data. If deserializing untrusted data, replace with TBD. + The method '{0}' is insecure when deserializing untrusted data. If deserializing untrusted data, replace with TBD. + + + + Do not use insecure deserialization with DataTable.ReadXml() + Do not use insecure deserialization with DataTable.ReadXml() + + HttpClients should enable certificate revocation list checks HttpClients debe habilitar las comprobaciones de la lista de revocación de certificados. diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.fr.xlf b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.fr.xlf index e597feebc6..d6743c64eb 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.fr.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.fr.xlf @@ -142,6 +142,76 @@ Fiabilité + + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + + + + Unsafe DataSet or DataTable type found in deserializable object graph + Unsafe DataSet or DataTable type found in deserializable object graph + + + + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + + + + Unsafe DataSet or DataTable in deserialized object graph can be vulnerable to remote code execution attacks + Unsafe DataSet or DataTable in deserialized object graph can be vulnerable to remote code execution attacks + + + + When deserializing untrusted input with an IFormatter-based serializer, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + When deserializing untrusted input with an IFormatter-based serializer, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + + + + Unsafe DataSet or DataTable in serializable type can be vulnerable to remote code execution attacks + Unsafe DataSet or DataTable in serializable type can be vulnerable to remote code execution attacks + + + + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + + + + Unsafe DataSet or DataTable in serializable type + Unsafe DataSet or DataTable in serializable type + + + + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + + + + Unsafe DataSet or DataTable type in web deserializable object graph + Unsafe DataSet or DataTable type in web deserializable object graph + + + + The method '{0}' is insecure when deserializing untrusted data. If deserializing untrusted data, replace with TBD. + The method '{0}' is insecure when deserializing untrusted data. If deserializing untrusted data, replace with TBD. + + + + Do not use insecure deserialization with DataSet.ReadXml() + Do not use insecure deserialization with DataSet.ReadXml() + + + + The method '{0}' is insecure when deserializing untrusted data. If deserializing untrusted data, replace with TBD. + The method '{0}' is insecure when deserializing untrusted data. If deserializing untrusted data, replace with TBD. + + + + Do not use insecure deserialization with DataTable.ReadXml() + Do not use insecure deserialization with DataTable.ReadXml() + + HttpClients should enable certificate revocation list checks HttpClients doit activer les vérifications de la liste de révocation de certificats diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.it.xlf b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.it.xlf index f0ce9ea677..8c5a937464 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.it.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.it.xlf @@ -142,6 +142,76 @@ Affidabilità + + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + + + + Unsafe DataSet or DataTable type found in deserializable object graph + Unsafe DataSet or DataTable type found in deserializable object graph + + + + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + + + + Unsafe DataSet or DataTable in deserialized object graph can be vulnerable to remote code execution attacks + Unsafe DataSet or DataTable in deserialized object graph can be vulnerable to remote code execution attacks + + + + When deserializing untrusted input with an IFormatter-based serializer, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + When deserializing untrusted input with an IFormatter-based serializer, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + + + + Unsafe DataSet or DataTable in serializable type can be vulnerable to remote code execution attacks + Unsafe DataSet or DataTable in serializable type can be vulnerable to remote code execution attacks + + + + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + + + + Unsafe DataSet or DataTable in serializable type + Unsafe DataSet or DataTable in serializable type + + + + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + + + + Unsafe DataSet or DataTable type in web deserializable object graph + Unsafe DataSet or DataTable type in web deserializable object graph + + + + The method '{0}' is insecure when deserializing untrusted data. If deserializing untrusted data, replace with TBD. + The method '{0}' is insecure when deserializing untrusted data. If deserializing untrusted data, replace with TBD. + + + + Do not use insecure deserialization with DataSet.ReadXml() + Do not use insecure deserialization with DataSet.ReadXml() + + + + The method '{0}' is insecure when deserializing untrusted data. If deserializing untrusted data, replace with TBD. + The method '{0}' is insecure when deserializing untrusted data. If deserializing untrusted data, replace with TBD. + + + + Do not use insecure deserialization with DataTable.ReadXml() + Do not use insecure deserialization with DataTable.ReadXml() + + HttpClients should enable certificate revocation list checks HttpClients deve abilitare i controlli dell'elenco di revoche di certificati diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ja.xlf b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ja.xlf index f8aa873824..4d8530ffcc 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ja.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ja.xlf @@ -142,6 +142,76 @@ 信頼性 + + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + + + + Unsafe DataSet or DataTable type found in deserializable object graph + Unsafe DataSet or DataTable type found in deserializable object graph + + + + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + + + + Unsafe DataSet or DataTable in deserialized object graph can be vulnerable to remote code execution attacks + Unsafe DataSet or DataTable in deserialized object graph can be vulnerable to remote code execution attacks + + + + When deserializing untrusted input with an IFormatter-based serializer, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + When deserializing untrusted input with an IFormatter-based serializer, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + + + + Unsafe DataSet or DataTable in serializable type can be vulnerable to remote code execution attacks + Unsafe DataSet or DataTable in serializable type can be vulnerable to remote code execution attacks + + + + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + + + + Unsafe DataSet or DataTable in serializable type + Unsafe DataSet or DataTable in serializable type + + + + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + + + + Unsafe DataSet or DataTable type in web deserializable object graph + Unsafe DataSet or DataTable type in web deserializable object graph + + + + The method '{0}' is insecure when deserializing untrusted data. If deserializing untrusted data, replace with TBD. + The method '{0}' is insecure when deserializing untrusted data. If deserializing untrusted data, replace with TBD. + + + + Do not use insecure deserialization with DataSet.ReadXml() + Do not use insecure deserialization with DataSet.ReadXml() + + + + The method '{0}' is insecure when deserializing untrusted data. If deserializing untrusted data, replace with TBD. + The method '{0}' is insecure when deserializing untrusted data. If deserializing untrusted data, replace with TBD. + + + + Do not use insecure deserialization with DataTable.ReadXml() + Do not use insecure deserialization with DataTable.ReadXml() + + HttpClients should enable certificate revocation list checks HttpClients では証明書失効リストの確認を有効にする必要があります diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ko.xlf b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ko.xlf index 892d932fcc..db20db52de 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ko.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ko.xlf @@ -142,6 +142,76 @@ 안정성 + + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + + + + Unsafe DataSet or DataTable type found in deserializable object graph + Unsafe DataSet or DataTable type found in deserializable object graph + + + + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + + + + Unsafe DataSet or DataTable in deserialized object graph can be vulnerable to remote code execution attacks + Unsafe DataSet or DataTable in deserialized object graph can be vulnerable to remote code execution attacks + + + + When deserializing untrusted input with an IFormatter-based serializer, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + When deserializing untrusted input with an IFormatter-based serializer, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + + + + Unsafe DataSet or DataTable in serializable type can be vulnerable to remote code execution attacks + Unsafe DataSet or DataTable in serializable type can be vulnerable to remote code execution attacks + + + + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + + + + Unsafe DataSet or DataTable in serializable type + Unsafe DataSet or DataTable in serializable type + + + + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + + + + Unsafe DataSet or DataTable type in web deserializable object graph + Unsafe DataSet or DataTable type in web deserializable object graph + + + + The method '{0}' is insecure when deserializing untrusted data. If deserializing untrusted data, replace with TBD. + The method '{0}' is insecure when deserializing untrusted data. If deserializing untrusted data, replace with TBD. + + + + Do not use insecure deserialization with DataSet.ReadXml() + Do not use insecure deserialization with DataSet.ReadXml() + + + + The method '{0}' is insecure when deserializing untrusted data. If deserializing untrusted data, replace with TBD. + The method '{0}' is insecure when deserializing untrusted data. If deserializing untrusted data, replace with TBD. + + + + Do not use insecure deserialization with DataTable.ReadXml() + Do not use insecure deserialization with DataTable.ReadXml() + + HttpClients should enable certificate revocation list checks HttpClients에서 인증서 해지 목록 확인을 사용하도록 설정해야 함 diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.pl.xlf b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.pl.xlf index 4e9e9a0b27..a847eaf57d 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.pl.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.pl.xlf @@ -142,6 +142,76 @@ Niezawodność + + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + + + + Unsafe DataSet or DataTable type found in deserializable object graph + Unsafe DataSet or DataTable type found in deserializable object graph + + + + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + + + + Unsafe DataSet or DataTable in deserialized object graph can be vulnerable to remote code execution attacks + Unsafe DataSet or DataTable in deserialized object graph can be vulnerable to remote code execution attacks + + + + When deserializing untrusted input with an IFormatter-based serializer, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + When deserializing untrusted input with an IFormatter-based serializer, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + + + + Unsafe DataSet or DataTable in serializable type can be vulnerable to remote code execution attacks + Unsafe DataSet or DataTable in serializable type can be vulnerable to remote code execution attacks + + + + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + + + + Unsafe DataSet or DataTable in serializable type + Unsafe DataSet or DataTable in serializable type + + + + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + + + + Unsafe DataSet or DataTable type in web deserializable object graph + Unsafe DataSet or DataTable type in web deserializable object graph + + + + The method '{0}' is insecure when deserializing untrusted data. If deserializing untrusted data, replace with TBD. + The method '{0}' is insecure when deserializing untrusted data. If deserializing untrusted data, replace with TBD. + + + + Do not use insecure deserialization with DataSet.ReadXml() + Do not use insecure deserialization with DataSet.ReadXml() + + + + The method '{0}' is insecure when deserializing untrusted data. If deserializing untrusted data, replace with TBD. + The method '{0}' is insecure when deserializing untrusted data. If deserializing untrusted data, replace with TBD. + + + + Do not use insecure deserialization with DataTable.ReadXml() + Do not use insecure deserialization with DataTable.ReadXml() + + HttpClients should enable certificate revocation list checks Klienci HttpClients powinni włączyć sprawdzanie listy odwołania certyfikatów diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.pt-BR.xlf b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.pt-BR.xlf index bcd642d916..9aa6872f32 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.pt-BR.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.pt-BR.xlf @@ -142,6 +142,76 @@ Confiabilidade + + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + + + + Unsafe DataSet or DataTable type found in deserializable object graph + Unsafe DataSet or DataTable type found in deserializable object graph + + + + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + + + + Unsafe DataSet or DataTable in deserialized object graph can be vulnerable to remote code execution attacks + Unsafe DataSet or DataTable in deserialized object graph can be vulnerable to remote code execution attacks + + + + When deserializing untrusted input with an IFormatter-based serializer, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + When deserializing untrusted input with an IFormatter-based serializer, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + + + + Unsafe DataSet or DataTable in serializable type can be vulnerable to remote code execution attacks + Unsafe DataSet or DataTable in serializable type can be vulnerable to remote code execution attacks + + + + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + + + + Unsafe DataSet or DataTable in serializable type + Unsafe DataSet or DataTable in serializable type + + + + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + + + + Unsafe DataSet or DataTable type in web deserializable object graph + Unsafe DataSet or DataTable type in web deserializable object graph + + + + The method '{0}' is insecure when deserializing untrusted data. If deserializing untrusted data, replace with TBD. + The method '{0}' is insecure when deserializing untrusted data. If deserializing untrusted data, replace with TBD. + + + + Do not use insecure deserialization with DataSet.ReadXml() + Do not use insecure deserialization with DataSet.ReadXml() + + + + The method '{0}' is insecure when deserializing untrusted data. If deserializing untrusted data, replace with TBD. + The method '{0}' is insecure when deserializing untrusted data. If deserializing untrusted data, replace with TBD. + + + + Do not use insecure deserialization with DataTable.ReadXml() + Do not use insecure deserialization with DataTable.ReadXml() + + HttpClients should enable certificate revocation list checks Os HttpClients devem habilitar as verificações da lista de certificados revogados diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ru.xlf b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ru.xlf index 4a17f1ff2e..117ab5df75 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ru.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ru.xlf @@ -142,6 +142,76 @@ Надежность + + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + + + + Unsafe DataSet or DataTable type found in deserializable object graph + Unsafe DataSet or DataTable type found in deserializable object graph + + + + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + + + + Unsafe DataSet or DataTable in deserialized object graph can be vulnerable to remote code execution attacks + Unsafe DataSet or DataTable in deserialized object graph can be vulnerable to remote code execution attacks + + + + When deserializing untrusted input with an IFormatter-based serializer, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + When deserializing untrusted input with an IFormatter-based serializer, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + + + + Unsafe DataSet or DataTable in serializable type can be vulnerable to remote code execution attacks + Unsafe DataSet or DataTable in serializable type can be vulnerable to remote code execution attacks + + + + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + + + + Unsafe DataSet or DataTable in serializable type + Unsafe DataSet or DataTable in serializable type + + + + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + + + + Unsafe DataSet or DataTable type in web deserializable object graph + Unsafe DataSet or DataTable type in web deserializable object graph + + + + The method '{0}' is insecure when deserializing untrusted data. If deserializing untrusted data, replace with TBD. + The method '{0}' is insecure when deserializing untrusted data. If deserializing untrusted data, replace with TBD. + + + + Do not use insecure deserialization with DataSet.ReadXml() + Do not use insecure deserialization with DataSet.ReadXml() + + + + The method '{0}' is insecure when deserializing untrusted data. If deserializing untrusted data, replace with TBD. + The method '{0}' is insecure when deserializing untrusted data. If deserializing untrusted data, replace with TBD. + + + + Do not use insecure deserialization with DataTable.ReadXml() + Do not use insecure deserialization with DataTable.ReadXml() + + HttpClients should enable certificate revocation list checks Для клиентов HTTP (HttpClients) следует включить проверки списка отзыва сертификатов. diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.tr.xlf b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.tr.xlf index 52b20f1b42..f3b442e651 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.tr.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.tr.xlf @@ -142,6 +142,76 @@ Güvenilirlik + + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + + + + Unsafe DataSet or DataTable type found in deserializable object graph + Unsafe DataSet or DataTable type found in deserializable object graph + + + + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + + + + Unsafe DataSet or DataTable in deserialized object graph can be vulnerable to remote code execution attacks + Unsafe DataSet or DataTable in deserialized object graph can be vulnerable to remote code execution attacks + + + + When deserializing untrusted input with an IFormatter-based serializer, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + When deserializing untrusted input with an IFormatter-based serializer, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + + + + Unsafe DataSet or DataTable in serializable type can be vulnerable to remote code execution attacks + Unsafe DataSet or DataTable in serializable type can be vulnerable to remote code execution attacks + + + + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + + + + Unsafe DataSet or DataTable in serializable type + Unsafe DataSet or DataTable in serializable type + + + + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + + + + Unsafe DataSet or DataTable type in web deserializable object graph + Unsafe DataSet or DataTable type in web deserializable object graph + + + + The method '{0}' is insecure when deserializing untrusted data. If deserializing untrusted data, replace with TBD. + The method '{0}' is insecure when deserializing untrusted data. If deserializing untrusted data, replace with TBD. + + + + Do not use insecure deserialization with DataSet.ReadXml() + Do not use insecure deserialization with DataSet.ReadXml() + + + + The method '{0}' is insecure when deserializing untrusted data. If deserializing untrusted data, replace with TBD. + The method '{0}' is insecure when deserializing untrusted data. If deserializing untrusted data, replace with TBD. + + + + Do not use insecure deserialization with DataTable.ReadXml() + Do not use insecure deserialization with DataTable.ReadXml() + + HttpClients should enable certificate revocation list checks HttpClients, sertifika iptal listesi denetimlerini etkinleştirmelidir diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.zh-Hans.xlf b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.zh-Hans.xlf index d0091e1d99..717bbf54a2 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.zh-Hans.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.zh-Hans.xlf @@ -142,6 +142,76 @@ 可靠性 + + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + + + + Unsafe DataSet or DataTable type found in deserializable object graph + Unsafe DataSet or DataTable type found in deserializable object graph + + + + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + + + + Unsafe DataSet or DataTable in deserialized object graph can be vulnerable to remote code execution attacks + Unsafe DataSet or DataTable in deserialized object graph can be vulnerable to remote code execution attacks + + + + When deserializing untrusted input with an IFormatter-based serializer, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + When deserializing untrusted input with an IFormatter-based serializer, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + + + + Unsafe DataSet or DataTable in serializable type can be vulnerable to remote code execution attacks + Unsafe DataSet or DataTable in serializable type can be vulnerable to remote code execution attacks + + + + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + + + + Unsafe DataSet or DataTable in serializable type + Unsafe DataSet or DataTable in serializable type + + + + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + + + + Unsafe DataSet or DataTable type in web deserializable object graph + Unsafe DataSet or DataTable type in web deserializable object graph + + + + The method '{0}' is insecure when deserializing untrusted data. If deserializing untrusted data, replace with TBD. + The method '{0}' is insecure when deserializing untrusted data. If deserializing untrusted data, replace with TBD. + + + + Do not use insecure deserialization with DataSet.ReadXml() + Do not use insecure deserialization with DataSet.ReadXml() + + + + The method '{0}' is insecure when deserializing untrusted data. If deserializing untrusted data, replace with TBD. + The method '{0}' is insecure when deserializing untrusted data. If deserializing untrusted data, replace with TBD. + + + + Do not use insecure deserialization with DataTable.ReadXml() + Do not use insecure deserialization with DataTable.ReadXml() + + HttpClients should enable certificate revocation list checks HttpClients 应启用证书吊销列表检查 diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.zh-Hant.xlf b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.zh-Hant.xlf index 618bb1be3a..fc7ac0ca6f 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.zh-Hant.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.zh-Hant.xlf @@ -142,6 +142,76 @@ 可靠性 + + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + + + + Unsafe DataSet or DataTable type found in deserializable object graph + Unsafe DataSet or DataTable type found in deserializable object graph + + + + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + + + + Unsafe DataSet or DataTable in deserialized object graph can be vulnerable to remote code execution attacks + Unsafe DataSet or DataTable in deserialized object graph can be vulnerable to remote code execution attacks + + + + When deserializing untrusted input with an IFormatter-based serializer, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + When deserializing untrusted input with an IFormatter-based serializer, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + + + + Unsafe DataSet or DataTable in serializable type can be vulnerable to remote code execution attacks + Unsafe DataSet or DataTable in serializable type can be vulnerable to remote code execution attacks + + + + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + + + + Unsafe DataSet or DataTable in serializable type + Unsafe DataSet or DataTable in serializable type + + + + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. + + + + Unsafe DataSet or DataTable type in web deserializable object graph + Unsafe DataSet or DataTable type in web deserializable object graph + + + + The method '{0}' is insecure when deserializing untrusted data. If deserializing untrusted data, replace with TBD. + The method '{0}' is insecure when deserializing untrusted data. If deserializing untrusted data, replace with TBD. + + + + Do not use insecure deserialization with DataSet.ReadXml() + Do not use insecure deserialization with DataSet.ReadXml() + + + + The method '{0}' is insecure when deserializing untrusted data. If deserializing untrusted data, replace with TBD. + The method '{0}' is insecure when deserializing untrusted data. If deserializing untrusted data, replace with TBD. + + + + Do not use insecure deserialization with DataTable.ReadXml() + Do not use insecure deserialization with DataTable.ReadXml() + + HttpClients should enable certificate revocation list checks HttpClients 應啟用憑證撤銷清單檢查 diff --git a/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.md b/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.md index 8c54acf9ff..bc6e9fc01b 100644 --- a/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.md +++ b/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.md @@ -8,7 +8,7 @@ Rule ID | Title | Category | Enabled | Severity | CodeFix | Description | [CA1005](https://docs.microsoft.com/visualstudio/code-quality/ca1005) | Avoid excessive parameters on generic types | Design | False | Warning | False | The more type parameters a generic type contains, the more difficult it is to know and remember what each type parameter represents. | [CA1008](https://docs.microsoft.com/visualstudio/code-quality/ca1008) | Enums should have zero value | Design | False | Warning | True | The default value of an uninitialized enumeration, just as other value types, is zero. A nonflags-attributed enumeration should define a member by using the value of zero so that the default value is a valid value of the enumeration. If an enumeration that has the FlagsAttribute attribute applied defines a zero-valued member, its name should be ""None"" to indicate that no values have been set in the enumeration. | [CA1010](https://docs.microsoft.com/visualstudio/code-quality/ca1010) | Generic interface should also be implemented | Design | True | Hidden | False | To broaden the usability of a type, implement one of the generic interfaces. This is especially true for collections as they can then be used to populate generic collection types. | -[CA1012](https://docs.microsoft.com/visualstudio/code-quality/ca1012) | Abstract types should not have constructors | Design | False | Warning | True | Constructors on abstract types can be called only by derived types. Because public constructors create instances of a type, and you cannot create instances of an abstract type, an abstract type that has a public constructor is incorrectly designed. | +[CA1012](https://docs.microsoft.com/visualstudio/code-quality/ca1012) | Abstract types should not have public constructors | Design | False | Warning | True | Constructors on abstract types can be called only by derived types. Because public constructors create instances of a type, and you cannot create instances of an abstract type, an abstract type that has a public constructor is incorrectly designed. | [CA1014](https://docs.microsoft.com/visualstudio/code-quality/ca1014) | Mark assemblies with CLSCompliant | Design | False | Warning | False | The Common Language Specification (CLS) defines naming restrictions, data types, and rules to which assemblies must conform if they will be used across programming languages. Good design dictates that all assemblies explicitly indicate CLS compliance by using CLSCompliantAttribute . If this attribute is not present on an assembly, the assembly is not compliant. | [CA1016](https://docs.microsoft.com/visualstudio/code-quality/ca1016) | Mark assemblies with assembly version | Design | True | Info | False | The .NET Framework uses the version number to uniquely identify an assembly, and to bind to types in strongly named assemblies. The version number is used together with version and publisher policy. By default, applications run only with the assembly version with which they were built. | [CA1017](https://docs.microsoft.com/visualstudio/code-quality/ca1017) | Mark assemblies with ComVisible | Design | False | Warning | False | ComVisibleAttribute determines how COM clients access managed code. Good design dictates that assemblies explicitly indicate COM visibility. COM visibility can be set for the whole assembly and then overridden for individual types and type members. If this attribute is not present, the contents of the assembly are visible to COM clients. | @@ -62,7 +62,7 @@ Rule ID | Title | Category | Enabled | Severity | CodeFix | Description | [CA1505](https://docs.microsoft.com/visualstudio/code-quality/ca1505) | Avoid unmaintainable code | Maintainability | False | Warning | False | The maintainability index is calculated by using the following metrics: lines of code, program volume, and cyclomatic complexity. Program volume is a measure of the difficulty of understanding of a symbol that is based on the number of operators and operands in the code. Cyclomatic complexity is a measure of the structural complexity of the type or method. A low maintainability index indicates that code is probably difficult to maintain and would be a good candidate to redesign. | [CA1506](https://docs.microsoft.com/visualstudio/code-quality/ca1506) | Avoid excessive class coupling | Maintainability | False | Warning | False | This rule measures class coupling by counting the number of unique type references that a symbol contains. Symbols that have a high degree of class coupling can be difficult to maintain. It is a good practice to have types and methods that exhibit low coupling and high cohesion. To fix this violation, try to redesign the code to reduce the number of types to which it is coupled. | [CA1507](https://docs.microsoft.com/visualstudio/code-quality/ca1507) | Use nameof to express symbol names | Maintainability | True | Info | True | Using nameof helps keep your code valid when refactoring. | -[CA1508](https://docs.microsoft.com/visualstudio/code-quality/ca1508) | Avoid dead conditional code | Maintainability | False | Warning | False | '{0}' is always '{1}'. Remove or refactor the condition(s) to avoid dead code. | +[CA1508](https://docs.microsoft.com/visualstudio/code-quality/ca1508) | Avoid dead conditional code | Maintainability | False | Warning | False | '{0}' is never '{1}'. Remove or refactor the condition(s) to avoid dead code. | [CA1509](https://docs.microsoft.com/visualstudio/code-quality/ca1509) | Invalid entry in code metrics rule specification file | Maintainability | False | Warning | False | Invalid entry in code metrics rule specification file | [CA1700](https://docs.microsoft.com/visualstudio/code-quality/ca1700) | Do not name enum values 'Reserved' | Naming | False | Warning | False | This rule assumes that an enumeration member that has a name that contains "reserved" is not currently used but is a placeholder to be renamed or removed in a future version. Renaming or removing a member is a breaking change. | [CA1707](https://docs.microsoft.com/visualstudio/code-quality/ca1707) | Identifiers should not contain underscores | Naming | True | Hidden | False | By convention, identifier names do not contain the underscore (_) character. This rule checks namespaces, types, members, and parameters. | @@ -79,7 +79,7 @@ Rule ID | Title | Category | Enabled | Severity | CodeFix | Description | [CA1725](https://docs.microsoft.com/visualstudio/code-quality/ca1725) | Parameter names should match base declaration | Naming | True | Hidden | True | Consistent naming of parameters in an override hierarchy increases the usability of the method overrides. A parameter name in a derived method that differs from the name in the base declaration can cause confusion about whether the method is an override of the base method or a new overload of the method. | [CA1801](https://docs.microsoft.com/visualstudio/code-quality/ca1801) | Review unused parameters | Usage | False | Warning | True | Avoid unused paramereters in your code. If the parameter cannot be removed, then change its name so it starts with an underscore and is optionally followed by an integer, such as '_', '_1', '_2', etc. These are treated as special discard symbol names. | [CA1802](https://docs.microsoft.com/visualstudio/code-quality/ca1802) | Use literals where appropriate | Performance | False | Warning | True | A field is declared static and read-only (Shared and ReadOnly in Visual Basic), and is initialized by using a value that is computable at compile time. Because the value that is assigned to the targeted field is computable at compile time, change the declaration to a const (Const in Visual Basic) field so that the value is computed at compile time instead of at run?time. | -[CA1805](https://docs.microsoft.com/visualstudio/code-quality/ca1805) | Do not initialize unnecessarily | Performance | True | Info | True | The common language runtime initializes all fields to their default values before running the constructor. In most cases, initializing a field to its default value in a constructor is redundant, which adds to maintenance costs and may degrade performance (such as with increased assembly size). One case where it is not redundant occurs when the constructor calls another constructor of the same class or a base class constructor and that constructor initializes the field to a non-default value. In this case, changing the value of the field back to its default value can be appropriate. | +[CA1805](https://docs.microsoft.com/visualstudio/code-quality/ca1805) | Do not initialize unnecessarily | Performance | True | Info | True | The .NET runtime initializes all fields of reference types to their default values before running the constructor. In most cases, explicitly initializing a field to its default value in a constructor is redundant, adding maintenance costs and potentially degrading performance (such as with increased assembly size), and the explicit initialization can be removed. In some cases, such as with static readonly fields that permanently retain their default value, consider instead changing them to be constants or properties. | [CA1806](https://docs.microsoft.com/visualstudio/code-quality/ca1806) | Do not ignore method results | Performance | True | Info | False | A new object is created but never used; or a method that creates and returns a new string is called and the new string is never used; or a COM or P/Invoke method returns an HRESULT or error code that is never used. | [CA1810](https://docs.microsoft.com/visualstudio/code-quality/ca1810) | Initialize reference type static fields inline | Performance | False | Warning | False | A reference type declares an explicit static constructor. To fix a violation of this rule, initialize all static data when it is declared and remove the static constructor. | [CA1812](https://docs.microsoft.com/visualstudio/code-quality/ca1812) | Avoid uninstantiated internal classes | Performance | False | Warning | False | An instance of an assembly-level type is not created by code in the assembly. | @@ -103,7 +103,7 @@ Rule ID | Title | Category | Enabled | Severity | CodeFix | Description | [CA1832](https://docs.microsoft.com/visualstudio/code-quality/ca1832) | Use AsSpan or AsMemory instead of Range-based indexers when appropriate | Performance | True | Info | True | The Range-based indexer on array values produces a copy of requested portion of the array. This copy is usually unnecessary when it is implicitly used as a ReadOnlySpan or ReadOnlyMemory value. Use the AsSpan method to avoid the unnecessary copy. | [CA1833](https://docs.microsoft.com/visualstudio/code-quality/ca1833) | Use AsSpan or AsMemory instead of Range-based indexers when appropriate | Performance | True | Info | True | The Range-based indexer on array values produces a copy of requested portion of the array. This copy is often unwanted when it is implicitly used as a Span or Memory value. Use the AsSpan method to avoid the copy. | [CA1834](https://docs.microsoft.com/visualstudio/code-quality/ca1834) | Consider using 'StringBuilder.Append(char)' when applicable. | Performance | True | Info | True | 'StringBuilder.Append(char)' is more efficient than 'StringBuilder.Append(string)' when the string is a single character. When calling 'Append' with a constant, prefer using a constant char rather than a constant string containing one character. | -[CA1835](https://docs.microsoft.com/visualstudio/code-quality/ca1835) | Prefer the 'Memory'-based overloads for 'ReadAsync' and 'WriteAsync'. | Performance | True | Info | True | 'Stream' has a 'ReadAsync' overload that takes a 'Memory' as the first argument, and a 'WriteAsync' overload that takes a 'ReadOnlyMemory' as the first argument. Prefer calling the memory based overloads, which are more efficient. | +[CA1835](https://docs.microsoft.com/visualstudio/code-quality/ca1835) | Prefer the 'Memory'-based overloads for 'ReadAsync' and 'WriteAsync' | Performance | True | Info | True | 'Stream' has a 'ReadAsync' overload that takes a 'Memory' as the first argument, and a 'WriteAsync' overload that takes a 'ReadOnlyMemory' as the first argument. Prefer calling the memory based overloads, which are more efficient. | [CA1836](https://docs.microsoft.com/visualstudio/code-quality/ca1836) | Prefer IsEmpty over Count | Performance | True | Info | True | For determining whether the object contains or not any items, prefer using 'IsEmpty' property rather than retrieving the number of items from the 'Count' property and comparing it to 0 or 1. | [CA2000](https://docs.microsoft.com/visualstudio/code-quality/ca2000) | Dispose objects before losing scope | Reliability | False | Warning | False | If a disposable object is not explicitly disposed before all references to it are out of scope, the object will be disposed at some indeterminate time when the garbage collector runs the finalizer of the object. Because an exceptional event might occur that will prevent the finalizer of the object from running, the object should be explicitly disposed instead. | [CA2002](https://docs.microsoft.com/visualstudio/code-quality/ca2002) | Do not lock on objects with weak identity | Reliability | False | Warning | False | An object is said to have a weak identity when it can be directly accessed across application domain boundaries. A thread that tries to acquire a lock on an object that has a weak identity can be blocked by a second thread in a different application domain that has a lock on the same object. | @@ -115,6 +115,7 @@ Rule ID | Title | Category | Enabled | Severity | CodeFix | Description | [CA2013](https://docs.microsoft.com/visualstudio/code-quality/ca2013) | Do not use ReferenceEquals with value types | Reliability | True | Warning | False | Value type typed arguments are uniquely boxed for each call to this method, therefore the result is always false. | [CA2014](https://docs.microsoft.com/visualstudio/code-quality/ca2014) | Do not use stackalloc in loops. | Reliability | True | Warning | False | Stack space allocated by a stackalloc is only released at the end of the current method's invocation. Using it in a loop can result in unbounded stack growth and eventual stack overflow conditions. | [CA2015](https://docs.microsoft.com/visualstudio/code-quality/ca2015) | Do not define finalizers for types derived from MemoryManager | Reliability | True | Warning | False | Adding a finalizer to a type derived from MemoryManager may permit memory to be freed while it is still in use by a Span. | +[CA2016](https://docs.microsoft.com/visualstudio/code-quality/ca2016) | Forward the 'CancellationToken' parameter to methods that take one | Reliability | True | Info | True | Forward the 'CancellationToken' parameter to methods that take one to ensure the operation cancellation notifications gets properly propagated, or pass in 'CancellationToken.None' explicitly to indicate intentionally not propagating the token. | [CA2100](https://docs.microsoft.com/visualstudio/code-quality/ca2100) | Review SQL queries for security vulnerabilities | Security | False | Warning | False | SQL queries that directly use user input can be vulnerable to SQL injection attacks. Review this SQL query for potential vulnerabilities, and consider using a parameterized SQL query. | [CA2101](https://docs.microsoft.com/visualstudio/code-quality/ca2101) | Specify marshaling for P/Invoke string arguments | Globalization | True | Info | True | A platform invoke member allows partially trusted callers, has a string parameter, and does not explicitly marshal the string. This can cause a potential security vulnerability. | [CA2109](https://docs.microsoft.com/visualstudio/code-quality/ca2109) | Review visible event handlers | Security | False | Warning | False | A public or protected event-handling method was detected. Event-handling methods should not be exposed unless absolutely necessary. | @@ -165,6 +166,13 @@ Rule ID | Title | Category | Enabled | Severity | CodeFix | Description | [CA2328](https://docs.microsoft.com/visualstudio/code-quality/ca2328) | Ensure that JsonSerializerSettings are secure | Security | False | Warning | False | When deserializing untrusted input, allowing arbitrary types to be deserialized is insecure. When using JsonSerializerSettings, ensure TypeNameHandling.None is specified, or for values other than None, ensure a SerializationBinder is specified to restrict deserialized types. | [CA2329](https://docs.microsoft.com/visualstudio/code-quality/ca2329) | Do not deserialize with JsonSerializer using an insecure configuration | Security | False | Warning | False | When deserializing untrusted input, allowing arbitrary types to be deserialized is insecure. When using deserializing JsonSerializer, use TypeNameHandling.None, or for values other than None, restrict deserialized types with a SerializationBinder. | [CA2330](https://docs.microsoft.com/visualstudio/code-quality/ca2330) | Ensure that JsonSerializer has a secure configuration when deserializing | Security | False | Warning | False | When deserializing untrusted input, allowing arbitrary types to be deserialized is insecure. When using deserializing JsonSerializer, use TypeNameHandling.None, or for values other than None, restrict deserialized types with a SerializationBinder. | +[CA2350](https://docs.microsoft.com/visualstudio/code-quality/ca2350) | Do not use insecure deserialization with DataTable.ReadXml() | Security | False | Warning | False | The method '{0}' is insecure when deserializing untrusted data. If deserializing untrusted data, replace with TBD. | +[CA2351](https://docs.microsoft.com/visualstudio/code-quality/ca2351) | Do not use insecure deserialization with DataSet.ReadXml() | Security | False | Warning | False | The method '{0}' is insecure when deserializing untrusted data. If deserializing untrusted data, replace with TBD. | +[CA2352](https://docs.microsoft.com/visualstudio/code-quality/ca2352) | Unsafe DataSet or DataTable in serializable type can be vulnerable to remote code execution attacks | Security | False | Warning | False | When deserializing untrusted input with an IFormatter-based serializer, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. | +[CA2353](https://docs.microsoft.com/visualstudio/code-quality/ca2353) | Unsafe DataSet or DataTable in serializable type | Security | False | Warning | False | When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. | +[CA2354](https://docs.microsoft.com/visualstudio/code-quality/ca2354) | Unsafe DataSet or DataTable in deserialized object graph can be vulnerable to remote code execution attacks | Security | False | Warning | False | When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. | +[CA2355](https://docs.microsoft.com/visualstudio/code-quality/ca2355) | Unsafe DataSet or DataTable type found in deserializable object graph | Security | False | Warning | False | When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. | +[CA2356](https://docs.microsoft.com/visualstudio/code-quality/ca2356) | Unsafe DataSet or DataTable type in web deserializable object graph | Security | False | Warning | False | When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}. | [CA3001](https://docs.microsoft.com/visualstudio/code-quality/ca3001) | Review code for SQL injection vulnerabilities | Security | False | Warning | False | Potential SQL injection vulnerability was found where '{0}' in method '{1}' may be tainted by user-controlled data from '{2}' in method '{3}'. | [CA3002](https://docs.microsoft.com/visualstudio/code-quality/ca3002) | Review code for XSS vulnerabilities | Security | False | Warning | False | Potential cross-site scripting (XSS) vulnerability was found where '{0}' in method '{1}' may be tainted by user-controlled data from '{2}' in method '{3}'. | [CA3003](https://docs.microsoft.com/visualstudio/code-quality/ca3003) | Review code for file path injection vulnerabilities | Security | False | Warning | False | Potential file path injection vulnerability was found where '{0}' in method '{1}' may be tainted by user-controlled data from '{2}' in method '{3}'. | diff --git a/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.sarif b/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.sarif index 4bf787b032..fe3d1321da 100644 --- a/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.sarif +++ b/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.sarif @@ -177,6 +177,24 @@ ] } }, + "CA2016": { + "id": "CA2016", + "shortDescription": "Forward the 'CancellationToken' parameter to methods that take one", + "fullDescription": "Forward the 'CancellationToken' parameter to methods that take one to ensure the operation cancellation notifications gets properly propagated, or pass in 'CancellationToken.None' explicitly to indicate intentionally not propagating the token.", + "defaultLevel": "note", + "helpUri": "https://docs.microsoft.com/visualstudio/code-quality/ca2016", + "properties": { + "category": "Reliability", + "isEnabledByDefault": true, + "typeName": "CSharpForwardCancellationTokenToInvocationsAnalyzer", + "languages": [ + "C#" + ], + "tags": [ + "Telemetry" + ] + } + }, "CA2200": { "id": "CA2200", "shortDescription": "Rethrow to preserve stack details.", @@ -383,7 +401,7 @@ }, "CA1012": { "id": "CA1012", - "shortDescription": "Abstract types should not have constructors", + "shortDescription": "Abstract types should not have public constructors", "fullDescription": "Constructors on abstract types can be called only by derived types. Because public constructors create instances of a type, and you cannot create instances of an abstract type, an abstract type that has a public constructor is incorrectly designed.", "defaultLevel": "warning", "helpUri": "https://docs.microsoft.com/visualstudio/code-quality/ca1012", @@ -1339,7 +1357,7 @@ "CA1508": { "id": "CA1508", "shortDescription": "Avoid dead conditional code", - "fullDescription": "'{0}' is always '{1}'. Remove or refactor the condition(s) to avoid dead code.", + "fullDescription": "'{0}' is never '{1}'. Remove or refactor the condition(s) to avoid dead code.", "defaultLevel": "warning", "helpUri": "https://docs.microsoft.com/visualstudio/code-quality/ca1508", "properties": { @@ -1678,7 +1696,7 @@ "CA1805": { "id": "CA1805", "shortDescription": "Do not initialize unnecessarily", - "fullDescription": "The common language runtime initializes all fields to their default values before running the constructor. In most cases, initializing a field to its default value in a constructor is redundant, which adds to maintenance costs and may degrade performance (such as with increased assembly size). One case where it is not redundant occurs when the constructor calls another constructor of the same class or a base class constructor and that constructor initializes the field to a non-default value. In this case, changing the value of the field back to its default value can be appropriate.", + "fullDescription": "The .NET runtime initializes all fields of reference types to their default values before running the constructor. In most cases, explicitly initializing a field to its default value in a constructor is redundant, adding maintenance costs and potentially degrading performance (such as with increased assembly size), and the explicit initialization can be removed. In some cases, such as with static readonly fields that permanently retain their default value, consider instead changing them to be constants or properties.", "defaultLevel": "note", "helpUri": "https://docs.microsoft.com/visualstudio/code-quality/ca1805", "properties": { @@ -2107,7 +2125,7 @@ }, "CA1835": { "id": "CA1835", - "shortDescription": "Prefer the 'Memory'-based overloads for 'ReadAsync' and 'WriteAsync'.", + "shortDescription": "Prefer the 'Memory'-based overloads for 'ReadAsync' and 'WriteAsync'", "fullDescription": "'Stream' has a 'ReadAsync' overload that takes a 'Memory' as the first argument, and a 'WriteAsync' overload that takes a 'ReadOnlyMemory' as the first argument. Prefer calling the memory based overloads, which are more efficient.", "defaultLevel": "note", "helpUri": "https://docs.microsoft.com/visualstudio/code-quality/ca1835", @@ -3243,6 +3261,139 @@ ] } }, + "CA2350": { + "id": "CA2350", + "shortDescription": "Do not use insecure deserialization with DataTable.ReadXml()", + "fullDescription": "The method '{0}' is insecure when deserializing untrusted data. If deserializing untrusted data, replace with TBD.", + "defaultLevel": "warning", + "helpUri": "https://docs.microsoft.com/visualstudio/code-quality/ca2350", + "properties": { + "category": "Security", + "isEnabledByDefault": false, + "typeName": "DoNotUseDataTableReadXml", + "languages": [ + "C#", + "Visual Basic" + ], + "tags": [ + "Telemetry" + ] + } + }, + "CA2351": { + "id": "CA2351", + "shortDescription": "Do not use insecure deserialization with DataSet.ReadXml()", + "fullDescription": "The method '{0}' is insecure when deserializing untrusted data. If deserializing untrusted data, replace with TBD.", + "defaultLevel": "warning", + "helpUri": "https://docs.microsoft.com/visualstudio/code-quality/ca2351", + "properties": { + "category": "Security", + "isEnabledByDefault": false, + "typeName": "DoNotUseDataSetReadXml", + "languages": [ + "C#", + "Visual Basic" + ], + "tags": [ + "Telemetry" + ] + } + }, + "CA2352": { + "id": "CA2352", + "shortDescription": "Unsafe DataSet or DataTable in serializable type can be vulnerable to remote code execution attacks", + "fullDescription": "When deserializing untrusted input with an IFormatter-based serializer, deserializing a {0} object is insecure. '{1}' either is or derives from {0}.", + "defaultLevel": "warning", + "helpUri": "https://docs.microsoft.com/visualstudio/code-quality/ca2352", + "properties": { + "category": "Security", + "isEnabledByDefault": false, + "typeName": "DataSetDataTableInSerializableTypeAnalyzer", + "languages": [ + "C#", + "Visual Basic" + ], + "tags": [ + "Telemetry" + ] + } + }, + "CA2353": { + "id": "CA2353", + "shortDescription": "Unsafe DataSet or DataTable in serializable type", + "fullDescription": "When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}.", + "defaultLevel": "warning", + "helpUri": "https://docs.microsoft.com/visualstudio/code-quality/ca2353", + "properties": { + "category": "Security", + "isEnabledByDefault": false, + "typeName": "DataSetDataTableInSerializableTypeAnalyzer", + "languages": [ + "C#", + "Visual Basic" + ], + "tags": [ + "Telemetry" + ] + } + }, + "CA2354": { + "id": "CA2354", + "shortDescription": "Unsafe DataSet or DataTable in deserialized object graph can be vulnerable to remote code execution attacks", + "fullDescription": "When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}.", + "defaultLevel": "warning", + "helpUri": "https://docs.microsoft.com/visualstudio/code-quality/ca2354", + "properties": { + "category": "Security", + "isEnabledByDefault": false, + "typeName": "DataSetDataTableInIFormatterSerializableObjectGraphAnalyzer", + "languages": [ + "C#", + "Visual Basic" + ], + "tags": [ + "Telemetry" + ] + } + }, + "CA2355": { + "id": "CA2355", + "shortDescription": "Unsafe DataSet or DataTable type found in deserializable object graph", + "fullDescription": "When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}.", + "defaultLevel": "warning", + "helpUri": "https://docs.microsoft.com/visualstudio/code-quality/ca2355", + "properties": { + "category": "Security", + "isEnabledByDefault": false, + "typeName": "DataSetDataTableInSerializableObjectGraphAnalyzer", + "languages": [ + "C#", + "Visual Basic" + ], + "tags": [ + "Telemetry" + ] + } + }, + "CA2356": { + "id": "CA2356", + "shortDescription": "Unsafe DataSet or DataTable type in web deserializable object graph", + "fullDescription": "When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0}.", + "defaultLevel": "warning", + "helpUri": "https://docs.microsoft.com/visualstudio/code-quality/ca2356", + "properties": { + "category": "Security", + "isEnabledByDefault": false, + "typeName": "DataSetDataTableInWebSerializableObjectGraphAnalyzer", + "languages": [ + "C#", + "Visual Basic" + ], + "tags": [ + "Telemetry" + ] + } + }, "CA3001": { "id": "CA3001", "shortDescription": "Review code for SQL injection vulnerabilities", @@ -4647,6 +4798,24 @@ ] } }, + "CA2016": { + "id": "CA2016", + "shortDescription": "Forward the 'CancellationToken' parameter to methods that take one", + "fullDescription": "Forward the 'CancellationToken' parameter to methods that take one to ensure the operation cancellation notifications gets properly propagated, or pass in 'CancellationToken.None' explicitly to indicate intentionally not propagating the token.", + "defaultLevel": "note", + "helpUri": "https://docs.microsoft.com/visualstudio/code-quality/ca2016", + "properties": { + "category": "Reliability", + "isEnabledByDefault": true, + "typeName": "BasicForwardCancellationTokenToInvocationsAnalyzer", + "languages": [ + "Visual Basic" + ], + "tags": [ + "Telemetry" + ] + } + }, "CA2200": { "id": "CA2200", "shortDescription": "Rethrow to preserve stack details.", diff --git a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Security/DataSetDataTableInIFormatterObjectGraphTests.cs b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Security/DataSetDataTableInIFormatterObjectGraphTests.cs new file mode 100644 index 0000000000..d1058456c3 --- /dev/null +++ b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Security/DataSetDataTableInIFormatterObjectGraphTests.cs @@ -0,0 +1,265 @@ +// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Collections.Immutable; +using System.Threading.Tasks; +using Microsoft.CodeAnalysis.Testing; +using Test.Utilities; +using Xunit; +using VerifyCS = Test.Utilities.CSharpSecurityCodeFixVerifier< + Microsoft.NetCore.Analyzers.Security.DataSetDataTableInIFormatterSerializableObjectGraphAnalyzer, + Microsoft.CodeAnalysis.Testing.EmptyCodeFixProvider>; + +namespace Microsoft.NetCore.Analyzers.Security.UnitTests +{ + public class DataSetDataTableInIFormatterObjectGraphTests + { + [Fact] + public async Task BinaryFormatter_Cast_Diagnostic() + { + await VerifyCSharpAnalyzerAsync(@" +using System; +using System.Data; +using System.IO; +using System.Runtime.Serialization.Formatters.Binary; + +namespace Blah +{ + [Serializable] + public class BlahClass + { + public DataSet DS; + + public BlahClass Method(MemoryStream ms) + { + BinaryFormatter bf = new BinaryFormatter(); + BlahClass bc = (BlahClass) bf.Deserialize(ms); + return bc; + } + } +}", + GetCSharpResultAt(17, 28, "DataSet", "DataSet BlahClass.DS")); + } + + [Fact] + public async Task NetDataContractSerializer_Cast_Diagnostic() + { + await VerifyCSharpAnalyzerAsync(@" +using System; +using System.Data; +using System.IO; +using System.Runtime.Serialization; + +namespace Blah +{ + [Serializable] + public class BlahClass + { + public DataSet DS; + + public BlahClass Method(MemoryStream ms) + { + NetDataContractSerializer ndcs = new NetDataContractSerializer(); + BlahClass bc = (BlahClass) ndcs.Deserialize(ms); + return bc; + } + } +}", + GetCSharpResultAt(17, 28, "DataSet", "DataSet BlahClass.DS")); + } + + [Fact] + public async Task ObjectStateFormatter_Cast_Diagnostic() + { + await VerifyCSharpAnalyzerAsync(@" +using System; +using System.Data; +using System.IO; +using System.Web.UI; + +namespace Blah +{ + [Serializable] + public class BlahClass + { + public DataSet DS; + + public BlahClass Method(MemoryStream ms) + { + ObjectStateFormatter osf = new ObjectStateFormatter(); + BlahClass bc = (BlahClass) osf.Deserialize(ms); + return bc; + } + } +}", + GetCSharpResultAt(17, 28, "DataSet", "DataSet BlahClass.DS")); + } + + [Fact] + public async Task SoapFormatter_Cast_Diagnostic() + { + await VerifyCSharpAnalyzerAsync(@" +using System; +using System.Data; +using System.IO; +using System.Runtime.Serialization.Formatters.Soap; + +namespace Blah +{ + [Serializable] + public class BlahClass + { + public DataSet DS; + + public BlahClass Method(MemoryStream ms) + { + SoapFormatter sf = new SoapFormatter(); + BlahClass bc = (BlahClass) sf.Deserialize(ms); + return bc; + } + } +}", + GetCSharpResultAt(17, 28, "DataSet", "DataSet BlahClass.DS")); + } + + [Fact] + public async Task BinaryFormatter_As_Diagnostic() + { + await VerifyCSharpAnalyzerAsync(@" +using System; +using System.Data; +using System.IO; +using System.Runtime.Serialization.Formatters.Binary; + +namespace Blah +{ + [Serializable] + public class BlahClass + { + public DataSet DS; + + public BlahClass Method(MemoryStream ms) + { + BinaryFormatter bf = new BinaryFormatter(); + BlahClass bc = bf.Deserialize(ms) as BlahClass; + return bc; + } + } +}", + GetCSharpResultAt(17, 28, "DataSet", "DataSet BlahClass.DS")); + } + + [Fact] + public async Task BinaryFormatter_As_PrivateAutoProperty_Diagnostic() + { + await VerifyCSharpAnalyzerAsync(@" +using System; +using System.Data; +using System.IO; +using System.Runtime.Serialization.Formatters.Binary; + +namespace Blah +{ + [Serializable] + public class BlahClass + { + private DataSet DS { get; } + + public BlahClass Method(MemoryStream ms) + { + BinaryFormatter bf = new BinaryFormatter(); + BlahClass bc = bf.Deserialize(ms) as BlahClass; + return bc; + } + } +}", + GetCSharpResultAt(17, 28, "DataSet", "DataSet BlahClass.DS")); + } + + [Fact] + public async Task BinaryFormatter_Cast_ReferenceLoop_Diagnostic() + { + await VerifyCSharpAnalyzerAsync(@" +using System; +using System.Data; +using System.IO; +using System.Runtime.Serialization.Formatters.Binary; + +namespace Blah +{ + [Serializable] + public class BlahClass + { + public DataSet DS; + + public BlahClass Blah; + + public BlahClass Method(MemoryStream ms) + { + BinaryFormatter bf = new BinaryFormatter(); + BlahClass bc = (BlahClass) bf.Deserialize(ms); + return bc; + } + } +}", + GetCSharpResultAt(19, 28, "DataSet", "DataSet BlahClass.DS")); + } + + [Fact] + public async Task BinaryFormatter_Cast_ReferenceIndirectLoop_Diagnostic() + { + await VerifyCSharpAnalyzerAsync(@" +using System; +using System.Data; +using System.IO; +using System.Runtime.Serialization.Formatters.Binary; + +namespace Blah +{ + [Serializable] + public class BlahClass + { + public FooClass Foo; + + public BlahClass Method(MemoryStream ms) + { + BinaryFormatter bf = new BinaryFormatter(); + BlahClass bc = (BlahClass) bf.Deserialize(ms); + return bc; + } + } + + [Serializable] + public class FooClass + { + private DataTable DT; + private BlahClass Blah; + } +}", + GetCSharpResultAt(17, 28, "DataTable", "DataTable FooClass.DT")); + } + + private static async Task VerifyCSharpAnalyzerAsync(string source, params DiagnosticResult[] expected) + { + System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls12; + var csharpTest = new VerifyCS.Test + { + ReferenceAssemblies = AdditionalMetadataReferences + .DefaultWithSerialization + .AddAssemblies(ImmutableArray.Create("System.Web", "System.Runtime.Serialization.Formatters.Soap")), + TestState = + { + Sources = { source }, + } + }; + + csharpTest.ExpectedDiagnostics.AddRange(expected); + + await csharpTest.RunAsync(); + } + + private static DiagnosticResult GetCSharpResultAt(int line, int column, params string[] arguments) + => VerifyCS.Diagnostic(DataSetDataTableInIFormatterSerializableObjectGraphAnalyzer.ObjectGraphContainsDangerousTypeDescriptor) + .WithLocation(line, column) + .WithArguments(arguments); + } +} diff --git a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Security/DataSetDataTableInObjectGraphTests.cs b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Security/DataSetDataTableInObjectGraphTests.cs new file mode 100644 index 0000000000..ce7b598632 --- /dev/null +++ b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Security/DataSetDataTableInObjectGraphTests.cs @@ -0,0 +1,424 @@ +// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Collections.Immutable; +using System.Threading.Tasks; +using Microsoft.CodeAnalysis.Testing; +using Test.Utilities; +using Xunit; +using VerifyCS = Test.Utilities.CSharpSecurityCodeFixVerifier< + Microsoft.NetCore.Analyzers.Security.DataSetDataTableInSerializableObjectGraphAnalyzer, + Microsoft.CodeAnalysis.Testing.EmptyCodeFixProvider>; + +namespace Microsoft.NetCore.Analyzers.Security.UnitTests +{ + public class DataSetDataTableInSerializableObjectGraphTests + { + [Fact] + public async Task JavaScriptSerializer_Deserialize_Generic_Diagnostic() + { + await VerifyCSharpJssAsync(@" +using System; +using System.Data; +using System.Web.Script.Serialization; + +namespace Blah +{ + public class BlahClass + { + public DataTable DT; + + public BlahClass Method(string input) + { + JavaScriptSerializer jss = new JavaScriptSerializer(); + return jss.Deserialize(input); + } + } +}", + GetCSharpResultAt(15, 20, "DataTable", "DataTable BlahClass.DT")); + } + + [Fact] + public async Task JavaScriptSerializer_Deserialize_Generic_NoDiagnostic() + { + await VerifyCSharpJssAsync(@" +using System; +using System.Web.Script.Serialization; + +namespace Blah +{ + public class BlahClass + { + public object NotADataTable; + + public BlahClass Method(string input) + { + JavaScriptSerializer jss = new JavaScriptSerializer(); + return jss.Deserialize(input); + } + } +}"); + } + + [Fact] + public async Task JavaScriptSerializer_Deserialize_NonGeneric_Diagnostic() + { + await VerifyCSharpJssAsync(@" +using System; +using System.Data; +using System.Web.Script.Serialization; + +namespace Blah +{ + public class BlahClass + { + public DataTable DT; + + public BlahClass Method(string input) + { + JavaScriptSerializer jss = new JavaScriptSerializer(); + return (BlahClass) jss.Deserialize(input, typeof(BlahClass)); + } + } +}", + GetCSharpResultAt(15, 55, "DataTable", "DataTable BlahClass.DT")); + } + + [Fact] + public async Task JavaScriptSerializer_Deserialize_NonGeneric_OutOfOrderArguments_Diagnostic() + { + await VerifyCSharpJssAsync(@" +using System; +using System.Data; +using System.Web.Script.Serialization; + +namespace Blah +{ + public class BlahClass + { + public DataTable DT; + + public BlahClass Method(string input) + { + JavaScriptSerializer jss = new JavaScriptSerializer(); + return (BlahClass) jss.Deserialize(targetType: typeof(BlahClass), input: input); + } + } +}", + GetCSharpResultAt(15, 60, "DataTable", "DataTable BlahClass.DT")); + } + + [Fact] + public async Task JavaScriptSerializer_DeserializeObject_As_Diagnostic() + { + await VerifyCSharpJssAsync(@" +using System; +using System.Data; +using System.Web.Script.Serialization; + +namespace Blah +{ + public class BlahClass + { + public DataTable DT; + + public BlahClass Method(string input) + { + JavaScriptSerializer jss = new JavaScriptSerializer(); + return jss.DeserializeObject(input) as BlahClass; + } + } +}", + GetCSharpResultAt(15, 20, "DataTable", "DataTable BlahClass.DT")); + } + + [Fact] + public async Task DataContract_Type_Diagnostic() + { + await VerifyCSharpAsync(@" +using System; +using System.Data; +using System.Runtime.Serialization; +using System.Xml; + +namespace Blah +{ + public class BlahClass + { + public DataTable DT; + + public BlahClass Method(XmlReader reader) + { + DataContractSerializer dcs = new DataContractSerializer(typeof(BlahClass)); + return (BlahClass) dcs.ReadObject(reader); + } + } +}", + GetCSharpResultAt(15, 69, "DataTable", "DataTable BlahClass.DT")); + } + + [Fact] + public async Task DataContract_Type_Types_Diagnostic() + { + await VerifyCSharpAsync(@" +using System; +using System.Data; +using System.Runtime.Serialization; +using System.Xml; + +namespace Blah +{ + public class BlahClass + { + public DataTable DT; + + public BlahClass Method(XmlReader reader) + { + DataContractSerializer dcs = new DataContractSerializer(typeof(BlahClass), new[] { typeof(BlahClass) }); + return (BlahClass) dcs.ReadObject(reader); + } + } +}", + GetCSharpResultAt(15, 69, "DataTable", "DataTable BlahClass.DT"), + GetCSharpResultAt(15, 96, "DataTable", "DataTable BlahClass.DT")); + } + + [Fact] + public async Task XmlSerializer_Constructor_Diagnostic() + { + await VerifyCSharpAsync(@" +using System; +using System.Data; +using System.Xml; +using System.Xml.Serialization; + +namespace Blah +{ + public class BlahClass + { + public DataTable DT; + + public BlahClass Method(XmlReader reader) + { + XmlSerializer xs = new XmlSerializer(typeof(BlahClass)); + return (BlahClass) xs.Deserialize(reader); + } + } +}", + GetCSharpResultAt(15, 50, "DataTable", "DataTable BlahClass.DT")); + } + + [Fact] + public async Task XmlSerializer_FromType_Diagnostic() + { + await VerifyCSharpAsync(@" +using System; +using System.Data; +using System.Xml; +using System.Xml.Serialization; + +namespace Blah +{ + public class BlahClass + { + public DataTable DT; + + public BlahClass Method(XmlReader reader) + { + XmlSerializer[] xs = XmlSerializer.FromTypes(new[] { typeof(BlahClass) }); + return (BlahClass) xs[0].Deserialize(reader); + } + } +}", + GetCSharpResultAt(15, 66, "DataTable", "DataTable BlahClass.DT")); + } + + [Fact] + public async Task Newtonsoft_JsonSerializer_Deserialize_Casted_Diagnostic() + { + await VerifyCSharpNewtonsoftAsync(@" +using System; +using System.Data; +using Newtonsoft.Json; + +namespace Blah +{ + public class BlahClass + { + public DataTable DT; + + public BlahClass Method(JsonReader reader) + { + JsonSerializer js = new JsonSerializer(); + return (BlahClass) js.Deserialize(reader); + } + } +}", + GetCSharpResultAt(15, 20, "DataTable", "DataTable BlahClass.DT")); + } + + [Fact] + public async Task Newtonsoft_JsonSerializer_Deserialize_TypeSpecified_Diagnostic() + { + await VerifyCSharpNewtonsoftAsync(@" +using System; +using System.Data; +using Newtonsoft.Json; + +namespace Blah +{ + public class BlahClass + { + public DataTable DT; + + public object Method(JsonReader reader) + { + JsonSerializer js = new JsonSerializer(); + return js.Deserialize(reader, typeof(BlahClass)); + } + } +}", + GetCSharpResultAt(15, 43, "DataTable", "DataTable BlahClass.DT")); + } + + [Fact] + public async Task Newtonsoft_JsonSerializer_Deserialize_TypeSpecified_OutOfOrderArguments_Diagnostic() + { + await VerifyCSharpNewtonsoftAsync(@" +using System; +using System.Data; +using Newtonsoft.Json; + +namespace Blah +{ + public class BlahClass + { + public DataTable DT; + + public object Method(JsonReader reader) + { + JsonSerializer js = new JsonSerializer(); + return js.Deserialize(objectType: typeof(BlahClass), reader: reader); + } + } +}", + GetCSharpResultAt(15, 47, "DataTable", "DataTable BlahClass.DT")); + } + + [Fact] + public async Task Newtonsoft_JsonSerializer_Deserialize_Casted_JsonIgnore_NoDiagnostic() + { + await VerifyCSharpNewtonsoftAsync(@" +using System; +using System.Data; +using Newtonsoft.Json; + +namespace Blah +{ + public class BlahClass + { + [JsonIgnore] + public DataTable DT; + + public BlahClass Method(JsonReader reader) + { + JsonSerializer js = new JsonSerializer(); + return (BlahClass) js.Deserialize(reader); + } + } +}"); + } + + [Fact] + public async Task Newtonsoft_JsonConvert_DeserializeObject_Generic_Diagnostic() + { + await VerifyCSharpNewtonsoftAsync(@" +using System; +using System.Data; +using Newtonsoft.Json; + +namespace Blah +{ + public class BlahClass + { + public DataTable DT { get; set; } + + public BlahClass Method(string s) + { + return JsonConvert.DeserializeObject(s); + } + } +}", + GetCSharpResultAt(14, 20, "DataTable", "DataTable BlahClass.DT")); + } + + private static async Task VerifyCSharpAsync(string source, params DiagnosticResult[] expected) + { + var csharpTest = new VerifyCS.Test + { + ReferenceAssemblies = AdditionalMetadataReferences + .DefaultWithSerialization, + TestState = + { + Sources = { source }, + } + }; + + csharpTest.ExpectedDiagnostics.AddRange(expected); + + await csharpTest.RunAsync(); + } + + /// + /// Tests code using JavaScriptSerializer. + /// + /// Source code to test. + /// Expected diagnostics. + /// Task of the test run. + private static async Task VerifyCSharpJssAsync(string source, params DiagnosticResult[] expected) + { + var csharpTest = new VerifyCS.Test + { + ReferenceAssemblies = AdditionalMetadataReferences + .DefaultWithSystemWeb + .AddAssemblies(ImmutableArray.Create("System.Data")), + TestState = + { + Sources = { source }, + } + }; + + csharpTest.ExpectedDiagnostics.AddRange(expected); + + await csharpTest.RunAsync(); + } + + /// + /// Tests code using Newtonsoft Json.NET. + /// + /// Source code to test. + /// Expected diagnostics. + /// Task of the test run. + private static async Task VerifyCSharpNewtonsoftAsync(string source, params DiagnosticResult[] expected) + { + var csharpTest = new VerifyCS.Test + { + ReferenceAssemblies = AdditionalMetadataReferences + .DefaultWithNewtonsoftJson12 + .AddAssemblies(ImmutableArray.Create("System.Data")), + TestState = + { + Sources = { source }, + } + }; + + csharpTest.ExpectedDiagnostics.AddRange(expected); + + await csharpTest.RunAsync(); + } + + private static DiagnosticResult GetCSharpResultAt(int line, int column, params string[] arguments) + => VerifyCS.Diagnostic(DataSetDataTableInSerializableObjectGraphAnalyzer.ObjectGraphContainsDangerousTypeDescriptor) + .WithLocation(line, column) + .WithArguments(arguments); + } +} diff --git a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Security/DataSetDataTableInSerializableTypeTests.cs b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Security/DataSetDataTableInSerializableTypeTests.cs new file mode 100644 index 0000000000..6306c19928 --- /dev/null +++ b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Security/DataSetDataTableInSerializableTypeTests.cs @@ -0,0 +1,406 @@ +// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Threading.Tasks; +using Microsoft.CodeAnalysis.Testing; +using Test.Utilities; +using Xunit; +using VerifyCS = Test.Utilities.CSharpSecurityCodeFixVerifier< + Microsoft.NetCore.Analyzers.Security.DataSetDataTableInSerializableTypeAnalyzer, + Microsoft.CodeAnalysis.Testing.EmptyCodeFixProvider>; + +namespace Microsoft.NetCore.Analyzers.Security.UnitTests +{ + public class DataSetDataTableInSerializableTypeTests + { + [Fact] + public async Task Serializable_Field_Diagnostic() + { + await VerifyCSharpAnalyzerAsync(@" +using System; +using System.Data; + +namespace Blah +{ + [Serializable] + public class BlahClass + { + public DataSet DS; + } +}", + GetIFormatterCSharpResultAt(10, 24, "DataSet", "DataSet BlahClass.DS")); + } + + [Fact] + public async Task DataContract_Field_Diagnostic() + { + await VerifyCSharpAnalyzerAsync(@" +using System.Data; +using System.Runtime.Serialization; + +namespace Blah +{ + [DataContract] + public class BlahClass + { + [DataMember] + public DataSet DS; + } +}", + GetNonIFormatterCSharpResultAt(11, 24, "DataSet", "DataSet BlahClass.DS")); + } + + [Fact] + public async Task IgnoreDataMemberOnDataTable_Diagnostic() + { + await VerifyCSharpAnalyzerAsync(@" +using System.Data; +using System.Runtime.Serialization; + +namespace Blah +{ + public class BlahClass + { + [IgnoreDataMember] + public DataTable DT; + + public int I; + } +}"); + } + + [Fact] + public async Task IgnoreDataMemberOnNotDataTable_Diagnostic() + { + await VerifyCSharpAnalyzerAsync(@" +using System.Data; +using System.Runtime.Serialization; + +namespace Blah +{ + public class BlahClass + { + public DataTable DT; + + [IgnoreDataMember] + public int I; + } +}", + GetNonIFormatterCSharpResultAt(9, 26, "DataTable", "DataTable BlahClass.DT")); + } + + [Fact] + public async Task DataContract_PrivateProperty_Diagnostic() + { + await VerifyCSharpAnalyzerAsync(@" +using System.Data; +using System.Runtime.Serialization; + +namespace Blah +{ + [DataContract] + public class BlahClass + { + [DataMember] + private DataSet DS { get; set; } + } +}", + GetNonIFormatterCSharpResultAt(10, 9, "DataSet", "DataSet BlahClass.DS")); + } + + [Fact] + public async Task DataContract_KnownType_DataTable_Diagnostic() + { + await VerifyCSharpAnalyzerAsync(@" +using System.Data; +using System.Runtime.Serialization; + +namespace Blah +{ + [DataContract] + [KnownType(typeof(DataTable))] + public class BlahClass + { + [DataMember] + public object DT; + } +}", + GetNonIFormatterCSharpResultAt(8, 6, "DataTable", "typeof(System.Data.DataTable)")); + } + + [Fact] + public async Task DataContract_InheritedKnownType_DataTable_Diagnostic() + { + await VerifyCSharpAnalyzerAsync(@" +using System.Data; +using System.Runtime.Serialization; + +namespace Blah +{ + [KnownType(typeof(DataTable))] + public class BlahBase + { + public object DT; + } + + [DataContract] + public class BlahClass : BlahBase + { + } +}", + GetNonIFormatterCSharpResultAt(7, 6, "DataTable", "typeof(System.Data.DataTable)")); + } + + [Fact] + public async Task Serializable_FieldDerivedClass_Diagnostic() + { + await VerifyCSharpAnalyzerAsync(@" +using System; +using System.Data; + +namespace Blah +{ + public class MyDataSet : DataSet + { + } + + [Serializable] + public class BlahClass + { + public MyDataSet DS; + } +}", + GetIFormatterCSharpResultAt(14, 26, "DataSet", "MyDataSet BlahClass.DS")); + } + + [Fact] + public async Task Serializable_PrivateField_Diagnostic() + { + await VerifyCSharpAnalyzerAsync(@" +using System; +using System.Data; + +namespace Blah +{ + [Serializable] + public class BlahClass + { + private DataSet DS; + } +}", + GetIFormatterCSharpResultAt(10, 25, "DataSet", "DataSet BlahClass.DS")); + } + + [Fact] + public async Task Serializable_Property_Diagnostic() + { + await VerifyCSharpAnalyzerAsync(@" +using System; +using System.Data; + +namespace Blah +{ + [Serializable] + public class BlahClass + { + public DataSet DS { get; set; } + } +}", + GetIFormatterCSharpResultAt(10, 9, "DataSet", "DataSet BlahClass.DS")); + } + + [Fact] + public async Task Serializable_PropertyDerived_Diagnostic() + { + await VerifyCSharpAnalyzerAsync(@" +using System; +using System.Data; + +namespace Blah +{ + public class MyDataSet : DataSet + { + } + + [Serializable] + public class BlahClass + { + public MyDataSet DS { get; set; } + } +}", + GetIFormatterCSharpResultAt(14, 9, "DataSet", "MyDataSet BlahClass.DS")); + } + + [Fact] + public async Task Serializable_PropertyList_Diagnostic() + { + await VerifyCSharpAnalyzerAsync(@" +using System; +using System.Collections.Generic; +using System.Data; + +namespace Blah +{ + [Serializable] + public class BlahClass + { + public List DS { get; set; } + } +}", + GetIFormatterCSharpResultAt(11, 9, "DataSet", "List BlahClass.DS")); + } + + [Fact] + public async Task Serializable_PropertyListListList_Diagnostic() + { + await VerifyCSharpAnalyzerAsync(@" +using System; +using System.Collections.Generic; +using System.Data; + +namespace Blah +{ + [Serializable] + public class BlahClass + { + public List>> DS { get; set; } + } +}", + GetIFormatterCSharpResultAt(11, 9, "DataSet", "List>> BlahClass.DS")); + } + + [Fact] + public async Task Serializable_PropertyArray_Diagnostic() + { + await VerifyCSharpAnalyzerAsync(@" +using System; +using System.Data; + +namespace Blah +{ + [Serializable] + public class BlahClass + { + public DataSet[] DS { get; set; } + } +}", + GetIFormatterCSharpResultAt(10, 9, "DataSet", "DataSet[] BlahClass.DS")); + } + + [Fact] + public async Task Serializable_Property2DArray_Diagnostic() + { + await VerifyCSharpAnalyzerAsync(@" +using System; +using System.Data; + +namespace Blah +{ + [Serializable] + public class BlahClass + { + public DataSet[,] DS { get; set; } + } +}", + GetIFormatterCSharpResultAt(10, 9, "DataSet", "DataSet[,] BlahClass.DS")); + } + + [Fact] + public async Task Serializable_PropertyArrayArray_Diagnostic() + { + await VerifyCSharpAnalyzerAsync(@" +using System; +using System.Data; + +namespace Blah +{ + [Serializable] + public class BlahClass + { + public DataSet[][] DS { get; set; } + } +}", + GetIFormatterCSharpResultAt(10, 9, "DataSet", "DataSet[][] BlahClass.DS")); + } + + [Fact] + public async Task Serializable_PropertyNoExplicitSetter_Diagnostic() + { + await VerifyCSharpAnalyzerAsync(@" +using System; +using System.Data; + +namespace Blah +{ + [Serializable] + public class BlahClass + { + public DataSet DS { get; } + } +}", + GetIFormatterCSharpResultAt(10, 9, "DataSet", "DataSet BlahClass.DS")); + } + + [Fact] + public async Task XmlElement_Property_Diagnostic() + { + await VerifyCSharpAnalyzerAsync(@" +using System.Data; +using System.Xml.Serialization; + +namespace Blah +{ + public class BlahClass + { + [XmlElement] + public DataSet DS { get; set; } + } +}", + GetNonIFormatterCSharpResultAt(9, 9, "DataSet", "DataSet BlahClass.DS")); + } + + [Fact] + public async Task XmlIgnore_Property_Diagnostic() + { + await VerifyCSharpAnalyzerAsync(@" +using System.Data; +using System.Xml.Serialization; + +namespace Blah +{ + [XmlRoot] + public class BlahClass + { + [XmlIgnore] + public DataSet DS { get; set; } + } +}"); + } + + private static async Task VerifyCSharpAnalyzerAsync(string source, params DiagnosticResult[] expected) + { + System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls12; + var csharpTest = new VerifyCS.Test + { + ReferenceAssemblies = AdditionalMetadataReferences.DefaultWithSerialization, + TestState = + { + Sources = { source }, + } + }; + + csharpTest.ExpectedDiagnostics.AddRange(expected); + + await csharpTest.RunAsync(); + } + + private static DiagnosticResult GetNonIFormatterCSharpResultAt(int line, int column, params string[] arguments) + => VerifyCS.Diagnostic(DataSetDataTableInSerializableTypeAnalyzer.SerializableContainsDangerousType) + .WithLocation(line, column) + .WithArguments(arguments); + + private static DiagnosticResult GetIFormatterCSharpResultAt(int line, int column, params string[] arguments) + => VerifyCS.Diagnostic(DataSetDataTableInSerializableTypeAnalyzer.RceSerializableContainsDangerousType) + .WithLocation(line, column) + .WithArguments(arguments); + } +} diff --git a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Security/DataSetDataTableInWebSerializableObjectGraphTests.cs b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Security/DataSetDataTableInWebSerializableObjectGraphTests.cs new file mode 100644 index 0000000000..690dfeaf50 --- /dev/null +++ b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Security/DataSetDataTableInWebSerializableObjectGraphTests.cs @@ -0,0 +1,132 @@ +// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Collections.Immutable; +using System.Threading.Tasks; +using Microsoft.CodeAnalysis.Testing; +using Test.Utilities; +using Xunit; +using VerifyCS = Test.Utilities.CSharpSecurityCodeFixVerifier< + Microsoft.NetCore.Analyzers.Security.DataSetDataTableInWebSerializableObjectGraphAnalyzer, + Microsoft.CodeAnalysis.Testing.EmptyCodeFixProvider>; + +namespace Microsoft.NetCore.Analyzers.Security.UnitTests +{ + public class DataSetDataTableInWebSerializableObjectGraphTests + { + [Fact] + public async Task WebServiceDirectlyReferences() + { + await VerifyWebServicesCSharpAsync(@" +using System; +using System.Data; +using System.Web.Services; + +[WebService(Namespace = ""http://contoso.example.com/"")] +public class MyService : WebService +{ + [WebMethod] + public string MyWebMethod(DataTable dataTable) + { + return null; + } +} +", + GetCSharpResultAt(10, 31, "DataTable", "DataTable")); + } + + [Fact] + public async Task WebServiceIndirectlyReferences() + { + await VerifyWebServicesCSharpAsync(@" +using System; +using System.Data; +using System.Web.Services; + +[WebService(Namespace = ""http://contoso.example.com/"")] +public class MyService : WebService +{ + [WebMethod] + public string MyWebMethod(MyType boo) + { + return null; + } +} + +public class MyType +{ + public DataSet DS { get; set; } +} +", + GetCSharpResultAt(10, 31, "DataSet", "DataSet MyType.DS")); + } + + [Fact] + public async Task OperationContract() + { + await VerifyServiceModelCSharpAsync(@" +using System; +using System.Data; +using System.ServiceModel; + +[ServiceContract(Namespace = ""http://contoso.example.com/"")] +public interface IMyContract +{ + [OperationContract] + string MyMethod(DataTable dataTable); + [OperationContract] + string MyOtherMethod(MyClass data); +} + +public class MyClass +{ + // Property of type DataSet, automatically serialized and + // deserialized as part of the overall MyClass payload. + public DataSet MyDataSet { get; set; } +} +", + GetCSharpResultAt(10, 21, "DataTable", "DataTable"), + GetCSharpResultAt(12, 26, "DataSet", "DataSet MyClass.MyDataSet")); + } + + private static async Task VerifyServiceModelCSharpAsync(string source, params DiagnosticResult[] expected) + { + System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls12; + var csharpTest = new VerifyCS.Test + { + ReferenceAssemblies = ReferenceAssemblies.NetFramework.Net472.Default.AddAssemblies( + ImmutableArray.Create("System.Data", "System.ServiceModel")), + TestState = + { + Sources = { source }, + } + }; + + csharpTest.ExpectedDiagnostics.AddRange(expected); + + await csharpTest.RunAsync(); + } + + private static async Task VerifyWebServicesCSharpAsync(string source, params DiagnosticResult[] expected) + { + System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls12; + var csharpTest = new VerifyCS.Test + { + ReferenceAssemblies = ReferenceAssemblies.NetFramework.Net472.Default.AddAssemblies( + ImmutableArray.Create("System.Data", "System.Web.Services")), + TestState = + { + Sources = { source }, + } + }; + + csharpTest.ExpectedDiagnostics.AddRange(expected); + + await csharpTest.RunAsync(); + } + + private static DiagnosticResult GetCSharpResultAt(int line, int column, params string[] arguments) + => VerifyCS.Diagnostic(DataSetDataTableInWebSerializableObjectGraphAnalyzer.ObjectGraphContainsDangerousTypeDescriptor) + .WithLocation(line, column) + .WithArguments(arguments); + } +} diff --git a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Security/DoNotUseDataSetReadXmlTests.cs b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Security/DoNotUseDataSetReadXmlTests.cs new file mode 100644 index 0000000000..ca6e0022ff --- /dev/null +++ b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Security/DoNotUseDataSetReadXmlTests.cs @@ -0,0 +1,111 @@ +// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Threading.Tasks; +using Microsoft.CodeAnalysis.Testing; +using Xunit; +using VerifyCS = Test.Utilities.CSharpSecurityCodeFixVerifier< + Microsoft.NetCore.Analyzers.Security.DoNotUseDataSetReadXml, + Microsoft.CodeAnalysis.Testing.EmptyCodeFixProvider>; + +namespace Microsoft.NetCore.Analyzers.Security.UnitTests +{ + public class DoNotUseDataSetReadXmlTests + { + [Fact] + public async Task ReadXml_Diagnostic() + { + await VerifyCS.VerifyAnalyzerAsync(@" +using System.IO; +using System.Data; + +namespace Blah +{ + public class Program + { + public void Unsafe(Stream s) + { + DataSet dataSet = new DataSet(); + dataSet.ReadXml(s); + } + } +}", + GetCSharpResultAt(12, 13, "XmlReadMode DataSet.ReadXml(Stream stream)")); + } + + [Fact] + public async Task DerivedReadXml_Diagnostic() + { + await VerifyCS.VerifyAnalyzerAsync(@" +using System.IO; +using System.Data; + +namespace Blah +{ + public class Program + { + public void Unsafe(string s) + { + MyDataSet dataSet = new MyDataSet(); + dataSet.ReadXml(s); + } + } + + public class MyDataSet : DataSet + { + } +}", + GetCSharpResultAt(12, 13, "XmlReadMode DataSet.ReadXml(string fileName)")); + } + + [Fact] + public async Task DerivedReadXmlEvenWithReadXmlSchema_Diagnostic() + { + await VerifyCS.VerifyAnalyzerAsync(@" +using System.IO; +using System.Data; + +namespace Blah +{ + public class Program + { + public void Unsafe(string s) + { + MyDataSet dataSet = new MyDataSet(); + dataSet.ReadXmlSchema(""""); + dataSet.ReadXml(s); + } + } + + public class MyDataSet : DataSet + { + } +}", + GetCSharpResultAt(13, 13, "XmlReadMode DataSet.ReadXml(string fileName)")); + } + + [Fact] + public async Task RejectChanges_NoDiagnostic() + { + await VerifyCS.VerifyAnalyzerAsync(@" +using System.IO; +using System.Data; + +namespace Blah +{ + public class Program + { + public void Safe(Stream s) + { + DataSet dataSet = new DataSet(); + dataSet.RejectChanges(); + } + } +}"); + } + + private static DiagnosticResult GetCSharpResultAt(int line, int column, params string[] arguments) + => VerifyCS.Diagnostic(DoNotUseDataSetReadXml.RealMethodUsedDescriptor) + .WithLocation(line, column) + .WithArguments(arguments); + } +} diff --git a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Security/DoNotUseDataTableReadXmlTests.cs b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Security/DoNotUseDataTableReadXmlTests.cs new file mode 100644 index 0000000000..5c1f3e1c8e --- /dev/null +++ b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Security/DoNotUseDataTableReadXmlTests.cs @@ -0,0 +1,85 @@ +// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Threading.Tasks; +using Microsoft.CodeAnalysis.Testing; +using Xunit; +using VerifyCS = Test.Utilities.CSharpSecurityCodeFixVerifier< + Microsoft.NetCore.Analyzers.Security.DoNotUseDataTableReadXml, + Microsoft.CodeAnalysis.Testing.EmptyCodeFixProvider>; + +namespace Microsoft.NetCore.Analyzers.Security.UnitTests +{ + public class DoNotUseDataTableReadXmlTests + { + [Fact] + public async Task ReadXml_Diagnostic() + { + await VerifyCS.VerifyAnalyzerAsync(@" +using System.IO; +using System.Data; + +namespace Blah +{ + public class Program + { + public void Unsafe(Stream s) + { + DataTable dataTable = new DataTable(); + dataTable.ReadXml(s); + } + } +}", + GetCSharpResultAt(12, 13, "XmlReadMode DataTable.ReadXml(Stream stream)")); + } + + [Fact] + public async Task DerivedReadXml_Diagnostic() + { + await VerifyCS.VerifyAnalyzerAsync(@" +using System.IO; +using System.Data; + +namespace Blah +{ + public class Program + { + public void Unsafe(string s) + { + MyDataTable dataTable = new MyDataTable(); + dataTable.ReadXml(s); + } + } + + public class MyDataTable : DataTable + { + } +}", + GetCSharpResultAt(12, 13, "XmlReadMode DataTable.ReadXml(string fileName)")); + } + + [Fact] + public async Task RejectChanges_NoDiagnostic() + { + await VerifyCS.VerifyAnalyzerAsync(@" +using System.IO; +using System.Data; + +namespace Blah +{ + public class Program + { + public void Safe(Stream s) + { + DataTable dataTable = new DataTable(); + dataTable.RejectChanges(); + } + } +}"); + } + + private static DiagnosticResult GetCSharpResultAt(int line, int column, params string[] arguments) + => VerifyCS.Diagnostic(DoNotUseDataTableReadXml.RealMethodUsedDescriptor) + .WithLocation(line, column) + .WithArguments(arguments); + } +} diff --git a/src/NetAnalyzers/UnitTests/Microsoft.NetFramework.Analyzers/DoNotUseInsecureDtdProcessingXmlTextReaderConstructedWithNoSecureResolutionTests.cs b/src/NetAnalyzers/UnitTests/Microsoft.NetFramework.Analyzers/DoNotUseInsecureDtdProcessingXmlTextReaderConstructedWithNoSecureResolutionTests.cs index e1f7846704..05d80668ea 100644 --- a/src/NetAnalyzers/UnitTests/Microsoft.NetFramework.Analyzers/DoNotUseInsecureDtdProcessingXmlTextReaderConstructedWithNoSecureResolutionTests.cs +++ b/src/NetAnalyzers/UnitTests/Microsoft.NetFramework.Analyzers/DoNotUseInsecureDtdProcessingXmlTextReaderConstructedWithNoSecureResolutionTests.cs @@ -1408,6 +1408,31 @@ End Class ); } + [Fact] + public async Task ConstructXmlTextReaderOnlySetDtdProcessingProhibitTargetFx451ShouldNotGenerateDiagnostic() + { + await VerifyCS.VerifyAnalyzerAsync(@" +using System; +using System.Reflection; +using System.Xml; + +[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute("".NETFramework,Version=v4.5.1"", FrameworkDisplayName = "".NET Framework 4.5.1"")] + +namespace TestNamespace +{ + public class TestClass + { + public void TestMethod(string path) + { + XmlTextReader reader = new XmlTextReader(path); + reader.DtdProcessing = DtdProcessing.Prohibit; + } + } +} +" + ); + } + [Fact] public async Task ConstructXmlTextReaderOnlySetDtdProcessingProhibitTargetFx46ShouldNotGenerateDiagnostic() { diff --git a/src/Roslyn.Diagnostics.Analyzers/Roslyn.Diagnostics.Analyzers.md b/src/Roslyn.Diagnostics.Analyzers/Roslyn.Diagnostics.Analyzers.md index 38ff874427..b70b9e16ef 100644 --- a/src/Roslyn.Diagnostics.Analyzers/Roslyn.Diagnostics.Analyzers.md +++ b/src/Roslyn.Diagnostics.Analyzers/Roslyn.Diagnostics.Analyzers.md @@ -15,8 +15,6 @@ RS0038 | Prefer null literal | RoslynDiagnosticsMaintainability | True | Warning RS0040 | Defaultable types should have defaultable fields | RoslynDiagnosticsReliability | True | Warning | False | Defaultable types should have defaultable fields. | RS0042 | Do not copy value | RoslynDiagnosticsReliability | True | Warning | False | Do not unbox non-copyable value types. | RS0043 | Do not call 'GetTestAccessor()' | RoslynDiagnosticsMaintainability | True | Warning | False | 'GetTestAccessor()' is a helper method reserved for testing. Production code must not call this member. | -RS0044 | Create test accessor | RoslynDiagnosticsMaintainability | True | Hidden | True | This is a refactoring which simplifies the process of creating test accessors using the 'TestAccessor' pattern. | -RS0045 | Expose member for testing | RoslynDiagnosticsMaintainability | True | Hidden | True | Expose member for testing. | RS0046 | Avoid the 'Opt' suffix | RoslynDiagnosticsDesign | True | Warning | True | Avoid the 'Opt' suffix in a nullable-enabled code. | RS0100 | Statements must be placed on their own line | RoslynDiagnosticsMaintainability | True | Warning | True | Statements must be placed on their own line | RS0101 | Avoid multiple blank lines | RoslynDiagnosticsMaintainability | True | Warning | True | Avoid multiple blank lines | diff --git a/src/Roslyn.Diagnostics.Analyzers/Roslyn.Diagnostics.Analyzers.sarif b/src/Roslyn.Diagnostics.Analyzers/Roslyn.Diagnostics.Analyzers.sarif index 28bff00da2..1d604dd0c2 100644 --- a/src/Roslyn.Diagnostics.Analyzers/Roslyn.Diagnostics.Analyzers.sarif +++ b/src/Roslyn.Diagnostics.Analyzers/Roslyn.Diagnostics.Analyzers.sarif @@ -169,44 +169,6 @@ "Telemetry" ] } - }, - "RS0044": { - "id": "RS0044", - "shortDescription": "Create test accessor", - "fullDescription": "This is a refactoring which simplifies the process of creating test accessors using the 'TestAccessor' pattern.", - "defaultLevel": "hidden", - "properties": { - "category": "RoslynDiagnosticsMaintainability", - "isEnabledByDefault": true, - "typeName": "CreateTestAccessor", - "languages": [ - "C#", - "Visual Basic" - ], - "tags": [ - "Telemetry", - "NotConfigurable" - ] - } - }, - "RS0045": { - "id": "RS0045", - "shortDescription": "Expose member for testing", - "fullDescription": "Expose member for testing.", - "defaultLevel": "hidden", - "properties": { - "category": "RoslynDiagnosticsMaintainability", - "isEnabledByDefault": true, - "typeName": "ExposeMemberForTesting", - "languages": [ - "C#", - "Visual Basic" - ], - "tags": [ - "Telemetry", - "NotConfigurable" - ] - } } } }, diff --git a/src/Test.Utilities/CSharpCodeFixVerifier`2+Test.cs b/src/Test.Utilities/CSharpCodeFixVerifier`2+Test.cs index 3f83259516..23b6ec5e43 100644 --- a/src/Test.Utilities/CSharpCodeFixVerifier`2+Test.cs +++ b/src/Test.Utilities/CSharpCodeFixVerifier`2+Test.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Immutable; +using System.Net; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CodeFixes; using Microsoft.CodeAnalysis.CSharp; @@ -18,6 +19,20 @@ public static partial class CSharpCodeFixVerifier { public class Test : CSharpCodeFixTest { + static Test() + { + // If we have outdated defaults from the host unit test application targeting an older .NET Framework, use more + // reasonable TLS protocol version for outgoing connections. +#pragma warning disable CA5364 // Do Not Use Deprecated Security Protocols +#pragma warning disable CS0618 // Type or member is obsolete + if (ServicePointManager.SecurityProtocol == (SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls)) +#pragma warning restore CS0618 // Type or member is obsolete +#pragma warning restore CA5364 // Do Not Use Deprecated Security Protocols + { + ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12; + } + } + internal static readonly ImmutableDictionary NullableWarnings = GetNullableWarningsFromCompiler(); public Test() diff --git a/src/Test.Utilities/CSharpSecurityCodeFixVerifier`2+Test.cs b/src/Test.Utilities/CSharpSecurityCodeFixVerifier`2+Test.cs index 6386caecc9..1caef6c53a 100644 --- a/src/Test.Utilities/CSharpSecurityCodeFixVerifier`2+Test.cs +++ b/src/Test.Utilities/CSharpSecurityCodeFixVerifier`2+Test.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; +using System.Net; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CodeFixes; using Microsoft.CodeAnalysis.Diagnostics; @@ -15,6 +16,20 @@ public static partial class CSharpSecurityCodeFixVerifier { public class Test : CSharpCodeFixVerifier.Test { + static Test() + { + // If we have outdated defaults from the host unit test application targeting an older .NET Framework, use more + // reasonable TLS protocol version for outgoing connections. +#pragma warning disable CA5364 // Do Not Use Deprecated Security Protocols +#pragma warning disable CS0618 // Type or member is obsolete + if (ServicePointManager.SecurityProtocol == (SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls)) +#pragma warning restore CS0618 // Type or member is obsolete +#pragma warning restore CA5364 // Do Not Use Deprecated Security Protocols + { + ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12; + } + } + public Test() { // These analyzers run on generated code by default. diff --git a/src/Utilities/Compiler/Analyzer.Utilities.projitems b/src/Utilities/Compiler/Analyzer.Utilities.projitems index 57aa12d752..8faa931f36 100644 --- a/src/Utilities/Compiler/Analyzer.Utilities.projitems +++ b/src/Utilities/Compiler/Analyzer.Utilities.projitems @@ -99,11 +99,14 @@ + + + diff --git a/src/Utilities/Compiler/Extensions/IOperationExtensions.cs b/src/Utilities/Compiler/Extensions/IOperationExtensions.cs index 58cf8021bd..775c10dfb1 100644 --- a/src/Utilities/Compiler/Extensions/IOperationExtensions.cs +++ b/src/Utilities/Compiler/Extensions/IOperationExtensions.cs @@ -679,6 +679,38 @@ public static IOperation WalkUpConversion(this IOperation operation) return thrownObject?.Type; } + /// + /// Determines if the one of the invocation's arguments' values is an argument of the specified type, and if so, find + /// the first one. + /// + /// Invocation operation whose arguments to look through. + /// First found IArgumentOperation.Value of the specified type, order by the method's + /// signature's parameters (as opposed to how arguments are specified when invoked). + /// True if one is found, false otherwise. + /// + /// IInvocationOperation.Arguments are ordered by how they are specified, which may differ from the order in the method + /// signature if the caller specifies arguments by name. This will find the first typeof operation ordered by the + /// method signature's parameters. + /// + public static bool HasArgument( + this IInvocationOperation invocationOperation, + [NotNullWhen(returnValue: true)] out TOperation? firstFoundArgument) + where TOperation : class, IOperation + { + firstFoundArgument = null; + int minOrdinal = int.MaxValue; + foreach (IArgumentOperation argumentOperation in invocationOperation.Arguments) + { + if (argumentOperation.Parameter.Ordinal < minOrdinal && argumentOperation.Value is TOperation to) + { + minOrdinal = argumentOperation.Parameter.Ordinal; + firstFoundArgument = to; + } + } + + return firstFoundArgument != null; + } + public static bool HasAnyExplicitDescendant(this IOperation operation, Func? descendIntoOperation = null) { var stack = ArrayBuilder>.GetInstance(); diff --git a/src/Utilities/Compiler/Extensions/ISymbolExtensions.cs b/src/Utilities/Compiler/Extensions/ISymbolExtensions.cs index 7423863fb1..57e848d3dd 100644 --- a/src/Utilities/Compiler/Extensions/ISymbolExtensions.cs +++ b/src/Utilities/Compiler/Extensions/ISymbolExtensions.cs @@ -112,6 +112,30 @@ public static bool IsPropertyWithBackingField([NotNullWhen(returnValue: true)] t propertySymbol.ContainingType.GetMembers().OfType().Any(f => f.IsImplicitlyDeclared && Equals(f.AssociatedSymbol, symbol)); } + /// + /// Determines if the given symbol is a backing field for a property. + /// + /// This symbol to check. + /// The property that this field symbol is backing. + /// True if the given symbol is a backing field for a property, false otherwise. + public static bool IsBackingFieldForProperty( + [NotNullWhen(returnValue: true)] this ISymbol? symbol, + [NotNullWhen(returnValue: true)] out IPropertySymbol? propertySymbol) + { + if (symbol is IFieldSymbol fieldSymbol + && fieldSymbol.IsImplicitlyDeclared + && fieldSymbol.AssociatedSymbol is IPropertySymbol p) + { + propertySymbol = p; + return true; + } + else + { + propertySymbol = null; + return false; + } + } + public static bool IsUserDefinedOperator([NotNullWhen(returnValue: true)] this ISymbol? symbol) { return (symbol as IMethodSymbol)?.MethodKind == MethodKind.UserDefinedOperator; @@ -680,6 +704,48 @@ public static bool HasAttribute(this ISymbol symbol, [NotNullWhen(returnValue: t return attribute != null && symbol.GetAttributes().Any(attr => attr.AttributeClass.Equals(attribute)); } + /// + /// Determines if the given symbol has the specified attributes. + /// + /// Symbol to examine. + /// Type symbols of the attributes to check for. + /// Boolean array, same size and order as , indicating that the corresponding + /// attirbute is present. + public static bool[] HasAttributes(this ISymbol symbol, params INamedTypeSymbol?[] attributes) + { + bool[] isAttributePresent = new bool[attributes.Length]; + foreach (var attributeData in symbol.GetAttributes()) + { + for (int i = 0; i < attributes.Length; i++) + { + if (attributeData.AttributeClass.Equals(attributes[i])) + { + isAttributePresent[i] = true; + } + } + } + + return isAttributePresent; + } + + + /// + /// Gets enumeration of attributes that are of the specified type. + /// + /// This symbol whose attributes to get. + /// Type of attribute to look for. + /// Enumeration of attributes. + [SuppressMessage("RoslyDiagnosticsPerformance", "RS0001:Use SpecializedCollections.EmptyEnumerable()", Justification = "Not available in all projects")] + public static IEnumerable GetAttributes(this ISymbol symbol, INamedTypeSymbol? attributeType) + { + if (attributeType == null) + { + return Enumerable.Empty(); + } + + return symbol.GetAttributes().Where(attr => attr.AttributeClass.Equals(attributeType)); + } + /// /// Indicates if a symbol has at least one location in source. /// diff --git a/src/Utilities/Compiler/PooledObjects/PooledHashSet.cs b/src/Utilities/Compiler/PooledObjects/PooledHashSet.cs index 3ed9d4a19d..98a42cbdc2 100644 --- a/src/Utilities/Compiler/PooledObjects/PooledHashSet.cs +++ b/src/Utilities/Compiler/PooledObjects/PooledHashSet.cs @@ -13,7 +13,6 @@ namespace Analyzer.Utilities.PooledObjects { // HashSet that can be recycled via an object pool - // NOTE: these HashSets always have the default comparer. internal sealed class PooledHashSet : HashSet, IDisposable { private readonly ObjectPool>? _pool; diff --git a/src/Utilities/Compiler/PooledObjects/PooledSortedSet.cs b/src/Utilities/Compiler/PooledObjects/PooledSortedSet.cs new file mode 100644 index 0000000000..3f012cc2f0 --- /dev/null +++ b/src/Utilities/Compiler/PooledObjects/PooledSortedSet.cs @@ -0,0 +1,63 @@ +// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Diagnostics; + +#pragma warning disable CA1000 // Do not declare static members on generic types + +namespace Analyzer.Utilities.PooledObjects +{ + /// + /// Pooled . + /// + /// Type of elements in the set. + internal sealed class PooledSortedSet : SortedSet, IDisposable + { + private readonly ObjectPool>? _pool; + + public PooledSortedSet(ObjectPool>? pool, IComparer? comparer = null) + : base(comparer) + { + _pool = pool; + } + + public void Dispose() => Free(); + + public void Free() + { + this.Clear(); + _pool?.Free(this); + } + + // global pool + private static readonly ObjectPool> s_poolInstance = CreatePool(); + private static readonly ConcurrentDictionary, ObjectPool>> s_poolInstancesByComparer + = new ConcurrentDictionary, ObjectPool>>(); + + private static ObjectPool> CreatePool(IComparer? comparer = null) + { + ObjectPool>? pool = null; + pool = new ObjectPool>( + () => new PooledSortedSet(pool, comparer), + 128); + return pool; + } + + /// + /// Gets a pooled instance of a with an optional comparer. + /// + /// Comparer to use, or null for the element type's default comparer. + /// An empty . + public static PooledSortedSet GetInstance(IComparer? comparer = null) + { + var pool = comparer == null ? + s_poolInstance : + s_poolInstancesByComparer.GetOrAdd(comparer, c => CreatePool(c)); + var instance = pool.Allocate(); + Debug.Assert(instance.Count == 0); + return instance; + } + } +} diff --git a/src/Utilities/Compiler/SymbolByDisplayStringComparer.cs b/src/Utilities/Compiler/SymbolByDisplayStringComparer.cs new file mode 100644 index 0000000000..53a918c50b --- /dev/null +++ b/src/Utilities/Compiler/SymbolByDisplayStringComparer.cs @@ -0,0 +1,57 @@ +// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using Microsoft.CodeAnalysis; + +namespace Analyzer.Utilities +{ + /// + /// for s sorted by display strings. + /// +#pragma warning disable CA1812 // Is too instantiated. + internal class SymbolByDisplayStringComparer : IComparer +#pragma warning restore CA1812 + { + /// + /// Constructs. + /// + /// The compilation containing the types to be compared. + public SymbolByDisplayStringComparer(Compilation compilation) + : this(SymbolDisplayStringCache.GetOrCreate(compilation)) + { + } + + /// + /// Constructs. + /// + /// The cache display strings to use. + public SymbolByDisplayStringComparer(SymbolDisplayStringCache symbolDisplayStringCache) + { + this.SymbolDisplayStringCache = symbolDisplayStringCache ?? throw new ArgumentNullException(nameof(symbolDisplayStringCache)); + } + + /// + /// Cache of symbol display strings. + /// + public SymbolDisplayStringCache SymbolDisplayStringCache { get; } + + /// + /// Compares two type symbols by their display strings. + /// + /// First type symbol to compare. + /// Second type symbol to compare. + /// Less than 0 if is before , 0 if equal, greater than 0 if + /// is after . + public int Compare([AllowNull] ITypeSymbol x, [AllowNull] ITypeSymbol y) + { + RoslynDebug.Assert(x != null); + RoslynDebug.Assert(y != null); + + return StringComparer.Ordinal.Compare( + this.SymbolDisplayStringCache.GetDisplayString(x), + this.SymbolDisplayStringCache.GetDisplayString(y)); + } + } +} diff --git a/src/Utilities/Compiler/SymbolDisplayNameCache.cs b/src/Utilities/Compiler/SymbolDisplayNameCache.cs new file mode 100644 index 0000000000..5c38e98418 --- /dev/null +++ b/src/Utilities/Compiler/SymbolDisplayNameCache.cs @@ -0,0 +1,51 @@ +// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Collections.Concurrent; +using Microsoft.CodeAnalysis; + +namespace Analyzer.Utilities +{ + /// + /// Cache ISymbol.ToDisplayName() results, to avoid performance concerns. + /// + public sealed class SymbolDisplayNameCache + { + private static readonly BoundedCacheWithFactory s_byCompilationCache = + new BoundedCacheWithFactory(); + + /// + /// Mapping of a symbol to its ToDisplayString(). + /// + private readonly ConcurrentDictionary SymbolToDisplayNames = + new ConcurrentDictionary(); + + + private SymbolDisplayNameCache() + { + } + + /// + /// Gets the symbol display string cache for the compilation. + /// + /// + /// + public static SymbolDisplayNameCache GetOrCreate(Compilation compilation) + { + return s_byCompilationCache.GetOrCreateValue(compilation, CreateSymbolDisplayNameCache); + + // Local functions + static SymbolDisplayNameCache CreateSymbolDisplayNameCache(Compilation compilation) + => new SymbolDisplayNameCache(); + } + + /// + /// Gets the symbol's display string. + /// + /// Symbol to get the display string. + /// The symbol's display string. + public string GetDisplayString(ISymbol symbol) + { + return this.SymbolToDisplayNames.GetOrAdd(symbol, s => s.ToDisplayString()); + } + } +} diff --git a/src/Utilities/Compiler/SymbolDisplayStringCache.cs b/src/Utilities/Compiler/SymbolDisplayStringCache.cs new file mode 100644 index 0000000000..d73f09c121 --- /dev/null +++ b/src/Utilities/Compiler/SymbolDisplayStringCache.cs @@ -0,0 +1,56 @@ +// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Collections.Concurrent; +using Microsoft.CodeAnalysis; + +namespace Analyzer.Utilities +{ + /// + /// Cache ISymbol.ToDisplayName() results, to avoid performance concerns. + /// + internal sealed class SymbolDisplayStringCache + { + /// + /// Caches by compilation. + /// + private static readonly BoundedCacheWithFactory s_byCompilationCache = + new BoundedCacheWithFactory(); + + /// + /// Mapping of a symbol to its ToDisplayString(). + /// + private readonly ConcurrentDictionary SymbolToDisplayNames = + new ConcurrentDictionary(); + + /// + /// Doesn't construct. + /// + private SymbolDisplayStringCache() + { + } + + /// + /// Gets the symbol display string cache for the compilation. + /// + /// Compilation that this cache is for. + /// A SymbolDisplayStringCache. + public static SymbolDisplayStringCache GetOrCreate(Compilation compilation) + { + return s_byCompilationCache.GetOrCreateValue(compilation, CreateSymbolDisplayNameCache); + + // Local functions + static SymbolDisplayStringCache CreateSymbolDisplayNameCache(Compilation compilation) + => new SymbolDisplayStringCache(); + } + + /// + /// Gets the symbol's display string. + /// + /// Symbol to get the display string. + /// The symbol's display string. + public string GetDisplayString(ISymbol symbol) + { + return this.SymbolToDisplayNames.GetOrAdd(symbol, s => s.ToDisplayString()); + } + } +} diff --git a/src/Utilities/Compiler/TypeSymbolByMetadataNameComparer.cs b/src/Utilities/Compiler/TypeSymbolByMetadataNameComparer.cs new file mode 100644 index 0000000000..2128859d4d --- /dev/null +++ b/src/Utilities/Compiler/TypeSymbolByMetadataNameComparer.cs @@ -0,0 +1,38 @@ +// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Collections.Generic; +using Microsoft.CodeAnalysis; + +namespace Analyzer.Utilities +{ + /// + /// for s sorted by display strings. + /// + internal class TypeSymbolByMetadataNameComparer : IComparer + { + /// + /// Constructs. + /// + public TypeSymbolByMetadataNameComparer(Compilation compilation) + : this(SymbolDisplayStringCache.GetOrCreate(compilation)) + { + } + + /// + /// + /// + /// + public TypeSymbolByMetadataNameComparer(SymbolDisplayStringCache symbolDisplayStringCache) + { + this.SymbolDisplayStringCache = symbolDisplayStringCache ?? throw new ArgumentNullException(nameof(symbolDisplayStringCache)); + } + + public SymbolDisplayStringCache SymbolDisplayStringCache { get; } + + public int Compare(ITypeSymbol x, ITypeSymbol y) + { + return StringComparer.Ordinal.Compare(this.SymbolDisplayStringCache[x], y.ToDisplayString()); + } + } +} diff --git a/src/Utilities/Compiler/WellKnownTypeNames.cs b/src/Utilities/Compiler/WellKnownTypeNames.cs index 40391b10d1..7ea58615fe 100644 --- a/src/Utilities/Compiler/WellKnownTypeNames.cs +++ b/src/Utilities/Compiler/WellKnownTypeNames.cs @@ -67,6 +67,7 @@ internal static class WellKnownTypeNames public const string MicrosoftWindowsAzureStorageCloudStorageAccount = "Microsoft.WindowsAzure.Storage.CloudStorageAccount"; public const string MicrosoftWindowsAzureStorageSharedAccessProtocol = "Microsoft.WindowsAzure.Storage.SharedAccessProtocol"; public const string NewtonsoftJsonJsonConvert = "Newtonsoft.Json.JsonConvert"; + public const string NewtonsoftJsonJsonIgnoreAttribute = "Newtonsoft.Json.JsonIgnoreAttribute"; public const string NewtonsoftJsonJsonSerializer = "Newtonsoft.Json.JsonSerializer"; public const string NewtonsoftJsonJsonSerializerSettings = "Newtonsoft.Json.JsonSerializerSettings"; public const string NewtonsoftJsonTypeNameHandling = "Newtonsoft.Json.TypeNameHandling"; @@ -230,10 +231,16 @@ internal static class WellKnownTypeNames public const string SystemRuntimeInteropServicesSafeHandle = "System.Runtime.InteropServices.SafeHandle"; public const string SystemRuntimeInteropServicesStructLayoutAttribute = "System.Runtime.InteropServices.StructLayoutAttribute"; public const string SystemRuntimeInteropServicesUnmanagedType = "System.Runtime.InteropServices.UnmanagedType"; + public const string SystemRuntimeSerializationDataContractAttribute = "System.Runtime.Serialization.DataContractAttribute"; + public const string SystemRuntimeSerializationDataContractSerializer = "System.Runtime.Serialization.DataContractSerializer"; public const string SystemRuntimeSerializationDataMemberAttribute = "System.Runtime.Serialization.DataMemberAttribute"; public const string SystemRuntimeSerializationFormattersBinaryBinaryFormatter = "System.Runtime.Serialization.Formatters.Binary.BinaryFormatter"; + public const string SystemRuntimeSerializationFormattersSoapSoapFormatter = "System.Runtime.Serialization.Formatters.Soap.SoapFormatter"; public const string SystemRuntimeSerializationIDeserializationCallback = "System.Runtime.Serialization.IDeserializationCallback"; + public const string SystemRuntimeSerializationIgnoreDataMemberAttribute = "System.Runtime.Serialization.IgnoreDataMemberAttribute"; public const string SystemRuntimeSerializationISerializable = "System.Runtime.Serialization.ISerializable"; + public const string SystemRuntimeSerializationJsonDataContractJsonSerializer = "System.Runtime.Serialization.Json"; + public const string SystemRuntimeSerializationKnownTypeAttribute = "System.Runtime.Serialization.KnownTypeAttribute"; public const string SystemRuntimeSerializationNetDataContractSerializer = "System.Runtime.Serialization.NetDataContractSerializer"; public const string SystemRuntimeSerializationOnDeserializedAttribute = "System.Runtime.Serialization.OnDeserializedAttribute"; public const string SystemRuntimeSerializationOnDeserializingAttribute = "System.Runtime.Serialization.OnDeserializingAttribute"; @@ -269,6 +276,7 @@ internal static class WellKnownTypeNames public const string SystemSecurityCryptographyX509CertificatesX509Chain = "System.Security.Cryptography.X509Certificates.X509Chain"; public const string SystemSecurityCryptographyX509CertificatesX509Store = "System.Security.Cryptography.X509Certificates.X509Store"; public const string SystemSerializableAttribute = "System.SerializableAttribute"; + public const string SystemServiceModelOperationContractAttribute = "System.ServiceModel.OperationContractAttribute"; public const string SystemSingle = "System.Single"; public const string SystemSpan1 = "System.Span`1"; public const string SystemStackOverflowException = "System.StackOverflowException"; @@ -294,6 +302,7 @@ internal static class WellKnownTypeNames public const string SystemThreadingTasksValueTask = "System.Threading.Tasks.ValueTask"; public const string SystemThreadingThread = "System.Threading.Thread"; public const string SystemTimeSpan = "System.TimeSpan"; + public const string SystemType = "System.Type"; public const string SystemUri = "System.Uri"; public const string SystemWebConfigurationHttpRuntimeSection = "System.Web.Configuration.HttpRuntimeSection"; public const string SystemWebHttpApplication = "System.Web.HttpApplication"; @@ -432,6 +441,19 @@ internal static class WellKnownTypeNames public const string SystemXmlSchemaXmlSchema = "System.Xml.Schema.XmlSchema"; public const string SystemXmlSchemaXmlSchemaCollection = "System.Xml.Schema.XmlSchemaCollection"; public const string SystemXmlSchemaXmlSchemaXPath = "System.Xml.Schema.XmlSchemaXPath"; + public const string SystemXmlSerializationXmlAnyAttributeAttribute = "System.Xml.Serialization.XmlAnyAttributeAttribute"; + public const string SystemXmlSerializationXmlAnyElementAttribute = "System.Xml.Serialization.XmlAnyElementAttribute"; + public const string SystemXmlSerializationXmlArrayAttribute = "System.Xml.Serialization.XmlArrayAttribute"; + public const string SystemXmlSerializationXmlArrayItemAttribute = "System.Xml.Serialization.XmlArrayItemAttribute"; + public const string SystemXmlSerializationXmlAttributeAttribute = "System.Xml.Serialization.XmlAttributeAttribute"; + public const string SystemXmlSerializationXmlChoiceIdentifierAttribute = "System.Xml.Serialization.XmlChoiceIdentifierAttribute"; + public const string SystemXmlSerializationXmlElementAttribute = "System.Xml.Serialization.XmlElementAttribute"; + public const string SystemXmlSerializationXmlEnumAttribute = "System.Xml.Serialization.XmlEnumAttribute"; + public const string SystemXmlSerializationXmlIgnoreAttribute = "System.Xml.Serialization.XmlIgnoreAttribute"; + public const string SystemXmlSerializationXmlIncludeAttribute = "System.Xml.Serialization.XmlIncludeAttribute"; + public const string SystemXmlSerializationXmlRootAttribute = "System.Xml.Serialization.XmlRootAttribute"; + public const string SystemXmlSerializationXmlTextAttribute = "System.Xml.Serialization.XmlTextAttribute"; + public const string SystemXmlSerializationXmlTypeAttribute = "System.Xml.Serialization.XmlTypeAttribute"; public const string SystemXmlSerializationXmlSerializer = "System.Xml.Serialization.XmlSerializer"; public const string SystemXmlXmlAttribute = "System.Xml.XmlAttribute"; public const string SystemXmlXmlDocument = "System.Xml.XmlDocument";