diff --git a/src/Analyzer.Core.BuiltInRuleTests/TestRunner.cs b/src/Analyzer.Core.BuiltInRuleTests/TestRunner.cs index be275259..9ac6653f 100644 --- a/src/Analyzer.Core.BuiltInRuleTests/TestRunner.cs +++ b/src/Analyzer.Core.BuiltInRuleTests/TestRunner.cs @@ -51,6 +51,7 @@ public void TestRules(TestConfiguration ruleExpectations) var failingLines = thisRuleEvaluations .Where(e => !e.Passed) .SelectMany(e => GetAllFailedLines(e)) + .Distinct() .ToList(); failingLines.Sort(); @@ -59,7 +60,7 @@ public void TestRules(TestConfiguration ruleExpectations) var expectedLines = ruleExpectations.ReportedFailures.Select(failure => failure.LineNumber).ToList(); expectedLines.Sort(); Assert.IsTrue(failingLines.SequenceEqual(expectedLines), - "Expected failing lines do not match actual failed lines." + Environment.NewLine + + $"Expected failing lines do not match actual failed lines for rule {ruleExpectations.RuleId}." + Environment.NewLine + $"Expected: [{string.Join(",", expectedLines)}] Actual: [{string.Join(",", failingLines)}]" + (failingLines.Count > 0 ? "" : Environment.NewLine + "(Do the test directory and test config have the same name as the RuleId being tested?)")); } diff --git a/src/Analyzer.Core.BuiltInRuleTests/Tests/TA-000001/TA-000001.json b/src/Analyzer.Core.BuiltInRuleTests/Tests/TA-000001/TA-000001.json index ef2bc42f..27c420a3 100644 --- a/src/Analyzer.Core.BuiltInRuleTests/Tests/TA-000001/TA-000001.json +++ b/src/Analyzer.Core.BuiltInRuleTests/Tests/TA-000001/TA-000001.json @@ -44,15 +44,7 @@ }, { "LineNumber": 82, - "Description": "httpLoggingEnabled is not given a value" - }, - { - "LineNumber": 82, - "Description": "detailedErrorLoggingEnabled is not given a value" - }, - { - "LineNumber": 82, - "Description": "requestTracingEnabled is not given a value" + "Description": "httpLoggingEnabled, detailedErrorLoggingEnabled, and requestTracingEnabled are not given values" } ] }, diff --git a/src/Analyzer.Core.BuiltInRuleTests/Tests/TA-000002/RemoteDebugging-Failures.json b/src/Analyzer.Core.BuiltInRuleTests/Tests/TA-000002/RemoteDebugging-Failures.json new file mode 100644 index 00000000..91787629 --- /dev/null +++ b/src/Analyzer.Core.BuiltInRuleTests/Tests/TA-000002/RemoteDebugging-Failures.json @@ -0,0 +1,118 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Location for all resources." + } + } + }, + "resources": [ + { + "apiVersion": "2019-08-01", + "type": "Microsoft.Web/sites", + "kind": "api", + "name": "remoteDebuggingOn", + "location": "[parameters('location')]", + "properties": { + "siteConfig": { + "remoteDebuggingEnabled": true + } + } + }, + { + "apiVersion": "2019-08-01", + "type": "Microsoft.Web/sites", + "kind": "api", + "name": "offInResourceButOnInChildConfig", + "location": "[parameters('location')]", + "properties": { + "siteConfig": { + "remoteDebuggingEnabled": false + } + }, + "resources": [ + { + "apiVersion": "2019-08-01", + "type": "config", + "name": "web", + "dependsOn": [ + "[resourceId('Microsoft.Web/sites/', 'offInResourceButonInChildConfig')]" + ], + "properties": { + "remoteDebuggingEnabled": true + } + } + ] + }, + { + "apiVersion": "2019-08-01", + "type": "Microsoft.Web/sites", + "kind": "api", + "name": "onInResourceButOffInChildConfig", + "location": "[parameters('location')]", + "properties": { + "siteConfig": { + "remoteDebuggingEnabled": true + } + }, + "resources": [ + { + "apiVersion": "2019-08-01", + "type": "config", + "name": "web", + "dependsOn": [ + "[resourceId('Microsoft.Web/sites/', 'offInResourceButonInChildConfig')]" + ], + "properties": { + "remoteDebuggingEnabled": false + } + } + ] + }, + { + "apiVersion": "2019-08-01", + "type": "Microsoft.Web/sites", + "kind": "api", + "name": "onInChildConfig", + "location": "[parameters('location')]", + "properties": { }, + "resources": [ + { + "apiVersion": "2019-08-01", + "type": "config", + "name": "web", + "dependsOn": [ + "[resourceId('Microsoft.Web/sites/', 'onInChildConfig')]" + ], + "properties": { + "remoteDebuggingEnabled": true + } + } + ] + }, + { + "apiVersion": "2019-08-01", + "type": "Microsoft.Web/sites", + "kind": "api", + "name": "onInDependentConfig", + "location": "[parameters('location')]", + "properties": { } + }, + { + "apiVersion": "2019-08-01", + "type": "Microsoft.Web/sites/config", + "name": "onInDependentConfig/web", + "kind": "api", + "dependsOn": [ + "[resourceId('Microsoft.Web/sites/', 'onInDependentConfig')]" + ], + "properties": { + "remoteDebuggingEnabled": true + } + } + ] +} \ No newline at end of file diff --git a/src/Analyzer.Core.BuiltInRuleTests/Tests/TA-000002/RemoteDebugging-Passes.json b/src/Analyzer.Core.BuiltInRuleTests/Tests/TA-000002/RemoteDebugging-Passes.json new file mode 100644 index 00000000..b0786fa2 --- /dev/null +++ b/src/Analyzer.Core.BuiltInRuleTests/Tests/TA-000002/RemoteDebugging-Passes.json @@ -0,0 +1,119 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Location for all resources." + } + } + }, + "resources": [ + { + "apiVersion": "2019-08-01", + "type": "Microsoft.Web/sites", + "kind": "linux", + "name": "notApiKind", + "location": "[parameters('location')]", + "properties": { + } + }, + { + "apiVersion": "2019-08-01", + "type": "Microsoft.Web/sites", + "kind": "api", + "name": "withoutSpecifyingProperties", + "location": "[parameters('location')]", + "properties": { + } + }, + { + "apiVersion": "2019-08-01", + "type": "Microsoft.Web/sites", + "kind": "api", + "name": "remoteDebuggingOff", + "location": "[parameters('location')]", + "properties": { + "siteConfig": { + "remoteDebuggingEnabled": false + } + } + }, + { + "apiVersion": "2019-08-01", + "type": "Microsoft.Web/sites", + "kind": "api", + "name": "absentInChildConfig", + "location": "[parameters('location')]", + "properties": { + "siteConfig": { } + }, + "resources": [ + { + "apiVersion": "2019-08-01", + "type": "config", + "name": "web", + "dependsOn": [ + "[resourceId('Microsoft.Web/sites/', 'offInChildConfig')]" + ], + "properties": { } + } + ] + }, + { + "apiVersion": "2019-08-01", + "type": "Microsoft.Web/sites", + "kind": "api", + "name": "offInChildConfig", + "location": "[parameters('location')]", + "properties": { }, + "resources": [ + { + "apiVersion": "2019-08-01", + "type": "config", + "name": "web", + "dependsOn": [ + "[resourceId('Microsoft.Web/sites/', 'offInChildConfig')]" + ], + "properties": { + "remoteDebuggingEnabled": false + } + } + ] + }, + { + "apiVersion": "2019-08-01", + "type": "Microsoft.Web/sites", + "kind": "api", + "name": "offInDependentConfig", + "location": "[parameters('location')]", + "properties": { } + }, + { + "apiVersion": "2019-08-01", + "type": "Microsoft.Web/sites/config", + "name": "offInDependentConfig/web", + "kind": "api", + "dependsOn": [ + "[resourceId('Microsoft.Web/sites/', 'offInDependentConfig')]" + ], + "properties": { + "remoteDebuggingEnabled": false + } + }, + { + "apiVersion": "2019-08-01", + "type": "Microsoft.Web/sites/config", + "name": "offInDependentConfig/metadata", + "kind": "api", + "dependsOn": [ + "[resourceId('Microsoft.Web/sites/', 'offInDependentConfig')]" + ], + "properties": { + "remoteDebuggingEnabled": true + } + }, + ] +} \ No newline at end of file diff --git a/src/Analyzer.Core.BuiltInRuleTests/Tests/TA-000002/TA-000002.json b/src/Analyzer.Core.BuiltInRuleTests/Tests/TA-000002/TA-000002.json new file mode 100644 index 00000000..fd6bb7cc --- /dev/null +++ b/src/Analyzer.Core.BuiltInRuleTests/Tests/TA-000002/TA-000002.json @@ -0,0 +1,61 @@ +[ + { + "Template": "RemoteDebugging-Failures.json", + "ReportedFailures": [ + { + "LineNumber": 22, + "Description": "remoteDebuggingEnabled set to true in resource" + }, + { + "LineNumber": 46, + "Description": "remoteDebuggingEnabled set to true in child config (even though it's false in parent resource)" + }, + { + "LineNumber": 59, + "Description": "remoteDebuggingEnabled set to true in resource (even though it's false in child config)" + }, + { + "LineNumber": 92, + "Description": "remoteDebuggingEnabled set to true in child config" + }, + { + "LineNumber": 114, + "Description": "remoteDebuggingEnabled set to true in dependent config" + } + ] + }, + { + "Template": "RemoteDebugging-Passes.json", + "ReportedFailures": [ ], + "PassingSections": [ + { + "ResourceName": "notApiKind", + "Explanation": "Wrong resource kind" + }, + { + "ResourceName": "withoutSpecifyingProperties", + "Explanation": "remoteDebuggingEnabled is not defined" + }, + { + "ResourceName": "remoteDebuggingOff", + "Explanation": "remoteDebuggingEnabled is false" + }, + { + "ResourceName": "absentInChildConfig", + "Explanation": "remoteDebuggingEnabled not defined in web app or in child web app config" + }, + { + "ResourceName": "offInChildConfig", + "Explanation": "remoteDebuggingEnabled is false in a child config" + }, + { + "ResourceNames": [ + "offInDependentConfig", + "offInDependentConfig/web", + "offInDependentConfig/metadata" + ], + "Explanation": "remoteDebuggingEnabled is false in a dependent config. Config with name 'metadata' is not the right config type for this property, so it being defined with 'true' has no effect." + } + ] + } +] \ No newline at end of file diff --git a/src/Analyzer.Core.BuiltInRuleTests/Tests/TA-000005/LatestTLS-Failures.json b/src/Analyzer.Core.BuiltInRuleTests/Tests/TA-000005/LatestTLS-Failures.json new file mode 100644 index 00000000..642ae7c3 --- /dev/null +++ b/src/Analyzer.Core.BuiltInRuleTests/Tests/TA-000005/LatestTLS-Failures.json @@ -0,0 +1,146 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Location for all resources." + } + } + }, + "resources": [ + { + "apiVersion": "2019-08-01", + "type": "Microsoft.Web/sites", + "kind": "api", + "name": "tlsNotSet", + "location": "[parameters('location')]", + "properties": { + "siteConfig": { } + } + }, + { + "apiVersion": "2019-08-01", + "type": "Microsoft.Web/sites", + "kind": "api", + "name": "DisallowedTlsVersion", + "location": "[parameters('location')]", + "properties": { + "siteConfig": { + "minTlsVersion": "1.1" + } + } + }, + { + "apiVersion": "2019-08-01", + "type": "Microsoft.Web/sites", + "kind": "api", + "name": "minTlsMissingInResourceAndInChildConfig", + "location": "[parameters('location')]", + "properties": { + "siteConfig": { } + }, + "resources": [ + { + "apiVersion": "2019-08-01", + "type": "config", + "name": "web", + "dependsOn": [ + "[resourceId('Microsoft.Web/sites/', 'minTlsMissingInResourceAndInChildConfig')]" + ], + "properties": { } + } + ] + }, + { + "apiVersion": "2019-08-01", + "type": "Microsoft.Web/sites", + "kind": "api", + "name": "insecureInDependentConfig", + "location": "[parameters('location')]", + "properties": { } + }, + { + "apiVersion": "2019-08-01", + "type": "Microsoft.Web/sites/config", + "name": "insecureInDependentConfig/web", + "kind": "api", + "dependsOn": [ + "[resourceId('Microsoft.Web/sites/', 'insecureInDependentConfig')]" + ], + "properties": { + "minTlsVersion": "1.0" + } + }, + { + "apiVersion": "2019-08-01", + "type": "Microsoft.Web/sites", + "kind": "api", + "name": "missingInDependentConfig", + "location": "[parameters('location')]", + "properties": { } + }, + { + "apiVersion": "2019-08-01", + "type": "Microsoft.Web/sites/config", + "name": "missingInDependentConfig/web", + "kind": "api", + "dependsOn": [ + "[resourceId('Microsoft.Web/sites/', 'missingInDependentConfig')]" + ], + "properties": { } + }, + { + "apiVersion": "2019-08-01", + "type": "Microsoft.Web/sites", + "kind": "api", + "name": "secureInParentButInsecureInChildConfig", + "location": "[parameters('location')]", + "properties": { + "siteConfig": { + "minTlsVersion": "1.2" + } + }, + "resources": [ + { + "apiVersion": "2019-08-01", + "type": "config", + "name": "web", + "dependsOn": [ + "[resourceId('Microsoft.Web/sites/', 'secureInParentButInsecureInChildConfig')]" + ], + "properties": { + "minTlsVersion": "1.1" + } + } + ] + }, + { + "apiVersion": "2019-08-01", + "type": "Microsoft.Web/sites", + "kind": "api", + "name": "insecureInParentButSecureInChild", + "location": "[parameters('location')]", + "properties": { + "siteConfig": { + "minTlsVersion": "1.1" + } + }, + "resources": [ + { + "apiVersion": "2019-08-01", + "type": "config", + "name": "web", + "dependsOn": [ + "[resourceId('Microsoft.Web/sites/', 'insecureInParentButSecureInChild')]" + ], + "properties": { + "minTlsVersion": "1.2" + } + } + ] + } + ] +} \ No newline at end of file diff --git a/src/Analyzer.Core.BuiltInRuleTests/Tests/TA-000005/LatestTLS-Passes.json b/src/Analyzer.Core.BuiltInRuleTests/Tests/TA-000005/LatestTLS-Passes.json new file mode 100644 index 00000000..9aa5d748 --- /dev/null +++ b/src/Analyzer.Core.BuiltInRuleTests/Tests/TA-000005/LatestTLS-Passes.json @@ -0,0 +1,109 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Location for all resources." + } + } + }, + "resources": [ + { + "apiVersion": "2019-08-01", + "type": "Microsoft.Web/sites", + "kind": "linux", + "name": "notApiKind", + "location": "[parameters('location')]", + "properties": { } + }, + { + "apiVersion": "2019-08-01", + "type": "Microsoft.Web/sites", + "kind": "api", + "name": "usingSecureMinTls", + "location": "[parameters('location')]", + "properties": { + "siteConfig": { + "minTlsVersion": "1.2" + } + } + }, + { + "apiVersion": "2019-08-01", + "type": "Microsoft.Web/sites", + "kind": "api", + "name": "absentInChildConfigButSecureInParent", + "location": "[parameters('location')]", + "properties": { + "siteConfig": { + "minTlsVersion": "1.2" + } + }, + "resources": [ + { + "apiVersion": "2019-08-01", + "type": "config", + "name": "web", + "dependsOn": [ + "[resourceId('Microsoft.Web/sites/', 'absentInChildConfigButSecureInParent')]" + ], + "properties": { } + } + ] + }, + { + "apiVersion": "2019-08-01", + "type": "Microsoft.Web/sites", + "kind": "api", + "name": "absentInParentButSecureInChildConfig", + "location": "[parameters('location')]", + "properties": { }, + "resources": [ + { + "apiVersion": "2019-08-01", + "type": "config", + "name": "web", + "dependsOn": [ + "[resourceId('Microsoft.Web/sites/', 'absentInParentButSecureInChildConfig')]" + ], + "properties": { + "minTlsVersion": "1.2" + } + } + ] + }, + { + "apiVersion": "2019-08-01", + "type": "Microsoft.Web/sites", + "kind": "api", + "name": "absentInParentButSecureInDependentConfig", + "location": "[parameters('location')]", + "properties": { } + }, + { + "apiVersion": "2019-08-01", + "type": "Microsoft.Web/sites/config", + "name": "absentInParentButSecureInDependentConfig/web", + "kind": "api", + "dependsOn": [ + "[resourceId('Microsoft.Web/sites/', 'absentInParentButSecureInDependentConfig')]" + ], + "properties": { + "minTlsVersion": "1.2" + } + }, + { + "apiVersion": "2019-08-01", + "type": "Microsoft.Web/sites/config", + "name": "absentInParentButSecureInDependentConfig/metadata", + "kind": "api", + "dependsOn": [ + "[resourceId('Microsoft.Web/sites/', 'absentInParentButSecureInDependentConfig')]" + ], + "properties": { } + } + ] +} \ No newline at end of file diff --git a/src/Analyzer.Core.BuiltInRuleTests/Tests/TA-000005/TA-000005.json b/src/Analyzer.Core.BuiltInRuleTests/Tests/TA-000005/TA-000005.json new file mode 100644 index 00000000..acb77fe1 --- /dev/null +++ b/src/Analyzer.Core.BuiltInRuleTests/Tests/TA-000005/TA-000005.json @@ -0,0 +1,81 @@ +[ + { + "Template": "LatestTLS-Failures.json", + "ReportedFailures": [ + { + "LineNumber": 21, + "Description": "Minimum TLS is not set" + }, + { + "LineNumber": 32, + "Description": "Minimum TLS is set to an insecure version" + }, + { + "LineNumber": 43, + "Description": "Minimum TLS is not set in parent or child config (failure in parent)" + }, + { + "LineNumber": 53, + "Description": "Minimum TLS is not set in parent or child config (failure in child config)" + }, + { + "LineNumber": 63, + "Description": "Minimum TLS is not set in parent and is insecure in dependent config (failure in parent)" + }, + { + "LineNumber": 74, + "Description": "Minimum TLS is not set in parent and is insecure in this dependent config (failure in child config)" + }, + { + "LineNumber": 83, + "Description": "Minimum TLS is not set in parent and is missing in dependent config (failure in parent)" + }, + { + "LineNumber": 93, + "Description": "Minimum TLS is not set in parent and is missing in this dependent config (failure in child config)" + }, + { + "LineNumber": 115, + "Description": "Minimum TLS is set to secure version in parent but is set to insecure version in this child config" + }, + { + "LineNumber": 128, + "Description": "Minimum TLS is set to insecure version in parent even though it is set to secure version in child config" + }, + ] + }, + { + "Template": "LatestTLS-Passes.json", + "ReportedFailures": [ ], + "PassingSections": [ + { + "ResourceName": "notApiKind", + "Explanation": "Wrong resource kind" + }, + { + "ResourceName": "usingSecureMinTls", + "Explanation": "Minimum TLS is correctly set to 1.2" + }, + { + "ResourceName": "absentInChildConfigButSecureInParent", + "Explanation": "Minimum TLS is correctly set to 1.2 in the parent, even though it's missing in the child config" + }, + { + "ResourceName": "absentInParentButSecureInChildConfig", + "Explanation": "Minimum TLS is correctly set to 1.2 in the child config, even though it's missing in the parent" + }, + { + "ResourceName": "absentInParentButSecureInDependentConfig", + "Explanation": "Minimum TLS is correctly set to 1.2 in the dependent config, even though it's missing in the parent" + }, + { + "ResourceNames": [ + "absentInParentButSecureInDependentConfig", + "absentInParentButSecureInDependentConfig/web", + "absentInParentButSecureInDependentConfig/metadata" + ], + "Explanation": "Minimum TLS is correctly set to 1.2 in the dependent config, even though it's missing in the parent. It's insecure in 'metadata', but the property is not relevant for that config type." + } + ] + } +] \ No newline at end of file diff --git a/src/Analyzer.Core.BuiltInRuleTests/Tests/TA-000008/RemoteDebugging-Failures.json b/src/Analyzer.Core.BuiltInRuleTests/Tests/TA-000008/RemoteDebugging-Failures.json new file mode 100644 index 00000000..34ce59f8 --- /dev/null +++ b/src/Analyzer.Core.BuiltInRuleTests/Tests/TA-000008/RemoteDebugging-Failures.json @@ -0,0 +1,118 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Location for all resources." + } + } + }, + "resources": [ + { + "apiVersion": "2019-08-01", + "type": "Microsoft.Web/sites", + "kind": "functionapp", + "name": "remoteDebuggingOn", + "location": "[parameters('location')]", + "properties": { + "siteConfig": { + "remoteDebuggingEnabled": true + } + } + }, + { + "apiVersion": "2019-08-01", + "type": "Microsoft.Web/sites", + "kind": "functionapp,linux", + "name": "offInResourceButOnInChildConfig", + "location": "[parameters('location')]", + "properties": { + "siteConfig": { + "remoteDebuggingEnabled": false + } + }, + "resources": [ + { + "apiVersion": "2019-08-01", + "type": "config", + "name": "web", + "dependsOn": [ + "[resourceId('Microsoft.Web/sites/', 'offInResourceButonInChildConfig')]" + ], + "properties": { + "remoteDebuggingEnabled": true + } + } + ] + }, + { + "apiVersion": "2019-08-01", + "type": "Microsoft.Web/sites", + "kind": "functionapp", + "name": "onInResourceButOffInChildConfig", + "location": "[parameters('location')]", + "properties": { + "siteConfig": { + "remoteDebuggingEnabled": true + } + }, + "resources": [ + { + "apiVersion": "2019-08-01", + "type": "config", + "name": "web", + "dependsOn": [ + "[resourceId('Microsoft.Web/sites/', 'offInResourceButonInChildConfig')]" + ], + "properties": { + "remoteDebuggingEnabled": false + } + } + ] + }, + { + "apiVersion": "2019-08-01", + "type": "Microsoft.Web/sites", + "kind": "functionapp,linux", + "name": "onInChildConfig", + "location": "[parameters('location')]", + "properties": { }, + "resources": [ + { + "apiVersion": "2019-08-01", + "type": "config", + "name": "web", + "dependsOn": [ + "[resourceId('Microsoft.Web/sites/', 'onInChildConfig')]" + ], + "properties": { + "remoteDebuggingEnabled": true + } + } + ] + }, + { + "apiVersion": "2019-08-01", + "type": "Microsoft.Web/sites", + "kind": "functionapp", + "name": "onInDependentConfig", + "location": "[parameters('location')]", + "properties": { } + }, + { + "apiVersion": "2019-08-01", + "type": "Microsoft.Web/sites/config", + "name": "onInDependentConfig/web", + "kind": "functionapp,linux", + "dependsOn": [ + "[resourceId('Microsoft.Web/sites/', 'onInDependentConfig')]" + ], + "properties": { + "remoteDebuggingEnabled": true + } + } + ] +} \ No newline at end of file diff --git a/src/Analyzer.Core.BuiltInRuleTests/Tests/TA-000008/RemoteDebugging-Passes.json b/src/Analyzer.Core.BuiltInRuleTests/Tests/TA-000008/RemoteDebugging-Passes.json new file mode 100644 index 00000000..d38b6ae1 --- /dev/null +++ b/src/Analyzer.Core.BuiltInRuleTests/Tests/TA-000008/RemoteDebugging-Passes.json @@ -0,0 +1,119 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Location for all resources." + } + } + }, + "resources": [ + { + "apiVersion": "2019-08-01", + "type": "Microsoft.Web/sites", + "kind": "api", + "name": "notFunctionappKind", + "location": "[parameters('location')]", + "properties": { + } + }, + { + "apiVersion": "2019-08-01", + "type": "Microsoft.Web/sites", + "kind": "functionapp", + "name": "withoutSpecifyingProperties", + "location": "[parameters('location')]", + "properties": { + } + }, + { + "apiVersion": "2019-08-01", + "type": "Microsoft.Web/sites", + "kind": "functionapp,linux", + "name": "remoteDebuggingOff", + "location": "[parameters('location')]", + "properties": { + "siteConfig": { + "remoteDebuggingEnabled": false + } + } + }, + { + "apiVersion": "2019-08-01", + "type": "Microsoft.Web/sites", + "kind": "functionapp", + "name": "absentInChildConfig", + "location": "[parameters('location')]", + "properties": { + "siteConfig": { } + }, + "resources": [ + { + "apiVersion": "2019-08-01", + "type": "config", + "name": "web", + "dependsOn": [ + "[resourceId('Microsoft.Web/sites/', 'offInChildConfig')]" + ], + "properties": { } + } + ] + }, + { + "apiVersion": "2019-08-01", + "type": "Microsoft.Web/sites", + "kind": "functionapp,linux", + "name": "offInChildConfig", + "location": "[parameters('location')]", + "properties": { }, + "resources": [ + { + "apiVersion": "2019-08-01", + "type": "config", + "name": "web", + "dependsOn": [ + "[resourceId('Microsoft.Web/sites/', 'offInChildConfig')]" + ], + "properties": { + "remoteDebuggingEnabled": false + } + } + ] + }, + { + "apiVersion": "2019-08-01", + "type": "Microsoft.Web/sites", + "kind": "functionapp", + "name": "offInDependentConfig", + "location": "[parameters('location')]", + "properties": { } + }, + { + "apiVersion": "2019-08-01", + "type": "Microsoft.Web/sites/config", + "name": "offInDependentConfig/web", + "kind": "functionapp,linux", + "dependsOn": [ + "[resourceId('Microsoft.Web/sites/', 'offInDependentConfig')]" + ], + "properties": { + "remoteDebuggingEnabled": false + } + }, + { + "apiVersion": "2019-08-01", + "type": "Microsoft.Web/sites/config", + "name": "offInDependentConfig/metadata", + "kind": "functionapp", + "dependsOn": [ + "[resourceId('Microsoft.Web/sites/', 'offInDependentConfig')]" + ], + "properties": { + "remoteDebuggingEnabled": true + } + }, + ] +} \ No newline at end of file diff --git a/src/Analyzer.Core.BuiltInRuleTests/Tests/TA-000008/TA-000008.json b/src/Analyzer.Core.BuiltInRuleTests/Tests/TA-000008/TA-000008.json new file mode 100644 index 00000000..a3d3d72a --- /dev/null +++ b/src/Analyzer.Core.BuiltInRuleTests/Tests/TA-000008/TA-000008.json @@ -0,0 +1,61 @@ +[ + { + "Template": "RemoteDebugging-Failures.json", + "ReportedFailures": [ + { + "LineNumber": 22, + "Description": "remoteDebuggingEnabled set to true in resource" + }, + { + "LineNumber": 46, + "Description": "remoteDebuggingEnabled set to true in child config (even though it's false in parent resource)" + }, + { + "LineNumber": 59, + "Description": "remoteDebuggingEnabled set to true in resource (even though it's false in child config)" + }, + { + "LineNumber": 92, + "Description": "remoteDebuggingEnabled set to true in child config" + }, + { + "LineNumber": 114, + "Description": "remoteDebuggingEnabled set to true in dependent config" + } + ] + }, + { + "Template": "RemoteDebugging-Passes.json", + "ReportedFailures": [ ], + "PassingSections": [ + { + "ResourceName": "notFunctionappKind", + "Explanation": "Wrong resource kind" + }, + { + "ResourceName": "withoutSpecifyingProperties", + "Explanation": "remoteDebuggingEnabled is not defined" + }, + { + "ResourceName": "remoteDebuggingOff", + "Explanation": "remoteDebuggingEnabled is false" + }, + { + "ResourceName": "absentInChildConfig", + "Explanation": "remoteDebuggingEnabled not defined in web app or in child web app config" + }, + { + "ResourceName": "offInChildConfig", + "Explanation": "remoteDebuggingEnabled is false in a child config" + }, + { + "ResourceNames": [ + "offInDependentConfig", + "offInDependentConfig/web", + "offInDependentConfig/metadata" + ], + "Explanation": "remoteDebuggingEnabled is false in a dependent config. Config with name 'metadata' is not the right config type for this property, so it being defined with 'true' has no effect." + } + ] + } +] \ No newline at end of file diff --git a/src/Analyzer.Core.BuiltInRuleTests/Tests/TA-000011/LatestTLS-Failures.json b/src/Analyzer.Core.BuiltInRuleTests/Tests/TA-000011/LatestTLS-Failures.json new file mode 100644 index 00000000..0096692c --- /dev/null +++ b/src/Analyzer.Core.BuiltInRuleTests/Tests/TA-000011/LatestTLS-Failures.json @@ -0,0 +1,146 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Location for all resources." + } + } + }, + "resources": [ + { + "apiVersion": "2019-08-01", + "type": "Microsoft.Web/sites", + "kind": "functionapp", + "name": "tlsNotSet", + "location": "[parameters('location')]", + "properties": { + "siteConfig": { } + } + }, + { + "apiVersion": "2019-08-01", + "type": "Microsoft.Web/sites", + "kind": "functionapp,linux", + "name": "DisallowedTlsVersion", + "location": "[parameters('location')]", + "properties": { + "siteConfig": { + "minTlsVersion": "1.1" + } + } + }, + { + "apiVersion": "2019-08-01", + "type": "Microsoft.Web/sites", + "kind": "functionapp", + "name": "minTlsMissingInResourceAndInChildConfig", + "location": "[parameters('location')]", + "properties": { + "siteConfig": { } + }, + "resources": [ + { + "apiVersion": "2019-08-01", + "type": "config", + "name": "web", + "dependsOn": [ + "[resourceId('Microsoft.Web/sites/', 'minTlsMissingInResourceAndInChildConfig')]" + ], + "properties": { } + } + ] + }, + { + "apiVersion": "2019-08-01", + "type": "Microsoft.Web/sites", + "kind": "functionapp,linux", + "name": "insecureInDependentConfig", + "location": "[parameters('location')]", + "properties": { } + }, + { + "apiVersion": "2019-08-01", + "type": "Microsoft.Web/sites/config", + "name": "insecureInDependentConfig/web", + "kind": "functionapp,linux", + "dependsOn": [ + "[resourceId('Microsoft.Web/sites/', 'insecureInDependentConfig')]" + ], + "properties": { + "minTlsVersion": "1.0" + } + }, + { + "apiVersion": "2019-08-01", + "type": "Microsoft.Web/sites", + "kind": "functionapp", + "name": "missingInDependentConfig", + "location": "[parameters('location')]", + "properties": { } + }, + { + "apiVersion": "2019-08-01", + "type": "Microsoft.Web/sites/config", + "name": "missingInDependentConfig/web", + "kind": "functionapp", + "dependsOn": [ + "[resourceId('Microsoft.Web/sites/', 'missingInDependentConfig')]" + ], + "properties": { } + }, + { + "apiVersion": "2019-08-01", + "type": "Microsoft.Web/sites", + "kind": "functionapp,linux", + "name": "secureInParentButInsecureInChildConfig", + "location": "[parameters('location')]", + "properties": { + "siteConfig": { + "minTlsVersion": "1.2" + } + }, + "resources": [ + { + "apiVersion": "2019-08-01", + "type": "config", + "name": "web", + "dependsOn": [ + "[resourceId('Microsoft.Web/sites/', 'secureInParentButInsecureInChildConfig')]" + ], + "properties": { + "minTlsVersion": "1.1" + } + } + ] + }, + { + "apiVersion": "2019-08-01", + "type": "Microsoft.Web/sites", + "kind": "functionapp,linux", + "name": "insecureInParentButSecureInChild", + "location": "[parameters('location')]", + "properties": { + "siteConfig": { + "minTlsVersion": "1.1" + } + }, + "resources": [ + { + "apiVersion": "2019-08-01", + "type": "config", + "name": "web", + "dependsOn": [ + "[resourceId('Microsoft.Web/sites/', 'insecureInParentButSecureInChild')]" + ], + "properties": { + "minTlsVersion": "1.2" + } + } + ] + } + ] +} \ No newline at end of file diff --git a/src/Analyzer.Core.BuiltInRuleTests/Tests/TA-000011/LatestTLS-Passes.json b/src/Analyzer.Core.BuiltInRuleTests/Tests/TA-000011/LatestTLS-Passes.json new file mode 100644 index 00000000..fdf7dda1 --- /dev/null +++ b/src/Analyzer.Core.BuiltInRuleTests/Tests/TA-000011/LatestTLS-Passes.json @@ -0,0 +1,109 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Location for all resources." + } + } + }, + "resources": [ + { + "apiVersion": "2019-08-01", + "type": "Microsoft.Web/sites", + "kind": "api", + "name": "notFunctionAppKind", + "location": "[parameters('location')]", + "properties": { } + }, + { + "apiVersion": "2019-08-01", + "type": "Microsoft.Web/sites", + "kind": "functionapp", + "name": "usingSecureMinTls", + "location": "[parameters('location')]", + "properties": { + "siteConfig": { + "minTlsVersion": "1.2" + } + } + }, + { + "apiVersion": "2019-08-01", + "type": "Microsoft.Web/sites", + "kind": "functionapp,linux", + "name": "absentInChildConfigButSecureInParent", + "location": "[parameters('location')]", + "properties": { + "siteConfig": { + "minTlsVersion": "1.2" + } + }, + "resources": [ + { + "apiVersion": "2019-08-01", + "type": "config", + "name": "web", + "dependsOn": [ + "[resourceId('Microsoft.Web/sites/', 'absentInChildConfigButSecureInParent')]" + ], + "properties": { } + } + ] + }, + { + "apiVersion": "2019-08-01", + "type": "Microsoft.Web/sites", + "kind": "functionapp", + "name": "absentInParentButSecureInChildConfig", + "location": "[parameters('location')]", + "properties": { }, + "resources": [ + { + "apiVersion": "2019-08-01", + "type": "config", + "name": "web", + "dependsOn": [ + "[resourceId('Microsoft.Web/sites/', 'absentInParentButSecureInChildConfig')]" + ], + "properties": { + "minTlsVersion": "1.2" + } + } + ] + }, + { + "apiVersion": "2019-08-01", + "type": "Microsoft.Web/sites", + "kind": "functionapp,linux", + "name": "absentInParentButSecureInDependentConfig", + "location": "[parameters('location')]", + "properties": { } + }, + { + "apiVersion": "2019-08-01", + "type": "Microsoft.Web/sites/config", + "name": "absentInParentButSecureInDependentConfig/web", + "kind": "functionapp", + "dependsOn": [ + "[resourceId('Microsoft.Web/sites/', 'absentInParentButSecureInDependentConfig')]" + ], + "properties": { + "minTlsVersion": "1.2" + } + }, + { + "apiVersion": "2019-08-01", + "type": "Microsoft.Web/sites/config", + "name": "absentInParentButSecureInDependentConfig/metadata", + "kind": "functionapp", + "dependsOn": [ + "[resourceId('Microsoft.Web/sites/', 'absentInParentButSecureInDependentConfig')]" + ], + "properties": { } + } + ] +} \ No newline at end of file diff --git a/src/Analyzer.Core.BuiltInRuleTests/Tests/TA-000011/TA-000011.json b/src/Analyzer.Core.BuiltInRuleTests/Tests/TA-000011/TA-000011.json new file mode 100644 index 00000000..b7fd4218 --- /dev/null +++ b/src/Analyzer.Core.BuiltInRuleTests/Tests/TA-000011/TA-000011.json @@ -0,0 +1,81 @@ +[ + { + "Template": "LatestTLS-Failures.json", + "ReportedFailures": [ + { + "LineNumber": 21, + "Description": "Minimum TLS is not set" + }, + { + "LineNumber": 32, + "Description": "Minimum TLS is set to an insecure version" + }, + { + "LineNumber": 43, + "Description": "Minimum TLS is not set in parent or child config (failure in parent)" + }, + { + "LineNumber": 53, + "Description": "Minimum TLS is not set in parent or child config (failure in child config)" + }, + { + "LineNumber": 63, + "Description": "Minimum TLS is not set in parent and is insecure in dependent config (failure in parent)" + }, + { + "LineNumber": 74, + "Description": "Minimum TLS is not set in parent and is insecure in this dependent config (failure in child config)" + }, + { + "LineNumber": 83, + "Description": "Minimum TLS is not set in parent and is missing in dependent config (failure in parent)" + }, + { + "LineNumber": 93, + "Description": "Minimum TLS is not set in parent and is missing in this dependent config (failure in child config)" + }, + { + "LineNumber": 115, + "Description": "Minimum TLS is set to secure version in parent but is set to insecure version in this child config" + }, + { + "LineNumber": 128, + "Description": "Minimum TLS is set to insecure version in parent even though it is set to secure version in child config" + }, + ] + }, + { + "Template": "LatestTLS-Passes.json", + "ReportedFailures": [ ], + "PassingSections": [ + { + "ResourceName": "notFunctionAppKind", + "Explanation": "Wrong resource kind" + }, + { + "ResourceName": "usingSecureMinTls", + "Explanation": "Minimum TLS is correctly set to 1.2" + }, + { + "ResourceName": "absentInChildConfigButSecureInParent", + "Explanation": "Minimum TLS is correctly set to 1.2 in the parent, even though it's missing in the child config" + }, + { + "ResourceName": "absentInParentButSecureInChildConfig", + "Explanation": "Minimum TLS is correctly set to 1.2 in the child config, even though it's missing in the parent" + }, + { + "ResourceName": "absentInParentButSecureInDependentConfig", + "Explanation": "Minimum TLS is correctly set to 1.2 in the dependent config, even though it's missing in the parent" + }, + { + "ResourceNames": [ + "absentInParentButSecureInDependentConfig", + "absentInParentButSecureInDependentConfig/web", + "absentInParentButSecureInDependentConfig/metadata" + ], + "Explanation": "Minimum TLS is correctly set to 1.2 in the dependent config, even though it's missing in the parent. It's insecure in 'metadata', but the property is not relevant for that config type." + } + ] + } +] \ No newline at end of file diff --git a/src/Analyzer.Core.BuiltInRuleTests/Tests/TA-000014/RemoteDebugging-Failures.json b/src/Analyzer.Core.BuiltInRuleTests/Tests/TA-000014/RemoteDebugging-Failures.json new file mode 100644 index 00000000..cb8d9246 --- /dev/null +++ b/src/Analyzer.Core.BuiltInRuleTests/Tests/TA-000014/RemoteDebugging-Failures.json @@ -0,0 +1,117 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Location for all resources." + } + } + }, + "resources": [ + { + "apiVersion": "2019-08-01", + "type": "Microsoft.Web/sites", + "kind": "app", + "name": "remoteDebuggingOn", + "location": "[parameters('location')]", + "properties": { + "siteConfig": { + "remoteDebuggingEnabled": true + } + } + }, + { + "apiVersion": "2019-08-01", + "type": "Microsoft.Web/sites", + "kind": "app,linux", + "name": "offInResourceButOnInChildConfig", + "location": "[parameters('location')]", + "properties": { + "siteConfig": { + "remoteDebuggingEnabled": false + } + }, + "resources": [ + { + "apiVersion": "2019-08-01", + "type": "config", + "name": "web", + "dependsOn": [ + "[resourceId('Microsoft.Web/sites/', 'offInResourceButonInChildConfig')]" + ], + "properties": { + "remoteDebuggingEnabled": true + } + } + ] + }, + { + "apiVersion": "2019-08-01", + "type": "Microsoft.Web/sites", + "name": "onInResourceButOffInChildConfig", + "location": "[parameters('location')]", + "properties": { + "siteConfig": { + "remoteDebuggingEnabled": true + } + }, + "resources": [ + { + "apiVersion": "2019-08-01", + "type": "config", + "name": "web", + "dependsOn": [ + "[resourceId('Microsoft.Web/sites/', 'offInResourceButonInChildConfig')]" + ], + "properties": { + "remoteDebuggingEnabled": false + } + } + ] + }, + { + "apiVersion": "2019-08-01", + "type": "Microsoft.Web/sites", + "kind": "app", + "name": "onInChildConfig", + "location": "[parameters('location')]", + "properties": { }, + "resources": [ + { + "apiVersion": "2019-08-01", + "type": "config", + "name": "web", + "dependsOn": [ + "[resourceId('Microsoft.Web/sites/', 'onInChildConfig')]" + ], + "properties": { + "remoteDebuggingEnabled": true + } + } + ] + }, + { + "apiVersion": "2019-08-01", + "type": "Microsoft.Web/sites", + "kind": "app,linux", + "name": "onInDependentConfig", + "location": "[parameters('location')]", + "properties": { } + }, + { + "apiVersion": "2019-08-01", + "type": "Microsoft.Web/sites/config", + "name": "onInDependentConfig/web", + "kind": "app,linux", + "dependsOn": [ + "[resourceId('Microsoft.Web/sites/', 'onInDependentConfig')]" + ], + "properties": { + "remoteDebuggingEnabled": true + } + } + ] +} \ No newline at end of file diff --git a/src/Analyzer.Core.BuiltInRuleTests/Tests/TA-000014/RemoteDebugging-Passes.json b/src/Analyzer.Core.BuiltInRuleTests/Tests/TA-000014/RemoteDebugging-Passes.json new file mode 100644 index 00000000..5eaf252f --- /dev/null +++ b/src/Analyzer.Core.BuiltInRuleTests/Tests/TA-000014/RemoteDebugging-Passes.json @@ -0,0 +1,119 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Location for all resources." + } + } + }, + "resources": [ + { + "apiVersion": "2019-08-01", + "type": "Microsoft.Web/sites", + "kind": "api", + "name": "notAppKind", + "location": "[parameters('location')]", + "properties": { + } + }, + { + "apiVersion": "2019-08-01", + "type": "Microsoft.Web/sites", + "kind": "app", + "name": "withoutSpecifyingProperties", + "location": "[parameters('location')]", + "properties": { + } + }, + { + "apiVersion": "2019-08-01", + "type": "Microsoft.Web/sites", + "kind": "app,linux", + "name": "remoteDebuggingOff", + "location": "[parameters('location')]", + "properties": { + "siteConfig": { + "remoteDebuggingEnabled": false + } + } + }, + { + "apiVersion": "2019-08-01", + "type": "Microsoft.Web/sites", + "kind": "app", + "name": "absentInChildConfig", + "location": "[parameters('location')]", + "properties": { + "siteConfig": { } + }, + "resources": [ + { + "apiVersion": "2019-08-01", + "type": "config", + "name": "web", + "dependsOn": [ + "[resourceId('Microsoft.Web/sites/', 'offInChildConfig')]" + ], + "properties": { } + } + ] + }, + { + "apiVersion": "2019-08-01", + "type": "Microsoft.Web/sites", + "kind": "app,linux", + "name": "offInChildConfig", + "location": "[parameters('location')]", + "properties": { }, + "resources": [ + { + "apiVersion": "2019-08-01", + "type": "config", + "name": "web", + "dependsOn": [ + "[resourceId('Microsoft.Web/sites/', 'offInChildConfig')]" + ], + "properties": { + "remoteDebuggingEnabled": false + } + } + ] + }, + { + "apiVersion": "2019-08-01", + "type": "Microsoft.Web/sites", + "kind": "app", + "name": "offInDependentConfig", + "location": "[parameters('location')]", + "properties": { } + }, + { + "apiVersion": "2019-08-01", + "type": "Microsoft.Web/sites/config", + "name": "offInDependentConfig/web", + "kind": "app,linux", + "dependsOn": [ + "[resourceId('Microsoft.Web/sites/', 'offInDependentConfig')]" + ], + "properties": { + "remoteDebuggingEnabled": false + } + }, + { + "apiVersion": "2019-08-01", + "type": "Microsoft.Web/sites/config", + "name": "offInDependentConfig/metadata", + "kind": "app", + "dependsOn": [ + "[resourceId('Microsoft.Web/sites/', 'offInDependentConfig')]" + ], + "properties": { + "remoteDebuggingEnabled": true + } + }, + ] +} \ No newline at end of file diff --git a/src/Analyzer.Core.BuiltInRuleTests/Tests/TA-000014/TA-000014.json b/src/Analyzer.Core.BuiltInRuleTests/Tests/TA-000014/TA-000014.json new file mode 100644 index 00000000..947148bb --- /dev/null +++ b/src/Analyzer.Core.BuiltInRuleTests/Tests/TA-000014/TA-000014.json @@ -0,0 +1,61 @@ +[ + { + "Template": "RemoteDebugging-Failures.json", + "ReportedFailures": [ + { + "LineNumber": 22, + "Description": "remoteDebuggingEnabled set to true in resource" + }, + { + "LineNumber": 46, + "Description": "remoteDebuggingEnabled set to true in child config (even though it's false in parent resource)" + }, + { + "LineNumber": 58, + "Description": "remoteDebuggingEnabled set to true in resource (even though it's false in child config)" + }, + { + "LineNumber": 91, + "Description": "remoteDebuggingEnabled set to true in child config" + }, + { + "LineNumber": 113, + "Description": "remoteDebuggingEnabled set to true in dependent config" + } + ] + }, + { + "Template": "RemoteDebugging-Passes.json", + "ReportedFailures": [ ], + "PassingSections": [ + { + "ResourceName": "notAppKind", + "Explanation": "Wrong resource kind" + }, + { + "ResourceName": "withoutSpecifyingProperties", + "Explanation": "remoteDebuggingEnabled is not defined" + }, + { + "ResourceName": "remoteDebuggingOff", + "Explanation": "remoteDebuggingEnabled is false" + }, + { + "ResourceName": "absentInChildConfig", + "Explanation": "remoteDebuggingEnabled not defined in web app or in child web app config" + }, + { + "ResourceName": "offInChildConfig", + "Explanation": "remoteDebuggingEnabled is false in a child config" + }, + { + "ResourceNames": [ + "offInDependentConfig", + "offInDependentConfig/web", + "offInDependentConfig/metadata" + ], + "Explanation": "remoteDebuggingEnabled is false in a dependent config. Config with name 'metadata' is not the right config type for this property, so it being defined with 'true' has no effect." + } + ] + } +] \ No newline at end of file diff --git a/src/Analyzer.Core.BuiltInRuleTests/Tests/TA-000017/LatestTLS-Failures.json b/src/Analyzer.Core.BuiltInRuleTests/Tests/TA-000017/LatestTLS-Failures.json new file mode 100644 index 00000000..7f819117 --- /dev/null +++ b/src/Analyzer.Core.BuiltInRuleTests/Tests/TA-000017/LatestTLS-Failures.json @@ -0,0 +1,144 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Location for all resources." + } + } + }, + "resources": [ + { + "apiVersion": "2019-08-01", + "type": "Microsoft.Web/sites", + "kind": "app", + "name": "tlsNotSet", + "location": "[parameters('location')]", + "properties": { + "siteConfig": { } + } + }, + { + "apiVersion": "2019-08-01", + "type": "Microsoft.Web/sites", + "kind": "app,linux", + "name": "DisallowedTlsVersion", + "location": "[parameters('location')]", + "properties": { + "siteConfig": { + "minTlsVersion": "1.1" + } + } + }, + { + "apiVersion": "2019-08-01", + "type": "Microsoft.Web/sites", + "name": "minTlsMissingInResourceAndInChildConfig", + "location": "[parameters('location')]", + "properties": { + "siteConfig": { } + }, + "resources": [ + { + "apiVersion": "2019-08-01", + "type": "config", + "name": "web", + "dependsOn": [ + "[resourceId('Microsoft.Web/sites/', 'minTlsMissingInResourceAndInChildConfig')]" + ], + "properties": { } + } + ] + }, + { + "apiVersion": "2019-08-01", + "type": "Microsoft.Web/sites", + "kind": "app", + "name": "insecureInDependentConfig", + "location": "[parameters('location')]", + "properties": { } + }, + { + "apiVersion": "2019-08-01", + "type": "Microsoft.Web/sites/config", + "name": "insecureInDependentConfig/web", + "kind": "app", + "dependsOn": [ + "[resourceId('Microsoft.Web/sites/', 'insecureInDependentConfig')]" + ], + "properties": { + "minTlsVersion": "1.0" + } + }, + { + "apiVersion": "2019-08-01", + "type": "Microsoft.Web/sites", + "kind": "app,linux", + "name": "missingInDependentConfig", + "location": "[parameters('location')]", + "properties": { } + }, + { + "apiVersion": "2019-08-01", + "type": "Microsoft.Web/sites/config", + "name": "missingInDependentConfig/web", + "kind": "app,linux", + "dependsOn": [ + "[resourceId('Microsoft.Web/sites/', 'missingInDependentConfig')]" + ], + "properties": { } + }, + { + "apiVersion": "2019-08-01", + "type": "Microsoft.Web/sites", + "name": "secureInParentButInsecureInChildConfig", + "location": "[parameters('location')]", + "properties": { + "siteConfig": { + "minTlsVersion": "1.2" + } + }, + "resources": [ + { + "apiVersion": "2019-08-01", + "type": "config", + "name": "web", + "dependsOn": [ + "[resourceId('Microsoft.Web/sites/', 'secureInParentButInsecureInChildConfig')]" + ], + "properties": { + "minTlsVersion": "1.1" + } + } + ] + }, + { + "apiVersion": "2019-08-01", + "type": "Microsoft.Web/sites", + "kind": "app", + "name": "insecureInParentButSecureInChild", + "location": "[parameters('location')]", + "properties": { + "siteConfig": { + "minTlsVersion": "1.1" + } + }, + "resources": [ + { + "apiVersion": "2019-08-01", + "type": "config", + "name": "web", + "dependsOn": [ + "[resourceId('Microsoft.Web/sites/', 'insecureInParentButSecureInChild')]" + ], + "properties": { + "minTlsVersion": "1.2" + } + } + ] + } + ] +} \ No newline at end of file diff --git a/src/Analyzer.Core.BuiltInRuleTests/Tests/TA-000017/LatestTLS-Passes.json b/src/Analyzer.Core.BuiltInRuleTests/Tests/TA-000017/LatestTLS-Passes.json new file mode 100644 index 00000000..c89ef713 --- /dev/null +++ b/src/Analyzer.Core.BuiltInRuleTests/Tests/TA-000017/LatestTLS-Passes.json @@ -0,0 +1,108 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Location for all resources." + } + } + }, + "resources": [ + { + "apiVersion": "2019-08-01", + "type": "Microsoft.Web/sites", + "kind": "api", + "name": "notAppKind", + "location": "[parameters('location')]", + "properties": { } + }, + { + "apiVersion": "2019-08-01", + "type": "Microsoft.Web/sites", + "kind": "app", + "name": "usingSecureMinTls", + "location": "[parameters('location')]", + "properties": { + "siteConfig": { + "minTlsVersion": "1.2" + } + } + }, + { + "apiVersion": "2019-08-01", + "type": "Microsoft.Web/sites", + "kind": "app,linux", + "name": "absentInChildConfigButSecureInParent", + "location": "[parameters('location')]", + "properties": { + "siteConfig": { + "minTlsVersion": "1.2" + } + }, + "resources": [ + { + "apiVersion": "2019-08-01", + "type": "config", + "name": "web", + "dependsOn": [ + "[resourceId('Microsoft.Web/sites/', 'absentInChildConfigButSecureInParent')]" + ], + "properties": { } + } + ] + }, + { + "apiVersion": "2019-08-01", + "type": "Microsoft.Web/sites", + "name": "absentInParentButSecureInChildConfig", + "location": "[parameters('location')]", + "properties": { }, + "resources": [ + { + "apiVersion": "2019-08-01", + "type": "config", + "name": "web", + "dependsOn": [ + "[resourceId('Microsoft.Web/sites/', 'absentInParentButSecureInChildConfig')]" + ], + "properties": { + "minTlsVersion": "1.2" + } + } + ] + }, + { + "apiVersion": "2019-08-01", + "type": "Microsoft.Web/sites", + "kind": "app", + "name": "absentInParentButSecureInDependentConfig", + "location": "[parameters('location')]", + "properties": { } + }, + { + "apiVersion": "2019-08-01", + "type": "Microsoft.Web/sites/config", + "name": "absentInParentButSecureInDependentConfig/web", + "kind": "app", + "dependsOn": [ + "[resourceId('Microsoft.Web/sites/', 'absentInParentButSecureInDependentConfig')]" + ], + "properties": { + "minTlsVersion": "1.2" + } + }, + { + "apiVersion": "2019-08-01", + "type": "Microsoft.Web/sites/config", + "name": "absentInParentButSecureInDependentConfig/metadata", + "kind": "app", + "dependsOn": [ + "[resourceId('Microsoft.Web/sites/', 'absentInParentButSecureInDependentConfig')]" + ], + "properties": { } + } + ] +} \ No newline at end of file diff --git a/src/Analyzer.Core.BuiltInRuleTests/Tests/TA-000017/TA-000017.json b/src/Analyzer.Core.BuiltInRuleTests/Tests/TA-000017/TA-000017.json new file mode 100644 index 00000000..1dc544fc --- /dev/null +++ b/src/Analyzer.Core.BuiltInRuleTests/Tests/TA-000017/TA-000017.json @@ -0,0 +1,81 @@ +[ + { + "Template": "LatestTLS-Failures.json", + "ReportedFailures": [ + { + "LineNumber": 21, + "Description": "Minimum TLS is not set" + }, + { + "LineNumber": 32, + "Description": "Minimum TLS is set to an insecure version" + }, + { + "LineNumber": 42, + "Description": "Minimum TLS is not set in parent or child config (failure in parent)" + }, + { + "LineNumber": 52, + "Description": "Minimum TLS is not set in parent or child config (failure in child config)" + }, + { + "LineNumber": 62, + "Description": "Minimum TLS is not set in parent and is insecure in dependent config (failure in parent)" + }, + { + "LineNumber": 73, + "Description": "Minimum TLS is not set in parent and is insecure in this dependent config (failure in child config)" + }, + { + "LineNumber": 82, + "Description": "Minimum TLS is not set in parent and is missing in dependent config (failure in parent)" + }, + { + "LineNumber": 92, + "Description": "Minimum TLS is not set in parent and is missing in this dependent config (failure in child config)" + }, + { + "LineNumber": 113, + "Description": "Minimum TLS is set to secure version in parent but is set to insecure version in this child config" + }, + { + "LineNumber": 126, + "Description": "Minimum TLS is set to insecure version in parent even though it is set to secure version in child config" + }, + ] + }, + { + "Template": "LatestTLS-Passes.json", + "ReportedFailures": [ ], + "PassingSections": [ + { + "ResourceName": "notAppKind", + "Explanation": "Wrong resource kind" + }, + { + "ResourceName": "usingSecureMinTls", + "Explanation": "Minimum TLS is correctly set to 1.2" + }, + { + "ResourceName": "absentInChildConfigButSecureInParent", + "Explanation": "Minimum TLS is correctly set to 1.2 in the parent, even though it's missing in the child config" + }, + { + "ResourceName": "absentInParentButSecureInChildConfig", + "Explanation": "Minimum TLS is correctly set to 1.2 in the child config, even though it's missing in the parent" + }, + { + "ResourceName": "absentInParentButSecureInDependentConfig", + "Explanation": "Minimum TLS is correctly set to 1.2 in the dependent config, even though it's missing in the parent" + }, + { + "ResourceNames": [ + "absentInParentButSecureInDependentConfig", + "absentInParentButSecureInDependentConfig/web", + "absentInParentButSecureInDependentConfig/metadata" + ], + "Explanation": "Minimum TLS is correctly set to 1.2 in the dependent config, even though it's missing in the parent. It's insecure in 'metadata', but the property is not relevant for that config type." + } + ] + } +] \ No newline at end of file diff --git a/src/Analyzer.Core.BuiltInRuleTests/Tests/TA-000023/TA-000023.json b/src/Analyzer.Core.BuiltInRuleTests/Tests/TA-000023/TA-000023.json index 69097394..18f5f97a 100644 --- a/src/Analyzer.Core.BuiltInRuleTests/Tests/TA-000023/TA-000023.json +++ b/src/Analyzer.Core.BuiltInRuleTests/Tests/TA-000023/TA-000023.json @@ -4,11 +4,7 @@ "ReportedFailures": [ { "LineNumber": 42, - "Description": "authorizedIPRanges is not given a value" - }, - { - "LineNumber": 42, - "Description": "enablePrivateCluster is not given a value" + "Description": "authorizedIPRanges and enablePrivateCluster are not given a value" }, { "LineNumber": 62, diff --git a/src/Analyzer.Core/Rules/BuiltInRules.json b/src/Analyzer.Core/Rules/BuiltInRules.json index 7c7b757d..ef66465c 100644 --- a/src/Analyzer.Core/Rules/BuiltInRules.json +++ b/src/Analyzer.Core/Rules/BuiltInRules.json @@ -146,15 +146,32 @@ "path": "kind", "regex": "api$" }, - "anyOf": [ + "allOf": [ + { + "not": { + "path": "properties.siteConfig.minTlsVersion", + "in": ["1.0", "1.1"] + } + }, { "resourceType": "Microsoft.Web/sites/config", - "path": "properties.minTlsVersion", - "equals": "1.2" + "not": { + "path": "properties.minTlsVersion", + "in": ["1.0", "1.1"] + } }, { - "path": "properties.siteConfig.minTlsVersion", - "equals": "1.2" + "anyOf": [ + { + "resourceType": "Microsoft.Web/sites/config", + "path": "properties.minTlsVersion", + "equals": "1.2" + }, + { + "path": "properties.siteConfig.minTlsVersion", + "equals": "1.2" + } + ] } ] } @@ -305,15 +322,32 @@ "path": "kind", "regex": "^functionapp" }, - "anyOf": [ + "allOf": [ + { + "not": { + "path": "properties.siteConfig.minTlsVersion", + "in": ["1.0", "1.1"] + } + }, { "resourceType": "Microsoft.Web/sites/config", - "path": "properties.minTlsVersion", - "equals": "1.2" + "not": { + "path": "properties.minTlsVersion", + "in": ["1.0", "1.1"] + } }, { - "path": "properties.siteConfig.minTlsVersion", - "equals": "1.2" + "anyOf": [ + { + "resourceType": "Microsoft.Web/sites/config", + "path": "properties.minTlsVersion", + "equals": "1.2" + }, + { + "path": "properties.siteConfig.minTlsVersion", + "equals": "1.2" + } + ] } ] } @@ -496,15 +530,32 @@ } ] }, - "anyOf": [ + "allOf": [ + { + "not": { + "path": "properties.siteConfig.minTlsVersion", + "in": ["1.0", "1.1"] + } + }, { "resourceType": "Microsoft.Web/sites/config", - "path": "properties.minTlsVersion", - "equals": "1.2" + "not": { + "path": "properties.minTlsVersion", + "in": ["1.0", "1.1"] + } }, { - "path": "properties.siteConfig.minTlsVersion", - "equals": "1.2" + "anyOf": [ + { + "resourceType": "Microsoft.Web/sites/config", + "path": "properties.minTlsVersion", + "equals": "1.2" + }, + { + "path": "properties.siteConfig.minTlsVersion", + "equals": "1.2" + } + ] } ] } diff --git a/src/Analyzer.JsonRuleEngine.UnitTests/InOperatorTests.cs b/src/Analyzer.JsonRuleEngine.UnitTests/InOperatorTests.cs index 83093312..b9e8a774 100644 --- a/src/Analyzer.JsonRuleEngine.UnitTests/InOperatorTests.cs +++ b/src/Analyzer.JsonRuleEngine.UnitTests/InOperatorTests.cs @@ -41,7 +41,6 @@ public void EvaluateExpression_ValidDataType_ReturnsExpectedEvaluationResult(boo Assert.AreEqual(!evaluationResult, inOperatorNegated.EvaluateExpression(desiredValueJToken)); } - [TestMethod] public void EvaluateExpression_NullAsTokenToEvaluate_ReturnsFalse() { @@ -52,6 +51,16 @@ public void EvaluateExpression_NullAsTokenToEvaluate_ReturnsFalse() Assert.IsFalse(inOperator.EvaluateExpression(null)); } + [TestMethod] + public void EvaluateExpression_NullAsTokenToEvaluateAndNegated_ReturnsTrue() + { + string[] possibleValues = { "aValue", "anotherValue" }; + var operatorValue = JArray.FromObject(possibleValues); + var inOperator = new InOperator(operatorValue, isNegative: true); + + Assert.IsTrue(inOperator.EvaluateExpression(null)); + } + [TestMethod] public void GetName_ReturnsCorrectName() { diff --git a/src/Analyzer.JsonRuleEngine.UnitTests/RegexOperatorTests.cs b/src/Analyzer.JsonRuleEngine.UnitTests/RegexOperatorTests.cs index 16f2c4da..825253ea 100644 --- a/src/Analyzer.JsonRuleEngine.UnitTests/RegexOperatorTests.cs +++ b/src/Analyzer.JsonRuleEngine.UnitTests/RegexOperatorTests.cs @@ -62,6 +62,13 @@ public void EvaluateExpression_PropertyIsMissing_EvaluationIsFalse() Assert.IsFalse(regexOperator.EvaluateExpression(null)); } + [TestMethod] + public void EvaluateExpression_PropertyIsMissingAndNegated_EvaluationIsTrue() + { + var regexOperator = new RegexOperator("", isNegative: true); + Assert.IsTrue(regexOperator.EvaluateExpression(null)); + } + [TestMethod] [ExpectedException(typeof(System.ArgumentException))] public void EvaluateExpresssion_RegexPatternInvalid_ArgumentExceptionIsThrown() diff --git a/src/Analyzer.JsonRuleEngine/Operators/InOperator.cs b/src/Analyzer.JsonRuleEngine/Operators/InOperator.cs index e22161d7..ff9af448 100644 --- a/src/Analyzer.JsonRuleEngine/Operators/InOperator.cs +++ b/src/Analyzer.JsonRuleEngine/Operators/InOperator.cs @@ -35,7 +35,7 @@ public override bool EvaluateExpression(JToken tokenToEvaluate) { if (tokenToEvaluate == null) { - return false; + return this.IsNegative; } bool tokenMatched = false; diff --git a/src/Analyzer.JsonRuleEngine/Operators/RegexOperator.cs b/src/Analyzer.JsonRuleEngine/Operators/RegexOperator.cs index 3fff2d7e..a4ed1eb4 100644 --- a/src/Analyzer.JsonRuleEngine/Operators/RegexOperator.cs +++ b/src/Analyzer.JsonRuleEngine/Operators/RegexOperator.cs @@ -50,7 +50,7 @@ public override bool EvaluateExpression(JToken tokenToEvaluate) { if (tokenToEvaluate == null || tokenToEvaluate.Type != JTokenType.String) { - return false; + return this.IsNegative; } return regex.IsMatch(tokenToEvaluate.Value()) ^ this.IsNegative;