From d7a9fdc446156cfa0d1ca71db551404c0e9bfb00 Mon Sep 17 00:00:00 2001 From: Eric Jenkins Date: Thu, 17 Sep 2020 16:12:29 -0400 Subject: [PATCH] Increase Code Coverage of PowerSTIG to %75 (#742) * updated tests for increased code cov part 1 * fixed test * update changelog.md * update changelog * tes * reverted change * added VsphereNTPsetting tests * updated checklist test * updated DomainName Function tests * updated powerstig xml tests * added tests for Convertto-PowerSTIGxml and Compare * updated tests * updated webconfig property rule test * updated to convert all STIGS * removed redundant tests * update only select one of each STIG * added all office stigs * reverted some tests * updated tests: * removed dependency for helper files * updated tests * removed example folder * update based on feedback * updated test --- CHANGELOG.md | 1 + Tests/Unit/Module/.tests.header.ps1 | 26 ++- Tests/Unit/Module/AuditSettingRule.tests.ps1 | 31 +++ Tests/Unit/Module/Convert.CommonTests.ps1 | 9 +- .../Module/DnsServerSettingRule.tests.ps1 | 27 +++ Tests/Unit/Module/DocumentRule.tests.ps1 | 17 ++ Tests/Unit/Module/FileContentRule.tests.ps1 | 1 + Tests/Unit/Module/GroupRule.tests.ps1 | 2 - Tests/Unit/Module/HardCodedRule.tests.ps1 | 7 + Tests/Unit/Module/MimeTypeRule.tests.ps1 | 80 ++++++++ Tests/Unit/Module/STIG.Checklist.tests.ps1 | 35 ++++ Tests/Unit/Module/STIG.DomainName.tests.ps1 | 92 +++++++++ Tests/Unit/Module/STIG.PowerStigXml.tests.ps1 | 42 ++++ .../Module/VsphereNtpSettingsRule.tests.ps1 | 38 ++++ .../WebConfigurationPropertyRule.tests.ps1 | 182 +++++++++++++++++- .../Convert/AuditSettingRule.Convert.psm1 | 8 - .../DnsServerRootHintRule.Convert.psm1 | 8 - .../Convert/DocumentRule.Convert.psm1 | 8 - .../Convert/ManualRule.Convert.psm1 | 8 - .../Convert/Methods.ps1 | 8 +- .../VsphereNtpSettingsRule.Convert.psm1 | 2 +- .../StigData/Processed/IISServer-8.5-1.10.xml | 8 +- 22 files changed, 594 insertions(+), 46 deletions(-) create mode 100644 Tests/Unit/Module/STIG.DomainName.tests.ps1 create mode 100644 Tests/Unit/Module/STIG.PowerStigXml.tests.ps1 create mode 100644 Tests/Unit/Module/VsphereNtpSettingsRule.tests.ps1 diff --git a/CHANGELOG.md b/CHANGELOG.md index 76c830b42..7b1a63798 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## [Unreleased] +* Update PowerSTIG to increase code coverage of unit tests: [#737](https://github.com/microsoft/PowerStig/issues/737) * Update PowerSTIG with new SkipRuleSeverity Parameter to skip entire STIG Category/Severity Level(s): [711](https://github.com/microsoft/PowerStig/issues/711) ## [4.5.0] - 2020-09-01 diff --git a/Tests/Unit/Module/.tests.header.ps1 b/Tests/Unit/Module/.tests.header.ps1 index 8bc0326bb..af9bedc4b 100644 --- a/Tests/Unit/Module/.tests.header.ps1 +++ b/Tests/Unit/Module/.tests.header.ps1 @@ -65,6 +65,26 @@ switch ($psStackCommand) . $functionCheckListFile } + 'STIG.DomainName' + { + $functionDomainName = Join-Path -Path $script:moduleRoot -ChildPath '\Module\STIG\Functions.DomainName.ps1' + . $functionDomainName + } + + 'STIG.PowerStigXml' + { + $functionPowerStigXml = Join-Path -Path $script:moduleRoot -ChildPath '\Module\STIG\Convert\Functions.PowerStigXml.ps1' + . $functionPowerStigXml + $functionReport = Join-Path -Path $script:moduleRoot -ChildPath '\Module\STIG\Convert\Functions.Report.ps1' + . $functionReport + $dscResourceData = Join-Path -Path $script:moduleRoot -ChildPath '\Module\STIG\Convert\Data.ps1' + . $dscResourceData + $destinationPath = Join-Path -Path $PSScriptRoot -ChildPath '..\.DynamicClassImport\Rule.ps1' + [void] $setDynamicClassFileParams.Add('DestinationPath', $destinationPath) + [void] $setDynamicClassFileParams.Add('ClassModuleFileName', @('Rule.psm1', 'ConvertFactory.psm1','DocumentRule.Convert.psm1','Stig.psm1')) + } + + 'STIG' { $destinationPath = Join-Path -Path $PSScriptRoot -ChildPath '..\.DynamicClassImport\Convert.Main.ps1' @@ -81,11 +101,15 @@ switch ($psStackCommand) } } -if ($global:moduleName -ne 'STIG.Checklist') +if ($global:moduleName -ne 'STIG.Checklist' -and $global:moduleName -ne 'STIG.DomainName') { Set-DynamicClassFile @setDynamicClassFileParams . $setDynamicClassFileParams.DestinationPath } +else +{ + import-module $script:moduleRoot\Module\Common\Common.psm1 +} <# Several classes check for duplicate rules against a global variable stigSettings. diff --git a/Tests/Unit/Module/AuditSettingRule.tests.ps1 b/Tests/Unit/Module/AuditSettingRule.tests.ps1 index e9f89ab3a..8f945a589 100644 --- a/Tests/Unit/Module/AuditSettingRule.tests.ps1 +++ b/Tests/Unit/Module/AuditSettingRule.tests.ps1 @@ -22,6 +22,37 @@ try Some hardware vendors create a small FAT partition to store troubleshooting and recovery data. No other files must be stored here. This must be documented with the ISSO.' } + @{ + Query = "SELECT * FROM Win32_OperatingSystem" + Property = 'Version' + DesiredValue = '10.0.16299' + Operator = '-le' + OrganizationValueRequired = $false + CheckContent = 'Run "winver.exe". + + If the "About Windows" dialog box does not display: + + "Microsoft Windows Version 1709 (OS Build 16299.0)" + + or greater, this is a finding. + + Note: Microsoft has extended support for previous versions providing critical and important updates for Windows 10 Enterprise. + + Microsoft scheduled end of support dates for current Semi-Annual Channel versions: + v1703 - 8 October 2019 + v1709 - 14 April 2020 + v1803 - 10 November 2020 + v1809 - 13 April 2021 + v1903 - 8 December 2020 + + No preview versions will be used in a production environment. + + Special purpose systems using the Long-Term Servicing Branch\Channel (LTSC\B) may be at following versions which are not a finding: + + v1507 (Build 10240) + v1607 (Build 14393) + v1809 (Build 17763)' + } ) #endregion diff --git a/Tests/Unit/Module/Convert.CommonTests.ps1 b/Tests/Unit/Module/Convert.CommonTests.ps1 index 6355a5fab..6aef84df2 100644 --- a/Tests/Unit/Module/Convert.CommonTests.ps1 +++ b/Tests/Unit/Module/Convert.CommonTests.ps1 @@ -20,6 +20,12 @@ $stigRule = Get-TestStigRule -CheckContent $testRule.CheckContent -ReturnGroupOn # Create an instance of the convert class that is currently being tested $convertedRule = New-Object -TypeName ($global:moduleName + 'Convert') -ArgumentList $stigRule +Describe 'Exception Help' { + It 'Should not Return $null' { + $convertedrule.GetExceptionHelp() | Should -Not -BeNullOrEmpty + } +} + Describe "$($convertedRule.GetType().Name) Class Instance" { # Only run the base class test once if ($count -le 0) @@ -104,7 +110,7 @@ Describe "$($convertedRule.GetType().Name) Class Instance" { $checkContent = [System.Web.HttpUtility]::HtmlDecode( $testRule.checkContent ) # The manual rule is the default and does not contain a match method. - if ($convertedRule.GetType().Name -notmatch 'ManualRuleConvert') + if ($convertedRule.GetType().Name -notmatch 'ManualRuleConvert|GroupRuleConvert') { <# To dynamically call a static method, we have to get the static method @@ -119,3 +125,4 @@ Describe "$($convertedRule.GetType().Name) Class Instance" { } } } + diff --git a/Tests/Unit/Module/DnsServerSettingRule.tests.ps1 b/Tests/Unit/Module/DnsServerSettingRule.tests.ps1 index fff0b011c..d63e55e23 100644 --- a/Tests/Unit/Module/DnsServerSettingRule.tests.ps1 +++ b/Tests/Unit/Module/DnsServerSettingRule.tests.ps1 @@ -23,6 +23,33 @@ try If any option other than "Errors and warnings" or "All events" is selected, this is a finding.' } + @{ + IsExistingRule = $true + PropertyName = 'NoRecursion' + PropertyValue = '$true' + OrganizationValueRequired = $false + CheckContent = 'Note: If the Windows DNS server is in the classified network, this check is Not Applicable. + + Note: In Windows DNS Server, if forwarders are configured, the recursion setting must also be enabled since disabling recursion will disable forwarders. + + If forwarders are not used, recursion must be disabled. In both cases, the use of root hints must be disabled. + + Log on to the DNS server using the Domain Admin or Enterprise Admin account. + + Press Windows Key + R, execute dnsmgmt.msc. + + On the opened DNS Manager snap-in from the left pane, right-click on the server name for the DNS server and select “Properties”. + + Click on the “Forwarders” tab. + + If forwarders are not being used, this is not applicable. + + Review the IP address(es) for the forwarder(s) use. + + If the DNS Server does not forward to another DoD-managed DNS server or to the DoD Enterprise Recursive Services (ERS), this is a finding. + + If the "Use root hints if no forwarders are available" is selected, this is a finding.' + } ) #endregion diff --git a/Tests/Unit/Module/DocumentRule.tests.ps1 b/Tests/Unit/Module/DocumentRule.tests.ps1 index 60505c9ca..2b808bb22 100644 --- a/Tests/Unit/Module/DocumentRule.tests.ps1 +++ b/Tests/Unit/Module/DocumentRule.tests.ps1 @@ -15,6 +15,23 @@ try If unapproved shared accounts exist, this is a finding.' } + @{ + Id = "V-7069" + Severity = "medium" + title = "APPNET0055 CAS and Policy Config File Backups" + Dscresource = "None" + OrganizationValueRequired = $false + CheckContent = 'Ask the System Administrator if all CAS policy and policy configuration files are included in the system backup. If they are not, this is a finding. + + Ask the System Administrator if the policy and configuration files are backed up prior to migration, deployment, and reconfiguration. If they are not, this is a finding. + + Ask the System Administrator for documentation that shows CAS Policy configuration files are backed up as part of a disaster recovery plan. If they have no documentation proving the files are backed up, this is a finding.' + RawString = 'Ask the System Administrator if all CAS policy and policy configuration files are included in the system backup. If they are not, this is a finding. + + Ask the System Administrator if the policy and configuration files are backed up prior to migration, deployment, and reconfiguration. If they are not, this is a finding. + + Ask the System Administrator for documentation that shows CAS Policy configuration files are backed up as part of a disaster recovery plan. If they have no documentation proving the files are backed up, this is a finding.' + } ) #endregion diff --git a/Tests/Unit/Module/FileContentRule.tests.ps1 b/Tests/Unit/Module/FileContentRule.tests.ps1 index 27b63ca4e..eaa2bb2c4 100644 --- a/Tests/Unit/Module/FileContentRule.tests.ps1 +++ b/Tests/Unit/Module/FileContentRule.tests.ps1 @@ -11,6 +11,7 @@ try Key = 'security.default_personal_cert' Value = 'Ask Every Time' ArchiveFile = 'MozillaFirefox' + DscResource = 'ReplaceText' OrganizationValueRequired = $false CheckContent = 'Type "about:config" in the browser address bar. Verify Preference Name "security.default_personal_cert" is set to "Ask Every Time" and is locked to prevent the user from altering. diff --git a/Tests/Unit/Module/GroupRule.tests.ps1 b/Tests/Unit/Module/GroupRule.tests.ps1 index 5df2c32bb..5be2a2c63 100644 --- a/Tests/Unit/Module/GroupRule.tests.ps1 +++ b/Tests/Unit/Module/GroupRule.tests.ps1 @@ -60,9 +60,7 @@ try foreach ($testRule in $testRuleList) { - <# TODO uncomment when ready to parse group rules . $PSScriptRoot\Convert.CommonTests.ps1 - #> } #region Add Custom Tests Here diff --git a/Tests/Unit/Module/HardCodedRule.tests.ps1 b/Tests/Unit/Module/HardCodedRule.tests.ps1 index 708745119..462717209 100644 --- a/Tests/Unit/Module/HardCodedRule.tests.ps1 +++ b/Tests/Unit/Module/HardCodedRule.tests.ps1 @@ -196,6 +196,13 @@ try DscResource = 'xWinEventLog' IsEnabled = 'True' LogName = 'Microsoft-Windows-DnsServer/Analytical' + }, + @{ + RuleType = 'WindowsFeatureRule' + CheckContent = "HardCodedRule(WindowsFeatureRule)@{DscResource = 'WindowsFeature'; Ensure = `$null; Name = 'FeatureName'}" + DscResource = 'WindowsFeature' + Ensure = '' + Name = "FeatureName" } ) diff --git a/Tests/Unit/Module/MimeTypeRule.tests.ps1 b/Tests/Unit/Module/MimeTypeRule.tests.ps1 index 6edbff12e..a8c6cbd46 100644 --- a/Tests/Unit/Module/MimeTypeRule.tests.ps1 +++ b/Tests/Unit/Module/MimeTypeRule.tests.ps1 @@ -27,7 +27,87 @@ try .exe If any OS shell MIME types are configured, this is a finding.' + }, + @{ + Ensure = 'absent' + MimeType = 'application/x-msdownload' + Extension = '.dll' + OrganizationValueRequired = $false + CheckContent = 'Open the IIS 8.5 Manager. + + Click the IIS 8.5 web server name. + + Under IIS, double-click the “MIME Types” icon. + + From the "Group by:" drop-down list, select "Content Type". + + From the list of extensions under "Application", verify MIME types for OS shell program extensions have been removed, to include at a minimum, the following extensions: + + If any OS shell MIME types are configured, this is a finding. + + .dll + + If any OS shell MIME types are configured, this is a finding.' + }, + @{ + Ensure = 'absent' + MimeType = 'application/x-bat' + Extension = '.bat' + OrganizationValueRequired = $false + CheckContent = 'Open the IIS 8.5 Manager. + Click the IIS 8.5 web server name. + + Under IIS, double-click the “MIME Types” icon. + + From the "Group by:" drop-down list, select "Content Type". + + From the list of extensions under "Application", verify MIME types for OS shell program extensions have been removed, to include at a minimum, the following extensions: + + If any OS shell MIME types are configured, this is a finding. + + .bat' + + }, + @{ + Ensure = 'absent' + MimeType = 'application/x-csh' + Extension = '.csh' + OrganizationValueRequired = $false + CheckContent = 'Open the IIS 8.5 Manager. + + Click the IIS 8.5 web server name. + + Under IIS, double-click the “MIME Types” icon. + + From the "Group by:" drop-down list, select "Content Type". + + From the list of extensions under "Application", verify MIME types for OS shell program extensions have been removed, to include at a minimum, the following extensions: + + If any OS shell MIME types are configured, this is a finding. + + .csh' + + }, + @{ + Ensure = $null + MimeType = $null + Extension = '.not' + OrganizationValueRequired = $false + CheckContent = 'Open the IIS 8.5 Manager. + + Click the IIS 8.5 web server name. + + Under IIS, double-click the “MIME Types” icon. + + From the "Group by:" drop-down list, select "Content Type". + + From the list of extensions under "Application", verify MIME types for OS shell program extensions have been something, to include at a minimum, the following extensions: + + If any OS shell MIME types are configured, this is a finding. + + .not' } + ) #endregion diff --git a/Tests/Unit/Module/STIG.Checklist.tests.ps1 b/Tests/Unit/Module/STIG.Checklist.tests.ps1 index b79598bda..2cafd0e0d 100644 --- a/Tests/Unit/Module/STIG.Checklist.tests.ps1 +++ b/Tests/Unit/Module/STIG.Checklist.tests.ps1 @@ -3,6 +3,32 @@ #endregion Describe 'New-StigCheckList' { + + configuration Example + { + param + ( + [parameter()] + [string] + $NodeName = "localhost" + ) + + Import-DscResource -ModuleName PowerStig + + Node $NodeName + { + WindowsServer BaseLine + { + OsVersion = "2019" + OsRole = "MS" + SkipRuleType = "AccountPolicyRule","AuditPolicyRule","AuditSettingRule","DocumentRule","ManualRule","PermissionRule","SecurityOptionRule","UserRightRule","WindowsFeatureRule","ProcessMitigationRule","RegistryRule" + } + } + } + Example -OutputPath $TestDrive + + $mofTest = '{0}{1}' -f $TestDrive.fullname,"\localhost.mof" + # Test parameter validity -OutputPath It 'Should throw if an invalid path is provided' { {New-StigCheckList -MofFile 'test' -XccdfPath 'test' -OutputPath 'c:\asdf'} | Should -Throw @@ -25,5 +51,14 @@ Describe 'New-StigCheckList' { It 'Should throw if an invalid combination of parameters for Xccdf validation is provided' { {New-StigCheckList -DscResult 'foo' -MofFile 'bar' -OutputPath 'C:\Test'} | Should -Throw } + + It 'Generate a checklist given correct parameters' { + + { + $outputPath = Join-Path $Testdrive -ChildPath Checklist.ckl + $xccdfPath = ((Get-ChildItem -Path $script:moduleRoot\StigData\Archive -Include *xccdf.xml -Recurse | Where-Object -Property Name -Match "Server_2019_MS")[1]).FullName + New-StigChecklist -ReferenceConfiguration $mofTest -XccdfPath $xccdfPath -OutputPath $outputPath + } | Should -Not -Throw + } } diff --git a/Tests/Unit/Module/STIG.DomainName.tests.ps1 b/Tests/Unit/Module/STIG.DomainName.tests.ps1 new file mode 100644 index 000000000..43b51eed9 --- /dev/null +++ b/Tests/Unit/Module/STIG.DomainName.tests.ps1 @@ -0,0 +1,92 @@ +#region Header +. $PSScriptRoot\.tests.header.ps1 +#endregion + +$domainName = 'Domain.test' +$forestName = 'Forest.test' +$domainDistinguished = "DC={0},DC={1}" -f $domainName.Split(".") +$forestDistinguished = "DC={0},DC={1}" -f $forestName.Split(".") +$domainDistinguishedPart1 = "DC=Domain" +$domainDistinguishedPart2 = "DC=Domain,DC=Test" +$parts = @("Domain","Test") + +Describe 'Get-DomainName' { + # Test parameter validity -OutputPath + It 'Should return Domain FQDN' { + Get-DomainName -DomainName $domainName -Format 'FQDN' | Should -Match $domainName + } + + It 'Should return Forest FQDN' { + Get-DomainName -ForestName $forestName -Format 'FQDN' | Should -Match $forestName + } + + It 'Should return Domain NetbiosName' { + Get-DomainName -DomainName $domainName -Format 'NetbiosName' | Should -Match ($domainName.Split("."))[0] + } + + It 'Should return Forest NetbiosName' { + Get-DomainName -ForestName $forestName -Format 'NetbiosName' | Should -Match ($forestName.Split("."))[0] + } + + It 'Should return Domain DistinguishedName' { + Get-DomainName -DomainName $domainName -Format 'DistinguishedName' | Should -Match $domainDistinguished + } + + It 'Should return Forest DistinguishedName' { + Get-DomainName -ForestName $forestName -Format 'DistinguishedName' | Should -Match $forestDistinguished + } +} + +Describe 'Get-DomainFQDN' { + # Test parameter validity -OutputPath + It 'Should return $env:USERDNSDOMAIN' { + Get-DomainFQDN | Should -Match $env:USERDNSDOMAIN + } +} + +Describe 'Get-ForestFQDN' { + # Test parameter validity -OutputPath + It 'Should return $null' { + Get-ForestFQDN | Should -BeNullOrEmpty + } +} + +Describe 'Get-NetbiosName' { + # Test parameter validity -OutputPath + It 'Should test 2 parts and return Domain' { + Get-NetbiosName -FQDN $domainName | Should -Match ($domainName.Split("."))[0] + } + + It 'Should test 1 part and return Domain' { + Get-NetbiosName -FQDN "Domain" | Should -Match ($domainName.Split("."))[0] + } +} + +Describe 'Get-DistinguishedName' { + # Test parameter validity -OutputPath + It 'Should test 1 part and return "DC=Domain"' { + Get-DistinguishedName -FQDN "Domain" | Should -Match $domainDistinguishedPart1 + } + + It 'Should test 2 parts and return "DC=Domain,DC=Test"' { + Get-DistinguishedName -FQDN $domainName | Should -Match $domainDistinguishedPart2 + } +} + +Describe 'Format-DistinguishedName' { + # Test parameter validity -OutputPath + It 'Should test 2 parts and return "DC=Domain"' { + Format-DistinguishedName -Parts "Domain" | Should -Match $domainDistinguishedPart1 + } + + It 'Should test 1 part and return "DC=Domain,DC=Test"' { + Format-DistinguishedName -Parts $parts | Should -Match $domainDistinguishedPart2 + } +} + +Describe 'Get-DomainParts' { + # Test parameter validity -OutputPath + It 'Should split the FQDN' { + Get-DomainParts -FQDN $domainName | Should -eq $parts + } +} diff --git a/Tests/Unit/Module/STIG.PowerStigXml.tests.ps1 b/Tests/Unit/Module/STIG.PowerStigXml.tests.ps1 new file mode 100644 index 000000000..72dda172b --- /dev/null +++ b/Tests/Unit/Module/STIG.PowerStigXml.tests.ps1 @@ -0,0 +1,42 @@ +#region Header +. $PSScriptRoot\.tests.header.ps1 +#endregion + +$xccdfs = (Get-ChildItem -Path $script:moduleRoot\StigData\Archive -Include *xccdf.xml -Recurse | Where-Object -Property Name -Match "Server_2019_MS|IIS_10-0_Server")[1,3] +foreach ($xccdf in $xccdfs) +{ + Describe "ConvertTo-PowerStigXml $($xccdf.name)" { + + It 'Should return an 2 XML' { + ConvertTo-PowerStigXml -Path $xccdf.FullName -Destination $TestDrive -CreateOrgSettingsFile -RuleIdFilter $randomId + $converted = Get-ChildItem -Path $testdrive + $converted.FullName.EndsWith(".xml").Count | Should -Be 2 + } + } +} + +Describe 'Compare-PowerStigXml' { + + $dotNetSTIGS = (Get-ChildItem -Path $script:moduleRoot\StigData\Processed -Recurse | Where-Object -Property Name -Match "(DotNetFramework-4-.*\d.xml)").FullName + It 'Should return a PSObject' { + $compare = Compare-PowerStigXml -OldStigPath $dotNetSTIGS[0] -NewStigPath $dotNetSTIGS[1] + $compare.GetType().ToString() | Should -Be "System.Object[]" + } +} + +Describe 'Get-BaseRulePropertyName' { + + It 'Should return 11 base rule types' { + $baseRulePropertyName = Get-BaseRulePropertyName + $baseRulePropertyName.Count | Should -Be 11 + } +} + +Describe 'Get-DynamicParameterRuleTypeName' { + + Get-BaseRulePropertyName + It 'Should return a runtime defined parameter dictionary' { + $dynamicParameterRuleTypeName = Get-DynamicParameterRuleTypeName + $dynamicParameterRuleTypeName.GetType().ToString() | Should -Be "System.Management.Automation.RuntimeDefinedParameterDictionary" + } +} diff --git a/Tests/Unit/Module/VsphereNtpSettingsRule.tests.ps1 b/Tests/Unit/Module/VsphereNtpSettingsRule.tests.ps1 new file mode 100644 index 000000000..39e9c39dc --- /dev/null +++ b/Tests/Unit/Module/VsphereNtpSettingsRule.tests.ps1 @@ -0,0 +1,38 @@ +#region Header +. $PSScriptRoot\.tests.header.ps1 +#endregion + +try +{ + InModuleScope -ModuleName "$($global:moduleName).Convert" { + #region Test Setup + $testRuleList = @( + @{ + NtpServer = $null + OrganizationValueRequired = $true + OrganizationValueTestString = "{0} is set to a string array of authoritative DoD time sources" + CheckContent = 'From the vSphere Web Client select the ESXi Host and go to Configure >> System >> Time Configuration. Click Edit to verify the configured NTP servers and service startup policy. + + or + + From a PowerCLI command prompt while connected to the ESXi host run the following command: + + Get-VMHost | Get-VMHostNTPServer + Get-VMHost | Get-VMHostService | Where {$_.Label -eq "NTP Daemon"} + + If the NTP service is not configured with authoritative DoD time sources and the service is not configured to start and stop with the host and is running, this is a finding.' + + } + ) + #endregion + + foreach ($testRule in $testRuleList) + { + . $PSScriptRoot\Convert.CommonTests.ps1 + } + } +} +finally +{ + . $PSScriptRoot\.tests.footer.ps1 +} diff --git a/Tests/Unit/Module/WebConfigurationPropertyRule.tests.ps1 b/Tests/Unit/Module/WebConfigurationPropertyRule.tests.ps1 index 3414be875..add7a8674 100644 --- a/Tests/Unit/Module/WebConfigurationPropertyRule.tests.ps1 +++ b/Tests/Unit/Module/WebConfigurationPropertyRule.tests.ps1 @@ -70,8 +70,162 @@ try Click “Edit Feature Settings” in the "Actions" pane. If the "maxUrl" value is not set to "4096" or less, this is a finding.' + }, + @{ + ConfigSection = '/system.web/trust' + Key = 'level' + Value = '' + OrganizationValueRequired = $true + OrganizationValueTestString = "'{0}' -cmatch '^(Full|High)$'" + CheckContent = 'Note: If the server being reviewed is a non-production website, this is Not Applicable. + + Follow the procedures below for each site hosted on the IIS 10.0 web server: + + Open the IIS 10.0 Manager. + + Click the site name under review. + + Double-click the ".NET Trust Level" icon. + + If the ".NET Trust Level" is not set to Full or less, this is a finding.' + }, + @{ + ConfigSection = '/system.web/compilation' + Key = 'debug' + Value = 'false' + OrganizationValueRequired = $false + CheckContent = 'Note: If the ".NET feature" is not installed, this check is Not Applicable. + + Follow the procedures below for each site hosted on the IIS 10.0 web server: + + Open the IIS 10.0 Manager. + + Click the site name under review. + + Double-click ".NET Compilation". + + Scroll down to the "Behavior" section and verify the value for "Debug" is set to "False". + + If the "Debug" value is not set to "False", this is a finding.' + }, + @{ + ConfigSection = '/system.webServer/security/requestFiltering' + Key = 'allowHighBitCharacters' + Value = 'false' + OrganizationValueRequired = $false + CheckContent = 'Follow the procedures below for each site hosted on the IIS 10.0 web server: + + Open the IIS 10.0 Manager. + + Click the site name. + + Double-click the "Request Filtering" icon. + + Click "Edit Feature Settings" in the "Actions" pane. + + If the "Allow high-bit characters" check box is checked, this is a finding. + + Note: If this IIS 10.0 installation is supporting Microsoft Exchange, and not otherwise hosting any content, this requirement is Not Applicable.' + }, + @{ + ConfigSection = '/system.webServer/security/requestFiltering/fileExtensions' + Key = 'allowUnlisted' + Value = 'false' + OrganizationValueRequired = $false + CheckContent = 'Follow the procedures below for each site hosted on the IIS 10.0 web server: + + Open the IIS 10.0 Manager. + + Click the site name. + + Double-click the "Request Filtering" icon. + + Click "Edit Feature Settings" in the "Actions" pane. + + If the "Allow unlisted file name extensions" check box is checked, this is a finding. + + Note: If this IIS 10.0 installation is supporting Microsoft Exchange, and not otherwise hosting any content, this requirement is Not Applicable.' + }, + @{ + ConfigSection = '/system.webServer/httpErrors' + Key = 'errormode' + Value = 'DetailedLocalOnly' + OrganizationValueRequired = $false + CheckContent = 'Follow the procedures below for each site hosted on the IIS 10.0 web server: + + Open the IIS 10.0 Manager. + + Click the site name under review. + + Double-click the "Error Pages" icon. + + Click each error message and click "Edit Feature" setting from the "Actions" pane. + + If any error message is not set to "Detailed errors for local requests and custom error pages for remote requests", this is a finding.' + }, + @{ + ConfigSection = '/system.webServer/asp/session' + Key = 'keepSessionIdSecure' + Value = 'True' + OrganizationValueRequired = $false + CheckContent = 'Follow the procedures below for each site hosted on the IIS 10.0 web server: + + Access the IIS 10.0 Manager. + + Select the website being reviewed. + + Under "Management" section, double-click the "Configuration Editor" icon. + + From the "Section:" drop-down list, select "system.webServer/asp". + + Expand the "session" section. + + Verify the "keepSessionIdSecure" is set to "True". + + If the "keepSessionIdSecure" is not set to "True", this is a finding.' + }, + @{ + ConfigSection = '/system.web/sessionState' + Key = 'cookieless' + Value = 'UseCookies' + OrganizationValueRequired = $false + CheckContent = 'Follow the procedures below for each site hosted on the IIS 10.0 web server: + + Open the IIS 10.0 Manager. + + Click the site name. + + Under the "ASP.NET" section, select "Session State". + + Under "Cookie Settings", verify the "Use Cookies" mode is selected from the "Mode:" drop-down list. + + If the "Use Cookies" mode is selected, this is not a finding. + + Alternative method: + + Click the site name. + + Select "Configuration Editor" under the "Management" section. + + From the "Section:" drop-down list at the top of the configuration editor, locate "system.web/sessionState". + + Verify the "cookieless" is set to "UseCookies". + + If the "cookieless" is not set to "UseCookies", this is a finding. + + Note: If IIS 10.0 server/site is used only for system-to-system maintenance, does not allow users to connect to interface, and is restricted to specific system IPs, this is Not Applicable.' + }, + @{ + ConfigSection = $null + Key = $null + Value = $null + OrganizationValueRequired = $false + CheckContent = 'Follow the procedures below for each site hosted on the IIS 10.0 web server: + + Open the IIS 10.0 Manager. + + Click the site name.' } - # TODO There are many switch options in Get-ConfigSection that are not tested in Test data ) #endregion @@ -101,6 +255,32 @@ try Verify the "compressionEnabled" is set to "False". If both the "system.web/httpCookies:require SSL" is set to "True" and the "system.web/sessionState:compressionEnabled" is set to "False", this is not a finding.' + }, + @{ + Count = 2 + CheckContent = 'Open the IIS 8.5 Manager. + + Click the IIS 8.5 web server name. + + Double-click the "ISAPI and CGI restrictions" icon. + + Click “Edit Feature Settings". + + Verify the "Allow unspecified CGI modules" and the "Allow unspecified ISAPI modules" check boxes are NOT checked. + + If either or both of the "Allow unspecified CGI modules" and the "Allow unspecified ISAPI modules" check boxes are checked, this is a finding.' + }, + @{ + Count = 2 + CheckContent = 'Open the IIS 8.5 Manager. + + Click the IIS 8.5 web server name. + + Double-click the "Machine Key" icon in the website Home Pane. + + Verify "HMACSHA256" is selected for the Validation method and "Auto" is selected for the Encryption method. + + If "HMACSHA256" is not selected for the Validation method and/or "Auto" is not selected for the Encryption method, this is a finding.' } ) foreach ($testRule in $testRuleList) diff --git a/source/Module/Rule.AuditSetting/Convert/AuditSettingRule.Convert.psm1 b/source/Module/Rule.AuditSetting/Convert/AuditSettingRule.Convert.psm1 index 24751fdf4..2b41c46f7 100644 --- a/source/Module/Rule.AuditSetting/Convert/AuditSettingRule.Convert.psm1 +++ b/source/Module/Rule.AuditSetting/Convert/AuditSettingRule.Convert.psm1 @@ -2,14 +2,6 @@ # Licensed under the MIT License. using module .\..\..\Common\Common.psm1 using module .\..\AuditSettingRule.psm1 - -$exclude = @($MyInvocation.MyCommand.Name,'Template.*.txt') -$supportFileList = Get-ChildItem -Path $PSScriptRoot -Exclude $exclude -foreach ($supportFile in $supportFileList) -{ - Write-Verbose "Loading $($supportFile.FullName)" - . $supportFile.FullName -} # Header <# diff --git a/source/Module/Rule.DnsServerRootHint/Convert/DnsServerRootHintRule.Convert.psm1 b/source/Module/Rule.DnsServerRootHint/Convert/DnsServerRootHintRule.Convert.psm1 index f788d4d30..c4daa5ac3 100644 --- a/source/Module/Rule.DnsServerRootHint/Convert/DnsServerRootHintRule.Convert.psm1 +++ b/source/Module/Rule.DnsServerRootHint/Convert/DnsServerRootHintRule.Convert.psm1 @@ -2,14 +2,6 @@ # Licensed under the MIT License. using module .\..\..\Common\Common.psm1 using module .\..\DnsServerRootHintRule.psm1 - -$exclude = @($MyInvocation.MyCommand.Name,'Template.*.txt') -$supportFileList = Get-ChildItem -Path $PSScriptRoot -File -Exclude $exclude -foreach ($supportFile in $supportFileList) -{ - Write-Verbose "Loading $($supportFile.FullName)" - . $supportFile.FullName -} # Header <# diff --git a/source/Module/Rule.Document/Convert/DocumentRule.Convert.psm1 b/source/Module/Rule.Document/Convert/DocumentRule.Convert.psm1 index b30c15c48..6510aee3e 100644 --- a/source/Module/Rule.Document/Convert/DocumentRule.Convert.psm1 +++ b/source/Module/Rule.Document/Convert/DocumentRule.Convert.psm1 @@ -2,14 +2,6 @@ # Licensed under the MIT License. using module .\..\..\Common\Common.psm1 using module .\..\DocumentRule.psm1 - -$exclude = @($MyInvocation.MyCommand.Name,'Template.*.txt') -$supportFileList = Get-ChildItem -Path $PSScriptRoot -Exclude $exclude -foreach ($supportFile in $supportFileList) -{ - Write-Verbose "Loading $($supportFile.FullName)" - . $supportFile.FullName -} # Header <# diff --git a/source/Module/Rule.Manual/Convert/ManualRule.Convert.psm1 b/source/Module/Rule.Manual/Convert/ManualRule.Convert.psm1 index d16c811e0..2e1897b10 100644 --- a/source/Module/Rule.Manual/Convert/ManualRule.Convert.psm1 +++ b/source/Module/Rule.Manual/Convert/ManualRule.Convert.psm1 @@ -2,14 +2,6 @@ # Licensed under the MIT License. using module .\..\..\Common\Common.psm1 using module .\..\ManualRule.psm1 - -$exclude = @($MyInvocation.MyCommand.Name,'Template.*.txt') -$supportFileList = Get-ChildItem -Path $PSScriptRoot -Exclude $exclude -foreach ($supportFile in $supportFileList) -{ - Write-Verbose "Loading $($supportFile.FullName)" - . $supportFile.FullName -} # Header <# diff --git a/source/Module/Rule.VsphereNtpSettings/Convert/Methods.ps1 b/source/Module/Rule.VsphereNtpSettings/Convert/Methods.ps1 index d55374424..975756b8c 100644 --- a/source/Module/Rule.VsphereNtpSettings/Convert/Methods.ps1 +++ b/source/Module/Rule.VsphereNtpSettings/Convert/Methods.ps1 @@ -47,15 +47,15 @@ function Get-VsphereNtpSettings function Get-VsphereNtpSettingsOrganizationValueTestString { [CmdletBinding()] - [OutputType([string])] + [OutputType([object])] param ( [Parameter(Mandatory = $true)] - [string] - $Id + [psobject] + $CheckContent ) - if ($this.id -match "V-94039") + if ($CheckContent -match 'NTP service is not configured with authoritative DoD time sources') { return '{0} is set to a string array of authoritative DoD time sources' } diff --git a/source/Module/Rule.VsphereNtpSettings/Convert/VsphereNtpSettingsRule.Convert.psm1 b/source/Module/Rule.VsphereNtpSettings/Convert/VsphereNtpSettingsRule.Convert.psm1 index 2e787b386..f09cef0de 100644 --- a/source/Module/Rule.VsphereNtpSettings/Convert/VsphereNtpSettingsRule.Convert.psm1 +++ b/source/Module/Rule.VsphereNtpSettings/Convert/VsphereNtpSettingsRule.Convert.psm1 @@ -73,7 +73,7 @@ class VsphereNtpSettingsRuleConvert : VsphereNtpSettingsRule #> [void] SetOrganizationValueTestString () { - $OrganizationValueTestString = Get-VsphereNtpSettingsOrganizationValueTestString -Id $this.id + $OrganizationValueTestString = Get-VsphereNtpSettingsOrganizationValueTestString -CheckContent $this.SplitCheckContent if (-not $this.SetStatus($OrganizationValueTestString)) { diff --git a/source/StigData/Processed/IISServer-8.5-1.10.xml b/source/StigData/Processed/IISServer-8.5-1.10.xml index 749b25008..82db8f3fd 100644 --- a/source/StigData/Processed/IISServer-8.5-1.10.xml +++ b/source/StigData/Processed/IISServer-8.5-1.10.xml @@ -76,7 +76,7 @@ Note: If additional software is needed supporting documentation must be signed b False False - Obtain a list of the user accounts with access to the system, including all local and domain accounts. + Obtain a list of the user accounts with access to the system, including all local and domain accounts. Review the privileges to the web server for each account. @@ -114,7 +114,7 @@ Access an administrator command prompt and type "regedit <enter>" to acces Navigate to HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\ContentIndex\Catalogs\. -If this key exists, then indexing is enabled. +If this key exists, then indexing is enabled. If the key does not exist, this check is Not Applicable. @@ -289,7 +289,7 @@ Verify, at a minimum, the following tuning settings in the registry. Access the IIS 8.5 web server registry. -Verify the following keys are present and configured. The required setting depends upon the requirements of the application. +Verify the following keys are present and configured. The required setting depends upon the requirements of the application. Recommended settings are not provided as these settings have to be explicitly configured to show a conscientious tuning has been made. @@ -715,7 +715,7 @@ Access Apps menu. Under Administrative Tools, select Computer Management. In left pane, expand "Local Users and Groups" and click on "Users". -Review the local users listed in the middle pane. +Review the local users listed in the middle pane. If any local accounts are present and are used by IIS 8.5 verify with System Administrator that default passwords have been changed.